Exemplo n.º 1
0
    } // END CreateMasterILP

    public static void Main(string[] args)
    {
        try
        {
            string fileName = "../../../../examples/data/atsp.dat";

            // Check the command line arguments

            if (args.Length != 1 && args.Length != 2)
            {
                Usage();
                return;
            }

            if (!(args[0].Equals("0") || args[0].Equals("1")))
            {
                Usage();
                return;
            }

            bool sepFracSols = (args[0].ToCharArray()[0] == '0' ? false : true);

            if (sepFracSols)
            {
                System.Console.WriteLine("Benders' cuts separated to cut off: " +
                                         "Integer and fractional infeasible solutions.");
            }
            else
            {
                System.Console.WriteLine("Benders' cuts separated to cut off: " +
                                         "Only integer infeasible solutions.");
            }

            if (args.Length == 2)
            {
                fileName = args[1];
            }

            // Read arc_costs from data file (17 city problem)

            Data data = new Data(fileName);

            // create master ILP

            int         numNodes = data.numNodes;
            Cplex       cplex    = new Cplex();
            IIntVar[][] x        = new IIntVar[numNodes][];
            CreateMasterILP(cplex, data, x);

            // Create workerLP for Benders' cuts separation

            WorkerLP workerLP = new WorkerLP(numNodes);

            // Set up the cut callback to be used for separating Benders' cuts

            cplex.SetParam(Cplex.Param.Preprocessing.Presolve, false);

            // Set the maximum number of threads to 1.
            // This instruction is redundant: If MIP control callbacks are registered,
            // then by default CPLEX uses 1 (one) thread only.
            // Note that the current example may not work properly if more than 1 threads
            // are used, because the callback functions modify shared global data.
            // We refer the user to the documentation to see how to deal with multi-thread
            // runs in presence of MIP control callbacks.

            cplex.SetParam(Cplex.Param.Threads, 1);

            // Turn on traditional search for use with control callbacks

            cplex.SetParam(Cplex.Param.MIP.Strategy.Search, Cplex.MIPSearch.Traditional);

            cplex.Use(new BendersLazyConsCallback(x, workerLP));
            if (sepFracSols)
            {
                cplex.Use(new BendersUserCutCallback(x, workerLP));
            }

            // Solve the model and write out the solution

            if (cplex.Solve())
            {
                System.Console.WriteLine();
                System.Console.WriteLine("Solution status: " + cplex.GetStatus());
                System.Console.WriteLine("Objective value: " + cplex.ObjValue);

                if (cplex.GetStatus().Equals(Cplex.Status.Optimal))
                {
                    // Write out the optimal tour

                    int        i, j;
                    double[][] sol  = new double[numNodes][];
                    int[]      succ = new int[numNodes];
                    for (j = 0; j < numNodes; ++j)
                    {
                        succ[j] = -1;
                    }

                    for (i = 0; i < numNodes; ++i)
                    {
                        sol[i] = cplex.GetValues(x[i]);
                        for (j = 0; j < numNodes; ++j)
                        {
                            if (sol[i][j] > 1e-03)
                            {
                                succ[i] = j;
                            }
                        }
                    }

                    System.Console.WriteLine("Optimal tour:");
                    i = 0;
                    while (succ[i] != 0)
                    {
                        System.Console.Write(i + ", ");
                        i = succ[i];
                    }
                    System.Console.WriteLine(i);
                }
                else
                {
                    System.Console.WriteLine("Solution status is not Optimal");
                }
            }
            else
            {
                System.Console.WriteLine("No solution available");
            }

            workerLP.End();
            cplex.End();
        }
        catch (ILOG.Concert.Exception ex)
        {
            System.Console.WriteLine("Concert Error: " + ex);
        }
        catch (InputDataReader.InputDataReaderException ex)
        {
            System.Console.WriteLine("Data Error: " + ex);
        }
        catch (System.IO.IOException ex)
        {
            System.Console.WriteLine("IO Error: " + ex);
        }
    } // END Main
Exemplo n.º 2
0
 internal BendersUserCutCallback(IIntVar[][] x, WorkerLP workerLP)
 {
     this.x = x;
      this.workerLP = workerLP;
      numNodes = x.Length;
 }
Exemplo n.º 3
0
 internal BendersUserCutCallback(IIntVar[][] x, WorkerLP workerLP)
 {
     this.x        = x;
     this.workerLP = workerLP;
     numNodes      = x.Length;
 }
Exemplo n.º 4
0
    public static void Main(string[] args)
    {
        try
          {
         string fileName = "../../../../examples/data/atsp.dat";

         // Check the command line arguments

         if ( args.Length != 1 && args.Length != 2 )
         {
            Usage();
            return;
         }

         if ( ! (args[0].Equals("0") || args[0].Equals("1")) )
         {
            Usage();
            return;
         }

         bool sepFracSols = (args[0].ToCharArray()[0] == '0' ? false : true);

         if ( sepFracSols )
         {
            System.Console.WriteLine("Benders' cuts separated to cut off: " +
                                     "Integer and fractional infeasible solutions.");
         }
         else
         {
            System.Console.WriteLine("Benders' cuts separated to cut off: " +
                                     "Only integer infeasible solutions.");
         }

         if ( args.Length == 2 ) fileName = args[1];

         // Read arc_costs from data file (17 city problem)

         Data data = new Data(fileName);

         // create master ILP

         int numNodes = data.numNodes;
         Cplex cplex = new Cplex();
         IIntVar[][] x = new IIntVar[numNodes][];
         CreateMasterILP(cplex, data, x);

         // Create workerLP for Benders' cuts separation

         WorkerLP workerLP = new WorkerLP(numNodes);

         // Set up the cut callback to be used for separating Benders' cuts

         cplex.SetParam(Cplex.Param.Preprocessing.Presolve, false);

         // Set the maximum number of threads to 1.
         // This instruction is redundant: If MIP control callbacks are registered,
         // then by default CPLEX uses 1 (one) thread only.
         // Note that the current example may not work properly if more than 1 threads
         // are used, because the callback functions modify shared global data.
         // We refer the user to the documentation to see how to deal with multi-thread
         // runs in presence of MIP control callbacks.

         cplex.SetParam(Cplex.Param.Threads, 1);

         // Turn on traditional search for use with control callbacks

         cplex.SetParam(Cplex.Param.MIP.Strategy.Search, Cplex.MIPSearch.Traditional);

         cplex.Use(new BendersLazyConsCallback(x, workerLP));
         if ( sepFracSols )
            cplex.Use(new BendersUserCutCallback(x, workerLP));

         // Solve the model and write out the solution

         if ( cplex.Solve() )
         {
            System.Console.WriteLine();
            System.Console.WriteLine("Solution status: " + cplex.GetStatus());
            System.Console.WriteLine("Objective value: " + cplex.ObjValue);

            if ( cplex.GetStatus().Equals(Cplex.Status.Optimal) )
            {
               // Write out the optimal tour

               int i, j;
               double[][] sol = new double[numNodes][];
               int[] succ = new int[numNodes];
               for (j = 0; j < numNodes; ++j)
                  succ[j] = -1;

               for (i = 0; i < numNodes; ++i)
               {
                  sol[i] = cplex.GetValues(x[i]);
                  for (j = 0; j < numNodes; ++j)
                  {
                     if ( sol[i][j] > 1e-03 ) succ[i] = j;
                  }
               }

               System.Console.WriteLine("Optimal tour:");
               i = 0;
               while ( succ[i] != 0 )
               {
                  System.Console.Write(i + ", ");
                  i = succ[i];
               }
               System.Console.WriteLine(i);
            }
            else
            {
               System.Console.WriteLine("Solution status is not Optimal");
            }
         }
         else
         {
            System.Console.WriteLine("No solution available");
         }

         workerLP.End();
         cplex.End();
          }
          catch (ILOG.Concert.Exception ex)
          {
         System.Console.WriteLine("Concert Error: " + ex);
          }
          catch (InputDataReader.InputDataReaderException ex)
          {
         System.Console.WriteLine("Data Error: " + ex);
          }
          catch (System.IO.IOException ex)
          {
         System.Console.WriteLine("IO Error: " + ex);
          }
    }