func TestRandInvert(t *testing.T) { a := rand.Perm(8) b := make([]int, 8) copy(b, a) perm.RandInvert(b) flipped := false i, j := 0, 7 for { if j <= i { if !flipped { t.Fail() } return } else if a[i] == b[i] { i++ } else if a[j] == b[j] { j-- } else { if flipped { t.Fail() return } perm.Reverse(b[i : j+1]) flipped = true } } }
func TestReverse(t *testing.T) { slice := rand.Perm(8) rev := make([]int, 8) copy(rev, slice) perm.Reverse(rev) for i, j := 0, 7; i < j; i, j = i+1, j-1 { if slice[i] != rev[j] { t.Fail() } } }
// TwoOpt performs a 2-opt local search for improvement of the gene. The first // edge is selected at random and inversions between all other edges are // evaluated in random order. Even if an improvement is not found, the gene will // be rotated by an uniform-random amount. We use this search as a form of // mutation. func (t *tsp) TwoOpt() { t.once = sync.Once{} perm.Rotate(t.gene, rand.Intn(dim)) for _, i := range rand.Perm(dim) { if i < 2 { continue } a := cities[t.gene[0]] b := cities[t.gene[i-1]] y := cities[t.gene[i]] z := cities[t.gene[dim-1]] before := dist(b, y) + dist(z, a) after := dist(a, y) + dist(z, b) if after < before { perm.Reverse(t.gene[:i]) return } } }