private void Run() { // create a complete graph and run Kruskal with maximum degree constraint 2 CompleteGraph graph = new CompleteGraph(Nodes.Count, Directedness.Undirected); Func <Arc, double> arcCost = (arc => Cost(Nodes[graph.GetNodeIndex(graph.U(arc))], Nodes[graph.GetNodeIndex(graph.V(arc))])); Kruskal <double> kruskal = new Kruskal <double>(graph, arcCost, _ => 2); kruskal.Run(); Dictionary <Node, Arc> firstArc = new Dictionary <Node, Arc>(); Dictionary <Node, Arc> secondArc = new Dictionary <Node, Arc>(); foreach (var arc in kruskal.Forest) { var u = graph.U(arc); (firstArc.ContainsKey(u) ? secondArc : firstArc)[u] = arc; var v = graph.V(arc); (firstArc.ContainsKey(v) ? secondArc : firstArc)[v] = arc; } foreach (var startNode in graph.Nodes()) { if (kruskal.Degree[startNode] == 1) { Arc prevArc = Arc.Invalid; Node n = startNode; while (true) { tour.Add(Nodes[graph.GetNodeIndex(n)]); if (prevArc != Arc.Invalid && kruskal.Degree[n] == 1) { break; } Arc arc1 = firstArc[n]; prevArc = (arc1 != prevArc ? arc1 : secondArc[n]); n = graph.Other(prevArc, n); } tour.Add(Nodes[graph.GetNodeIndex(startNode)]); break; } } TourCost = TspUtils.GetTourCost(tour, Cost); }
private void Run() { CompleteGraph graph = new CompleteGraph(Nodes.Count, Directedness.Undirected); Func <Arc, double> cost = (Arc arc) => Cost(Nodes[graph.GetNodeIndex(graph.U(arc))], Nodes[graph.GetNodeIndex(graph.V(arc))]); Kruskal <double> kruskal = new Kruskal <double>(graph, cost, (Node _) => 2); kruskal.Run(); Dictionary <Node, Arc> dictionary = new Dictionary <Node, Arc>(); Dictionary <Node, Arc> dictionary2 = new Dictionary <Node, Arc>(); foreach (Arc item in kruskal.Forest) { Node key = graph.U(item); ((!dictionary.ContainsKey(key)) ? dictionary : dictionary2)[key] = item; Node key2 = graph.V(item); ((!dictionary.ContainsKey(key2)) ? dictionary : dictionary2)[key2] = item; } foreach (Node item2 in graph.Nodes()) { if (kruskal.Degree[item2] == 1) { Arc arc2 = Arc.Invalid; Node node = item2; while (true) { tour.Add(Nodes[graph.GetNodeIndex(node)]); if (arc2 != Arc.Invalid && kruskal.Degree[node] == 1) { break; } Arc arc3 = dictionary[node]; arc2 = ((!(arc3 != arc2)) ? dictionary2[node] : arc3); node = graph.Other(arc2, node); } tour.Add(Nodes[graph.GetNodeIndex(item2)]); break; } } TourCost = TspUtils.GetTourCost <TNode>((IEnumerable <TNode>)tour, Cost); }
/// Initializes the 2-OPT optimizer with the supplied tour. /// \param cost The cost function (should be symmetrical). /// \param tour The tour to improve with 2-OPT. The starting node must be repeated at the end. /// \param tourCost The known cost of \c tour. Use this parameter to speed up initialization. /// If \c null is supplied, then the tour cost is recalculated. public Opt2Tsp(Func <TNode, TNode, double> cost, IEnumerable <TNode> tour, double?tourCost) { Cost = cost; this.tour = tour.ToList(); TourCost = tourCost ?? TspUtils.GetTourCost(tour, cost); }
public Opt2Tsp(Func <TNode, TNode, double> cost, IEnumerable <TNode> tour, double?tourCost) { Cost = cost; this.tour = Enumerable.ToList <TNode>(tour); TourCost = ((!tourCost.HasValue) ? TspUtils.GetTourCost <TNode>(tour, cost) : tourCost.Value); }