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]);
        }