public void SimpleTest() { KnapsackProblemModel problem = new KnapsackProblemModel(9000, 100, new List <Item> { new Item(18, 114, 0), new Item(42, 136, 1), new Item(88, 192, 2), new Item(3, 223, 3) }); IKnapsackSolver solver = new BruteForceSolver(); int solve = solver.Solve(problem); Assert.AreEqual(473, solve); IKnapsackSolver solver2 = new BranchAndBoundSolver(); int solve2 = solver2.Solve(problem); Assert.AreEqual(473, solve2); IKnapsackSolver solver4 = new GeneticSolver(100, 100, new RouletteWheelSelection(), 0.01, 0.8, 0, false, false); solver4.Solve(problem); IKnapsackSolver solver5 = new FPTASSolver(0.9); solver5.Solve(problem); }
static void Main(string[] args) { Stopwatch stopwatch = new Stopwatch(); decimal frequency = Stopwatch.Frequency; if (CommandLine.Parser.Default.ParseArguments(args, Options)) { TextWriter reportWriter = Options.OutputFilePath == null ? Console.Out : new StreamWriter(Options.OutputFilePath); VerboseLog("Data parsing ..."); DataParser parser = new DataParser(); List <KnapsackProblemModel> knapsackProblemModels = parser.ParseProblem(Options.InputFiles); Dictionary <int, int> knownResults = null; Dictionary <int, Tuple <int, long> > bruteForceResults = new Dictionary <int, Tuple <int, long> >(); Dictionary <int, Tuple <int, long> > costToRatioHeuristicsResults = new Dictionary <int, Tuple <int, long> >(); Dictionary <int, Tuple <int, long> > branchAndBoundResults = new Dictionary <int, Tuple <int, long> >(); Dictionary <int, Tuple <int, long> > dynamicByCostResults = new Dictionary <int, Tuple <int, long> >(); Dictionary <int, Tuple <int, long> > fptasResults = new Dictionary <int, Tuple <int, long> >(); Dictionary <int, Tuple <int, long> > geneticResults = new Dictionary <int, Tuple <int, long> >(); if (Options.ResultFiles != null) { knownResults = parser.ParseResults(Options.ResultFiles); } VerboseLog("Done."); IKnapsackSolver bruteForceSolver = new BruteForceSolver(); IKnapsackSolver ratioHeuristicSolver = new RatioHeuristicSolver(); IKnapsackSolver branchAndBoundSolver = new BranchAndBoundSolver(); IKnapsackSolver dynamicByCostSolve = new DynamicByCostSolver(); IKnapsackSolver fptasSolver = null; IKnapsackSolver geneticSolver = null; if (Options.FPTAS) { fptasSolver = new FPTASSolver(Options.FPTASAccuracy); } if (Options.Genetics) { ISelectionMethod selectionMethod = null; switch (Options.SelectionMethod) { case "roulette": selectionMethod = new RouletteWheelSelection(); break; case "rank": selectionMethod = new RankSelection(); break; case "elitary": selectionMethod = new EliteSelection(); break; default: Console.WriteLine("Wrong selection method for genetics"); break; } if (selectionMethod == null) { return; } if (Options.GeneticMetaoptimization) { //Random selection portion for (int i = 0; i < 100; i++) { double randomSelectionPortion = (i * 0.001) + 0; //Crossover rate for (int j = 0; j < 1; j++) { double crossoverRate = (j * 0.03) + 0.22; //Mutation rate for (int k = 0; k < 1; k++) { double mutationRate = (k * 0.04) + 0.87; geneticSolver = new GeneticSolver(Options.PopulationSize, Options.IterationsCount, selectionMethod, mutationRate, crossoverRate, randomSelectionPortion, false, false); geneticResults.Clear(); foreach (KnapsackProblemModel problem in knapsackProblemModels) { int result = 0; try { stopwatch.Restart(); result = geneticSolver.Solve(problem); stopwatch.Stop(); } catch (Exception ex) { } geneticResults.Add(problem.ProblemId, new Tuple <int, long>(result, stopwatch.ElapsedTicks)); } decimal totalTime = 0; decimal totalError = 0; foreach (KnapsackProblemModel problem in knapsackProblemModels) { int problemId = problem.ProblemId; Tuple <int, long> result = geneticResults[problemId]; totalTime += (result.Item2 / frequency); totalError += CalculateRelativeError(knownResults[problemId], result.Item1); } decimal averageError = totalError / knapsackProblemModels.Count; reportWriter.WriteLine(randomSelectionPortion + "," + crossoverRate + "," + mutationRate + "," + totalTime + "," + averageError); } } } } geneticSolver = new GeneticSolver(Options.PopulationSize, Options.IterationsCount, selectionMethod, Options.MutationRate, Options.CrossoverRate, Options.RandomSelectionPortion, Options.DiversityCheck, true); } VerboseLog("Solving JIT instance"); KnapsackProblemModel jitProblem = new KnapsackProblemModel(-1, 100, new List <Item> { new Item(18, 114, 0), new Item(42, 136, 1), new Item(88, 192, 2), new Item(3, 223, 3) }); bruteForceSolver.Solve(jitProblem); ratioHeuristicSolver.Solve(jitProblem); branchAndBoundSolver.Solve(jitProblem); dynamicByCostSolve.Solve(jitProblem); if (fptasSolver != null) { fptasSolver.Solve(jitProblem); } if (geneticSolver != null) { geneticSolver.Solve(jitProblem); } VerboseLog("Calculation started"); foreach (KnapsackProblemModel problem in knapsackProblemModels) { VerboseLog("Solving problem:"); VerboseLog(problem); int knownResult = -1; if (knownResults != null) { knownResult = knownResults[problem.ProblemId]; VerboseLog("Result should be: " + knownResult); } if (Options.BruteForce) { VerboseLog("Brute force solver ..."); stopwatch.Restart(); int result = bruteForceSolver.Solve(problem); stopwatch.Stop(); bruteForceResults.Add(problem.ProblemId, new Tuple <int, long>(result, stopwatch.ElapsedTicks)); if (knownResult != -1 && result != knownResult) { Console.WriteLine("ERROR - Brute force algorithm not accurate for problem " + problem); Environment.Exit(1); } } if (Options.BranchAndBound) { VerboseLog("Branch and bound solver ..."); stopwatch.Restart(); int result = branchAndBoundSolver.Solve(problem); stopwatch.Stop(); branchAndBoundResults.Add(problem.ProblemId, new Tuple <int, long>(result, stopwatch.ElapsedTicks)); if (knownResult != -1 && result != knownResult) { Console.WriteLine("ERROR - Branch and bound algorithm not accurate for problem " + problem); Environment.Exit(1); } } if (Options.DynamicByCost) { VerboseLog("Dynamic by cost solver ..."); stopwatch.Restart(); int result = dynamicByCostSolve.Solve(problem); stopwatch.Stop(); dynamicByCostResults.Add(problem.ProblemId, new Tuple <int, long>(result, stopwatch.ElapsedTicks)); if (knownResult != -1 && result != knownResult) { Console.WriteLine("ERROR - Dynamic by cost algorithm not accurate for problem " + problem); Environment.Exit(1); } } if (Options.CostToRatioHeuristics) { VerboseLog("Ratio heuristics solver ..."); stopwatch.Restart(); int result = ratioHeuristicSolver.Solve(problem); stopwatch.Stop(); costToRatioHeuristicsResults.Add(problem.ProblemId, new Tuple <int, long>(result, stopwatch.ElapsedTicks)); } if (Options.FPTAS) { VerboseLog("FPTAS solver ..."); if (fptasSolver != null) { stopwatch.Restart(); int result = fptasSolver.Solve(problem); stopwatch.Stop(); fptasResults.Add(problem.ProblemId, new Tuple <int, long>(result, stopwatch.ElapsedTicks)); } } if (Options.Genetics) { VerboseLog("Genetics solver ..."); if (geneticSolver != null) { stopwatch.Restart(); int result = geneticSolver.Solve(problem); stopwatch.Stop(); geneticResults.Add(problem.ProblemId, new Tuple <int, long>(result, stopwatch.ElapsedTicks)); } } VerboseLog("Problem solved."); } reportWriter.Write("Problem ID;Items count"); if (knownResults != null) { reportWriter.Write(";Known result"); } if (Options.BruteForce) { reportWriter.Write(";Brute force result;Time [s]"); if (knownResults != null) { reportWriter.Write(";Relative error"); } } if (Options.CostToRatioHeuristics) { reportWriter.Write(";Cost to weight ration heuristics result;Time [s]"); if (knownResults != null) { reportWriter.Write(";Relative error"); } } if (Options.BranchAndBound) { reportWriter.Write(";Branch and bound result;Time [s]"); if (knownResults != null) { reportWriter.Write(";Relative error"); } } if (Options.DynamicByCost) { reportWriter.Write(";Dynamic programming by cost result;Time [s]"); if (knownResults != null) { reportWriter.Write(";Relative error"); } } if (Options.FPTAS) { reportWriter.Write(";FPTAS result;Time [s]"); if (knownResults != null) { reportWriter.Write(";Relative error;Max possible error"); } } if (Options.Genetics) { reportWriter.Write(";Genetics result;Time [s]"); if (knownResults != null) { reportWriter.Write(";Relative error"); } } reportWriter.WriteLine(); foreach (KnapsackProblemModel problem in knapsackProblemModels) { var problemId = problem.ProblemId; reportWriter.Write(problemId); reportWriter.Write(";" + problem.Items.Count); if (knownResults != null) { reportWriter.Write(";" + knownResults[problemId]); } if (Options.BruteForce) { Tuple <int, long> bruteForceResult = bruteForceResults[problemId]; reportWriter.Write(";" + bruteForceResult.Item1 + ";" + bruteForceResult.Item2 / frequency); if (knownResults != null) { reportWriter.Write(";" + CalculateRelativeError(knownResults[problemId], bruteForceResult.Item1)); } } if (Options.CostToRatioHeuristics) { Tuple <int, long> heuristicsResult = costToRatioHeuristicsResults[problemId]; reportWriter.Write(";" + heuristicsResult.Item1 + ";" + heuristicsResult.Item2 / frequency); if (knownResults != null) { reportWriter.Write(";" + CalculateRelativeError(knownResults[problemId], heuristicsResult.Item1)); } } if (Options.BranchAndBound) { Tuple <int, long> heuristicsResult = branchAndBoundResults[problemId]; reportWriter.Write(";" + heuristicsResult.Item1 + ";" + heuristicsResult.Item2 / frequency); if (knownResults != null) { reportWriter.Write(";" + CalculateRelativeError(knownResults[problemId], heuristicsResult.Item1)); } } if (Options.DynamicByCost) { Tuple <int, long> heuristicsResult = dynamicByCostResults[problemId]; reportWriter.Write(";" + heuristicsResult.Item1 + ";" + heuristicsResult.Item2 / frequency); if (knownResults != null) { reportWriter.Write(";" + CalculateRelativeError(knownResults[problemId], heuristicsResult.Item1)); } } if (Options.FPTAS) { Tuple <int, long> heuristicsResult = fptasResults[problemId]; reportWriter.Write(";" + heuristicsResult.Item1 + ";" + heuristicsResult.Item2 / frequency); if (knownResults != null) { reportWriter.Write(";" + CalculateRelativeError(knownResults[problemId], heuristicsResult.Item1)); reportWriter.Write(";" + ((FPTASSolver)fptasSolver).GetMaximumError(problem)); } } if (Options.Genetics) { Tuple <int, long> heuristicsResult = geneticResults[problemId]; reportWriter.Write(";" + heuristicsResult.Item1 + ";" + heuristicsResult.Item2 / frequency); if (knownResults != null) { reportWriter.Write(";" + CalculateRelativeError(knownResults[problemId], heuristicsResult.Item1)); } } reportWriter.WriteLine(); } if (Options.Genetics) { decimal totalTime = 0; decimal totalError = 0; foreach (KnapsackProblemModel problem in knapsackProblemModels) { int problemId = problem.ProblemId; Tuple <int, long> result = geneticResults[problemId]; totalTime += (result.Item2 / frequency); totalError += CalculateRelativeError(knownResults[problemId], result.Item1); } decimal averageError = totalError / knapsackProblemModels.Count; reportWriter.WriteLine("Aggregate results"); reportWriter.WriteLine("Aggregate time"); reportWriter.WriteLine(totalTime); reportWriter.WriteLine("Average error"); reportWriter.WriteLine(averageError); } } else { Environment.Exit(1); } Environment.Exit(0); }