public static TSPSolution GetNew(TSPSolution parent1, TSPSolution parent2) { PermutationStandard ps1 = new PermutationStandard(parent1); PermutationStandard ps2 = new PermutationStandard(parent2); PermutationStandard tmp = new PermutationStandard(parent2); // Keep track of elements, which have not been moved yet List <bool> moved = new List <bool>(tmp.size); for (int i = 0; i < tmp.size; ++i) { moved.Add(false); } // starting point of the cycle - first unmoved element moved[0] = true; while (moved.Contains(false)) { Cycle cycle = new Cycle(); int start = moved.IndexOf(false); // find the cycle while (!cycle.IsComplete()) { int through = ps2.perm[start]; int to = 0; for (int i = 0; i < ps1.perm.Length; ++i) { if (ps1.perm[i] == through) { to = i; } } cycle.Add(start, to); start = to; } // elements from ps1 where the cycle goes foreach (var startingPoint in cycle.GetStartingPoints()) { tmp.perm[startingPoint] = ps1.perm[startingPoint]; moved[startingPoint] = true; } // swap ps1 and ps2 var swap = ps1; ps1 = ps2; ps2 = swap; } return(tmp.convertToTSPSol()); }
private void BuildSCCs(Node start, Stack <Node> dfsStack, Stack <Node> sccStack, ref int depth, ref int workCount, CancellationToken cancel) { if ((bool)start.Marks[EnqueuedMark] == true) { return; } sccStack.Push(start); dfsStack.Push(start); start.Marks[EnqueuedMark] = true; start.Marks[OrderMark] = depth; start.Marks[SCCMark] = depth; start.Marks[NextMark] = start.Provides.GetEnumerator(); ++depth; IEnumerator <EndPoint> it; while (dfsStack.Count > 0) { if (workCount % CancelFreq == 0) { workCount = 1; if (cancel.IsCancellationRequested) { return; } } else { ++workCount; } var n = dfsStack.Peek(); it = (IEnumerator <EndPoint>)n.Marks[NextMark]; if (it.MoveNext()) { var m = (Node)it.Current.Target; if ((bool)m.Marks[EnqueuedMark] == true) { if (m.Marks[NextMark] != null) { n.Marks[SCCMark] = Math.Min((int)n.Marks[SCCMark], (int)m.Marks[OrderMark]); } } else { dfsStack.Push(m); sccStack.Push(m); m.Marks[EnqueuedMark] = true; m.Marks[OrderMark] = depth; m.Marks[SCCMark] = depth; m.Marks[NextMark] = m.Provides.GetEnumerator(); ++depth; } } else { dfsStack.Pop(); foreach (var ep in n.Provides) { var m = (Node)ep.Target; if (m.Marks[NextMark] != null) { n.Marks[SCCMark] = Math.Min((int)n.Marks[SCCMark], (int)m.Marks[SCCMark]); } } if ((int)n.Marks[OrderMark] == (int)n.Marks[SCCMark]) { Node m; if (n.HasLoop || sccStack.Peek() != n) { var cycle = new Cycle(this); sccs.Add(cycle); do { m = sccStack.Pop(); cycle.Add(m); m.Marks[NextMark] = null; Contract.Assert((int)m.Marks[SCCMark] >= (int)n.Marks[SCCMark]); }while (m != n); } else { m = sccStack.Pop(); Contract.Assert(n == m); m.Marks[NextMark] = null; sccs.Add(m); } } } } }