示例#1
0
        /// <summary>
        /// Create an exact solution using input data from the Console
        /// </summary>
        private static void RunExactConsole()
        {
            Node[]               inputAsNodes = IO.ReadInputAsNodes(CENTER_RESEMBLANCE_CAP, ARTICULATION_POINT_MINIMUM);
            RecursiveSplit       recSplit     = new RecursiveSplit(inputAsNodes);
            RecursiveTree <Node> recTree      = recSplit.GetBestTree();
            string               output       = recTree.ToString();

            Console.Write(output);
        }
示例#2
0
        /// <summary>
        /// Runs either the exact version of RecursiveSplit. Does not use any form of local search
        /// </summary>
        /// <param name="fileName">The name of the file to be used as input (without extension)</param>
        private static void RunExact(string fileName)
        {
            Console.WriteLine($"Starting file {fileName}...");

            Node[]         inputAsNodes = IO.ReadInputAsNodes($"..\\..\\..\\..\\..\\Testcases\\{fileName}.gr", CENTER_RESEMBLANCE_CAP, ARTICULATION_POINT_MINIMUM);
            RecursiveSplit recSplit     = new RecursiveSplit(inputAsNodes);

            RecursiveTree <Node> recTree;

            recTree = recSplit.GetBestTree();
            string output = recTree.ToString();

            using (StreamWriter sw = new StreamWriter($"..\\..\\..\\..\\..\\Results\\{fileName}.tree", false))
            {
                sw.Write(output);
            }

            Console.WriteLine($"Tree found with depth {recTree.Depth}.");
            Console.WriteLine();
        }
示例#3
0
        /// <summary>
        /// Execute the program using simulated annealing
        /// </summary>
        /// <param name="fileName">The name of the file to be run, or empty if the console is used</param>
        /// <param name="console">Whether input form the console is used. If so, the program runs in quiet mode</param>
        private static void SimulatedAnnealing(string fileName = "", bool console = true)
        {
            if (!console)
            {
                Console.WriteLine($"Starting file {fileName}...");
            }

            // The stopwatch keeps track of the total running time of the program
            stopwatchSingleRun.Start();

            // Read the input, depending on whether the console is used a file is being read or console input
            Node[] inputAsNodes;
            if (!console)
            {
                inputAsNodes = IO.ReadInputAsNodes($"..\\..\\..\\..\\..\\Testcases\\{fileName}.gr", CENTER_RESEMBLANCE_CAP, ARTICULATION_POINT_MINIMUM);
            }
            else
            {
                inputAsNodes = IO.ReadInputAsNodes(CENTER_RESEMBLANCE_CAP, ARTICULATION_POINT_MINIMUM);
            }
            allNodes = inputAsNodes;

            // Create instances for the simunlated annealing and recursivesplit classes
            SimulatedAnnealing <State <RecursiveTree <Node> >, RecursiveTree <Node> > simulatedAnnealing =
                new SimulatedAnnealing <State <RecursiveTree <Node> >, RecursiveTree <Node> >(random, START_TEMP, RESET_TEMPERATURE_THRESHOLD, TEMP_MULTIPLIER, MULTIPLY_TEMP_PER_ITERATIONS, stopwatchSingleRun, MAX_TIME_TOTAL_SECONDS);
            RecursiveSplit recursiveSplit = new RecursiveSplit(inputAsNodes);

            // Find an initial solution where all nodes are in a single line
            RecursiveTreeState heurInitState = new RecursiveTreeState(BaseSolutionGenerator.LineRecursiveTree(ref allRecTreeNodes, allNodes), random, allRecTreeNodes);

            bestStateSoFar = heurInitState.Data.ToString();
            if (!console)
            {
                Console.WriteLine($"Line found with depth {heurInitState.Data.Root.Depth}.");
            }

            initialSolutionsTimer.Start();
            RecursiveTree <Node> bestTree = null;

            // Find an initial solution using the RecursiveSplit using a fast but bad heuristic
            if (allNodes.Length <= FASTER_HEURISTIC_CAP)
            {
                double maxTime = MAX_TIME_INITIAL_SOLUTIONS_SECONDS;
                if (allNodes.Length > INDEPENDENT_SET_CAP)
                {
                    if (allNodes.Length > FAST_HEURISTIC_CAP)
                    {
                        maxTime *= 3;
                    }
                    else
                    {
                        maxTime *= 1.5;
                    }
                }
                else if (allNodes.Length > FAST_HEURISTIC_CAP)
                {
                    maxTime *= 1.5;
                }

                bestTree = recursiveSplit.GetHeuristicTree(initialSolutionsTimer, maxTime, true);
                if (!console)
                {
                    Console.WriteLine($"Fastest heuristic tree found with depth {bestTree.Depth}.");
                }
            }

            // Find an initial solution using the RecursiveSplit using a decent but pretty slow heuristic
            if (allNodes.Length <= FAST_HEURISTIC_CAP)
            {
                double maxTime = MAX_TIME_INITIAL_SOLUTIONS_SECONDS;
                if (allNodes.Length > INDEPENDENT_SET_CAP)
                {
                    maxTime *= 3;
                }
                else if (allNodes.Length > FASTER_HEURISTIC_CAP)
                {
                    maxTime *= 1.5;
                }
                else
                {
                    maxTime *= 2;
                }

                RecursiveTree <Node> treeFromFastHeuristic = recursiveSplit.GetHeuristicTree(initialSolutionsTimer, maxTime, false);
                if (bestTree == null || treeFromFastHeuristic.Depth < bestTree.Depth)
                {
                    bestTree = treeFromFastHeuristic;
                }
                if (!console)
                {
                    Console.WriteLine($"Fast heuristic tree found with depth {treeFromFastHeuristic.Depth}.");
                }
            }

            // If the problem instance is small enough, we would like to try to find an initial solution using independent sets
            if (allNodes.Length <= INDEPENDENT_SET_CAP)
            {
                double maxTime = MAX_TIME_INITIAL_SOLUTIONS_SECONDS * 3;
                RecursiveTree <Node> treeFromIndependentSet = IndependentSet.TreeFromIndependentSets(allNodes, initialSolutionsTimer, maxTime);
                if (bestTree == null || treeFromIndependentSet.Depth < bestTree.Depth)
                {
                    bestTree = treeFromIndependentSet;
                }
                if (!console)
                {
                    Console.WriteLine($"Independent set tree found with depth {treeFromIndependentSet.Depth}.");
                }
            }

            // Recreate the tree and save the best found initial solution as the initial solution for simulated annealing
            initialSolutionsTimer.Reset();
            if (bestTree != null)
            {
                bestStateSoFar = bestTree.ToString();
                RecreateTree(bestStateSoFar);
                heurInitState = new RecursiveTreeState(allRecTreeNodes[0].Root, random, allRecTreeNodes);
            }

            if (allNodes.Length <= SIMULATED_ANNEALING_CAP)
            {
                simulatedAnnealing.Search(heurInitState, ref bestStateSoFar);
            }

            // If the input from the console is not used, write the output to a file, otherwise write it back to the console
            if (!console)
            {
                using (StreamWriter sw = new StreamWriter($"..\\..\\..\\..\\..\\Results\\{fileName}.tree", false))
                {
                    sw.Write(bestStateSoFar);
                }
            }
            else
            {
                Console.Write(bestStateSoFar);
            }

            // Print the result and total time thus far
            if (!console)
            {
                // Stop the total of this problem instace
                stopwatchSingleRun.Stop();
                Console.WriteLine($"Tree found with depth {bestStateSoFar.Split('\n')[0]} in {stopwatchSingleRun.Elapsed} seconds. (Total time: {allRunsTotalStopwatch.Elapsed})");
                Console.WriteLine();
            }

            // Reset the stopwatch for the next time the program is run
            stopwatchSingleRun.Reset();
        }