Пример #1
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;
        }
Пример #2
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");
            }
        }