Пример #1
0
        public void Solve_ShouldReturnCorrectValue_IfAllItemsShouldBeInBag()
        {
            KnapsackProblemModel problem = new KnapsackProblemModel(9005, 100, new List <Item>
            {
                new Item(12, 66, 0), new Item(52, 167, 1), new Item(14, 150, 2), new Item(3, 180, 3)
            });

            IKnapsackSolver solver = new RatioHeuristicSolver();
            int             solve  = solver.Solve(problem);

            Assert.AreEqual(563, solve);

            IKnapsackSolver solver2 = new BruteForceSolver();
            int             solve2  = solver2.Solve(problem);

            Assert.AreEqual(563, solve2);

            IKnapsackSolver solver3 = new BranchAndBoundSolver();
            int             solve3  = solver3.Solve(problem);

            Assert.AreEqual(563, solve3);

            IKnapsackSolver solver4 = new DynamicByCostSolver();
            int             solve4  = solver4.Solve(problem);

            Assert.AreEqual(563, solve4);
        }
Пример #2
0
        public void SimpleTest2()
        {
            KnapsackProblemModel problem = new KnapsackProblemModel(9000, 100, new List <Item>
            {
                new Item(89, 196, 0), new Item(18, 62, 1), new Item(57, 34, 2), new Item(69, 112, 3)
            });

            IKnapsackSolver solver = new RatioHeuristicSolver();
            int             solve  = solver.Solve(problem);

            //Assert.AreEqual(473, solve);
        }
Пример #3
0
        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);
        }