Example #1
0
// GenTrialSolutions generates (initial) trial solutions
func GenTrialSolutions(sols []*Solution, prms *Parameters) {

	// floats
	n := len(sols) // cannot use Nsol here because subsets of Solutions may be provided; e.g. parallel code
	if prms.Nflt > 0 {

		// interior points
		switch prms.GenType {
		case "latin":
			K := rnd.LatinIHS(prms.Nflt, n, prms.LatinDup)
			for i := 0; i < n; i++ {
				for j := 0; j < prms.Nflt; j++ {
					sols[i].Flt[j] = prms.FltMin[j] + float64(K[j][i]-1)*prms.DelFlt[j]/float64(n-1)
				}
			}
		case "halton":
			H := rnd.HaltonPoints(prms.Nflt, n)
			for i := 0; i < n; i++ {
				for j := 0; j < prms.Nflt; j++ {
					sols[i].Flt[j] = prms.FltMin[j] + H[j][i]*prms.DelFlt[j]
				}
			}
		default:
			for i := 0; i < n; i++ {
				for j := 0; j < prms.Nflt; j++ {
					sols[i].Flt[j] = rnd.Float64(prms.FltMin[j], prms.FltMax[j])
				}
			}
		}

		// extra points
		if prms.UseMesh {
			initX := func(isol int) {
				for k := 0; k < prms.Nflt; k++ {
					sols[isol].Flt[k] = (prms.FltMin[k] + prms.FltMax[k]) / 2.0
				}
			}
			isol := prms.Nsol - prms.NumExtraSols
			for i := 0; i < prms.Nflt-1; i++ {
				for j := i + 1; j < prms.Nflt; j++ {
					// (min,min) corner
					initX(isol)
					sols[isol].Flt[i] = prms.FltMin[i]
					sols[isol].Flt[j] = prms.FltMin[j]
					sols[isol].Fixed = true
					isol++
					// (min,max) corner
					initX(isol)
					sols[isol].Flt[i] = prms.FltMin[i]
					sols[isol].Flt[j] = prms.FltMax[j]
					sols[isol].Fixed = true
					isol++
					// (max,max) corner
					initX(isol)
					sols[isol].Flt[i] = prms.FltMax[i]
					sols[isol].Flt[j] = prms.FltMax[j]
					sols[isol].Fixed = true
					isol++
					// (max,min) corner
					initX(isol)
					sols[isol].Flt[i] = prms.FltMax[i]
					sols[isol].Flt[j] = prms.FltMin[j]
					sols[isol].Fixed = true
					isol++
					// Xi-min middle points
					ndelta := float64(prms.Nbry - 1)
					for m := 0; m < prms.Nbry-2; m++ {
						initX(isol)
						sols[isol].Flt[i] = prms.FltMin[i]
						sols[isol].Flt[j] = prms.FltMin[j] + float64(m+1)*prms.DelFlt[j]/ndelta
						sols[isol].Fixed = true
						isol++
					}
					// Xi-max middle points
					for m := 0; m < prms.Nbry-2; m++ {
						initX(isol)
						sols[isol].Flt[i] = prms.FltMax[i]
						sols[isol].Flt[j] = prms.FltMin[j] + float64(m+1)*prms.DelFlt[j]/ndelta
						sols[isol].Fixed = true
						isol++
					}
					// Xj-min middle points
					for m := 0; m < prms.Nbry-2; m++ {
						initX(isol)
						sols[isol].Flt[i] = prms.FltMin[i] + float64(m+1)*prms.DelFlt[i]/ndelta
						sols[isol].Flt[j] = prms.FltMin[j]
						sols[isol].Fixed = true
						isol++
					}
					// Xj-max middle points
					for m := 0; m < prms.Nbry-2; m++ {
						initX(isol)
						sols[isol].Flt[i] = prms.FltMin[i] + float64(m+1)*prms.DelFlt[i]/ndelta
						sols[isol].Flt[j] = prms.FltMax[j]
						sols[isol].Fixed = true
						isol++
					}
				}
			}
			chk.IntAssert(isol, prms.Nsol)
		}
	}

	// skip if there are no ints
	if prms.Nint < 2 {
		return
	}

	// binary numbers
	if prms.BinInt > 0 {
		for i := 0; i < n; i++ {
			for j := 0; j < prms.Nint; j++ {
				if rnd.FlipCoin(0.5) {
					sols[i].Int[j] = 1
				} else {
					sols[i].Int[j] = 0
				}
			}
		}
		return
	}

	// general integers
	L := rnd.LatinIHS(prms.Nint, n, prms.LatinDup)
	for i := 0; i < n; i++ {
		for j := 0; j < prms.Nint; j++ {
			sols[i].Int[j] = prms.IntMin[j] + (L[j][i]-1)*prms.DelInt[j]/(n-1)
		}
	}
}
Example #2
0
// PopFltGen generates a population of individuals with float point numbers
// Notes: (1) ngenes = len(C.RangeFlt)
func PopFltGen(id int, C *ConfParams) Population {
	o := make([]*Individual, C.Ninds)
	ngenes := len(C.RangeFlt)
	for i := 0; i < C.Ninds; i++ {
		o[i] = NewIndividual(C.Nova, C.Noor, C.Nbases, make([]float64, ngenes))
	}
	if C.Latin {
		K := rnd.LatinIHS(ngenes, C.Ninds, C.LatinDf)
		dx := make([]float64, ngenes)
		for i := 0; i < ngenes; i++ {
			dx[i] = (C.RangeFlt[i][1] - C.RangeFlt[i][0]) / float64(C.Ninds-1)
		}
		for i := 0; i < ngenes; i++ {
			for j := 0; j < C.Ninds; j++ {
				o[j].SetFloat(i, C.RangeFlt[i][0]+float64(K[i][j]-1)*dx[i])
			}
		}
		return o
	}
	npts := int(math.Pow(float64(C.Ninds), 1.0/float64(ngenes))) // num points in 'square' grid
	ntot := int(math.Pow(float64(npts), float64(ngenes)))        // total num of individuals in grid
	den := 1.0                                                   // denominator to calculate dx
	if npts > 1 {
		den = float64(npts - 1)
	}
	var lfto int // leftover, e.g. n % (nx*ny)
	var rdim int // reduced dimension, e.g. (nx*ny)
	var idx int  // index of gene in grid
	var dx, x, mul, xmin, xmax float64
	for i := 0; i < C.Ninds; i++ {
		if i < ntot { // on grid
			lfto = i
			for j := 0; j < ngenes; j++ {
				rdim = int(math.Pow(float64(npts), float64(ngenes-1-j)))
				idx = lfto / rdim
				lfto = lfto % rdim
				xmin = C.RangeFlt[j][0]
				xmax = C.RangeFlt[j][1]
				dx = xmax - xmin
				x = xmin + float64(idx+id)*dx/den
				if C.Noise > 0 {
					mul = rnd.Float64(0, C.Noise)
					if rnd.FlipCoin(0.5) {
						x += mul * x
					} else {
						x -= mul * x
					}
				}
				if x < xmin {
					x = xmin + (xmin - x)
				}
				if x > xmax {
					x = xmax - (x - xmax)
				}
				o[i].SetFloat(j, x)
			}
		} else { // additional individuals
			for j := 0; j < ngenes; j++ {
				xmin = C.RangeFlt[j][0]
				xmax = C.RangeFlt[j][1]
				x = rnd.Float64(xmin, xmax)
				o[i].SetFloat(j, x)
			}
		}
	}
	return o
}