public override int[] GetPath(int n, IMeasure measure) { var baseState = new GenerationState { C = new double[n,n], Edges = new List<Edge>(n), N = n, VertexSet = new int[n] }; baseState.C = measure.GetMatrix(); for (int i = 0; i < n; i++) { baseState.C[i, i] = Inf; } baseState.J = ReductMatrix(n, baseState.C); for (int i = 0; i < n; i++) { baseState.VertexSet[i] = i; } var queue = new PriorityQueue<GenerationState>((a, b) => -a.J.CompareTo(b.J)); queue.Enqueue(baseState); while (queue.Count > 0) { var current = queue.Dequeue(); if (current.Edges.Count == n - 1) { var result = GetResult(n, current.Edges); return result; } Process(current, queue); } throw new ApplicationException("Path not found"); }
private void Process(GenerationState state, PriorityQueue<GenerationState> queue) { //state.J = ReductMatrix(state.N, state.C); int bestI = 0, bestJ = 0; double bestMax = -1; int n = state.N; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (state.C[i, j] < Eps) { double m = GetMinSum(n, state.C, i, j); if (bestMax < m) { bestMax = m; bestI = i; bestJ = j; } } } } if (state.C[bestI, bestJ] > InfBound) { return; } // get state 1 var stateWithoutEdge = new GenerationState { N = state.N, C = new double[n,n], Edges = state.Edges, VertexSet = state.VertexSet }; Array.Copy(state.C, stateWithoutEdge.C, state.C.Length); stateWithoutEdge.C[bestI, bestJ] = Inf; // TODO: Remove j -> i ?? double r2 = ReductMatrix(n, stateWithoutEdge.C); stateWithoutEdge.J = state.J + r2; // get state 2 var stateWithEdge = new GenerationState { N = state.N, C = new double[n, n], Edges = new List<Edge>(state.Edges), VertexSet = new int[n] }; Array.Copy(state.C, stateWithEdge.C, state.C.Length); for (int i = 0; i < n; i++) { stateWithEdge.C[i, bestJ] = Inf; } for (int j = 0; j < n; j++) { stateWithEdge.C[bestI, j] = Inf; } stateWithEdge.C[bestJ, bestI] = Inf; Array.Copy(state.VertexSet, stateWithEdge.VertexSet, n); int c1 = stateWithEdge.VertexSet[bestI]; int c2 = stateWithEdge.VertexSet[bestJ]; for (int i = 0; i < n; i++) { if (stateWithEdge.VertexSet[i] == c1) { for (int j = 0; j < n; j++) { if (stateWithEdge.VertexSet[j] == c2) { stateWithEdge.C[i, j] = Inf; stateWithEdge.C[j, i] = Inf; } } } } for (int i = 0; i < n; i++) { if (stateWithEdge.VertexSet[i] == c2) { stateWithEdge.VertexSet[i] = c1; } } double r1 = ReductMatrix(n, stateWithEdge.C); stateWithEdge.J = state.J + r1; stateWithEdge.Edges.Add(new Edge(bestI, bestJ)); queue.Enqueue(stateWithEdge); queue.Enqueue(stateWithoutEdge); return; }