예제 #1
0
// Init initialises Munkres' structure
func (o *Munkres) Init(nrow, ncol int) {
	chk.IntAssertLessThan(0, nrow) // nrow > 1
	chk.IntAssertLessThan(0, ncol) // ncol > 1
	o.nrow, o.ncol = nrow, ncol
	o.C = utl.DblsAlloc(o.nrow, o.ncol)
	o.M = make([][]Mask_t, o.nrow)
	for i := 0; i < o.nrow; i++ {
		o.M[i] = make([]Mask_t, o.ncol)
	}
	o.Links = make([]int, o.nrow)
	npath := 2*o.nrow + 1 // TODO: check this
	o.path = utl.IntsAlloc(npath, 2)
	o.row_covered = make([]bool, o.nrow)
	o.col_covered = make([]bool, o.ncol)
}
예제 #2
0
파일: intoperators.go 프로젝트: cpmech/goga
// CxIntOrd performs the crossover in a pair of individuals with integer numbers
// that correspond to a ordered sequence, e.g. for traveling salesman problem
//  Output:
//    a and b -- offspring chromosomes
//  Note: using OX1 method explained in [1] (proposed in [2])
//  References:
//   [1] Larrañaga P, Kuijpers CMH, Murga RH, Inza I and Dizdarevic S. Genetic Algorithms for the
//       Travelling Salesman Problem: A Review of Representations and Operators. Artificial
//       Intelligence Review, 13:129-170; 1999. doi:10.1023/A:1006529012972
//   [2] Davis L. Applying Adaptive Algorithms to Epistatic Domains. Proceedings of International
//       Joint Conference on Artificial Intelligence, 162-164; 1985.
//  Example:
//   data:
//         0 1   2 3 4   5 6 7
//     A = a b | c d e | f g h        size = 8
//     B = b d | f h g | e c a        cuts = [2, 5]
//             ↑       ↑       ↑      ends = [2, 5, 8]
//             2       5       8
//   first step: copy subtours
//     a = . . | f h g | . . .
//     b = . . | c d e | . . .
//   second step: copy unique from subtour's end, position 5
//               start adding here
//                       ↓                           5 6 7   0 1   2 3 4
//     a = d e | f h g | a b c         get from A: | f̶ g̶ h̶ | a b | c d e
//     b = h g | c d e | a b f         get from B: | e̶ c̶ a | b d̶ | f h g
func CxIntOrd(a, b, A, B []int, prms *Parameters) {
	size := len(A)
	if !rnd.FlipCoin(prms.IntPc) || size < 3 {
		for i := 0; i < len(A); i++ {
			a[i], b[i] = A[i], B[i]
		}
		return
	}
	var s, t int
	var cuts []int
	if len(cuts) == 2 {
		s, t = cuts[0], cuts[1]
	} else {
		s = rnd.Int(1, size-2)
		t = rnd.Int(s+1, size-1)
	}
	chk.IntAssertLessThan(s, t)
	acore := B[s:t]
	bcore := A[s:t]
	ncore := t - s
	acorehas := make(map[int]bool) // TODO: check if map can be replaced => improve efficiency
	bcorehas := make(map[int]bool)
	for i := 0; i < ncore; i++ {
		a[s+i] = acore[i]
		b[s+i] = bcore[i]
		acorehas[acore[i]] = true
		bcorehas[bcore[i]] = true
	}
	ja, jb := t, t
	for i := 0; i < size; i++ {
		k := (i + t) % size
		if !acorehas[A[k]] {
			a[ja] = A[k]
			ja++
			if ja == size {
				ja = 0
			}
		}
		if !bcorehas[B[k]] {
			b[jb] = B[k]
			jb++
			if jb == size {
				jb = 0
			}
		}
	}
	return
}
예제 #3
0
func (o *SimpleFltProb) find_best() (x, f, g, h []float64) {
	chk.IntAssertLessThan(0, o.Nfeasible) // 0 < nfeasible
	nx := len(o.C.RangeFlt)
	x = make([]float64, nx)
	f = make([]float64, o.nf)
	g = make([]float64, o.ng)
	h = make([]float64, o.nh)
	copy(x, o.Xbest[0])
	o.Fcn(f, g, h, x)
	for i := 1; i < o.Nfeasible; i++ {
		o.Fcn(o.ff[0], o.gg[0], o.hh[0], o.Xbest[i])
		_, other_dom := utl.DblsParetoMin(f, o.ff[0])
		if other_dom {
			copy(x, o.Xbest[i])
			copy(f, o.ff[0])
			copy(g, o.gg[0])
			copy(h, o.hh[0])
		}
	}
	return
}
예제 #4
0
// Set sets a constraint if it does NOT exist yet.
//  key   -- can be Dof key such as "ux", "uy" or constraint type such as "mpc" or "rigid"
//  extra -- is a keycode-style data. e.g. "!type:incsup2d !alp:30"
//  Notes: 1) the default for key is single point constraint; e.g. "ux", "uy", ...
//         2) hydraulic head can be set with key == "H"
func (o *EssentialBcs) Set(key string, nodes []*Node, fcn fun.Func, extra string) (err error) {

	// len(nod) must be greater than 0
	chk.IntAssertLessThan(0, len(nodes)) // 0 < len(nod)

	// skip nil node
	if nodes[0] == nil {
		return
	}

	// space dimension
	ndim := len(nodes[0].Vert.C)

	// rigid element
	if key == "rigid" {
		a := nodes[0].Dofs
		for i := 1; i < len(nodes); i++ {
			for j, b := range nodes[i].Dofs {
				o.add(key, []int{a[j].Eq, b.Eq}, []float64{1, -1}, &fun.Zero)
			}
		}
		return // success
	}

	// inclined support
	if key == "incsup" {

		// check
		if ndim != 2 {
			return chk.Err("inclined support works only in 2D for now")
		}

		// get data
		var α float64
		if val, found := io.Keycode(extra, "alp"); found {
			α = io.Atof(val) * math.Pi / 180.0
		}
		co, si := math.Cos(α), math.Sin(α)

		// set for all nodes
		for _, nod := range nodes {

			// find existent constraints and deactivate them
			eqx := nod.Dofs[0].Eq
			eqy := nod.Dofs[1].Eq
			for _, eq := range []int{eqx, eqy} {
				for _, idx := range o.Eq2idx[eq] {
					pair := o.BcsTmp[idx]
					if pair.bc.Key != "rigid" {
						pair.bc.Inact = true
					}
				}
			}

			// set constraint
			o.add(key, []int{eqx, eqy}, []float64{co, si}, &fun.Zero)
		}
		return // success
	}

	// hydraulic head
	if key == "hst" {

		// set for all nodes
		for _, nod := range nodes {

			// create function
			// Note: fcn is a shift such that  pl = pl(z) - shift(t)
			d := nod.GetDof("pl")
			if d == nil {
				continue // node doesn't have key. ex: pl in qua8/qua4 elements
			}
			z := nod.Vert.C[1] // 2D
			if ndim == 3 {
				z = nod.Vert.C[2] // 3D
			}
			plVal, _, err := o.HydFcn.Calc(z)
			if err != nil {
				return chk.Err("cannot set hst (hydrostatic) essential boundary condition")
			}
			pl := fun.Add{
				B: 1, Fb: &fun.Cte{C: plVal},
				A: -1, Fa: fcn,
			}

			// set constraint
			o.add_single("pl", d.Eq, &pl)
		}
		return // success
	}

	// single-point constraint
	for _, nod := range nodes {
		d := nod.GetDof(key)
		if d == nil {
			return // success
		}
		o.add_single(key, d.Eq, fcn)
	}

	// success
	return
}