Пример #1
0
        public void SavePath(string outPathFileName, PathDesc pathDesc)
        {
            string outFileDir = Path.GetDirectoryName(outPathFileName);

            if (!Directory.Exists(outFileDir))
            {
                Directory.CreateDirectory(outFileDir);
            }
            string[] items = { pathDesc.Cost.ToString(), string.Join(", ", pathDesc.Path) };
            File.WriteAllLines(outPathFileName, items);
        }
Пример #2
0
        public static void RunAlgorithm(string fileName, int repetitions, bool reportMemoryUsage, string outFileName, string outPathFileName)
        {
            Logger.GetLogger.LogNewFile(fileName);

            Graph graph = new Graph(fileName);

            Logger.GetLogger.LogGraph(graph);

            int  bestCost  = int.MaxValue;
            long bestTime  = long.MaxValue;
            long avgTime   = 0;
            long avgMemory = 0;

            for (int i = 0; i < repetitions; i++)
            {
                Stopwatch sw     = Stopwatch.StartNew();
                PathDesc  result = FindBestCycle(graph, reportMemoryUsage, out long peakMemory);
                sw.Stop();

                long timeMikros = sw.Elapsed.Ticks / (TimeSpan.TicksPerMillisecond / 1000);

                if (reportMemoryUsage)
                {
                    Logger.GetLogger.Log(string.Format("Peak memory use: {0}", peakMemory));
                }

                Logger.GetLogger.LogResult(result.Cost, timeMikros);
                Logger.GetLogger.LogPath(result);

                avgTime   += timeMikros;
                avgMemory += peakMemory;
                if (result.Cost < bestCost)
                {
                    bestCost = result.Cost;
                }
                if (timeMikros < bestTime)
                {
                    bestTime = timeMikros;
                }

                if (i == repetitions - 1)
                {
                    Logger.GetLogger.SavePath(outPathFileName, result);
                }
            }
            avgTime   /= repetitions;
            avgMemory /= repetitions;
            Logger.GetLogger.SaveResults(graph.Name, outFileName, bestCost, bestTime, avgTime, avgMemory, graph.VertexCount);
            Logger.GetLogger.LogFinalResults(bestCost, bestTime, avgTime);
        }
Пример #3
0
 public void LogPath(PathDesc pathDesc)
 {
     Console.WriteLine("Path:");
     Console.WriteLine("Cost: {0}", pathDesc.Cost);
     Console.WriteLine(string.Join(", ", pathDesc.Path));
 }
Пример #4
0
        // Main loop of DP algorithm
        // Note: Start and end vertex is n - 1, not 0
        public static PathDesc FindBestCycle(Graph graph, bool reportMemoryUsage, out long maxBytesMemory)
        {
            maxBytesMemory = 0;
            int n          = graph.VertexCount;
            int cycleStart = graph.VertexCount - 1;

            Solution[] currentSolutions = new Solution[n - 1];

            // Initialization for all paths i-j-cycleStart
            for (int i = 0; i < cycleStart; i++)
            {
                Solution sol = new Solution();
                for (int j = 0; j < i; j++)
                {
                    HashSet <int> vertexSet = new HashSet <int>(new List <int>()
                    {
                        j
                    });
                    List <int> path = new List <int>()
                    {
                        i, j, cycleStart
                    };
                    sol[vertexSet] = new PathDesc(graph[i, j] + graph[j, cycleStart], path);
                }
                for (int j = i + 1; j < cycleStart; j++)
                {
                    HashSet <int> vertexSet = new HashSet <int>(new List <int>()
                    {
                        j
                    });
                    List <int> path = new List <int>()
                    {
                        i, j, cycleStart
                    };
                    sol[vertexSet] = new PathDesc(graph[i, j] + graph[j, cycleStart], path);
                }
                currentSolutions[i] = sol;
            }

            // k == number of edges on each path from the previous iteration
            for (int k = 2; k < n - 1; k++)
            {
                Solution[] nextSolutions = new Solution[n - 1];
                for (int i = 0; i < cycleStart; i++)
                {
                    Solution sol = new Solution();
                    // Iterate over all k-sized subsets of [n - 1]\{i, cycleStart}
                    // (all previously found paths from jm to cycleStart of length k).
                    // i is the start of the longer (k + 1 edges) path.
                    // Find best shorter path jm...cycleStart to join i to.
                    foreach (
                        HashSet <int> vertexSet in CombinationsWithout(cycleStart - 1, k, i))
                    {
                        sol[vertexSet] = FindBestPath(graph, currentSolutions, i, vertexSet);
                    }
                    nextSolutions[i] = sol;
                }
                currentSolutions = nextSolutions;
                if (reportMemoryUsage)
                {
                    var memory = GC.GetTotalMemory(true);
                    if (memory > maxBytesMemory)
                    {
                        maxBytesMemory = memory;
                    }
                }
            }

            // Get the final solution - join cycleStart to best (n - 1)-sized
            // jm...cycleStart path.
            HashSet <int> fullVertexSet = new HashSet <int>(Enumerable.Range(0, n - 1));
            PathDesc      bestCycle     = FindBestPath(graph, currentSolutions, cycleStart, fullVertexSet);

            return(bestCycle);
        }