コード例 #1
0
        static void VNS(Instance instance, Process process, Random rnd, Stopwatch clock, string choice)
        {
            int typeSol = 0;

            List <int>[] listArray = Utility.BuildSLComplete(instance);
            PathStandard incumbentSol;
            PathStandard solHeuristic = Utility.NearestNeightbor(instance, rnd, listArray);

            incumbentSol = (PathStandard)solHeuristic.Clone();
            Utility.PrintHeuristicSolution(instance, process, incumbentSol, incumbentSol.cost, typeSol);

            do
            {
                TwoOpt(instance, solHeuristic);

                if (incumbentSol.cost > solHeuristic.cost)
                {
                    incumbentSol = (PathStandard)solHeuristic.Clone();

                    Utility.PrintHeuristicSolution(instance, process, incumbentSol, incumbentSol.cost, typeSol);

                    Console.WriteLine("Incumbed changed");
                }
                else
                {
                    Console.WriteLine("Incumbed not changed");
                }

                VNS(instance, solHeuristic, rnd);
            } while (clock.ElapsedMilliseconds / 1000.0 < instance.TimeLimit);

            Console.WriteLine("Best distance found within the timelit is: " + incumbentSol.cost);
        }
コード例 #2
0
ファイル: Utility.cs プロジェクト: korr4k/TSPCsharp
        public static void SwapRoute(int c, int b, PathStandard pathG)
        {
            int from = b;
            int to   = pathG.path[from];

            do
            {
                int tmpTo = pathG.path[to];
                pathG.path[to] = from;
                from           = to;
                to             = tmpTo;
            } while (from != c);
        }
コード例 #3
0
        public static void TwoOpt(Instance instance, PathStandard pathG)
        {
            int  indexStart = 0;
            int  cnt        = 0;
            bool found      = false;

            do
            {
                found = false;
                int a = indexStart;
                int b = pathG.path[a];
                int c = pathG.path[b];
                int d = pathG.path[c];

                for (int i = 0; i < instance.NNodes - 3; i++)
                {
                    double distAC = Point.Distance(instance.Coord[a], instance.Coord[c], instance.EdgeType);
                    double distBD = Point.Distance(instance.Coord[b], instance.Coord[d], instance.EdgeType);
                    double distAD = Point.Distance(instance.Coord[a], instance.Coord[d], instance.EdgeType);
                    double distBC = Point.Distance(instance.Coord[b], instance.Coord[c], instance.EdgeType);

                    double distTotABCD = Point.Distance(instance.Coord[a], instance.Coord[b], instance.EdgeType) +
                                         Point.Distance(instance.Coord[c], instance.Coord[d], instance.EdgeType);

                    if (distAC + distBD < distTotABCD)
                    {
                        Utility.SwapRoute(c, b, pathG);

                        pathG.path[a] = c;
                        pathG.path[b] = d;

                        pathG.cost = pathG.cost - distTotABCD + distAC + distBD;

                        indexStart = 0;
                        cnt        = 0;
                        found      = true;
                        break;
                    }

                    c = d;
                    d = pathG.path[c];
                }

                if (!found)
                {
                    indexStart = b;
                    cnt++;
                }
            } while (cnt < instance.NNodes);
        }
コード例 #4
0
        static void TabuSearch(Instance instance, Process process, Random rnd, Stopwatch clock, string choice)
        {
            int typeSol = 0;

            List <int>[] listArray = Utility.BuildSLComplete(instance);
            PathStandard incumbentSol;
            PathStandard solHeuristic = Utility.NearestNeightbor(instance, rnd, listArray);

            incumbentSol = (PathStandard)solHeuristic.Clone();

            Utility.PrintHeuristicSolution(instance, process, incumbentSol, incumbentSol.cost, typeSol);

            Tabu tabu = new Tabu("A", instance, 100);

            TabuSearch(instance, process, tabu, solHeuristic, incumbentSol, clock);

            solHeuristic = (PathStandard)incumbentSol.Clone();
            TwoOpt(instance, solHeuristic);

            Utility.PrintHeuristicSolution(instance, process, solHeuristic, incumbentSol.cost, typeSol);

            Console.WriteLine("Best distance found within the timelit is: " + incumbentSol.cost);
        }
コード例 #5
0
ファイル: Utility.cs プロジェクト: korr4k/TSPCsharp
        public static void PrintHeuristicSolution(Instance instance, Process process, PathStandard pathG, double incumbentCost, int typeSol)
        {
            //Init the StreamWriter for the current solution
            StreamWriter file = new StreamWriter(instance.InputFile + ".dat", false);

            //Printing the optimal solution and the GNUPlot input file
            for (int i = 0; i < instance.NNodes; i++)
            {
                /*
                 * Current GNUPlot format is:
                 *-- previus link --
                 *<Blank line>
                 * Xi Yi <index(i)>
                 * Xj Yj <index(i)>
                 *<Blank line>
                 *-- next link --
                 */
                file.WriteLine(instance.Coord[i].X + " " + instance.Coord[i].Y + " " + (i + 1));
                file.WriteLine(instance.Coord[pathG.path[i]].X + " " + instance.Coord[pathG.path[i]].Y + " " + (pathG.path[i] + 1) + "\nEdges");
            }

            //GNUPlot input file needs to be closed
            file.Close();

            //Accessing GNUPlot to read the file
            if (Program.VERBOSE >= -1)
            {
                if (pathG.cost != incumbentCost)
                {
                    PrintGNUPlot(process, instance.InputFile, typeSol, pathG.cost, incumbentCost);
                }
                else
                {
                    PrintGNUPlot(process, instance.InputFile, typeSol, pathG.cost, -1);
                }
            }
        }
コード例 #6
0
        static void LocalBranching(Cplex cplex, Instance instance, Process process, Random rnd, Stopwatch clock)
        {
            //Define the possible value that the radius can be assume
            int[] possibleRadius = { 3, 5, 7, 10 };

            //We start whit a radius of 3
            int currentRange = 0;

            //Don't want print every candidate incumbent solution inside the lazy constraint callback
            bool BlockPrint = false;

            //Define the vector where is  coded the incumbent solution
            double[] incumbentSol = new double[(instance.NNodes - 1) * instance.NNodes / 2];

            //Variable where is store the cost of the incumbent solution
            double incumbentCost = double.MaxValue;

            //Create the vector conten that it will contain the last best solution find befor time limit or when it can't be  improved
            instance.BestSol = new double[(instance.NNodes - 1) * instance.NNodes / 2];

            //Build the model
            INumVar[] x = Utility.BuildModel(cplex, instance, -1);

            //List use in NearestNeightbor method
            List <int>[] listArray = Utility.BuildSLComplete(instance);

            //Create a heuristic solution
            PathStandard heuristicSol = Utility.NearestNeightbor(instance, rnd, listArray);

            //Apply 2-opt algotithm in order to improve the cost to the heuristicSol
            TwoOpt(instance, heuristicSol);


            //The heuristic solution is the incumbent, translate the encode in the format used by Cplex
            for (int i = 0; i < instance.NNodes; i++)
            {
                int position = Utility.xPos(i, heuristicSol.path[i], instance.NNodes);

                //Set to one only the edge that belong to euristic solution
                incumbentSol[position] = 1;
            }

            //Installation of the Lazy Constraint Callback
            cplex.Use(new TSPLazyConsCallback(cplex, x, instance, process, BlockPrint));

            //Set the number of thread equal to the number of logical core present in the processor
            cplex.SetParam(Cplex.Param.Threads, cplex.GetNumCores());

            //Provide to Cplex a warm start
            cplex.AddMIPStart(x, incumbentSol);

            //Create a empty expression
            ILinearNumExpr expr = cplex.LinearNumExpr();

            //Create the firts member of the local branch constraint
            for (int i = 0; i < instance.NNodes; i++)
            {
                expr.AddTerm(x[Utility.xPos(i, heuristicSol.path[i], instance.NNodes)], 1);
            }

            //Create a new local branch constraint
            IAddable localBranchConstraint = cplex.Ge(expr, instance.NNodes - possibleRadius[currentRange]);

            //Add the constraint
            cplex.Add(localBranchConstraint);

            do
            {
                //Solve the model
                cplex.Solve();

                if (incumbentCost > cplex.GetObjValue())
                {
                    incumbentCost = cplex.ObjValue;
                    incumbentSol  = cplex.GetValues(x);

                    //Eliminate the previous local branch constraint
                    cplex.Remove(localBranchConstraint);

                    //Create an empty expression
                    expr = cplex.LinearNumExpr();

                    StreamWriter file = new StreamWriter(instance.InputFile + ".dat", false);

                    //Print the new incombent solution
                    for (int i = 0; i < instance.NNodes; i++)
                    {
                        for (int j = i + 1; j < instance.NNodes; j++)
                        {
                            int position = Utility.xPos(i, j, instance.NNodes);

                            if (incumbentSol[position] >= 0.5)
                            {
                                file.WriteLine(instance.Coord[i].X + " " + instance.Coord[i].Y + " " + (i + 1));
                                file.WriteLine(instance.Coord[j].X + " " + instance.Coord[j].Y + " " + (j + 1) + "\n");

                                //Create the firts member of the local branch constraint
                                expr.AddTerm(x[position], 1);
                            }
                        }
                    }

                    Utility.PrintGNUPlot(process, instance.InputFile, 1, incumbentCost, -1);
                    file.Close();

                    //Create a local branch constraint
                    localBranchConstraint = cplex.Ge(expr, instance.NNodes - possibleRadius[currentRange]);

                    //Add the local branch constraint
                    cplex.Add(localBranchConstraint);
                }
                else
                {
                    if (possibleRadius[currentRange] != 10)
                    {
                        //Increase the radius
                        currentRange++;

                        //Remove the previous local branch constraint
                        cplex.Remove(localBranchConstraint);

                        //Create the new local branch constraint
                        localBranchConstraint = cplex.Ge(expr, instance.NNodes - possibleRadius[currentRange]);

                        //Add the local branch constraint to the model
                        cplex.Add(localBranchConstraint);
                    }
                    else
                    {
                        break;
                    }
                }
            } while (clock.ElapsedMilliseconds / 1000.0 < instance.TimeLimit);

            //Store in the appropriate fields inside instance the last incumbent solution find and the relative cost
            instance.BestSol = incumbentSol;
            instance.BestLb  = incumbentCost;
        }
コード例 #7
0
        static void HardFixing(Cplex cplex, Instance instance, Process process, Random rnd, Stopwatch clock)
        {
            StreamWriter file;

            //Vector used to encode the path that rappresent the best integer solution note
            double[] currentIncumbentSol = new double[(instance.NNodes - 1) * instance.NNodes / 2];

            //Cost of the best integer solution note
            double currentIncumbentCost = Double.MaxValue;

            List <int>[] listArray = Utility.BuildSLComplete(instance);

            //Serve per differenziarsi rispetto alla lazy "normale" in cui stampo ogni soluzione intera(anche che non è un subtour)
            bool BlockPrint = false;

            const int VALUECONSITENOTIMPROV = 3;

            //Defined the max number of consecutive run of cplex whithout finds a improvement of the incumbent
            int consecutiveiterationNotImprov = VALUECONSITENOTIMPROV;

            //Defined the percentage of edge in the current solution that fixed
            double percentageFixing = 0.8;

            instance.BestSol = new double[(instance.NNodes - 1) * instance.NNodes / 2];

            //Create the model
            INumVar[] x = Utility.BuildModel(cplex, instance, -1);

            //Create a heuristic solution
            PathStandard heuristicSol = Utility.NearestNeightbor(instance, rnd, listArray);

            //Apply 2-opt algorithm in order to improve the costo o the heiristicSol
            TwoOpt(instance, heuristicSol);

            //The heuristic solution is the Incumbent, translate the encode in the format used by Cplex
            for (int i = 0; i < instance.NNodes; i++)
            {
                int position = Utility.xPos(i, heuristicSol.path[i], instance.NNodes);

                //Set to one only the edge that belong to heuristic solution
                currentIncumbentSol[position] = 1;
            }

            currentIncumbentCost = heuristicSol.cost;

            //Installation of the Lazy Constraint CallBack

            TSPLazyConsCallback tspLazy = new TSPLazyConsCallback(cplex, x, instance, process, BlockPrint);

            cplex.Use(tspLazy);

            //Provide to Cplex a warm start
            cplex.AddMIPStart(x, currentIncumbentSol);

            //Set the number of thread equal to the number of logical core present in the processor
            cplex.SetParam(Cplex.Param.Threads, cplex.GetNumCores());

            cplex.SetParam(Cplex.LongParam.IntSolLim, 2);

            do
            {
                //Modify the Model according to the current Incumbent solution
                Utility.ModifyModel(instance, x, rnd, percentageFixing, currentIncumbentSol);

                //Solve the model
                cplex.Solve();

                if (currentIncumbentCost > cplex.GetObjValue(Cplex.IncumbentId))
                {
                    file = new StreamWriter(instance.InputFile + ".dat", false);

                    currentIncumbentCost = cplex.GetObjValue(Cplex.IncumbentId);
                    currentIncumbentSol  = cplex.GetValues(x, Cplex.IncumbentId);

                    //Print solution
                    for (int i = 0; i < instance.NNodes; i++)
                    {
                        for (int j = i + 1; j < instance.NNodes; j++)
                        {
                            int position = Utility.xPos(i, j, instance.NNodes);

                            if (currentIncumbentSol[position] >= 0.5)
                            {
                                file.WriteLine(instance.Coord[i].X + " " + instance.Coord[i].Y + " " + (i + 1));
                                file.WriteLine(instance.Coord[j].X + " " + instance.Coord[j].Y + " " + (j + 1) + "\n");
                            }
                        }
                    }

                    file.Close();

                    Utility.PrintGNUPlot(process, instance.InputFile, 1, currentIncumbentCost, -1);

                    //Restorarion the variable consecutiveIterationNotImprov to the value VALUECONSITENOTIMPROV
                    consecutiveiterationNotImprov = VALUECONSITENOTIMPROV;
                }
                else
                {
                    //If don't have improvement decrease variable consecutiveIterationNotImprov
                    consecutiveiterationNotImprov--;
                }

                if (consecutiveiterationNotImprov == 0)
                {
                    if (percentageFixing > 0.2)
                    {
                        percentageFixing -= 0.1;
                        consecutiveiterationNotImprov = VALUECONSITENOTIMPROV;
                    }
                    else
                    {
                        consecutiveiterationNotImprov = VALUECONSITENOTIMPROV;
                    }
                }

                //Restoration the lower and upper bound of all variable.
                for (int i = 0; i < x.Length; i++)
                {
                    x[i].LB = 0;
                    x[i].UB = 1;
                }
            } while (clock.ElapsedMilliseconds / 1000.0 < instance.TimeLimit);

            instance.XBest   = currentIncumbentCost;
            instance.BestSol = currentIncumbentSol;

            //Empty line
            cplex.Output().WriteLine();

            cplex.Output().WriteLine("x = " + instance.XBest + "\n");

            if (Program.VERBOSE >= -1)
            {
                cplex.ExportModel(instance.InputFile + ".lp");
            }
        }
コード例 #8
0
        static void VNS(Instance instance, PathStandard currentSol, Random rnd)
        {
            int a, b, c, d, e, f;

            a = rnd.Next(currentSol.path.Length);
            b = currentSol.path[a];

            do
            {
                c = rnd.Next(currentSol.path.Length);
                d = currentSol.path[c];
            } while ((a == c && b == d) || a == d || b == c);

            do
            {
                e = rnd.Next(currentSol.path.Length);
                f = currentSol.path[e];
            } while ((e == a && f == b) || e == b || f == a || (e == c && f == d) || e == d || f == c);

            List <int> order = new List <int>();

            for (int i = 0, index = 0; i < currentSol.path.Length && order.Count != 4; i++, index = currentSol.path[index])
            {
                if (a == index)
                {
                    order.Add(a);
                    order.Add(b);
                    i++;
                    index = currentSol.path[index];
                }
                else if (c == index)
                {
                    order.Add(c);
                    order.Add(d);
                    i++;
                    index = currentSol.path[index];
                }
                else if (e == index)
                {
                    order.Add(e);
                    order.Add(f);
                    i++;
                    index = currentSol.path[index];
                }
            }

            if (order[0] != a && order[2] != a)
            {
                order.Add(a);
                order.Add(b);
            }
            else if (order[0] != c && order[2] != c)
            {
                order.Add(c);
                order.Add(d);
            }
            else
            {
                order.Add(e);
                order.Add(f);
            }

            Utility.SwapRoute(order[2], order[1], currentSol);

            currentSol.path[order[0]] = order[2];

            Utility.SwapRoute(order[4], order[3], currentSol);

            currentSol.path[order[1]] = order[4];

            currentSol.path[order[3]] = order[5];

            currentSol.cost += Point.Distance(instance.Coord[order[0]], instance.Coord[order[2]], instance.EdgeType) +
                               Point.Distance(instance.Coord[order[1]], instance.Coord[order[4]], instance.EdgeType) +
                               Point.Distance(instance.Coord[order[3]], instance.Coord[order[5]], instance.EdgeType) -
                               Point.Distance(instance.Coord[a], instance.Coord[b], instance.EdgeType) -
                               Point.Distance(instance.Coord[c], instance.Coord[d], instance.EdgeType) -
                               Point.Distance(instance.Coord[e], instance.Coord[f], instance.EdgeType);
        }
コード例 #9
0
        static void TabuSearch(Instance instance, Process process, Tabu tabu, PathStandard currentSol, PathStandard incumbentPath, Stopwatch clock)
        {
            int    typeSol;
            int    indexStart = 0;
            string nextBestMove = "";
            string nextWorstMove = "";
            double bestGain = double.MaxValue;
            double worstGain = double.MinValue;
            int    a, b, c, d;
            double distAC, distBD, distTotABCD;

            do
            {
                for (int j = 0; j < instance.NNodes; j++, indexStart = b)
                {
                    a = indexStart;
                    b = currentSol.path[a];
                    c = currentSol.path[b];
                    d = currentSol.path[c];

                    for (int i = 0; i < instance.NNodes - 3; i++, c = d, d = currentSol.path[c])
                    {
                        if (!tabu.IsTabu(a, c) && !tabu.IsTabu(b, d))
                        {
                            distAC = Point.Distance(instance.Coord[a], instance.Coord[c], instance.EdgeType);
                            distBD = Point.Distance(instance.Coord[b], instance.Coord[d], instance.EdgeType);

                            distTotABCD = Point.Distance(instance.Coord[a], instance.Coord[b], instance.EdgeType) +
                                          Point.Distance(instance.Coord[c], instance.Coord[d], instance.EdgeType);

                            if ((distAC + distBD) - distTotABCD < bestGain && (distAC + distBD) != distTotABCD)
                            {
                                nextBestMove = a + ";" + b + ";" + c + ";" + d;
                                bestGain     = (distAC + distBD) - distTotABCD;
                            }

                            if ((distAC + distBD) - distTotABCD > worstGain && (distAC + distBD) != distTotABCD)
                            {
                                nextWorstMove = a + ";" + b + ";" + c + ";" + d;
                                worstGain     = (distAC + distBD) - distTotABCD;
                            }
                        }
                    }
                }

                string[] currentElements = nextBestMove.Split(';');
                a = int.Parse(currentElements[0]);
                b = int.Parse(currentElements[1]);
                c = int.Parse(currentElements[2]);
                d = int.Parse(currentElements[3]);

                Utility.SwapRoute(c, b, currentSol);

                currentSol.path[a] = c;
                currentSol.path[b] = d;

                currentSol.cost += bestGain;

                if (incumbentPath.cost > currentSol.cost)
                {
                    incumbentPath = (PathGenetic)currentSol.Clone();
                }

                if (bestGain < 0)
                {
                    typeSol = 0;
                }
                else
                {
                    tabu.AddTabu(a, b, c, d);
                    typeSol = 1;
                }

                Utility.PrintHeuristicSolution(instance, process, currentSol, incumbentPath.cost, typeSol);
                bestGain  = double.MaxValue;
                worstGain = double.MinValue;
            } while (clock.ElapsedMilliseconds / 1000.0 < instance.TimeLimit);
        }