示例#1
0
        public void Test1MoveImpossible()
        {
            // create the problem and make sure 0->1->2->3->4 is the solution.
            var objective = new TSPTWObjective();
            var problem   = TSPTWHelper.CreateTSPTW(0, 0, 5, 10);

            problem.Times[0][1] = 1;
            problem.Times[0][3] = 2;
            problem.Times[1][2] = 1;
            problem.Times[2][3] = 1;
            problem.Times[3][4] = 1;
            problem.Times[4][0] = 1;

            problem.Times[3][1] = 100;
            problem.Windows[3]  = new TimeWindow()
            {
                Min = 1,
                Max = 2
            };
            problem.Windows[2] = new TimeWindow()
            {
                Min = 11,
                Max = 12
            };

            var route = new Optimization.Tours.Tour(new int[] { 0, 3, 2, 1, 4 }, 0);

            var localSearch = new Local2Opt();
            var delta       = 0.0f;

            Assert.IsFalse(localSearch.Apply(problem, objective, route, out delta));
        }
示例#2
0
        public void Test1MoveImpossible()
        {
            // create the problem and make sure 0->1->2->3->4 is the solution.
            var objective = new TSPTWObjective();
            var problem   = TSPTWHelper.CreateDirectedTSPTW(0, 0, 5, 10, 1);

            problem.Times.SetWeight(0, 1, 1);
            problem.Times.SetWeight(0, 3, 2);
            problem.Times.SetWeight(1, 2, 1);
            problem.Times.SetWeight(2, 3, 1);
            problem.Times.SetWeight(3, 4, 1);
            problem.Times.SetWeight(4, 0, 1);

            problem.Times.SetWeight(3, 1, 100);
            problem.Windows[3] = new TimeWindow()
            {
                Min = 1,
                Max = 2
            };
            problem.Windows[2] = new TimeWindow()
            {
                Min = 11,
                Max = 12
            };

            var route = new Optimization.Tours.Tour(new int[] { 0, 13, 9, 4, 16 }, 0);

            var localSearch = new Local2Opt();
            var delta       = 0.0f;

            Assert.IsFalse(localSearch.Apply(problem, objective, route, out delta));
        }
示例#3
0
        public void TestOneShiftNonViolatedForward()
        {
            // create the problem and make sure 0->1->2->3->4 is the solution.
            var objective = new TSPTWFeasibleObjective();
            var problem   = TSPTWHelper.CreateTSPTW(0, 0, 5, 2);

            problem.Windows[2] = new TimeWindow()
            {
                Min = 1,
                Max = 3
            };

            // create a route with one shift.
            var route = new Optimization.Tours.Tour(new int[] { 0, 1, 2, 3, 4 }, 0);

            // apply the 1-shift local search, it should find the customer to replocate.
            var localSearch = new Local1Shift <TSPTWFeasibleObjective>();
            var delta       = 0.0f;

            Assert.IsTrue(localSearch.MoveNonViolatedForward(problem, objective, route, out delta)); // shifts 1 after 2.

            // test result.
            Assert.AreEqual(1, delta);
            Assert.AreEqual(new int[] { 0, 2, 1, 3, 4 }, route.ToArray());

            // create a feasible route.
            route = new Optimization.Tours.Tour(new int[] { 0, 2, 4, 1, 3 }, 0);

            // apply the 1-shift local search, it should find the customer to replocate.
            Assert.IsFalse(localSearch.MoveNonViolatedForward(problem, objective, route, out delta));
        }
        public void TestWindowsValidOnlyWithWait()
        {
            // create problem.
            var problem = TSPTWHelper.CreateDirectedTSPTW(0, 0, 5, 10, 1);

            problem.Windows[1] = new TimeWindow()
            {
                Min = 5,
                Max = 15
            };
            problem.Windows[2] = new TimeWindow()
            {
                Min = 15,
                Max = 25
            };
            problem.Windows[3] = new TimeWindow()
            {
                Min = 35, // wait here until it's '35'.
                Max = 45
            };
            problem.Windows[4] = new TimeWindow()
            {
                Min = 45,
                Max = 55
            };

            // calculate objective function.
            var objective = new TSPTWFeasibleObjective();

            Assert.AreEqual(0, objective.Calculate(problem, new Optimization.Tours.Tour(new int[] { 0, 4, 8, 12, 16 })));
        }
示例#5
0
        public void TestFixedViolatedUnmovableCustomerValidBackward()
        {
            // create the problem and make sure 0->1->2->3->4 is the solution.
            var objective = new TSPTWFeasibleObjective();
            var problem   = TSPTWHelper.CreateTSPTW(0, 4, 5, 10);

            problem.Times[0][1] = 2;
            problem.Times[1][2] = 2;
            problem.Times[2][3] = 2;
            problem.Times[3][4] = 2;
            problem.Times[4][0] = 2;
            problem.Windows[4]  = new TimeWindow()
            {
                Min = 7,
                Max = 9
            };

            // create a route with one shift.
            var route = new Optimization.Tours.Tour(new int[] { 0, 1, 3, 2, 4 }, 0);

            // apply the 1-shift local search, it should find the customer to replocate.
            var localSearch = new Local1Shift <TSPTWFeasibleObjective>();
            var delta       = 0.0f;

            Assert.IsTrue(localSearch.MoveNonViolatedBackward(problem, objective, route, out delta)); // shifts 2 after 1

            // test result.
            Assert.AreEqual(23, delta);
            Assert.AreEqual(new int[] { 0, 1, 2, 3, 4 }, route.ToArray());
        }
        public void TestWindowsOneInvalid()
        {
            // create problem.
            var problem = TSPTWHelper.CreateDirectedTSPTW(0, 0, 5, 10, 1);

            problem.Windows[1] = new TimeWindow()
            {
                Min = 5,
                Max = 15
            };
            problem.Windows[2] = new TimeWindow()
            {
                Min = 15,
                Max = 25
            };
            problem.Windows[3] = new TimeWindow()
            {
                Min = 25,
                Max = 29 // invalid max.
            };
            problem.Windows[4] = new TimeWindow()
            {
                Min = 35,
                Max = 45
            };

            // calculate objective function.
            var objective = new TSPTWFeasibleObjective();

            Assert.AreEqual(1, objective.Calculate(problem, new Optimization.Tours.Tour(new int[] { 0, 4, 8, 12, 16 })));
        }
示例#7
0
        public void TestShift1and3()
        {
            // create the problem and make sure 0->1->2->3->4 is the solution.
            var objective = new TSPTWObjective();
            var problem   = TSPTWHelper.CreateDirectedTSPTW(0, 0, 5, 10, 1);

            problem.Windows[2] = new TimeWindow()
            {
                Min = 1,
                Max = 3
            };

            // create a route with one shift.
            var route = new Optimization.Tours.Tour(new int[] { 0, 5, 8, 12, 17 }, 0);

            // apply the operator this should shift 5 to 4.
            var localSearch = new Local1ShiftTurn();
            var delta       = 0.0f;

            Assert.IsTrue(localSearch.Apply(problem, objective, route, out delta));
            Assert.AreEqual(2, delta);
            Assert.AreEqual(new int[] { 0, 4, 8, 12, 17 }, route.ToArray());

            // apply the operator again, this should shift 17 to 16.
            Assert.IsTrue(localSearch.Apply(problem, objective, route, out delta));
            Assert.AreEqual(2, delta);
            Assert.AreEqual(new int[] { 0, 4, 8, 12, 16 }, route.ToArray());
        }
示例#8
0
        public void Test1MovePossible()
        {
            // create the problem and make sure 0->1->2->3->4 is the solution.
            var objective = new TSPTWObjective();
            var problem   = TSPTWHelper.CreateDirectedTSPTW(0, 0, 5, 10, 1);

            problem.Times.SetWeight(0, 1, 1);
            problem.Times.SetWeight(1, 2, 1);
            problem.Times.SetWeight(2, 3, 1);
            problem.Times.SetWeight(3, 4, 1);
            problem.Times.SetWeight(4, 0, 1);

            problem.Times.SetWeight(3, 1, 100);

            var route = new Optimization.Tours.Tour(new int[] { 0, 13, 9, 5, 17 }, 0);

            var localSearch = new Local2Opt();
            var delta       = 0.0f;

            Assert.IsTrue(localSearch.Apply(problem, objective, route, out delta));

            // test result.
            Assert.AreEqual(42, delta);
            Assert.AreEqual(new int[] { 0, 4, 8, 12, 17 }, route.ToArray());
        }
示例#9
0
        public void Test1MovePossible()
        {
            // create the problem and make sure 0->1->2->3->4 is the solution.
            var objective = new TSPTWObjective();
            var problem   = TSPTWHelper.CreateTSPTW(0, 0, 5, 10);

            problem.Times[0][1] = 1;
            problem.Times[1][2] = 1;
            problem.Times[2][3] = 1;
            problem.Times[3][4] = 1;
            problem.Times[4][0] = 1;

            problem.Times[3][1] = 100;

            var route = new Optimization.Tours.Tour(new int[] { 0, 3, 2, 1, 4 }, 0);

            var localSearch = new Local2Opt();
            var delta       = 0.0f;

            Assert.IsTrue(localSearch.Apply(problem, objective, route, out delta));

            // test result.
            Assert.AreEqual(36, delta);
            Assert.AreEqual(new int[] { 0, 1, 2, 3, 4 }, route.ToArray());
        }
示例#10
0
        public void TestSolution5ClosedFixed()
        {
            // create problem.
            var problem = TSPTWHelper.CreateDirectedTSPTW(0, 4, 5, 10, 1);

            problem.Windows[1] = new TimeWindow()
            {
                Min = 5,
                Max = 15
            };
            problem.Windows[2] = new TimeWindow()
            {
                Min = 15,
                Max = 25
            };
            problem.Windows[3] = new TimeWindow()
            {
                Min = 25,
                Max = 35
            };
            problem.Windows[4] = new TimeWindow()
            {
                Min = 35,
                Max = 45
            };

            // create the solver.
            var solver = new VNSConstructionSolver();

            solver.IntermidiateResult += (x) =>
            {
                var fitness = (new TSPTWFeasibleObjective()).Calculate(problem, x);
                fitness = fitness + 0;
            };
            for (int i = 0; i < 10; i++)
            {
                // generate solution.
                float fitness;
                var   solution = solver.Solve(problem, new TSPTWFeasibleObjective(), out fitness);

                // test contents.
                Assert.AreEqual(0, fitness);
                var solutionList = new List <int>();
                foreach (var directed in solution)
                {
                    solutionList.Add(DirectedHelper.ExtractId(directed));
                }
                Assert.AreEqual(0, solutionList[0]);
                Assert.AreEqual(4, solutionList[4]);
                Assert.IsTrue(solutionList.Remove(0));
                Assert.IsTrue(solutionList.Remove(1));
                Assert.IsTrue(solutionList.Remove(2));
                Assert.IsTrue(solutionList.Remove(3));
                Assert.IsTrue(solutionList.Remove(4));
                Assert.AreEqual(0, solutionList.Count);
            }
        }
示例#11
0
        public void TestPerturbationSomeViolations()
        {
            // set the seed manually.
            RandomGeneratorExtensions.GetGetNewRandom = () => new RandomGenerator(4541247);

            // create the perturber.
            var perturber = new Random1Shift <TSPTWObjective>();

            // create a problem where any move would violate windows.
            var problem = TSPTWHelper.CreateDirectedTSPTW(0, 0, 5, 2, 1);

            problem.Windows[2] = new TimeWindow()
            {
                Min = 4,
                Max = 5
            };
            problem.Windows[3] = new TimeWindow()
            {
                Min = 6,
                Max = 7
            };
            var objective = new TSPTWObjective();

            // execute random shifts.
            for (int i = 0; i < 1000; i++)
            {
                // create solution.
                var solution      = new Optimization.Tours.Tour(new int[] { 0, 4, 8, 12, 16 });
                var fitnessBefore = objective.Calculate(problem, solution);

                // shift one customer.
                float difference;
                perturber.Apply(problem, objective, solution, out difference);

                // check if valid solution.
                var solutionList = new List <int>();
                foreach (var directed in solution)
                {
                    solutionList.Add(DirectedHelper.ExtractId(directed));
                }
                Assert.AreEqual(0, solutionList[0]);
                Assert.IsTrue(solutionList.Remove(0));
                Assert.IsTrue(solutionList.Remove(1));
                Assert.IsTrue(solutionList.Remove(2));
                Assert.IsTrue(solutionList.Remove(3));
                Assert.IsTrue(solutionList.Remove(4));
                Assert.AreEqual(0, solutionList.Count);

                // test if first is still first.
                Assert.AreEqual(problem.First, solution.First);

                // calculate expected difference.
                var fitnessAfter = objective.Calculate(problem, solution);

                Assert.AreEqual(fitnessAfter - fitnessBefore, difference, 0.0000001);
            }
        }
示例#12
0
        public void TestSolutions5ClosedNotFixed()
        {
            RandomGeneratorExtensions.GetGetNewRandom = () =>
            {
                return(new RandomGenerator(45841647));
            };

            // create problem.
            var problem = TSPTWHelper.CreateDirectedTSPTW(0, 0, 5, 10, 1);

            problem.Windows[1] = new TimeWindow()
            {
                Min = 5,
                Max = 15
            };
            problem.Windows[2] = new TimeWindow()
            {
                Min = 15,
                Max = 25
            };
            problem.Windows[3] = new TimeWindow()
            {
                Min = 25,
                Max = 35
            };
            problem.Windows[4] = new TimeWindow()
            {
                Min = 35,
                Max = 45
            };

            // create the solver.
            var solver = new VNDOperator();

            for (int i = 0; i < 10; i++)
            {
                // generate solution.
                float fitness;
                var   solution = solver.Solve(problem, new TSPTWObjective(), out fitness);

                // test contents.
                Assert.AreEqual(50, fitness, string.Format("Solution was: {0} with fitness {1}.", solution.ToInvariantString(), fitness));
                var solutionList = new List <int>();
                foreach (var directedId in solution)
                {
                    solutionList.Add(DirectedHelper.ExtractId(directedId));
                }
                Assert.AreEqual(0, solutionList[0]);
                Assert.IsTrue(solutionList.Remove(0));
                Assert.IsTrue(solutionList.Remove(1));
                Assert.IsTrue(solutionList.Remove(2));
                Assert.IsTrue(solutionList.Remove(3));
                Assert.IsTrue(solutionList.Remove(4));
                Assert.AreEqual(0, solutionList.Count);
            }
        }
        public void TestNoWindows()
        {
            // create problem.
            var problem = TSPTWHelper.CreateDirectedTSPTW(0, 0, 5, 10, 1);

            // calculate objective function.
            var objective = new TSPTWFeasibleObjective();

            Assert.AreEqual(0, objective.Calculate(problem, new Optimization.Tours.Tour(new int[] { 0, 4, 8, 12, 16 })));
        }
示例#14
0
        public void TestTimeAndViolationsSuccess()
        {
            var problem = TSPTWHelper.CreateDirectedTSPTW(0, 5, 100, new TimeWindow[] {
                new TimeWindow()
                {
                    Min = 0,
                    Max = 5
                },
                new TimeWindow()
                {
                    Min = 5,
                    Max = 15
                },
                new TimeWindow()
                {
                    Min = 15,
                    Max = 25
                },
                new TimeWindow()
                {
                    Min = 25,
                    Max = 35
                },
                new TimeWindow()
                {
                    Min = 35,
                    Max = 45
                }
            }, 1);
            var w = 10;

            problem.Times.SetWeight(0, 1, w, w, w, w);
            problem.Times.SetWeight(1, 2, w, w, w, w);
            problem.Times.SetWeight(2, 3, w, w, w, w);
            problem.Times.SetWeight(3, 4, w, w, w, w);
            problem.Times.SetWeight(4, 0, w, w, w, w);

            float time, waitTime, violatedTime;
            var   validFlags = new bool[5];
            var   invalids   = problem.TimeAndViolations(new Optimization.Tours.Tour(new int[] { 0, 4, 8, 12, 16 }), out time, out waitTime, out violatedTime, ref validFlags);

            Assert.AreEqual(0, invalids);
            Assert.AreEqual(50, time);
            Assert.AreEqual(0, waitTime);
            Assert.AreEqual(0, violatedTime);
            Assert.IsTrue(validFlags[0]);
            Assert.IsTrue(validFlags[1]);
            Assert.IsTrue(validFlags[2]);
            Assert.IsTrue(validFlags[3]);
            Assert.IsTrue(validFlags[4]);
        }
示例#15
0
        public void TestSolutions5ClosedNotFixed()
        {
            // create problem.
            var problem = TSPTWHelper.CreateTSPTW(0, 0, 5, 10);

            problem.Windows[1] = new TimeWindow()
            {
                Min = 5,
                Max = 15
            };
            problem.Windows[2] = new TimeWindow()
            {
                Min = 15,
                Max = 25
            };
            problem.Windows[3] = new TimeWindow()
            {
                Min = 25,
                Max = 35
            };
            problem.Windows[4] = new TimeWindow()
            {
                Min = 35,
                Max = 45
            };

            // create the solver.
            var solver = new VNDOperator();

            for (int i = 0; i < 10; i++)
            {
                // generate solution.
                float fitness;
                var   solution = solver.Solve(problem, new TSPTWObjective(), out fitness);

                // test contents.
                Assert.AreEqual(50, fitness);
                var solutionList = new List <int>(solution);
                Assert.AreEqual(0, solutionList[0]);
                Assert.IsTrue(solutionList.Remove(0));
                Assert.IsTrue(solutionList.Remove(1));
                Assert.IsTrue(solutionList.Remove(2));
                Assert.IsTrue(solutionList.Remove(3));
                Assert.IsTrue(solutionList.Remove(4));
                Assert.AreEqual(0, solutionList.Count);
            }
        }
示例#16
0
        public void TestSolution5ClosedFixed()
        {
            // create problem.
            var problem = TSPTWHelper.CreateDirectedTSPTW(0, 4, 5, 10, 1);

            problem.Times.SetWeight(0, 1, 2);
            problem.Times.SetWeight(1, 2, 2);
            problem.Times.SetWeight(2, 3, 2);
            problem.Times.SetWeight(3, 4, 2);
            problem.Times.SetWeight(4, 0, 2);
            problem.Windows[2] = new TimeWindow()
            {
                Min = 3,
                Max = 5
            };
            problem.Windows[4] = new TimeWindow()
            {
                Min = 7,
                Max = 9
            };
            var objective = new TSPTWObjective();

            // create the solver.
            var solver = new VNSSolver();

            for (int i = 0; i < 10; i++)
            {
                // generate solution.
                float fitness;
                var   solution = solver.Solve(problem, objective, out fitness);

                // test contents.
                Assert.IsTrue(fitness <= 12);
                var solutionList = new List <int>();
                foreach (var directed in solution)
                {
                    solutionList.Add(DirectedHelper.ExtractId(directed));
                }
                Assert.AreEqual(5, solutionList.Count);
                Assert.AreEqual(0, solutionList[0]);
                Assert.AreEqual(4, solutionList[4]);
            }
        }
示例#17
0
        public void TestSolution5ClosedNotFixed()
        {
            // create problem.
            var problem = TSPTWHelper.CreateTSPTW(0, 0, 5, 10);

            problem.Times[0][1] = 2;
            problem.Times[1][2] = 2;
            problem.Times[2][3] = 2;
            problem.Times[3][4] = 2;
            problem.Times[4][0] = 2;
            problem.Windows[2]  = new TimeWindow()
            {
                Min = 3,
                Max = 5
            };
            problem.Windows[4] = new TimeWindow()
            {
                Min = 7,
                Max = 9
            };
            var objective = new TSPTWObjective();

            // create the solver.
            var solver = new VNSSolver();

            for (int i = 0; i < 10; i++)
            {
                // generate solution.
                float fitness;
                var   solution = solver.Solve(problem, objective, out fitness);

                // test contents.
                Assert.AreEqual(10, fitness);
                var solutionList = new List <int>(solution);
                Assert.AreEqual(0, solutionList[0]);
                Assert.IsTrue(solutionList.Remove(0));
                Assert.IsTrue(solutionList.Remove(1));
                Assert.IsTrue(solutionList.Remove(2));
                Assert.IsTrue(solutionList.Remove(3));
                Assert.IsTrue(solutionList.Remove(4));
                Assert.AreEqual(0, solutionList.Count);
            }
        }
示例#18
0
        public void TestPerturbation()
        {
            // set the seed manually.
            RandomGeneratorExtensions.GetGetNewRandom = () => new RandomGenerator(4541247);

            // create the perturber.
            var perturber = new Random1Shift <TSPTWObjective>();

            // create a problem.
            var problem   = TSPTWHelper.CreateTSPTW(0, 0, 5, 10);
            var objective = new TSPTWObjective();

            // execute random shifts.
            for (int i = 0; i < 1000; i++)
            {
                // create solution.
                var solution      = new Optimization.Tours.Tour(new int[] { 0, 1, 2, 3, 4 });
                var fitnessBefore = objective.Calculate(problem, solution);

                // shift one customer.
                float difference;
                perturber.Apply(problem, objective, solution, out difference);

                // check if valid solution.
                var solutionList = new List <int>(solution);
                Assert.AreEqual(0, solutionList[0]);
                Assert.IsTrue(solutionList.Remove(0));
                Assert.IsTrue(solutionList.Remove(1));
                Assert.IsTrue(solutionList.Remove(2));
                Assert.IsTrue(solutionList.Remove(3));
                Assert.IsTrue(solutionList.Remove(4));
                Assert.AreEqual(0, solutionList.Count);

                // test if first is still first.
                Assert.AreEqual(problem.First, solution.First);

                // calculate expected difference.
                var fitnessAfter = objective.Calculate(problem, solution);

                Assert.AreEqual(fitnessAfter - fitnessBefore, difference, 0.0000001);
            }
        }
示例#19
0
        public void TestSolution1()
        {
            // create problem.
            var problem   = TSPTWHelper.CreateDirectedTSPTW(0, 0, 1, 0, 1);
            var objective = new TSPTWObjective();

            // create the solver.
            var solver = new VNSSolver();

            for (int i = 0; i < 10; i++)
            {
                // generate solution.
                float fitness;
                var   solution = solver.Solve(problem, objective, out fitness);

                // test contents.
                Assert.IsTrue(fitness < 2);
                var solutionList = new List <int>(solution);
                Assert.AreEqual(0, DirectedHelper.ExtractId(solutionList[0]));
            }
        }
示例#20
0
        public void TestOneShiftViolatedForward()
        {
            // create the problem and make sure 0->1->2->3->4 is the solution.
            var objective = new TSPTWFeasibleObjective();
            var problem   = TSPTWHelper.CreateDirectedTSPTW(0, 0, 5, 10, 1);

            problem.Times.SetWeight(0, 3, 1, 1, 1, 1); // [0][3] = 1;
            problem.Times.SetWeight(3, 1, 1, 1, 1, 1); // [3][1] = 1;
            problem.Windows[1] = new TimeWindow()
            {
                Min = 1,
                Max = 3
            };
            problem.Windows[3] = new TimeWindow()
            {
                Min = 0,
                Max = 2
            };

            // create a route with one shift.
            var route = new Optimization.Tours.Tour(new int[] { 0, 4, 12, 8, 16 }, 0);

            // apply the 1-shift local search, it should find the customer to replocate.
            var localSearch = new Local1Shift <TSPTWFeasibleObjective>();
            var delta       = 0.0f;

            Assert.IsTrue(localSearch.MoveViolatedForward(problem, objective, route, out delta)); // shifts 4 after 12.

            // test result.
            Assert.AreEqual(25, delta);
            Assert.AreEqual(new int[] { 0, 12, 4, 8, 16 }, route.ToArray());

            // create a feasible route.
            route = new Optimization.Tours.Tour(new int[] { 0, 12, 4, 8, 16 }, 0);

            // apply the 1-shift local search, it should find the customer to replocate.
            Assert.IsFalse(localSearch.MoveViolatedForward(problem, objective, route, out delta));
        }
示例#21
0
        public void TestSolution1()
        {
            // create problem.
            var problem   = TSPTWHelper.CreateTSPTW(0, 0, 1, 0);
            var objective = new TSPTWObjective();

            // create the solver.
            var solver = new VNSSolver();

            for (int i = 0; i < 10; i++)
            {
                // generate solution.
                float fitness;
                var   solution = solver.Solve(problem, objective, out fitness);

                // test contents.
                Assert.AreEqual(0, fitness);
                var solutionList = new List <int>(solution);
                Assert.AreEqual(0, solutionList[0]);
                Assert.IsTrue(solutionList.Remove(0));
                Assert.AreEqual(0, solutionList.Count);
            }
        }
示例#22
0
        public void TestSolution5ClosedNotFixed()
        {
            // create problem.
            var problem = TSPTWHelper.CreateDirectedTSPTW(0, 0, 5, 10, 1);

            problem.Times.SetWeight(0, 1, 2);
            problem.Times.SetWeight(1, 2, 2);
            problem.Times.SetWeight(2, 3, 2);
            problem.Times.SetWeight(3, 4, 2);
            problem.Times.SetWeight(4, 0, 2);
            problem.Windows[2] = new TimeWindow()
            {
                Min = 3,
                Max = 5
            };
            problem.Windows[4] = new TimeWindow()
            {
                Min = 7,
                Max = 9
            };
            var objective = new TSPTWObjective();

            // create the solver.
            var solver = new VNSSolver();

            for (int i = 0; i < 10; i++)
            {
                // generate solution.
                float fitness;
                var   solution = solver.Solve(problem, objective, out fitness);

                // test contents.
                Assert.AreEqual(10, fitness);
                var solutionList = new List <int>(solution);
                Assert.AreEqual(5, solutionList.Count);
            }
        }