// 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) }
// 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 }
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 }
// 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 }