private void FindDynamicRoad(uint visited, uint previous) { uint nextVisited = visited + McMath.Power2(previous); Status.Transition tempTransition = null; foreach (Status.Transition transition in status.transitions) { if (transition.visited == nextVisited && transition.previous == previous) { if (tempTransition == null) { tempTransition = transition; } else if (transition.distance < tempTransition.distance) { tempTransition = transition; } } } if (tempTransition != null) { bestRoad.Add(tempTransition.destination); FindDynamicRoad(nextVisited, tempTransition.destination); } }
private void GenerateStatusList(uint size) { uint[,] state = new uint[size, McMath.Power2(size) - 1]; for (int i = 0; i < size; i++) { for (int j = 0; j < McMath.Power2(size) - 1; j++) { state[i, j] = uint.MaxValue; } } roadLengths = state; }
public uint TravellingSalesmanDynamicProgrammingRecursion(uint previous, uint visited, Status status) { // Czy następny sprawdzany wierzchołek jest ostatnim? if (visited == McMath.Power2((uint)Math.Sqrt(graphArray.Length)) - 1) { // Jeśli tak to zwracamy drogę od ostatniego do pierwszego return(graphArray[previous, 0]); } // Sprawdza czy obliczyliśmy już drogę przy pomocy tych wierzchołków if (status.roadLengths[previous, visited] != uint.MaxValue) { // Jeśli tak to zwraca jej koszt return(status.roadLengths[previous, visited]); } // Pętla przechodzi przez wszystkie wierzchołkie w grafie for (uint i = 0; i < Math.Sqrt(graphArray.Length); i++) { // Czy następny sprawdzany wierzchołek jest poprzednim || Czy następny sprawdzany wierzchołek był już wcześniej uwzględniany if (i == previous || 0 != (visited & (McMath.Power2(i)))) { // Jeśli tak to pomijamy ponowe obliczanie dorgi do niego continue; } // McMath.Power2(i) | visited - poprzednie sprawdzane wierzchołki + akutalnie sprawdzany uint newVisited = McMath.Power2(i) | visited; // Obliczamy koszt nowej drogi od ostatniego wierzchołka do następnego badanego + następne uint distance = graphArray[previous, i] + TravellingSalesmanDynamicProgrammingRecursion(i, newVisited, status); // Sprawdza czy koszt nowej drogi jest lepszy od najlepszej poprzedniej if (distance < status.roadLengths[previous, visited]) { // Jeśli tak to podmieniamy poprzedni koszt ta nowy lepszy (mniejszy) status.transitions.Add(new Status.Transition(previous, i, visited, distance)); status.roadLengths[previous, visited] = distance; } } // Zwraca koszt drogi prowadzącej przez visited od previous return(status.roadLengths[previous, visited]); }