コード例 #1
0
        static void Main()
        {
            CP      cp          = new CP();
            IIntVar Belgium     = cp.IntVar(0, 3);
            IIntVar Denmark     = cp.IntVar(0, 3);
            IIntVar France      = cp.IntVar(0, 3);
            IIntVar Germany     = cp.IntVar(0, 3);
            IIntVar Netherlands = cp.IntVar(0, 3);
            IIntVar Luxembourg  = cp.IntVar(0, 3);

            cp.Add(cp.Neq(Belgium, France));
            cp.Add(cp.Neq(Belgium, Germany));
            cp.Add(cp.Neq(Belgium, Netherlands));
            cp.Add(cp.Neq(Belgium, Luxembourg));
            cp.Add(cp.Neq(Denmark, Germany));
            cp.Add(cp.Neq(France, Germany));
            cp.Add(cp.Neq(France, Luxembourg));
            cp.Add(cp.Neq(Germany, Luxembourg));
            cp.Add(cp.Neq(Germany, Netherlands));

            // Search for a solution
            if (cp.Solve())
            {
                Console.WriteLine("Solution: ");
                Console.WriteLine("Belgium:     " + Names[cp.GetIntValue(Belgium)]);
                Console.WriteLine("Denmark:     " + Names[cp.GetIntValue(Denmark)]);
                Console.WriteLine("France:      " + Names[cp.GetIntValue(France)]);
                Console.WriteLine("Germany:     " + Names[cp.GetIntValue(Germany)]);
                Console.WriteLine("Netherlands: " + Names[cp.GetIntValue(Netherlands)]);
                Console.WriteLine("Luxembourg:  " + Names[cp.GetIntValue(Luxembourg)]);
            }
        }
コード例 #2
0
    private void BuildModel()
    {
        // Create the decision variables, cost, and the model
        scene = new IIntVar[numScenes];
        for (int s = 0; s < numScenes; s++)
        {
            scene[s] = cp.IntVar(0, numScenes - 1);
        }

        // Expression representing the global cost
        idleCost = cp.IntExpr();

        // Make the slot-based secondary model
        IIntVar[] slot = new IIntVar[numScenes];
        for (int s = 0; s < numScenes; s++)
        {
            slot[s] = cp.IntVar(0, numScenes - 1);
        }
        cp.Add(cp.Inverse(scene, slot));

        // Loop over all actors, building cost
        for (int a = 0; a < numActors; a++)
        {
            // Expression for the waiting time for this actor
            IIntExpr actorWait = cp.IntExpr();

            // Calculate the first and last slots where this actor plays
            List <IIntVar> position = new List <IIntVar>();

            System.Collections.IEnumerator en = actorInScene[a].GetEnumerator();
            while (en.MoveNext())
            {
                position.Add(slot[(int)en.Current]);
            }

            IIntExpr firstSlot = cp.Min(position.ToArray());
            IIntExpr lastSlot  = cp.Max(position.ToArray());

            // If an actor is not in a scene, he waits
            // if he is on set when the scene is filmed
            for (int s = 0; s < numScenes; s++)
            {
                if (!actorInScene[a].Contains(s))
                { // not in scene
                    IIntExpr wait = cp.And(cp.Le(firstSlot, slot[s]), cp.Le(
                                               slot[s], lastSlot));
                    actorWait = cp.Sum(actorWait, cp.Prod(sceneDuration[s],
                                                          wait));
                }
            }

            // Accumulate the cost of waiting time for this actor
            idleCost = cp.Sum(idleCost, cp.Prod(actorPay[a], actorWait));
        }
        cp.Add(cp.Minimize(idleCost));
    }
コード例 #3
0
        //
        // Matrix operations
        //
        static private IIntVar[][] Transpose(IIntVar[][] x)
        {
            int m = x.Length;
            int n = x[0].Length;

            IIntVar[][] y = new IIntVar[n][];
            for (int i = 0; i < n; i++)
            {
                y[i] = new IIntVar[m];
                for (int j = 0; j < m; j++)
                {
                    y[i][j] = x[j][i];
                }
            }
            return(y);
        }
コード例 #4
0
 static private void SolveModel(string filename)
 {
     try {
         CP cp = new CP();
         cp.ImportModel(filename);
         // Force blue color (zero) for France:
         IIntVar varFrance = cp.GetIIntVar("France");
         varFrance.Max = 0;
         // Search for a solution
         if (cp.Solve())
         {
             Console.WriteLine("Solution: ");
             IIntVar[] vars = cp.GetAllIIntVars();
             for (int i = 0; i < vars.Length; i++)
             {
                 Console.WriteLine(vars[i].Name + ": " + Names[cp.GetIntValue(vars[i])]);
             }
         }
     } catch (ILOG.Concert.Exception e) {
         Console.WriteLine("ERROR:" + e);
     }
 }
コード例 #5
0
        internal static IIntVar[][][][] Generate4DNumVar(IMPModeler model,
                                                         int intCount1, int intCount2, int intCount3, int intCount4)
        {
            if (intCount1 < 0)
            {
                intCount1 = 0;
            }

            IIntVar[][][][] x = new IIntVar[intCount1][][][];
            for (int i = 0; i < intCount1; i++)
            {
                x[i] = new IIntVar[intCount2][][];
                for (int j = 0; j < intCount2; j++)
                {
                    x[i][j] = new IIntVar[intCount3][];
                    for (int k = 0; k < intCount3; k++)
                    {
                        x[i][j][k] = model.BoolVarArray(intCount4);
                    }
                }
            }

            return(x);
        }
コード例 #6
0
 static private void CreateModel(string filename)
 {
     try {
         CP      cp          = new CP();
         IIntVar Belgium     = cp.IntVar(0, 3, "Belgium");
         IIntVar Denmark     = cp.IntVar(0, 3, "Denmark");
         IIntVar France      = cp.IntVar(0, 3, "France");
         IIntVar Germany     = cp.IntVar(0, 3, "Germany");
         IIntVar Netherlands = cp.IntVar(0, 3, "Netherlands");
         IIntVar Luxembourg  = cp.IntVar(0, 3, "Luxembourg");
         cp.Add(cp.Neq(Belgium, France));
         cp.Add(cp.Neq(Belgium, Germany));
         cp.Add(cp.Neq(Belgium, Netherlands));
         cp.Add(cp.Neq(Belgium, Luxembourg));
         cp.Add(cp.Neq(Denmark, Germany));
         cp.Add(cp.Neq(France, Germany));
         cp.Add(cp.Neq(France, Luxembourg));
         cp.Add(cp.Neq(Germany, Luxembourg));
         cp.Add(cp.Neq(Germany, Netherlands));
         cp.DumpModel(filename);
     } catch (ILOG.Concert.Exception e) {
         Console.WriteLine("ERROR:" + e);
     }
 }
コード例 #7
0
        static void Main(string[] args)
        {
            String filename;

            if (args.Length > 0)
            {
                filename = args[0];
            }
            else
            {
                filename = "../../../../examples/data/plant_location.data";
            }

            DataReader data       = new DataReader(filename);
            int        nbCustomer = data.Next();
            int        nbLocation = data.Next();

            int[][] cost = new int[nbCustomer][];
            for (int c = 0; c < nbCustomer; c++)
            {
                cost[c] = new int[nbLocation];
                for (int l = 0; l < nbLocation; l++)
                {
                    cost[c][l] = data.Next();
                }
            }
            int[] demand      = new int[nbCustomer];
            int   totalDemand = 0;

            for (int c = 0; c < nbCustomer; c++)
            {
                demand[c]    = data.Next();
                totalDemand += demand[c];
            }
            int[] fixedCost = new int[nbLocation];
            for (int l = 0; l < nbLocation; l++)
            {
                fixedCost[l] = data.Next();
            }
            int[] capacity = new int[nbLocation];
            for (int l = 0; l < nbLocation; l++)
            {
                capacity[l] = data.Next();
            }

            CP cp = new CP();

            IIntVar[] cust = new IIntVar[nbCustomer];
            for (int c = 0; c < nbCustomer; c++)
            {
                cust[c] = cp.IntVar(0, nbLocation - 1);
            }
            IIntVar[] open = new IIntVar[nbLocation];
            IIntVar[] load = new IIntVar[nbLocation];
            for (int l = 0; l < nbLocation; l++)
            {
                open[l] = cp.IntVar(0, 1);
                load[l] = cp.IntVar(0, capacity[l]);
            }

            for (int l = 0; l < nbLocation; l++)
            {
                cp.Add(cp.Eq(open[l], cp.Gt(load[l], 0)));
            }
            cp.Add(cp.Pack(load, cust, demand));
            IIntExpr obj = cp.Prod(open, fixedCost);

            for (int c = 0; c < nbCustomer; c++)
            {
                obj = cp.Sum(obj, cp.Element(cost[c], cust[c]));
            }
            cp.Add(cp.Minimize(obj));

            cp.AddKPI(cp.Quot(totalDemand, cp.ScalProd(open, capacity)), "Mean occupancy");
            INumExpr[] usage = new INumExpr[nbLocation];
            for (int w = 0; w < nbLocation; w++)
            {
                usage[w] = cp.Sum(cp.Quot(load[w], capacity[w]), cp.Diff(1, open[w]));
            }
            cp.AddKPI(cp.Min(usage), "Min occupancy");

            int[] custValues =
            {
                19,  0, 11,  8, 29,  9, 29, 28, 17, 15,  7,  9, 18, 15,  1, 17, 25, 18, 17, 27,
                22,  1, 26,  3, 22,  2, 20, 27,  2, 16,  1, 16, 12, 28, 19,  2, 20, 14, 13, 27,
                3,   9, 18,  0, 13, 19, 27, 14, 12,  1, 15, 14, 17,  0,  7, 12, 11,  0, 25, 16,
                22, 13, 16,  8, 18, 27, 19, 23, 26, 13, 11, 11, 19, 22, 28, 26, 23,  3, 18, 23,
                26, 14, 29, 18,  9,  7, 12, 27,  8, 20
            };

            ISolution sol = cp.Solution();

            for (int c = 0; c < nbCustomer; c++)
            {
                sol.SetValue(cust[c], custValues[c]);
            }

            cp.SetStartingPoint(sol);
            cp.SetParameter(CP.DoubleParam.TimeLimit, 10);
            cp.SetParameter(CP.IntParam.LogPeriod, 10000);
            cp.Solve();
        }
コード例 #8
0
ファイル: Truckfleet.cs プロジェクト: andreasmattas/testcode
        public static void Main(string[] args)
        {
            CP cp = new CP();
            int nbTruckConfigs = 7; // number of possible configurations for the truck
            int nbOrders       = 21;
            int nbCustomers    = 3;
            int nbTrucks       = 15; //max number of travels of the truck
            int[]   maxTruckConfigLoad = { //Capacity of the truck depends on its config
            11, 11, 11, 11,10,10,10};
            int     maxLoad        = Max(maxTruckConfigLoad) ;
            int[]   customerOfOrder = {
            0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
            1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
            2};
            int[]   volumes = {
            3, 4, 3, 2, 5, 4, 11, 4, 5, 2,
            4, 7, 3, 5, 2, 5, 6, 11, 1, 6,
            3};
            int[]   colors = {
            1, 2, 0, 1, 1, 1, 0, 0, 0, 0,
            2, 2, 2 ,0, 2, 1, 0, 2, 0, 0,
            0};
            int[]   truckCost = { //cost for loading a truck of a given config
            2, 2, 2, 3, 3, 3, 4};

            //Decision variables
            IIntVar[] truckConfigs = cp.IntVarArray(nbTrucks,0,nbTruckConfigs-1); //configuration of the truck
            IIntVar[] where = cp.IntVarArray(nbOrders, 0, nbTrucks - 1); //In which truck is an order
            IIntVar[] load = cp.IntVarArray(nbTrucks, 0, maxLoad); //load of a truck
            IIntVar numUsed = cp.IntVar(0, nbTrucks); // number of trucks used
            IIntVar[] customerOfTruck = cp.IntVarArray(nbTrucks, 0, nbCustomers);

            // transition costs between trucks
            IIntTupleSet costTuples = cp.IntTable(3);
            cp.AddTuple(costTuples, new int[] {0,0,0});
            cp.AddTuple(costTuples, new int[] {0,1,0});
            cp.AddTuple(costTuples, new int[] {0,2,0});
            cp.AddTuple(costTuples, new int[] {0,3,10});
            cp.AddTuple(costTuples, new int[] {0,4,10});
            cp.AddTuple(costTuples, new int[] {0,5,10});
            cp.AddTuple(costTuples, new int[] {0,6,15});
            cp.AddTuple(costTuples, new int[] {1,0,0});
            cp.AddTuple(costTuples, new int[] {1,1,0});
            cp.AddTuple(costTuples, new int[] {1,2,0});
            cp.AddTuple(costTuples, new int[] {1,3,10});
            cp.AddTuple(costTuples, new int[] {1,4,10});
            cp.AddTuple(costTuples, new int[] {1,5,10});
            cp.AddTuple(costTuples, new int[] {1,6,15});
            cp.AddTuple(costTuples, new int[] {2,0,0});
            cp.AddTuple(costTuples, new int[] {2,1,0});
            cp.AddTuple(costTuples, new int[] {2,2,0});
            cp.AddTuple(costTuples, new int[] {2,3,10});
            cp.AddTuple(costTuples, new int[] {2,4,10});
            cp.AddTuple(costTuples, new int[] {2,5,10});
            cp.AddTuple(costTuples, new int[] {2,6,15});
            cp.AddTuple(costTuples, new int[] {3,0,3});
            cp.AddTuple(costTuples, new int[] {3,1,3});
            cp.AddTuple(costTuples, new int[] {3,2,3});
            cp.AddTuple(costTuples, new int[] {3,3,0});
            cp.AddTuple(costTuples, new int[] {3,4,10});
            cp.AddTuple(costTuples, new int[] {3,5,10});
            cp.AddTuple(costTuples, new int[] {3,6,15});
            cp.AddTuple(costTuples, new int[] {4,0,3});
            cp.AddTuple(costTuples, new int[] {4,1,3});
            cp.AddTuple(costTuples, new int[] {4,2,3});
            cp.AddTuple(costTuples, new int[] {4,3,10});
            cp.AddTuple(costTuples, new int[] {4,4,0});
            cp.AddTuple(costTuples, new int[] {4,5,10});
            cp.AddTuple(costTuples, new int[] {4,6,15});
            cp.AddTuple(costTuples, new int[] {5,0,3});
            cp.AddTuple(costTuples, new int[] {5,1,3});
            cp.AddTuple(costTuples, new int[] {5,2,3});
            cp.AddTuple(costTuples, new int[] {5,3,10});
            cp.AddTuple(costTuples, new int[] {5,4,10});
            cp.AddTuple(costTuples, new int[] {5,5,0});
            cp.AddTuple(costTuples, new int[] {5,6,15});
            cp.AddTuple(costTuples, new int[] {6,0,3});
            cp.AddTuple(costTuples, new int[] {6,1,3});
            cp.AddTuple(costTuples, new int[] {6,2,3});
            cp.AddTuple(costTuples, new int[] {6,3,10});
            cp.AddTuple(costTuples, new int[] {6,4,10});
            cp.AddTuple(costTuples, new int[] {6,5,10});
            cp.AddTuple(costTuples, new int[] {6,6,0});

            IIntVar[] transitionCost = cp.IntVarArray(nbTrucks-1, 0, 1000);
            for (int i = 1; i < nbTrucks; i++) {
            IIntVar[] auxVars = new IIntVar[3];
            auxVars[0]= truckConfigs[i-1];
            auxVars[1]= truckConfigs[i];
            auxVars[2]= transitionCost[i-1];
            cp.Add(cp.AllowedAssignments(auxVars, costTuples));
            }

            // constrain the volume of the orders in each truck
            cp.Add(cp.Pack(load, where, volumes, numUsed));
            for (int i = 0; i < nbTrucks; i++) {
            cp.Add(cp.Le(load[i], cp.Element(maxTruckConfigLoad, truckConfigs[i])));
            }

            // compatibility between the colors of an order and the configuration of its truck
            int[][] allowedContainerConfigs = new int[3][];
            allowedContainerConfigs[0] = new int[] {0, 3, 4, 6};
            allowedContainerConfigs[1] = new int[] {1, 3, 5, 6};
            allowedContainerConfigs[2] = new int[] {2, 4, 5, 6};
            for (int j = 0; j < nbOrders; j++) {
            IIntVar configOfContainer = cp.IntVar(allowedContainerConfigs[colors[j]]);
            cp.Add(cp.Eq(configOfContainer, cp.Element(truckConfigs,where[j])));
            }

            // only one customer per truck
            for (int j = 0; j < nbOrders; j++) {
            cp.Add(cp.Eq( cp.Element(customerOfTruck,where[j]), customerOfOrder[j]));
            }

            // non used trucks are at the end
            for (int j = 1; j < nbTrucks; j++) {
            cp.Add(cp.Or( cp.Gt(load[j-1], 0) , cp.Eq(load[j], 0)));
            }

            // Dominance: the non used trucks keep the last used configuration
            cp.Add(cp.Gt(load[0],0));
            for (int i = 1; i < nbTrucks; i++) {
            cp.Add(cp.Or(cp.Gt(load[i], 0), cp.Eq(truckConfigs[i], truckConfigs[i-1])));
            }

            //Dominance:  regroup deliveries with same configuration
            for (int i = nbTrucks-2; i >0; i--) {
            IConstraint Ct = cp.TrueConstraint();
            for (int p = i+1; p < nbTrucks; p++)
                Ct = cp.And( cp.Neq(truckConfigs[p], truckConfigs[i-1]) , Ct);
            cp.Add( cp.Or(cp.Eq(truckConfigs[i], truckConfigs[i-1]), Ct));
            }

            // Objective: first criterion for minimizing the cost for configuring and loading trucks
            //            second criterion for minimizing the number of trucks

            IIntExpr obj1 = cp.Constant(0);
            for(int i = 0; i < nbTrucks; i++){
            obj1 = cp.Sum(obj1, cp.Prod( cp.Element(truckCost,truckConfigs[i]),cp.Neq(load[i],0)));
            }
            obj1 = cp.Sum(obj1, cp.Sum(transitionCost));

            IIntExpr obj2 = numUsed;

            // Search strategy: first assign order to truck
            ISearchPhase phase = cp.SearchPhase(where);

            // Multicriteria lexicographic optimization
            cp.Add(cp.Minimize(cp.StaticLex(obj1,obj2)));
            cp.SetParameter(CP.DoubleParam.TimeLimit, 20);
            cp.SetParameter(CP.IntParam.LogPeriod, 50000);
            cp.Solve(phase);
            double[] obj = cp.GetObjValues();
            Console.WriteLine("Configuration cost: "+ (int)obj[0] +
                           " Number of Trucks: " + (int)obj[1]);
            for(int i = 0; i < nbTrucks; i++) {
            if (cp.GetValue(load[i]) > 0) {
                Console.Write("Truck " +  i +
                              ": Config=" +  cp.GetIntValue(truckConfigs[i])
                              + " Items= ");
                for (int j = 0; j < nbOrders; j++) {
                    if (cp.GetValue(where[j]) == i) {
                         Console.Write("<" + j + "," + colors[j] + "," + volumes[j] + "> ");
                    }
                }
                Console.WriteLine();
            }
            }
        }
コード例 #9
0
ファイル: Steelmill.cs プロジェクト: andreasmattas/testcode
        static void Main(string[] args)
        {
            CP cp = new CP();

            int weightSum=0;
            for (int o = 0; o < nbOrders; o++)
                  weightSum += weight[o];

            IIntVar[] where = new IIntVar[nbOrders];
            for(int o = 0; o < nbOrders; o++)
              where[o] = cp.IntVar(0, nbSlabs-1);
            IIntVar[] load = new IIntVar[nbSlabs];
            for(int m = 0; m < nbSlabs; m++)
              load[m] = cp.IntVar(0, weightSum);

            // Pack constraint
            cp.Add(cp.Pack(load, where, weight));

            // Color constraints
            for(int m = 0; m < nbSlabs; m++) {
                  IIntExpr[] colorExpArray = new IIntExpr[nbColors];
                  for(int c = 0; c < nbColors; c++) {
                    IConstraint orCt =  cp.FalseConstraint();
                    for(int o = 0; o < nbOrders; o++){
                          if (colors[o] == c){
                            orCt = cp.Or(orCt, cp.Eq(where[o], m));
                          }
                    }
                    colorExpArray[c] =  cp.IntExpr(orCt);
                  }
                  cp.Add(cp.Le(cp.Sum(colorExpArray), 2));
            }

            // Objective function
            int sizeLossValues = capacities[capacities.Length-1] - capacities[0] + 1;
            int[] lossValues  = new int[sizeLossValues];
            lossValues[0]= 0;
            int indexValue= 1;
            for(int q = 1; q < capacities.Length; q++){
                  for(int p = capacities[q-1] + 1; p <= capacities[q]; p++){
                    lossValues[indexValue] = capacities[q] - p;
                    indexValue++;
                  }
            }
            IIntExpr obj = cp.Constant(0);
            for(int m = 0; m < nbSlabs; m++){
                  obj = cp.Sum(obj,  cp.Element(lossValues, load[m]));
            }
            cp.Add(cp.Minimize(obj));

            // - A symmetry breaking constraint that is useful for small instances
            for(int m = 1; m < nbSlabs; m++){
                  cp.Add(cp.Ge(load[m-1],load[m]));
            }

            if (cp.Solve()){
              Console.WriteLine("Optimal value: " + cp.GetValue(obj));
              for (int m = 0; m < nbSlabs; m++) {
            int p = 0;
            for (int o = 0; o < nbOrders; o++)
              if (cp.GetValue(where[o]) == m) ++p;
            if (p == 0) continue;
            Console.Write("Slab " + m + " is used for order");
            if (p > 1) Console.Write("s");
            Console.Write(" :");
            for (int o = 0; o < nbOrders; o++) {
              if (cp.GetValue(where[o]) == m)
                Console.Write(" " + o);
            }
            Console.WriteLine();
              }
            }
        }
コード例 #10
0
        static void Main(string[] args)
        {
            CP cp = new CP();

            coaching = new int[nbPersons];
            int i;

            for (i = 0; i < nbPersons; i++)
            {
                coaching[i] = -1;
            }
            for (i = 0; i < 12; i = i + 2) // the 12 first of Service A are couples of coached/coach
            {
                coaching[i]     = i + 1;
                coaching[i + 1] = i;
            }
            for (i = 20; i < 32; i = i + 2)// the 12 first of Service B are couples of coached/coach
            {
                coaching[i]     = i + 1;
                coaching[i + 1] = i;
            }
            for (i = 40; i < nbPersons; i += 5) // the 4 first of Services C,D,E,F are couples of coached/coach
            {
                coaching[i]     = i + 1;
                coaching[i + 1] = i;
                coaching[i + 2] = i + 3;
                coaching[i + 3] = i + 2;
            }
            //compute the possible solutions of a team
            IIntTupleSet tupleSet = MakeTeamTuples(cp);

            // groups[i] represents the ordered set of people in the team i
            IIntVar[][] groups = new IIntVar[nbTeams][];
            for (i = 0; i < nbTeams; i++)
            {
                groups[i] = cp.IntVarArray(teamSize, 0, nbPersons - 1);
                cp.Add(cp.AllowedAssignments(groups[i], tupleSet));
            }

            IIntVar[] allVars = cp.IntVarArray(nbPersons);
            int       s       = 0;
            int       w;
            int       p;

            for (w = 0; w < nbTeams; ++w)
            {
                for (p = 0; p < teamSize; ++p)
                {
                    allVars[s] = groups[w][p];
                    ++s;
                }
            }
            cp.Add(cp.AllDiff(allVars));

            // team[i] represents the number of the team of people number i
            IIntVar[] team = cp.IntVarArray(nbPersons, 0, nbTeams);
            for (w = 0; w < nbTeams; ++w)
            {
                for (p = 0; p < teamSize; ++p)
                {
                    cp.Add(cp.Eq(cp.Element(team, groups[w][p]), w));
                }
            }

            // Additional constraints
            // to improve efficiency we could force the following
            // first three constraints directly in MakeTeamTuples but the fourth
            // constraint cannot be expressed as a restriction of
            // the tuple set, since it is not local to a tuple

            cp.Add(cp.Or(cp.Eq(team[5], team[41]), cp.Eq(team[5], team[51])));
            cp.Add(cp.Or(cp.Eq(team[15], team[40]), cp.Eq(team[15], team[51])));
            cp.Add(cp.Or(cp.Eq(team[25], team[40]), cp.Eq(team[25], team[50])));
            cp.Add(cp.Or(cp.Eq(team[20], team[24]), cp.Eq(team[22], team[50])));

            //break symmetry: the teams are ordered according to the smallest in each team
            for (i = 0; i < nbTeams - 1; i++)
            {
                cp.Add(cp.Lt(groups[i][0], groups[i + 1][0]));
            }


            cp.SetParameter(CP.IntParam.AllDiffInferenceLevel,
                            CP.ParameterValues.Extended);

            if (cp.Solve())
            {
                Console.WriteLine();
                Console.WriteLine("SOLUTION");
                for (p = 0; p < nbTeams; ++p)
                {
                    Console.Write("team " + p + " : ");
                    for (w = 0; w < teamSize; ++w)
                    {
                        Console.Write((int)cp.GetValue(groups[p][w]) + " ");
                    }
                    Console.WriteLine();
                }
            }
            else
            {
                Console.WriteLine("**** NO SOLUTION ****");
            }
        }
コード例 #11
0
ファイル: Ppp.cs プロジェクト: andreasmattas/testcode
        public static void Main(string[] args)
        {
            int numPeriods = 6;
              if (args.Length > 0)
            numPeriods = Int32.Parse(args[0]);

              CP cp = new CP();
              //
              // Variables
              //

              // Host boat choice
              IIntVar[] host = new IIntVar[numBoats];
              for (int j = 0; j < numBoats; j++) {
            host[j] = cp.IntVar(0, 1, String.Format("H{0}", j));
              }

              // Who is where each time period (time- and boat-based views)
              IIntVar[][] timePeriod = new IIntVar[numPeriods][];
              for (int i = 0; i < numPeriods; i++) {
            timePeriod[i] = new IIntVar[numBoats];
            for (int j = 0; j < numBoats; j++) {
              timePeriod[i][j] = cp.IntVar(0, numBoats-1, String.Format("T{0},{1}", i, j));
            }
              }
              IIntVar[][]  visits = Transpose(timePeriod);

              //
              // Objective
              //
              IIntVar numHosts = cp.IntVar(numPeriods, numBoats);
              cp.Add(cp.Eq(numHosts, cp.Sum(host)));
              cp.Add(cp.Minimize(numHosts));

              //
              // Constraints
              //

              // Stay in my boat (host) or only visit other boats (guest)
              for (int i = 0; i < numBoats; i++)
            cp.Add(cp.Eq(cp.Count(visits[i], i), cp.Prod(host[i], numPeriods)));

              // Capacity constraints: only hosts have capacity
              for (int p = 0; p < numPeriods; p++) {
            IIntVar[] load = new IIntVar[numBoats];
            for (int j = 0; j < numBoats; j++) {
              load[j] = cp.IntVar(0, boatSize[j], String.Format("L{0},{1}", p, j));
              cp.Add(cp.Le(load[j], cp.Prod(host[j], boatSize[j])));
            }
            cp.Add(cp.Pack(load, timePeriod[p], crewSize, numHosts));
              }

              // No two crews meet more than once
              for (int i = 0; i < numBoats; i++) {
            for (int j = i + 1; j < numBoats; j++) {
              IIntExpr timesMet = cp.Constant(0);
              for (int p = 0; p < numPeriods; p++)
            timesMet = cp.Sum(timesMet, cp.Eq(visits[i][p], visits[j][p]));
              cp.Add(cp.Le(timesMet, 1));
            }
              }

              // Host and guest boat constraints: given in problem spec
              cp.Add(cp.Eq(host[0], 1));
              cp.Add(cp.Eq(host[1], 1));
              cp.Add(cp.Eq(host[2], 1));
              cp.Add(cp.Eq(host[39], 0));
              cp.Add(cp.Eq(host[40], 0));
              cp.Add(cp.Eq(host[41], 0));

              //
              // Solving
              //
              if (cp.Solve()) {
            Console.WriteLine("Solution at cost = {0}", cp.GetValue(numHosts));
            Console.Write("Hosts: ");
            for (int i = 0; i < numBoats; i++)
              Console.Write(cp.GetValue(host[i]));
            Console.WriteLine();

            for (int p = 0; p < numPeriods; p++) {
              Console.WriteLine("Period {0}", p);
              for (int h = 0; h < numBoats; h++) {
            if (cp.GetValue(host[h]) > 0) {
              Console.Write("\tHost {0} : ", h);
              int load = 0;
              for (int i = 0; i < numBoats; i++) {
                if (cp.GetValue(visits[i][p]) == h) {
                  load += crewSize[i];
                  Console.Write("{0} ({1}) ",i, crewSize[i]);
                }
              }
              Console.WriteLine(" --- {0} / {1}", load, boatSize[h]);
            }
              }
            }
            Console.WriteLine();
              }
        }
コード例 #12
0
ファイル: Sports.cs プロジェクト: andreasmattas/testcode
        static void Main(string[] args)
        {
            try
              {
            int n = 10;
            if (args.Length > 0)
              n = Int32.Parse(args[0]);
            if ((n % 2) == 1)
              n++;
            Console.WriteLine("Finding schedule for {0} teams", n);
            int nbWeeks = 2 * (n - 1);
            int nbGamesPerWeek = n / 2;
            int nbGames = n * (n - 1);
            CP cp = new CP();

            IIntVar[][] games = new IIntVar[nbWeeks][];
            IIntVar[][] home = new IIntVar[nbWeeks][];
            IIntVar[][] away = new IIntVar[nbWeeks][];

            for (int i = 0; i < nbWeeks; i++)
            {
              home[i] = cp.IntVarArray(nbGamesPerWeek, 0, n - 1);
              away[i] = cp.IntVarArray(nbGamesPerWeek, 0, n - 1);
              games[i] = cp.IntVarArray(nbGamesPerWeek, 0, nbGames - 1);
            }
            //
            // For each play slot, set up correspondance between game id,
            // home team, and away team
            //

            IIntTupleSet gha = cp.IntTable(3);
            int[] tuple = new int[3];
            for (int i = 0; i < n; i++)
            {
              tuple[0] = i;
              for (int j = 0; j < n; j++)
              {
            if (i != j)
            {
              tuple[1] = j;
              tuple[2] = Game(i, j, n);
              cp.AddTuple(gha, tuple);
            }
              }
            }

            for (int i = 0; i < nbWeeks; i++)
            {
              for (int j = 0; j < nbGamesPerWeek; j++)
              {
            IIntVar[] vars = cp.IntVarArray(3);
            vars[0] = home[i][j];
            vars[1] = away[i][j];
            vars[2] = games[i][j];
            cp.Add(cp.AllowedAssignments(vars, gha));
              }
            }
            //
            // All teams play each week
            //
            for (int i = 0; i < nbWeeks; i++)
            {
              IIntVar[] teamsThisWeek = cp.IntVarArray(n);
              for (int j = 0; j < nbGamesPerWeek; j++)
              {
            teamsThisWeek[j] = home[i][j];
            teamsThisWeek[nbGamesPerWeek + j] = away[i][j];
              }
              cp.Add(cp.AllDiff(teamsThisWeek));
            }
            //
            // Dual representation: for each game id, the play slot is maintained
            //
            IIntVar[] weekOfGame = cp.IntVarArray(nbGames, 0, nbWeeks - 1);
            IIntVar[] allGames = cp.IntVarArray(nbGames);
            IIntVar[] allSlots = cp.IntVarArray(nbGames, 0, nbGames - 1);
            for (int i = 0; i < nbWeeks; i++)
              for (int j = 0; j < nbGamesPerWeek; j++)
            allGames[i * nbGamesPerWeek + j] = games[i][j];
            cp.Add(cp.Inverse(allGames, allSlots));
            for (int i = 0; i < nbGames; i++)
              cp.Add(cp.Eq(weekOfGame[i], cp.Div(allSlots[i], nbGamesPerWeek)));
            //
            // Two half schedules.  Cannot play the same pair twice in the same half.
            // Plus, impose a minimum number of weeks between two games involving
            // the same teams (up to six weeks)
            //
            int mid = nbWeeks / 2;
            int overlap = 0;
            if (n >= 6)
              overlap = min(n / 2, 6);
            for (int i = 0; i < n; i++)
            {
              for (int j = i + 1; j < n; j++)
              {
            int g1 = Game(i, j, n);
            int g2 = Game(j, i, n);
            cp.Add(cp.Equiv(cp.Ge(weekOfGame[g1], mid), cp.Lt(weekOfGame[g2], mid)));
            // Six week difference...
            if (overlap != 0)
              cp.Add(cp.Ge(cp.Abs(cp.Diff(weekOfGame[g1], weekOfGame[g2])), overlap));
              }
            }

            //
            // Can't have three homes or three aways in a row.
            //
            IIntVar[][] playHome = new IIntVar[n][];
            for (int i = 0; i < n; i++)
            {
              playHome[i] = cp.IntVarArray(nbWeeks, 0, 1);
              for (int j = 0; j < nbWeeks; j++)
            cp.Add(cp.Eq(playHome[i][j], cp.Count(home[j], i)));
              for (int j = 0; j < nbWeeks - 3; j++)
              {
            IIntVar[] window = cp.IntVarArray(3);
            for (int k = j; k < j + 3; k++)
              window[k - j] = playHome[i][k];
            IIntExpr windowSum = cp.Sum(window);
            cp.Add(cp.Le(1, windowSum));
            cp.Add(cp.Le(windowSum, 2));
              }
            }

            //
            // If we start the season home, we finish away and vice versa.
            //
            for (int i = 0; i < n; i++)
              cp.Add(cp.Neq(playHome[i][0], playHome[i][nbWeeks - 1]));

            //
            // Objective: minimize the number of `breaks'.  A break is
            //            two consecutive home or away matches for a
            //            particular team
            IIntVar[] teamBreaks = cp.IntVarArray(n, 0, nbWeeks / 2);
            for (int i = 0; i < n; i++)
            {
              IIntExpr nbreaks = cp.Constant(0);
              for (int j = 1; j < nbWeeks; j++)
            nbreaks = cp.Sum(nbreaks, cp.IntExpr(cp.Eq(playHome[i][j - 1], playHome[i][j])));
              cp.Add(cp.Eq(teamBreaks[i], nbreaks));
            }
            IIntVar breaks = cp.IntVar(n - 2, n * (nbWeeks / 2));
            cp.Add(cp.Eq(breaks, cp.Sum(teamBreaks)));
            cp.Add(cp.Minimize(breaks));

            //
            // Catalyzing constraints
            //

            // Each team plays home the same number of times as away
            for (int i = 0; i < n; i++)
              cp.Add(cp.Eq(cp.Sum(playHome[i]), nbWeeks / 2));

            // Breaks must be even for each team
            for (int i = 0; i < n; i++)
              cp.Add(cp.Eq(cp.Modulo(teamBreaks[i], 2), 0));

            //
            // Symmetry breaking constraints
            //

            // Teams are interchangeable.  Fix first week.
            // Also breaks reflection symmetry of the whole schedule.
            for (int i = 0; i < nbGamesPerWeek; i++)
            {
              cp.Add(cp.Eq(home[0][i], i * 2));
              cp.Add(cp.Eq(away[0][i], i * 2 + 1));
            }

            // Order of games in each week is arbitrary.
            // Break symmetry by forcing an order.
            for (int i = 0; i < nbWeeks; i++)
              for (int j = 1; j < nbGamesPerWeek; j++)
            cp.Add(cp.Gt(games[i][j], games[i][j - 1]));

            cp.SetParameter(CP.DoubleParam.TimeLimit, 20);
            cp.SetParameter(CP.IntParam.LogPeriod, 10000);
            IVarSelector varSel = cp.SelectSmallest(cp.VarIndex(allGames)); ;
            IValueSelector valSel = cp.SelectRandomValue();

            ISearchPhase phase = cp.SearchPhase(allGames,
                                            cp.IntVarChooser(varSel),
                                            cp.IntValueChooser(valSel));
            cp.StartNewSearch(phase);
            while (cp.Next())
            {
              Console.WriteLine("Solution at {0}", cp.GetValue(breaks));
            }
            cp.EndSearch();
              }
              catch (ILOG.Concert.Exception e)
              {
               Console.WriteLine("Error {0}", e);
              }
        }
コード例 #13
0
ファイル: BendersATSP.cs プロジェクト: andreasmattas/testcode
    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);
          }
    }
コード例 #14
0
        static void Main()
        {
            try
            {
                string resultFilename = "./ResultFiles/MTSP_MTZ.csv";
                string filename       = "./DataFiles/Data.dat";
                Data   data           = new Data(filename);

                double timeFactor     = 0;
                double distanceFactor = 1;
                double step           = 0.1;
                int    routeCounter   = 0;

                File.WriteAllText(resultFilename, "");

                do
                {
                    using (Cplex cplex = new Cplex())
                    {
                        #region [Decision Variables]
                        IIntVar[][] x = new IIntVar[data.n][];
                        IIntVar     Q = cplex.IntVar(1, 250, "Q");

                        for (int i = 0; i < data.n; i++)
                        {
                            x[i] = cplex.BoolVarArray(data.n);
                            cplex.Add(x[i]);
                        }
                        #endregion

                        #region [Objective Function]
                        INumExpr obj = cplex.NumExpr();
                        for (int i = 0; i < data.n; i++)
                        {
                            for (int j = 0; j < data.n; j++)
                            {
                                if (i != j)
                                {
                                    obj = cplex.Sum(obj,
                                                    cplex.Prod(
                                                        (
                                                            (timeFactor * data.timeNormalized[i][j]) +
                                                            (distanceFactor * data.distanceNormalized[i][j])
                                                        ), x[i][j]));
                                }
                            }
                        }
                        cplex.AddMinimize(obj);
                        #endregion

                        #region [Restrictions]
                        for (int j = 0; j < data.n; j++)
                        {
                            ILinearNumExpr sumj = cplex.LinearNumExpr();
                            for (int i = 0; i < data.n; i++)
                            {
                                if (i != j)
                                {
                                    sumj.AddTerm(1, x[i][j]);
                                }
                            }
                            cplex.AddEq(sumj, 1);
                        }

                        for (int i = 0; i < data.n; i++)
                        {
                            ILinearNumExpr sumi = cplex.LinearNumExpr();
                            for (int j = 0; j < data.n; j++)
                            {
                                if (i != j)
                                {
                                    sumi.AddTerm(1, x[i][j]);
                                }
                            }
                            cplex.AddEq(sumi, 1);
                        }
                        #endregion

                        cplex.SetParam(Cplex.DoubleParam.WorkMem, 4000.0);
                        cplex.SetParam(Cplex.Param.MIP.Strategy.File, 2);
                        cplex.SetParam(Cplex.DoubleParam.EpGap, 0.1);
                        cplex.SetParam(Cplex.BooleanParam.MemoryEmphasis, true);
                        cplex.SetParam(Cplex.IntParam.VarSel, 4);

SOLVE:

                        Stopwatch stopWatch = new Stopwatch();
                        stopWatch.Start();
                        if (cplex.Solve())
                        {
                            stopWatch.Stop();
                            double[][] sol_x = new double[data.n][];
                            for (int i = 0; i < data.n; i++)
                            {
                                sol_x[i] = cplex.GetValues(x[i]);
                            }
                            int[] tour = FindSubTour(sol_x);
                            if (tour.Length < data.n)
                            {
                                ILinearNumExpr sumx = cplex.LinearNumExpr();
                                for (int i = 0; i < tour.Length; i++)
                                {
                                    for (int j = 0; j < tour.Length; j++)
                                    {
                                        sumx.AddTerm(1, x[tour[i]][tour[j]]);
                                    }
                                }
                                cplex.AddLazyConstraint(cplex.AddLe(cplex.Diff(sumx, tour.Length), -1));
                                goto SOLVE;
                            }

                            double timeTotal     = 0;
                            double distanceTotal = 0;
                            for (int i = 0; i < data.n; i++)
                            {
                                for (int j = 0; j < data.n; j++)
                                {
                                    timeTotal     += data.time[i][j] * sol_x[i][j];
                                    distanceTotal += data.distance[i][j] * sol_x[i][j];
                                }
                            }

                            StreamWriter file = new StreamWriter(resultFilename, true);
                            file.WriteLine($"{timeFactor},{distanceFactor},{stopWatch.Elapsed.TotalSeconds},{cplex.ObjValue},{timeTotal},{distanceTotal}");
                            file.Close();

                            StreamWriter fileRouteResult = new StreamWriter($"./ResultFiles/Route-{routeCounter}.txt");
                            for (int i = 0; i < data.n; i++)
                            {
                                for (int j = 0; j < data.n; j++)
                                {
                                    if (sol_x[i][j] == 1)
                                    {
                                        fileRouteResult.WriteLine($"From city {i} to city {j}");
                                    }
                                }
                            }
                            fileRouteResult.Close();
                        }
                        cplex.End();
                    }

                    timeFactor     += step;
                    distanceFactor -= step;
                    routeCounter++;
                } while (timeFactor <= 1);
            }
            catch (ILOG.Concert.Exception ex)
            {
                StreamWriter errorfile = new StreamWriter("./ErrorLog.txt");
                errorfile.WriteLine("Exception Kind: ILOG.Concert.Exception (Concert Error)");
                errorfile.WriteLine("Message: " + ex.Message);
                errorfile.WriteLine("StackTrace: " + ex.StackTrace);
                errorfile.Close();
            }
            catch (InputDataReader.InputDataReaderException ex)
            {
                StreamWriter errorfile = new StreamWriter("./ErrorLog.txt");
                errorfile.WriteLine("Exception Kind: InputDataReader.InputDataReaderException (Data Error)");
                errorfile.WriteLine("Message: " + ex.Message);
                errorfile.WriteLine("StackTrace: " + ex.StackTrace);
                errorfile.Close();
            }
            catch (System.IO.IOException ex)
            {
                StreamWriter errorfile = new StreamWriter("./ErrorLog.txt");
                errorfile.WriteLine("Exception Kind: System.IO.IOException (IO Error)");
                errorfile.WriteLine("Message: " + ex.Message);
                errorfile.WriteLine("StackTrace: " + ex.StackTrace);
                errorfile.Close();
            }
        }
コード例 #15
0
        static void Main(string[] args)
        {
            String filename;
            if (args.Length > 0)
                filename = args[0];
            else
                filename = "../../../../examples/data/plant_location.data";

            DataReader data = new DataReader(filename);
            int nbCustomer = data.Next();
            int nbLocation = data.Next();

            int[][] cost = new int[nbCustomer][];
            for (int c = 0; c < nbCustomer; c++)
            {
              cost[c] = new int[nbLocation];
              for (int l = 0; l < nbLocation; l++)
                cost[c][l] = data.Next();
            }
            int[] demand = new int[nbCustomer];
            for (int c = 0; c < nbCustomer; c++)
            {
                demand[c] = data.Next();
            }
            int[] fixedCost = new int[nbLocation];
            for (int l = 0; l < nbLocation; l++)
            {
                fixedCost[l] = data.Next();
            }
            int[] capacity = new int[nbLocation];
            for (int l = 0; l < nbLocation; l++)
            {
                capacity[l] = data.Next();
            }

            CP cp = new CP();

            IIntVar[] cust = new IIntVar[nbCustomer];
            for (int c = 0; c < nbCustomer; c++)
            {
                cust[c] = cp.IntVar(0, nbLocation - 1);
            }
            IIntVar[] open = new IIntVar[nbLocation];
            IIntVar[] load = new IIntVar[nbLocation];
            for (int l = 0; l < nbLocation; l++)
            {
                open[l] = cp.IntVar(0, 1);
                load[l] = cp.IntVar(0, capacity[l]);
            }

            for (int l = 0; l < nbLocation; l++)
            {
               cp.Add(cp.Eq(open[l], cp.Gt(load[l], 0)));
            }
            cp.Add(cp.Pack(load, cust, demand));
            IIntExpr obj = cp.Prod(open, fixedCost);
            for (int c = 0; c < nbCustomer; c++)
            {
                obj = cp.Sum(obj, cp.Element(cost[c], cust[c]));
            }
            cp.Add(cp.Minimize(obj));

            int[] custValues = {
                19, 0, 11, 8, 29, 9, 29, 28, 17, 15, 7, 9, 18, 15, 1, 17, 25, 18, 17, 27,
                22, 1, 26, 3, 22, 2, 20, 27, 2, 16, 1, 16, 12, 28, 19, 2, 20, 14, 13, 27,
                3, 9, 18, 0, 13, 19, 27, 14, 12, 1, 15, 14, 17, 0, 7, 12, 11, 0, 25, 16,
                22, 13, 16, 8, 18, 27, 19, 23, 26, 13, 11, 11, 19, 22, 28, 26, 23, 3, 18, 23,
                26, 14, 29, 18, 9, 7, 12, 27, 8, 20 };

            ISolution sol = cp.Solution();
            for (int c = 0; c < nbCustomer; c++)
                sol.SetValue(cust[c], custValues[c]);

            cp.SetStartingPoint(sol);
            cp.SetParameter(CP.DoubleParam.TimeLimit, 10);
            cp.SetParameter(CP.IntParam.LogPeriod, 10000);
            cp.Solve();
        }
コード例 #16
0
        static void Main(string[] args)
        {
            int D = 5;
            int W = 5;
            int H = 3;
            int G = 2;
            int T = 12;

            int[] k_g  = new int[] { 2, 2 };
            int   ALLK = 4;

            int[] cc_d     = new int[] { 2, 1, 2, 1, 2 };
            int[] ave      = new int[] { 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1 };
            int[] dur      = new int[] { 1, 2, 1, 1, 2 };
            int[] prf_D    = new int[] { 2, 1, 1, 1, 100 };
            int[] indexg_d = new int[] { 0, 1, 1, 1, 0 };

            CP roster = new CP();

            // intern availbility
            INumToNumStepFunction resource_AveIntern = roster.NumToNumStepFunction(0, T, 100, "AvailibilityOfIntern");

            for (int t = 0; t < T; t++)
            {
                if (ave[t] == 0)
                {
                    resource_AveIntern.SetValue(t, t + 1, 0);
                }
            }



            // discipline
            IIntervalVar[]     discipline_d  = new IIntervalVar[D];
            ICumulFunctionExpr hospitalNotRR = roster.CumulFunctionExpr();

            for (int d = 0; d < D; d++)
            {
                discipline_d[d]           = roster.IntervalVar();
                discipline_d[d].EndMax    = T;
                discipline_d[d].EndMin    = dur[d];
                discipline_d[d].LengthMax = dur[d];
                discipline_d[d].LengthMin = dur[d];
                discipline_d[d].SizeMax   = dur[d];
                discipline_d[d].SizeMin   = dur[d];
                discipline_d[d].StartMax  = T;
                discipline_d[d].StartMin  = 0;
                discipline_d[d].SetIntensity(resource_AveIntern, 100);
                hospitalNotRR.Add(roster.Pulse(discipline_d[d], 1));
                discipline_d[d].SetOptional();
            }
            IIntervalSequenceVar dis = roster.IntervalSequenceVar(discipline_d);

            roster.Add(roster.Ge(roster.PresenceOf(discipline_d[1]), roster.PresenceOf(discipline_d[4])));
            roster.Add(roster.Before(dis, discipline_d[1], discipline_d[4]));

            roster.Add(roster.NoOverlap(discipline_d));
            // desciplien  for not renewable resources
            IIntVar[] height_t = new IIntVar[T];
            for (int t = 0; t < T; t++)
            {
                height_t[t] = roster.IntVar(0, 1);
            }

            INumToNumSegmentFunction piecewise = roster.NumToNumSegmentFunction(new double[] { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11 },
                                                                                new double[] { 10, 0, 10, 1, 10, 2, 10, 3, 10, 4, 10, 5, 10, 6, 10, 7, 10, 8, 10, 9, 10, 10, 10, 11 });



            INumExpr rc = roster.NumExpr();

            for (int d = 0; d < D; d++)
            {
                rc = roster.Sum(rc, roster.StartEval(discipline_d[d], piecewise, 0));
            }


            for (int t = 0; t < T; t++)
            {
            }

            IIntervalVar[] disciplineNR_d = new IIntervalVar[D];

            for (int d = 0; d < D; d++)
            {
                disciplineNR_d[d]           = roster.IntervalVar();
                disciplineNR_d[d].EndMax    = T;
                disciplineNR_d[d].EndMin    = T;
                disciplineNR_d[d].LengthMax = T;
                disciplineNR_d[d].LengthMin = T;
                disciplineNR_d[d].SizeMax   = T;
                disciplineNR_d[d].SizeMin   = T;
                disciplineNR_d[d].StartMax  = T;
                disciplineNR_d[d].StartMin  = 0;
                disciplineNR_d[d].SetOptional();
                roster.IfThen(roster.PresenceOf(discipline_d[d]), roster.PresenceOf(disciplineNR_d[d]));
            }
            //roster.Add(roster.IfThen(roster.PresenceOf(discipline_d[4]), roster.And(roster.Le(roster.EndOf(discipline_d[4]), roster.StartOf(discipline_d[0])),roster.PresenceOf(discipline_d[0]))));
            //roster.Add(roster.StartBeforeEnd(discipline_d[4],discipline_d[0]));
            // hospital changes
            //ICumulFunctionExpr[] hospital

            //for (int d = 0; d < D; d++)
            //{
            //    roster.IfThen(roster.PresenceOf(disciplineNR_d[d]),);
            //}



            // hospital assignment
            IIntervalVar[][] Hospital_dh = new IIntervalVar[D][];
            for (int d = 0; d < D; d++)
            {
                Hospital_dh[d] = new IIntervalVar[H];
                for (int h = 0; h < H; h++)
                {
                    Hospital_dh[d][h]           = roster.IntervalVar();
                    Hospital_dh[d][h].EndMax    = T;
                    Hospital_dh[d][h].EndMin    = dur[d];
                    Hospital_dh[d][h].LengthMax = dur[d];
                    Hospital_dh[d][h].LengthMin = dur[d];
                    Hospital_dh[d][h].SizeMax   = dur[d];
                    Hospital_dh[d][h].SizeMin   = dur[d];
                    Hospital_dh[d][h].StartMax  = T;
                    Hospital_dh[d][h].StartMin  = 0;

                    Hospital_dh[d][h].SetOptional();
                    if (h == 0 && (d != 4))
                    {
                        Hospital_dh[d][h].SetAbsent();
                    }
                    if (h == 1 && (d == 4))
                    {
                        Hospital_dh[d][h].SetAbsent();
                    }
                    if (h == 2 && (d == 4))
                    {
                        Hospital_dh[d][h].SetAbsent();
                    }
                }
                roster.Add(roster.Alternative(discipline_d[d], Hospital_dh[d]));
            }

            IIntervalVar[] disHospSetUp_dh = new IIntervalVar[D * H];
            int[]          type            = new int[D * H];
            for (int dh = 0; dh < D * H; dh++)
            {
                int dIndex = dh % D;
                int hIndex = dh / D;
                disHospSetUp_dh[dh] = roster.IntervalVar("DsiHosp" + "[" + dIndex + "][" + hIndex + "]");
                type[dh]            = hIndex;
                disHospSetUp_dh[dh].SetOptional();
                disHospSetUp_dh[dh] = Hospital_dh[dIndex][hIndex];
            }
            // changes
            IIntervalSequenceVar cc = roster.IntervalSequenceVar(disHospSetUp_dh, type);

            roster.NoOverlap(cc);
            IIntVar[][] change_dD = new IIntVar[D][];
            for (int d = 0; d < D; d++)
            {
                change_dD[d] = new IIntVar[D];
                for (int dd = 0; dd < D; dd++)
                {
                    change_dD[d][dd] = roster.IntVar(0, 1, "change_dD[" + d + "][" + dd + "]");
                }
            }
            IIntVar[] change_d = new IIntVar[D];
            for (int d = 0; d < D; d++)
            {
                change_d[d] = roster.IntVar(0, 1, "change_d[" + d + "]");
            }
            for (int dh = 0; dh < D * H; dh++)
            {
                int      dIndex = dh % D;
                int      hIndex = dh / D;
                IIntExpr chngD  = roster.IntExpr();
                chngD = roster.Sum(chngD, change_d[dIndex]);
                roster.Add(roster.IfThen(roster.And(roster.PresenceOf(disHospSetUp_dh[dh]), roster.Neq(roster.TypeOfNext(cc, disHospSetUp_dh[dh], hIndex, hIndex), hIndex)), roster.Eq(chngD, 1)));
                for (int ddh = 0; ddh < D * H; ddh++)
                {
                    int ddIndex = ddh % D;
                    int hhIndex = ddh / D;
                    if (hhIndex == hIndex || dIndex == ddIndex)
                    {
                        continue;
                    }
                }
            }



            //IIntVar[][] y_dD = new IIntVar[D][];
            //for (int d = 0; d < D; d++)
            //{
            //    y_dD[d] = new IIntVar[D];
            //    for (int dd= 0; dd < D; dd++)
            //    {
            //        y_dD[d][dd] = roster.IntVar(0,1);
            //        if (d == dd)
            //        {
            //            y_dD[d][dd] = roster.IntVar(0, 0);
            //        }
            //    }
            //}
            //for (int d = 0; d < D; d++)
            //{
            //    for (int dd = 0; dd < D; dd++)
            //    {
            //        if (d != dd)
            //        {
            //            for (int h = 0; h < H; h++)
            //            {
            //                for (int hh = 0; hh < H; hh++)
            //                {
            //                    if (d != dd && h != hh && true)
            //                    {
            //                        IIntExpr yyy = roster.IntExpr();
            //                        yyy = roster.Sum(yyy,roster.Prod(T,y_dD[d][dd]));
            //                        yyy = roster.Sum(yyy, roster.Prod(1, roster.EndOf(Hospital_dh[dd][hh])));
            //                        yyy = roster.Sum(yyy, roster.Prod(-1, roster.StartOf(Hospital_dh[d][h])));
            //                        roster.Add( roster.IfThen(roster.And(roster.PresenceOf(Hospital_dh[d][h]), roster.PresenceOf(Hospital_dh[dd][hh])), roster.AddGe(yyy, 0)));
            //                    }
            //                }
            //            }
            //        }
            //    }
            //}
            //for (int d = 0; d < D; d++)
            //{
            //    for (int dd = 0; dd < D; dd++)
            //    {
            //        if (d == dd)
            //        {
            //            continue;
            //        }
            //        IIntExpr change = roster.IntExpr();
            //        change = roster.Sum(change, change_dD[dd][d]);
            //        change = roster.Sum(change, roster.Prod(-1, y_dD[dd][d]));
            //        for (int ddd = 0; ddd < D; ddd++)
            //        {
            //            if (ddd == d || ddd == dd)
            //            {
            //                continue;
            //            }
            //            change = roster.Sum(change, change_dD[dd][ddd]);
            //        }
            //        roster.Add(roster.IfThen(roster.And(roster.PresenceOf(discipline_d[d]), roster.PresenceOf(discipline_d[dd])), roster.AddEq(change, 0)));


            //    }

            //}

            // all group assignment
            IIntExpr allPossibleCourses = roster.IntExpr();

            for (int d = 0; d < D; d++)
            {
                allPossibleCourses = roster.Sum(allPossibleCourses, roster.Prod(cc_d[d], roster.PresenceOf(discipline_d[d])));
            }
            roster.AddEq(allPossibleCourses, ALLK);

            // group assignment
            for (int g = 0; g < G; g++)
            {
                IIntExpr groupedCours_g = roster.IntExpr();
                for (int d = 0; d < D; d++)
                {
                    if (indexg_d[d] == g)
                    {
                        groupedCours_g = roster.Sum(groupedCours_g, roster.Prod(cc_d[d], roster.PresenceOf(discipline_d[d])));
                    }
                }
                roster.AddGe(groupedCours_g, k_g[g]);
            }


            // stay in one hospital



            // objective function
            INumExpr objExp = roster.NumExpr();

            // discipline desire
            for (int d = 0; d < D; d++)
            {
                objExp = roster.Sum(objExp, roster.Prod(prf_D[d], roster.PresenceOf(discipline_d[d])));
                for (int dd = 0; dd < D; dd++)
                {
                    objExp = roster.Sum(objExp, roster.Prod(-1, change_d[d]));
                }
            }
            objExp = roster.Sum(objExp, rc);
            IIntExpr makespan = roster.IntExpr();

            for (int d = 0; d < D; d++)
            {
                makespan = roster.Max(makespan, roster.EndOf(discipline_d[d]));
            }

            IIntVar  wait      = roster.IntVar(0, T);
            IIntExpr waitConst = roster.IntExpr();

            waitConst = roster.Sum(waitConst, wait);
            waitConst = roster.Sum(waitConst, roster.Prod(-1, makespan));
            for (int d = 0; d < D; d++)
            {
                waitConst = roster.Sum(waitConst, roster.Prod(dur[d], roster.PresenceOf(discipline_d[d])));
            }
            roster.AddEq(waitConst, 0);
            roster.AddMaximize(objExp);

            roster.ExportModel("Roster.cpo");
            roster.SetParameter(CP.IntParam.TimeMode, CP.ParameterValues.ElapsedTime);
            roster.SetParameter(CP.IntParam.LogVerbosity, CP.ParameterValues.Quiet);
            roster.SetParameter(CP.IntParam.SolutionLimit, 10);


            // solve it now
            if (roster.Solve())
            {
                Console.WriteLine("this is the cost of the CP column {0}", roster.ObjValue);
                for (int d = 0; d < D; d++)
                {
                    if (roster.IsPresent(discipline_d[d]))
                    {
                        Console.WriteLine("Discipline {0} with CC {1} and Dur {2} and Prf {3} started at time {4} and finished at time {5}", d, cc_d[d], dur[d], prf_D[d], roster.GetStart(discipline_d[d]), roster.GetEnd(discipline_d[d]));
                    }
                }

                for (int d = 0; d < D; d++)
                {
                    for (int h = 0; h < H; h++)
                    {
                        if (roster.IsPresent(Hospital_dh[d][h]))
                        {
                            Console.WriteLine("Discipline {0} with CC {1} and Dur {2} and Prf {3} started at time {4} and finished at time {5} at Hospitail {6}", d, cc_d[d], dur[d], prf_D[d], roster.GetStart(Hospital_dh[d][h]), roster.GetEnd(Hospital_dh[d][h]), h);
                        }
                    }
                }
                for (int d = 0; d < D * H; d++)
                {
                    int dIndex = d % D;
                    int hIndex = d / D;
                    if (roster.IsPresent(disHospSetUp_dh[d]))
                    {
                        Console.WriteLine("discpline " + dIndex + " in hospital " + hIndex);
                    }
                }

                for (int d = 0; d < D; d++)
                {
                    if (roster.GetValue(change_d[d]) > 0.5)
                    {
                        Console.WriteLine("We have change for discipline {0}", d);
                    }
                    for (int dd = 0; dd < D; dd++)
                    {
                        if (d == dd)
                        {
                            continue;
                        }
                    }
                }

                Console.WriteLine("=========================================");
                Console.WriteLine("Wainting time {0}", roster.GetValue(wait));
            }
        }
コード例 #17
0
ファイル: Solver.cs プロジェクト: touzov1012/rummikub-ai
        /// <summary>
        /// return a list of words that can be played, left over letters are the last word
        /// </summary>
        /// <param name="chips">All of the chips to conisder, first ones are on the board</param>
        /// <param name="numberOnBoard">The number of leading chips are on the board already</param>
        /// <returns></returns>
        public static List <Chip[]> Solve(List <Chip> chips, int numberOnBoard, bool suppress = true)
        {
            if (chips == null || chips.Count == 0)
            {
                Utility.Warning("Chips is null or empty!");
                return(null);
            }

            int chip_count = chips.Count;
            int word_count = chip_count / 3 + 1;

            Cplex model = new Cplex();

            IIntVar[]   X  = model.BoolVarArray(chip_count);    // should we place the ith chip
            IIntVar[][] Y  = new IIntVar[chip_count][];         // which word do we place the ith chip on
            IIntVar[]   WO = model.BoolVarArray(word_count);    // flag for if the jth word is an order word or not
            IIntVar[]   WC = model.BoolVarArray(word_count);    // flag for if the jth word is a color word or not
            IIntVar[]   WN = model.BoolVarArray(word_count);    // flag for if the jth word is not used or is used
            IIntVar[][] UO = new IIntVar[word_count][];         // what is the number associated with this word (used only if a color word)
            IIntVar[][] UC = new IIntVar[word_count][];         // what is the color associated with this word (used only if a order word)
            IIntVar[][] PC = new IIntVar[word_count][];         // if i maps to word j and j is a color word, this will be 1 at [j][i]
            IIntVar[][] PO = new IIntVar[word_count][];         // if i maps to word j and j is a order word, this will be 1 at [j][i] (if and only if)

            // Initialize
            for (int i = 0; i < chip_count; i++)
            {
                Y[i] = model.BoolVarArray(word_count);
            }

            for (int i = 0; i < word_count; i++)
            {
                UC[i] = model.BoolVarArray(Chip.COLORCOUNT);
            }

            for (int i = 0; i < word_count; i++)
            {
                UO[i] = model.BoolVarArray(Chip.NUMBERCOUNT);
            }

            for (int i = 0; i < word_count; i++)
            {
                PC[i] = model.BoolVarArray(chip_count);
            }

            for (int i = 0; i < word_count; i++)
            {
                PO[i] = model.BoolVarArray(chip_count);
            }

            // for each word which chips map to it
            IIntVar[][] Yt = new IIntVar[word_count][];
            for (int i = 0; i < word_count; i++)
            {
                Yt[i] = new IIntVar[chip_count];
                for (int j = 0; j < chip_count; j++)
                {
                    Yt[i][j] = Y[j][i];
                }
            }

            // maximize the number of placed chips
            model.AddMaximize(model.Sum(X));

            // if we place i, we need to map it to some word
            for (int i = 0; i < chip_count; i++)
            {
                model.AddLe(X[i], model.Sum(Y[i]));
            }

            // we can map to at most 1 value
            for (int i = 0; i < chip_count; i++)
            {
                model.AddLe(model.Sum(Y[i]), 1);
            }

            // if any chip maps to word j, turn the not used flag off
            for (int j = 0; j < word_count; j++)
            {
                for (int i = 0; i < chip_count; i++)
                {
                    model.AddLe(Y[i][j], model.Diff(1, WN[j]));
                }
            }

            // if a word is used, make sure it has at least 3 chips
            for (int j = 0; j < word_count; j++)
            {
                model.AddLe(model.Prod(3, model.Diff(1, WN[j])), model.Sum(Yt[j]));
            }

            // first 'numberOnBoard' chips are on the board and thus must be placed
            for (int i = 0; i < numberOnBoard; i++)
            {
                model.AddEq(X[i], 1);
            }

            // each word is either an order word or a color word
            for (int i = 0; i < word_count; i++)
            {
                model.AddEq(model.Sum(WO[i], WC[i], WN[i]), 1);
            }

            // if i maps to word j and j is a color word make sure PC[j][i] is 1
            for (int j = 0; j < word_count; j++)
            {
                for (int i = 0; i < chip_count; i++)
                {
                    model.AddGe(model.Sum(1, PC[j][i]), model.Sum(WC[j], Y[i][j]));
                }
            }

            // if i maps to word j and j is a order word, PO will be 1 at [j][i] (if and only if)
            for (int j = 0; j < word_count; j++)
            {
                for (int i = 0; i < chip_count; i++)
                {
                    model.AddGe(model.Sum(1, PO[j][i]), model.Sum(WO[j], Y[i][j]));
                    model.AddLe(PO[j][i], WO[j]);
                    model.AddLe(PO[j][i], Y[i][j]);
                }
            }

            // ************************************************
            // ************ TYPE CONSTRAINTS ******************
            // ************************************************

            for (int i = 0; i < chip_count; i++)
            {
                for (int j = 0; j < word_count; j++)
                {
                    // if this is a color word and a chip maps to it then the numbers of each chip on this word must match
                    for (int k = 0; k < Chip.NUMBERCOUNT; k++)
                    {
                        var bnd = model.Sum(WO[j], model.Diff(1, Y[i][j]));
                        model.AddLe(model.Diff(UO[j][k], chips[i].number[k] ? 1 : 0), bnd);
                        model.AddLe(model.Diff(chips[i].number[k] ? 1 : 0, UO[j][k]), bnd);
                    }

                    // if this is a order word and a chip maps to it then the colors of each chip on this word must match
                    for (int k = 0; k < Chip.COLORCOUNT; k++)
                    {
                        var bnd = model.Sum(WC[j], model.Diff(1, Y[i][j]));
                        model.AddLe(model.Diff(UC[j][k], chips[i].color[k] ? 1 : 0), bnd);
                        model.AddLe(model.Diff(chips[i].color[k] ? 1 : 0, UC[j][k]), bnd);
                    }
                }
            }

            // if this is a color word, ensure that at most one of each color is allowed
            for (int j = 0; j < word_count; j++)
            {
                for (int k = 0; k < Chip.COLORCOUNT; k++)
                {
                    int[] colstack = new int[chip_count];
                    for (int i = 0; i < chip_count; i++)
                    {
                        colstack[i] = chips[i].color[k] ? 1 : 0;
                    }

                    model.Add(model.IfThen(model.Eq(WC[j], 1), model.Le(model.ScalProd(colstack, PC[j]), 1)));
                }
            }

            // ensure that the numbers in an order word are sequential
            for (int j = 0; j < word_count; j++)
            {
                IIntVar[] V = model.BoolVarArray(Chip.NUMBERCOUNT);
                for (int k = 0; k < Chip.NUMBERCOUNT; k++)
                {
                    int[] numstack = new int[chip_count];
                    for (int i = 0; i < chip_count; i++)
                    {
                        numstack[i] = chips[i].number[k] ? 1 : 0;
                    }

                    // if this is an order word put the binary numbers into a vector of flags for those numbers
                    model.Add(model.IfThen(model.Eq(WO[j], 1), model.Eq(model.ScalProd(numstack, PO[j]), V[k])));
                }

                // for each number either the next flag is strictly larger, meaning the start of the sequence
                // or every flag after a decrease is 0, the end of a sequence
                for (int i = 0; i < Chip.NUMBERCOUNT - 1; i++)
                {
                    IIntVar Z = model.BoolVar();
                    model.AddLe(model.Diff(V[i], V[i + 1]), Z);

                    for (int k = i + 1; k < Chip.NUMBERCOUNT; k++)
                    {
                        model.AddLe(V[k], model.Diff(1, Z));
                    }
                }
            }

            List <Chip[]> words = new List <Chip[]>();

            if (suppress)
            {
                model.SetOut(null);
            }

            Utility.Log("Thinking...");

            if (model.Solve())
            {
                for (int j = 0; j < word_count; j++)
                {
                    if (model.GetValue(WN[j]) > 0.5)
                    {
                        continue;
                    }

                    List <Chip> word  = new List <Chip>();
                    double[]    flags = model.GetValues(Yt[j]);
                    for (int i = 0; i < chip_count; i++)
                    {
                        if (flags[i] > 0.5)
                        {
                            word.Add(chips[i]);
                        }
                    }

                    // if this is a color word else it is an order word
                    if (model.GetValue(WC[j]) > 0.5)
                    {
                        words.Add(word.OrderBy(p => Array.IndexOf(p.color, true)).ToArray());
                    }
                    else
                    {
                        words.Add(word.OrderBy(p => Array.IndexOf(p.number, true)).ToArray());
                    }
                }
            }
            else
            {
                Utility.Warning("No possible moves found!");
            }

            model.Dispose();

            Chip[] notplayed = chips.Where(p => !words.Any(q => q.Contains(p))).ToArray();
            words.Add(notplayed);

            return(words);
        }
コード例 #18
0
        static public void Main(string[] args)
        {
            int numPeriods = 6;

            if (args.Length > 0)
            {
                numPeriods = Int32.Parse(args[0]);
            }

            CP cp = new CP();

            //
            // Variables
            //

            // Host boat choice
            IIntVar[] host = new IIntVar[numBoats];
            for (int j = 0; j < numBoats; j++)
            {
                host[j] = cp.IntVar(0, 1, String.Format("H{0}", j));
            }

            // Who is where each time period (time- and boat-based views)
            IIntVar[][] timePeriod = new IIntVar[numPeriods][];
            for (int i = 0; i < numPeriods; i++)
            {
                timePeriod[i] = new IIntVar[numBoats];
                for (int j = 0; j < numBoats; j++)
                {
                    timePeriod[i][j] = cp.IntVar(0, numBoats - 1, String.Format("T{0},{1}", i, j));
                }
            }
            IIntVar[][] visits = Transpose(timePeriod);

            //
            // Objective
            //
            IIntVar numHosts = cp.IntVar(numPeriods, numBoats);

            cp.Add(cp.Eq(numHosts, cp.Sum(host)));
            cp.Add(cp.Minimize(numHosts));

            //
            // Constraints
            //

            // Stay in my boat (host) or only visit other boats (guest)
            for (int i = 0; i < numBoats; i++)
            {
                cp.Add(cp.Eq(cp.Count(visits[i], i), cp.Prod(host[i], numPeriods)));
            }

            // Capacity constraints: only hosts have capacity
            for (int p = 0; p < numPeriods; p++)
            {
                IIntVar[] load = new IIntVar[numBoats];
                for (int j = 0; j < numBoats; j++)
                {
                    load[j] = cp.IntVar(0, boatSize[j], String.Format("L{0},{1}", p, j));
                    cp.Add(cp.Le(load[j], cp.Prod(host[j], boatSize[j])));
                }
                cp.Add(cp.Pack(load, timePeriod[p], crewSize, numHosts));
            }

            // No two crews meet more than once
            for (int i = 0; i < numBoats; i++)
            {
                for (int j = i + 1; j < numBoats; j++)
                {
                    IIntExpr timesMet = cp.Constant(0);
                    for (int p = 0; p < numPeriods; p++)
                    {
                        timesMet = cp.Sum(timesMet, cp.Eq(visits[i][p], visits[j][p]));
                    }
                    cp.Add(cp.Le(timesMet, 1));
                }
            }

            // Host and guest boat constraints: given in problem spec
            cp.Add(cp.Eq(host[0], 1));
            cp.Add(cp.Eq(host[1], 1));
            cp.Add(cp.Eq(host[2], 1));
            cp.Add(cp.Eq(host[39], 0));
            cp.Add(cp.Eq(host[40], 0));
            cp.Add(cp.Eq(host[41], 0));

            //
            // Solving
            //
            if (cp.Solve())
            {
                Console.WriteLine("Solution at cost = {0}", cp.GetValue(numHosts));
                Console.Write("Hosts: ");
                for (int i = 0; i < numBoats; i++)
                {
                    Console.Write(cp.GetValue(host[i]));
                }
                Console.WriteLine();

                for (int p = 0; p < numPeriods; p++)
                {
                    Console.WriteLine("Period {0}", p);
                    for (int h = 0; h < numBoats; h++)
                    {
                        if (cp.GetValue(host[h]) > 0)
                        {
                            Console.Write("\tHost {0} : ", h);
                            int load = 0;
                            for (int i = 0; i < numBoats; i++)
                            {
                                if (cp.GetValue(visits[i][p]) == h)
                                {
                                    load += crewSize[i];
                                    Console.Write("{0} ({1}) ", i, crewSize[i]);
                                }
                            }
                            Console.WriteLine(" --- {0} / {1}", load, boatSize[h]);
                        }
                    }
                }
                Console.WriteLine();
            }
        }
コード例 #19
0
    private void runModel(List <Employee> employees, List <Shift> shifts)
    {
        StreamWriter writer = File.CreateText(@"C:\Users\user\Desktop\cplex log\result9.txt");

        try
        {
            Cplex model = new Cplex();

            model.SetOut(writer);

            //------------------------------
            //---Variable initialization-----
            //------------------------------
            //Assignment variables
            IDictionary <string, IIntVar> assignVars = new Dictionary <string, IIntVar>();
            employees.ForEach(employee =>
            {
                shifts.ForEach(shift =>
                {
                    string name = getAssignVarName(employee, shift);
                    assignVars.Add(name, model.BoolVar(name));
                });
            });

            //Total assignment hours
            INumVar totalAssignHourVar = model.NumVar(0, Double.MaxValue, getTotalAssignVarName());

            //----------------------------------
            //---Constraints initialization-----
            //-----------------------------------

            //1) Min rest constraint
            //2) Goal total assigned hours constraint
            ILinearNumExpr sumAssignHourExpr = model.LinearNumExpr();
            sumAssignHourExpr.AddTerm(-1.0, totalAssignHourVar);
            employees.ForEach(employee =>
            {
                shifts.ForEach(shift1 =>
                {
                    ILinearNumExpr sumOverlapExpr = model.LinearNumExpr();
                    string name1       = getAssignVarName(employee, shift1);
                    IIntVar assignVar1 = assignVars[name1];
                    sumOverlapExpr.AddTerm(1.0, assignVar1);
                    shifts.ForEach(shift2 =>
                    {
                        if (shift1 != shift2 && this.isDurationOverlap(shift1, shift2))
                        {
                            string name2 = getAssignVarName(employee, shift2);
                            sumOverlapExpr.AddTerm(1.0, assignVars[name2]);
                        }
                    });
                    model.AddLe(sumOverlapExpr, 1.0, "MinRestConst");

                    sumAssignHourExpr.AddTerm((shift1.end - shift1.begin).TotalMinutes, assignVar1);
                });
            });

            //3) No overassignment constraint
            shifts.ForEach(shift =>
            {
                ILinearNumExpr sumAssigsExpr = model.LinearNumExpr();
                employees.ForEach(employee =>
                {
                    string name1       = getAssignVarName(employee, shift);
                    IIntVar assignVar1 = assignVars[name1];
                    sumAssigsExpr.AddTerm(1.0, assignVar1);
                });
                model.AddLe(sumAssigsExpr, shift.shiftNumber, "NoOverAssignConst");
            });
            model.AddEq(sumAssignHourExpr, 0.0, "TotalAssignedHourConst");
            INumVar[] goalVars = { totalAssignHourVar };
            double[]  coeffs   = { 1.0 };
            model.AddMaximize(model.ScalProd(goalVars, coeffs));

            model.ExportModel(@"C:\Users\user\Desktop\cplex log\model1.lp");
            bool feasible = model.Solve();
            if (feasible)
            {
                double objVal = model.ObjValue;
                model.Output().WriteLine("Solution value = " + model.ObjValue);
                shifts.ForEach(shift =>
                {
                    ILinearNumExpr sumAssigsExpr = model.LinearNumExpr();
                    employees.ForEach(employee =>
                    {
                        string name = getAssignVarName(employee, shift);
                    });
                    model.AddLe(sumAssigsExpr, shift.shiftNumber, "NoOverAssignConst");
                });
            }
            else
            {
            }
        }
        catch (System.Exception ex)
        {
            Response.ContentType = "application/json; charset=utf-8";
            Response.Write(ex.Message);
            Response.End();
        }
        writer.Close();
    }
コード例 #20
0
ファイル: BendersATSP.cs プロジェクト: andreasmattas/testcode
    } // 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
コード例 #21
0
ファイル: BendersATSP.cs プロジェクト: andreasmattas/testcode
    // This method creates the master ILP (arc variables x and degree constraints).
    //
    // Modeling variables:
    // forall (i,j) in A:
    //    x(i,j) = 1, if arc (i,j) is selected
    //           = 0, otherwise
    //
    // Objective:
    // minimize sum((i,j) in A) c(i,j) * x(i,j)
    //
    // Degree constraints:
    // forall i in V: sum((i,j) in delta+(i)) x(i,j) = 1
    // forall i in V: sum((j,i) in delta-(i)) x(j,i) = 1
    //
    // Binary constraints on arc variables:
    // forall (i,j) in A: x(i,j) in {0, 1}
    //
    internal static void CreateMasterILP(IModeler model,
                                        Data data,
                                        IIntVar[][] x)
    {
        int i, j;
          int numNodes = data.numNodes;

          // Create variables x(i,j) for (i,j) in A
          // For simplicity, also dummy variables x(i,i) are created.
          // Those variables are fixed to 0 and do not partecipate to
          // the constraints.

          for (i = 0; i < numNodes; ++i)
          {
         x[i] = new IIntVar[numNodes];
         for (j = 0; j < numNodes; ++j)
         {
            x[i][j] = model.BoolVar("x." + i + "." + j);
            model.Add(x[i][j]);
         }
         x[i][i].UB = 0;
          }

          // Create objective function: minimize sum((i,j) in A ) c(i,j) * x(i,j)

          ILinearNumExpr objExpr = model.LinearNumExpr();
          for (i = 0; i < numNodes; ++i)
         objExpr.Add(model.ScalProd(x[i], data.arcCost[i]));
          model.AddMinimize(objExpr);

          // Add the out degree constraints.
          // forall i in V: sum((i,j) in delta+(i)) x(i,j) = 1

          for (i = 0; i < numNodes; ++i)
          {
         ILinearNumExpr expr = model.LinearNumExpr();
         for (j = 0; j < i; ++j) expr.AddTerm(x[i][j], 1.0);
         for (j = i + 1; j < numNodes; ++j) expr.AddTerm(x[i][j], 1.0);
         model.AddEq(expr, 1.0);
          }

          // Add the in degree constraints.
          // forall i in V: sum((j,i) in delta-(i)) x(j,i) = 1

          for (i = 0; i < numNodes; ++i)
          {
         ILinearNumExpr expr = model.LinearNumExpr();
         for (j = 0; j < i; ++j) expr.AddTerm(x[j][i], 1.0);
         for (j = i + 1; j < numNodes; ++j) expr.AddTerm(x[j][i], 1.0);
         model.AddEq(expr, 1.0);
          }
    }
コード例 #22
0
        // Step 4 *****************************************************************************************************
        // Step 4 *****************************************************************************************************
        internal static void PopulateByRow(IMPModeler model, out IIntVar[][][] var2, out IIntVar[][][][] var3,
                                           out IIntVar[][][][][] var4, out IRange[][] rng,
                                           CRegion lscrg, CRegion sscrg, double[,] adblTD, string strAreaAggregation)
        {
            var aCph        = lscrg.GetCphCol().ToArray();
            int intCpgCount = lscrg.GetCphCount();
            //double dblILPSmallValue = 0.000000001;
            //double dblILPSmallValue = 0;

            var x = new IIntVar[intCpgCount][][];

            for (int i = 0; i < intCpgCount; i++)
            {
                x[i] = new IIntVar[intCpgCount][];
                for (int j = 0; j < intCpgCount; j++)
                {
                    x[i][j] = model.BoolVarArray(intCpgCount);
                }
            }

            //cost in terms of type change
            var y = Generate4DNumVar(model, intCpgCount - 1, intCpgCount, intCpgCount, intCpgCount);

            //cost in terms of compactness (length of interior boundaries)
            var z = Generate4DNumVar(model, intCpgCount - 2, intCpgCount, intCpgCount, intCpgCount);


            var c = Generate4DNumVar(model, intCpgCount - 2, intCpgCount, intCpgCount, intCpgCount);

            var3    = new IIntVar[1][][][];
            var4    = new IIntVar[3][][][][];
            var3[0] = x;
            var4[0] = y;
            var4[1] = z;
            var4[2] = c;


            //model.AddEq(x[2][0][3], 1.0, "X1");
            //model.AddEq(x[2][1][3], 1.0, "X2");
            //model.AddEq(x[2][2][2], 1.0, "X3");
            //model.AddEq(x[2][3][3], 1.0, "X4");

            //add minimizations
            ILinearNumExpr pTypeCostExpr = model.LinearNumExpr();

            //ILinearNumExpr pTypeCostAssitantExpr = model.LinearNumExpr();
            for (int i = 0; i < intCpgCount - 1; i++)   //i represents indices
            {
                for (int j = 0; j < intCpgCount; j++)
                {
                    for (int k = 0; k < intCpgCount; k++)
                    {
                        for (int l = 0; l < intCpgCount; l++)
                        {
                            double dblCoe = aCph[j].dblArea * adblTD[aCph[k].intTypeIndex, aCph[l].intTypeIndex];
                            pTypeCostExpr.AddTerm(y[i][j][k][l], dblCoe);
                            //pTypeCostAssitantExpr.AddTerm(y[i][j][k][l], dblILPSmallValueMinimization);
                        }
                    }
                }
            }


            //this is actually for t=1, whose compactness is known
            double         dblCompCostFirstPart    = 0;
            ILinearNumExpr pCompCostSecondPartExpr = model.LinearNumExpr();
            var            pAdjCorrCphsSD          = lscrg.AdjCorrCphsSD;
            double         dblConst = Convert.ToDouble(intCpgCount - 1) / Convert.ToDouble(intCpgCount - 2);

            for (int i = 0; i < intCpgCount - 2; i++)   //i represents indices
            {
                double dblNminusT = intCpgCount - i - 2;
                //double dblTemp = (intCpgCount - i) * dblConst;
                dblCompCostFirstPart += 1 / dblNminusT;
                double dblSecondPartDenominator = lscrg.dblInteriorSegLength * dblNminusT * 2;

                //we don't need to divide the value by 2 because every boundary is only counted once
                foreach (var pCorrCphs in pAdjCorrCphsSD.Keys)
                {
                    for (int l = 0; l < intCpgCount; l++)
                    {
                        pCompCostSecondPartExpr.AddTerm(pCorrCphs.dblSharedSegLength / dblSecondPartDenominator,
                                                        z[i][pCorrCphs.FrCph.ID][pCorrCphs.ToCph.ID][l]);
                        pCompCostSecondPartExpr.AddTerm(pCorrCphs.dblSharedSegLength / dblSecondPartDenominator,
                                                        z[i][pCorrCphs.ToCph.ID][pCorrCphs.FrCph.ID][l]);
                    }
                }
                //var pSecondPartExpr =  model.Prod(pCompCostSecondPartExpr, 1 / dblSecondPartDenominator);
            }

            if (intCpgCount == 1)
            {
                model.AddMinimize(pTypeCostExpr);  //we just use an empty expression
            }
            else
            {
                //Our Model***************************************
                var Ftp = model.Prod(pTypeCostExpr, 1 / lscrg.dblArea);
                var Fcp = model.Prod(dblConst, model.Sum(dblCompCostFirstPart, model.Negative(pCompCostSecondPartExpr)));
                //model.AddMinimize(model.Prod(model.Sum(Ftp, Fcp), 0.5));
                model.AddMinimize(model.Sum(
                                      model.Prod(1 - CAreaAgg_Base.dblLamda, Ftp), model.Prod(CAreaAgg_Base.dblLamda, Fcp)));
                //model.AddMinimize(Fcp);
                //model.AddMaximize(Fcp);
                //model.AddObjective()
            }

            //for showing slacks
            var IRangeLt = new List <IRange>();

            //a polygon $p$ is assigned to exactly one polygon at a step $t$
            for (int i = 0; i < intCpgCount; i++)   //i represents indices
            {
                for (int j = 0; j < intCpgCount; j++)
                {
                    ILinearNumExpr pOneCenterExpr = model.LinearNumExpr();
                    for (int l = 0; l < intCpgCount; l++)
                    {
                        pOneCenterExpr.AddTerm(x[i][j][l], 1.0);
                    }
                    model.AddEq(pOneCenterExpr, 1.0, "AssignToOnlyOneCenter");
                }
            }

            //polygon $r$, which is assigned by other polygons, must be a center
            for (int i = 0; i < intCpgCount; i++)   //i represents indices
            {
                for (int j = 0; j < intCpgCount; j++)
                {
                    for (int l = 0; l < intCpgCount; l++)
                    {
                        model.AddLe(x[i][j][l], x[i][l][l], "AssignedIsCenter__" + i + "__" + j + "__" + l);
                    }
                }
            }

            //only one patch is aggregated into another patch at each step
            for (int i = 0; i < intCpgCount; i++)   //i represents indices
            {
                ILinearNumExpr pOneAggregationExpr = model.LinearNumExpr();
                for (int j = 0; j < intCpgCount; j++)
                {
                    pOneAggregationExpr.AddTerm(x[i][j][j], 1.0);
                }
                model.AddEq(pOneAggregationExpr, intCpgCount - i, "CountCenters");
            }

            //a center can disappear, but will never reappear afterwards
            for (int i = 0; i < intCpgCount - 1; i++)   //i represents indices
            {
                for (int j = 0; j < intCpgCount; j++)
                {
                    model.AddGe(x[i][j][j], x[i + 1][j][j], "SteadyCenters");
                }
            }


            //to make sure that the final aggregated polygon has the same color as the target polygon
            ILinearNumExpr pFinalStateExpr  = model.LinearNumExpr();
            int            intTypeIndexGoal = sscrg.GetSoloCphTypeIndex();

            for (int i = 0; i < intCpgCount; i++)
            {
                if (aCph[i].intTypeIndex == intTypeIndexGoal)
                {
                    pFinalStateExpr.AddTerm(x[intCpgCount - 1][i][i], 1.0);
                }
            }
            model.AddEq(pFinalStateExpr, 1.0, "EnsureTarget");


            //to restrict *y*
            for (int i = 0; i < intCpgCount - 1; i++)   //i represents indices
            {
                for (int j = 0; j < intCpgCount; j++)
                {
                    for (int k = 0; k < intCpgCount; k++)
                    {
                        //IRangeLt.Add(model.AddLe(model.Sum(y[i][j][k][k], x[i][j][k], x[i + 1][j][k]), 2.0 , "RestrictY"));

                        for (int l = 0; l < intCpgCount; l++)
                        {
                            var LieYRight = model.LinearIntExpr(-1);
                            LieYRight.AddTerm(x[i][j][k], 1);
                            LieYRight.AddTerm(x[i + 1][j][l], 1);

                            model.AddGe(y[i][j][k][l], LieYRight, "RestrictY1");
                            model.AddLe(y[i][j][k][l], x[i][j][k], "RestrictY2");
                            model.AddLe(y[i][j][k][l], x[i + 1][j][l], "RestrictY3");
                        }
                    }
                }
            }

            //to restrict *z*
            for (int i = 0; i < intCpgCount - 2; i++)   //i represents indices
            {
                for (int j = 0; j < intCpgCount; j++)
                {
                    //for (int k = j; k < intCpgCount; k++)  // pay attention
                    for (int k = 0; k < intCpgCount; k++)
                    {
                        for (int l = 0; l < intCpgCount; l++)
                        {
                            var LieZRight = model.LinearIntExpr(-1);
                            LieZRight.AddTerm(x[i + 1][j][l], 1);
                            LieZRight.AddTerm(x[i + 1][k][l], 1);

                            model.AddGe(z[i][j][k][l], LieZRight, "RestrictZ1");
                            model.AddLe(z[i][j][k][l], x[i + 1][j][l], "RestrictZ2");
                            model.AddLe(z[i][j][k][l], x[i + 1][k][l], "RestrictZ3");
                        }
                    }
                }
            }

            //to restrict *c*
            double dblCpgCountReciprocal = 1 / Convert.ToDouble(intCpgCount);

            for (int i = 0; i < intCpgCount - 2; i++)   //i represents indices
            {
                for (int j = 0; j < intCpgCount; j++)
                {
                    //for (int k = j; k < intCpgCount; k++)  // pay attention
                    for (int k = 0; k < intCpgCount; k++)
                    {
                        for (int l = 0; l < intCpgCount; l++)
                        {
                            if (k == l)
                            {
                                continue;
                            }

                            model.AddLe(c[i][j][k][l], x[i][j][k], "RestrictC1");

                            var pLieContiguityExpr = model.LinearIntExpr();
                            //pContiguityExpr.AddTerm(x[i][j][k], 1.0);  //including polygon j itself
                            foreach (var pAdjacentCph in aCph[j].AdjacentCphSS)
                            {
                                pLieContiguityExpr.AddTerm(x[i][pAdjacentCph.ID][l], 1);
                            }
                            model.AddLe(c[i][j][k][l], pLieContiguityExpr, "Contiguity");


                            foreach (var pAdjacentCph in aCph[j].AdjacentCphSS)
                            {
                                var pContiguityExpr2 = model.LinearNumExpr(-1);
                                pContiguityExpr2.AddTerm(x[i][j][k], 1);
                                pContiguityExpr2.AddTerm(x[i][pAdjacentCph.ID][l], 1);

                                model.AddGe(c[i][j][k][l], pContiguityExpr2, "Contiguity2");
                            }

                            var pContiguityExprRight3 = model.LinearIntExpr();
                            for (int m = 0; m < intCpgCount; m++)
                            {
                                pContiguityExprRight3.AddTerm(c[i][m][k][l], 1);
                            }
                            model.AddLe(y[i][k][k][l], pContiguityExprRight3, "Contiguity3");
                        }
                    }
                }
            }


            //If two polygons have been aggregated into one polygon, then they will
            //be aggregated together in later steps. Our sixth constraint achieve this by requiring
            for (int i = 0; i < intCpgCount - 3; i++)   //i represents indices
            {
                for (int j = 0; j < intCpgCount; j++)
                {
                    for (int k = 0; k < intCpgCount; k++)
                    {
                        var pAssignTogetherExprPre   = model.LinearIntExpr();
                        var pAssignTogetherExprAfter = model.LinearIntExpr();
                        for (int l = 0; l < intCpgCount; l++)
                        {
                            pAssignTogetherExprPre.AddTerm(z[i][j][k][l], 1);
                            pAssignTogetherExprAfter.AddTerm(z[i + 1][j][k][l], 1);
                        }
                        model.AddLe(pAssignTogetherExprPre, pAssignTogetherExprAfter, "AssignTogether");
                    }
                }
            }

            var2 = new IIntVar[1][][];
            if (strAreaAggregation == _strSmallest)
            {
                IIntVar[][] w = new IIntVar[intCpgCount - 1][];
                for (int i = 0; i < intCpgCount - 1; i++)
                {
                    w[i] = model.BoolVarArray(intCpgCount);
                }
                var2[0] = w;

                //there is only one smallest patch will be involved in each aggregation step
                for (int i = 0; i < intCpgCount - 1; i++)   //i represents indices
                {
                    var pOneSmallestExpr = model.LinearIntExpr();
                    for (int j = 0; j < intCpgCount; j++)
                    {
                        pOneSmallestExpr.AddTerm(w[i][j], 1);
                    }

                    model.AddEq(pOneSmallestExpr, 1.0, "OneSmallest");
                }

                //forces that the aggregation must involve the smallest patch.
                for (int i = 0; i < intCpgCount - 1; i++)   //i represents indices
                {
                    for (int j = 0; j < intCpgCount; j++)
                    {
                        var pInvolveSmallestExpr = model.LinearIntExpr();
                        for (int k = 0; k < intCpgCount; k++)
                        {
                            if (j == k) //o != r
                            {
                                continue;
                            }
                            pInvolveSmallestExpr.AddTerm(y[i][j][j][k], 1);
                            pInvolveSmallestExpr.AddTerm(y[i][k][k][j], 1);
                        }
                        model.AddLe(w[i][j], pInvolveSmallestExpr, "InvolveSmallest");
                    }
                }

                //To guarantee that patch $o$ is involved in aggregation is indeed the smallest patch
                double dblM = 1.1 * lscrg.dblArea;        //a very large value
                for (int i = 0; i < intCpgCount - 1; i++) //i represents indices
                {
                    var aAreaExpr = ComputeAreaExpr(model, x[i], aCph);
                    for (int j = 0; j < intCpgCount; j++)
                    {
                        for (int k = 0; k < intCpgCount; k++)
                        {
                            if (j == k) //o != r
                            {
                                continue;
                            }

                            var pSumExpr  = model.Sum(2.0, model.Negative(model.Sum(w[i][j], x[i][k][k]))); //(2-w_{t,o}-x_{t,r,r})
                            var pProdExpr = model.Prod(pSumExpr, dblM);                                     //M(2-w_{t,o}-x_{t,r,r})

                            //A_{t,o}-A_{t,r}<= M(2-w_{t,o}-x_{t,r,r})
                            model.AddLe(model
                                        .Sum(aAreaExpr[j], model.Negative(aAreaExpr[k])), pProdExpr, "IndeedSmallest");
                        }
                    }
                }
            }


            //***************compare with number of constraints counted manually************
            rng    = new IRange[1][];
            rng[0] = new IRange[IRangeLt.Count];
            for (int i = 0; i < IRangeLt.Count; i++)
            {
                rng[0][i] = IRangeLt[i];
            }
        }
コード例 #23
0
ファイル: BendersATSP.cs プロジェクト: andreasmattas/testcode
    }     // END WorkerLP

    // This method creates the master ILP (arc variables x and degree constraints).
    //
    // Modeling variables:
    // forall (i,j) in A:
    //    x(i,j) = 1, if arc (i,j) is selected
    //           = 0, otherwise
    //
    // Objective:
    // minimize sum((i,j) in A) c(i,j) * x(i,j)
    //
    // Degree constraints:
    // forall i in V: sum((i,j) in delta+(i)) x(i,j) = 1
    // forall i in V: sum((j,i) in delta-(i)) x(j,i) = 1
    //
    // Binary constraints on arc variables:
    // forall (i,j) in A: x(i,j) in {0, 1}
    //
    internal static void CreateMasterILP(IModeler model,
                                         Data data,
                                         IIntVar[][] x)
    {
        int i, j;
        int numNodes = data.numNodes;

        // Create variables x(i,j) for (i,j) in A
        // For simplicity, also dummy variables x(i,i) are created.
        // Those variables are fixed to 0 and do not partecipate to
        // the constraints.

        for (i = 0; i < numNodes; ++i)
        {
            x[i] = new IIntVar[numNodes];
            for (j = 0; j < numNodes; ++j)
            {
                x[i][j] = model.BoolVar("x." + i + "." + j);
                model.Add(x[i][j]);
            }
            x[i][i].UB = 0;
        }

        // Create objective function: minimize sum((i,j) in A ) c(i,j) * x(i,j)

        ILinearNumExpr objExpr = model.LinearNumExpr();

        for (i = 0; i < numNodes; ++i)
        {
            objExpr.Add(model.ScalProd(x[i], data.arcCost[i]));
        }
        model.AddMinimize(objExpr);

        // Add the out degree constraints.
        // forall i in V: sum((i,j) in delta+(i)) x(i,j) = 1

        for (i = 0; i < numNodes; ++i)
        {
            ILinearNumExpr expr = model.LinearNumExpr();
            for (j = 0; j < i; ++j)
            {
                expr.AddTerm(x[i][j], 1.0);
            }
            for (j = i + 1; j < numNodes; ++j)
            {
                expr.AddTerm(x[i][j], 1.0);
            }
            model.AddEq(expr, 1.0);
        }

        // Add the in degree constraints.
        // forall i in V: sum((j,i) in delta-(i)) x(j,i) = 1

        for (i = 0; i < numNodes; ++i)
        {
            ILinearNumExpr expr = model.LinearNumExpr();
            for (j = 0; j < i; ++j)
            {
                expr.AddTerm(x[j][i], 1.0);
            }
            for (j = i + 1; j < numNodes; ++j)
            {
                expr.AddTerm(x[j][i], 1.0);
            }
            model.AddEq(expr, 1.0);
        }
    } // END CreateMasterILP
コード例 #24
0
ファイル: BendersATSP.cs プロジェクト: andreasmattas/testcode
 internal BendersUserCutCallback(IIntVar[][] x, WorkerLP workerLP)
 {
     this.x = x;
      this.workerLP = workerLP;
      numNodes = x.Length;
 }
コード例 #25
0
ファイル: Ppp.cs プロジェクト: andreasmattas/testcode
 //
 // Matrix operations
 //
 private static IIntVar[][] Transpose(IIntVar[][] x)
 {
     int m = x.Length;
       int n = x[0].Length;
       IIntVar[][] y = new IIntVar[n][];
       for (int i = 0; i < n; i++) {
     y[i] = new IIntVar[m];
     for (int j = 0; j < m; j++)
       y[i][j] = x[j][i];
       }
       return y;
 }
コード例 #26
0
ファイル: BendersATSP.cs プロジェクト: andreasmattas/testcode
        // This method separates Benders' cuts violated by the current x solution.
        // Violated cuts are found by solving the worker LP
        //
        public IRange Separate(double[][] xSol, IIntVar[][] x)
        {
            int i, j, k;

             IRange cut = null;

             // Update the objective function in the worker LP:
             // minimize sum(k in V0) sum((i,j) in A) x(i,j) * v(k,i,j)
             //          - sum(k in V0) u(k,0) + sum(k in V0) u(k,k)

             ILinearNumExpr objExpr = cplex.LinearNumExpr();
             for (k = 1; k < numNodes; ++k)
             {
            for (i = 0; i < numNodes; ++i)
            {
               for (j = 0; j < numNodes; ++j)
               {
                  objExpr.AddTerm(v[k-1][i][j], xSol[i][j]);
               }
            }
             }
             for (k = 1; k < numNodes; ++k)
             {
            objExpr.AddTerm(u[k-1][k], 1.0);
            objExpr.AddTerm(u[k-1][0], -1.0);
             }
             cplex.GetObjective().Expr = objExpr;

             // Solve the worker LP

             cplex.Solve();

             // A violated cut is available iff the solution status is Unbounded

             if ( cplex.GetStatus().Equals(Cplex.Status.Unbounded) )
             {

            // Get the violated cut as an unbounded ray of the worker LP

            ILinearNumExpr rayExpr = cplex.Ray;

            // Compute the cut from the unbounded ray. The cut is:
            // sum((i,j) in A) (sum(k in V0) v(k,i,j)) * x(i,j) >=
            // sum(k in V0) u(k,0) - u(k,k)

            ILinearNumExpr cutLhs = cplex.LinearNumExpr();
            double cutRhs = 0.0;
            ILinearNumExprEnumerator rayEnum = rayExpr.GetLinearEnumerator();

            while ( rayEnum.MoveNext() ) {
               INumVar var = rayEnum.NumVar;
               bool varFound = false;
               for (k = 1; k < numNodes && !varFound; ++k) {
                  for (i = 0; i < numNodes && !varFound; ++i) {
                     for (j = 0; j < numNodes && !varFound; ++j) {
                        if ( var.Equals(v[k-1][i][j]) ) {
                           cutLhs.AddTerm(x[i][j], rayEnum.Value);
                           varFound = true;
                        }
                     }
                  }
               }
               for (k = 1; k < numNodes && !varFound; ++k) {
                  for (i = 0; i < numNodes && !varFound; ++i) {
                     if ( var.Equals(u[k-1][i]) ) {
                        if ( i == 0 )
                           cutRhs += rayEnum.Value;
                        else if ( i == k )
                           cutRhs -= rayEnum.Value;
                         varFound = true;
                     }
                  }
               }
            }

            cut = cplex.Ge(cutLhs, cutRhs);
             }

             return cut;
        }
コード例 #27
0
        static public void Main(string[] args)
        {
            CP  cp             = new CP();
            int nbTruckConfigs = 7; // number of possible configurations for the truck
            int nbOrders       = 21;
            int nbCustomers    = 3;
            int nbTrucks       = 15;   //max number of travels of the truck

            int[] maxTruckConfigLoad = //Capacity of the truck depends on its config
            {
                11, 11, 11, 11, 10, 10, 10
            };
            int maxLoad = Max(maxTruckConfigLoad);

            int[] customerOfOrder =
            {
                0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
                1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
                2
            };
            int[] volumes =
            {
                3, 4, 3, 2, 5, 4, 11,  4, 5, 2,
                4, 7, 3, 5, 2, 5,  6, 11, 1, 6,
                3
            };
            int[] colors =
            {
                1, 2, 0, 1, 1, 1, 0, 0, 0, 0,
                2, 2, 2, 0, 2, 1, 0, 2, 0, 0,
                0
            };
            int[] truckCost = //cost for loading a truck of a given config
            {
                2, 2, 2, 3, 3, 3, 4
            };

            //Decision variables
            IIntVar[] truckConfigs = cp.IntVarArray(nbTrucks, 0, nbTruckConfigs - 1); //configuration of the truck
            IIntVar[] where = cp.IntVarArray(nbOrders, 0, nbTrucks - 1);              //In which truck is an order
            IIntVar[] load    = cp.IntVarArray(nbTrucks, 0, maxLoad);                 //load of a truck
            IIntVar   numUsed = cp.IntVar(0, nbTrucks);                               // number of trucks used

            IIntVar[] customerOfTruck = cp.IntVarArray(nbTrucks, 0, nbCustomers);

            // transition costs between trucks
            IIntTupleSet costTuples = cp.IntTable(3);

            cp.AddTuple(costTuples, new int[] { 0, 0, 0 });
            cp.AddTuple(costTuples, new int[] { 0, 1, 0 });
            cp.AddTuple(costTuples, new int[] { 0, 2, 0 });
            cp.AddTuple(costTuples, new int[] { 0, 3, 10 });
            cp.AddTuple(costTuples, new int[] { 0, 4, 10 });
            cp.AddTuple(costTuples, new int[] { 0, 5, 10 });
            cp.AddTuple(costTuples, new int[] { 0, 6, 15 });
            cp.AddTuple(costTuples, new int[] { 1, 0, 0 });
            cp.AddTuple(costTuples, new int[] { 1, 1, 0 });
            cp.AddTuple(costTuples, new int[] { 1, 2, 0 });
            cp.AddTuple(costTuples, new int[] { 1, 3, 10 });
            cp.AddTuple(costTuples, new int[] { 1, 4, 10 });
            cp.AddTuple(costTuples, new int[] { 1, 5, 10 });
            cp.AddTuple(costTuples, new int[] { 1, 6, 15 });
            cp.AddTuple(costTuples, new int[] { 2, 0, 0 });
            cp.AddTuple(costTuples, new int[] { 2, 1, 0 });
            cp.AddTuple(costTuples, new int[] { 2, 2, 0 });
            cp.AddTuple(costTuples, new int[] { 2, 3, 10 });
            cp.AddTuple(costTuples, new int[] { 2, 4, 10 });
            cp.AddTuple(costTuples, new int[] { 2, 5, 10 });
            cp.AddTuple(costTuples, new int[] { 2, 6, 15 });
            cp.AddTuple(costTuples, new int[] { 3, 0, 3 });
            cp.AddTuple(costTuples, new int[] { 3, 1, 3 });
            cp.AddTuple(costTuples, new int[] { 3, 2, 3 });
            cp.AddTuple(costTuples, new int[] { 3, 3, 0 });
            cp.AddTuple(costTuples, new int[] { 3, 4, 10 });
            cp.AddTuple(costTuples, new int[] { 3, 5, 10 });
            cp.AddTuple(costTuples, new int[] { 3, 6, 15 });
            cp.AddTuple(costTuples, new int[] { 4, 0, 3 });
            cp.AddTuple(costTuples, new int[] { 4, 1, 3 });
            cp.AddTuple(costTuples, new int[] { 4, 2, 3 });
            cp.AddTuple(costTuples, new int[] { 4, 3, 10 });
            cp.AddTuple(costTuples, new int[] { 4, 4, 0 });
            cp.AddTuple(costTuples, new int[] { 4, 5, 10 });
            cp.AddTuple(costTuples, new int[] { 4, 6, 15 });
            cp.AddTuple(costTuples, new int[] { 5, 0, 3 });
            cp.AddTuple(costTuples, new int[] { 5, 1, 3 });
            cp.AddTuple(costTuples, new int[] { 5, 2, 3 });
            cp.AddTuple(costTuples, new int[] { 5, 3, 10 });
            cp.AddTuple(costTuples, new int[] { 5, 4, 10 });
            cp.AddTuple(costTuples, new int[] { 5, 5, 0 });
            cp.AddTuple(costTuples, new int[] { 5, 6, 15 });
            cp.AddTuple(costTuples, new int[] { 6, 0, 3 });
            cp.AddTuple(costTuples, new int[] { 6, 1, 3 });
            cp.AddTuple(costTuples, new int[] { 6, 2, 3 });
            cp.AddTuple(costTuples, new int[] { 6, 3, 10 });
            cp.AddTuple(costTuples, new int[] { 6, 4, 10 });
            cp.AddTuple(costTuples, new int[] { 6, 5, 10 });
            cp.AddTuple(costTuples, new int[] { 6, 6, 0 });

            IIntVar[] transitionCost = cp.IntVarArray(nbTrucks - 1, 0, 1000);
            for (int i = 1; i < nbTrucks; i++)
            {
                IIntVar[] auxVars = new IIntVar[3];
                auxVars[0] = truckConfigs[i - 1];
                auxVars[1] = truckConfigs[i];
                auxVars[2] = transitionCost[i - 1];
                cp.Add(cp.AllowedAssignments(auxVars, costTuples));
            }

            // constrain the volume of the orders in each truck
            cp.Add(cp.Pack(load, where, volumes, numUsed));
            for (int i = 0; i < nbTrucks; i++)
            {
                cp.Add(cp.Le(load[i], cp.Element(maxTruckConfigLoad, truckConfigs[i])));
            }

            // compatibility between the colors of an order and the configuration of its truck
            int[][] allowedContainerConfigs = new int[3][];
            allowedContainerConfigs[0] = new int[] { 0, 3, 4, 6 };
            allowedContainerConfigs[1] = new int[] { 1, 3, 5, 6 };
            allowedContainerConfigs[2] = new int[] { 2, 4, 5, 6 };
            for (int j = 0; j < nbOrders; j++)
            {
                IIntVar configOfContainer = cp.IntVar(allowedContainerConfigs[colors[j]]);
                cp.Add(cp.Eq(configOfContainer, cp.Element(truckConfigs, where[j])));
            }

            // only one customer per truck
            for (int j = 0; j < nbOrders; j++)
            {
                cp.Add(cp.Eq(cp.Element(customerOfTruck, where[j]), customerOfOrder[j]));
            }

            // non used trucks are at the end
            for (int j = 1; j < nbTrucks; j++)
            {
                cp.Add(cp.Or(cp.Gt(load[j - 1], 0), cp.Eq(load[j], 0)));
            }

            // Dominance: the non used trucks keep the last used configuration
            cp.Add(cp.Gt(load[0], 0));
            for (int i = 1; i < nbTrucks; i++)
            {
                cp.Add(cp.Or(cp.Gt(load[i], 0), cp.Eq(truckConfigs[i], truckConfigs[i - 1])));
            }

            //Dominance:  regroup deliveries with same configuration
            for (int i = nbTrucks - 2; i > 0; i--)
            {
                IConstraint Ct = cp.TrueConstraint();
                for (int p = i + 1; p < nbTrucks; p++)
                {
                    Ct = cp.And(cp.Neq(truckConfigs[p], truckConfigs[i - 1]), Ct);
                }
                cp.Add(cp.Or(cp.Eq(truckConfigs[i], truckConfigs[i - 1]), Ct));
            }

            // Objective: first criterion for minimizing the cost for configuring and loading trucks
            //            second criterion for minimizing the number of trucks

            IIntExpr obj1 = cp.Constant(0);

            for (int i = 0; i < nbTrucks; i++)
            {
                obj1 = cp.Sum(obj1, cp.Prod(cp.Element(truckCost, truckConfigs[i]), cp.Neq(load[i], 0)));
            }
            obj1 = cp.Sum(obj1, cp.Sum(transitionCost));

            IIntExpr obj2 = numUsed;

            // Multicriteria lexicographic optimization
            cp.Add(cp.Minimize(cp.StaticLex(obj1, obj2)));
            cp.SetParameter(CP.DoubleParam.TimeLimit, 20);
            cp.SetParameter(CP.IntParam.LogPeriod, 50000);
            cp.Solve();
            double[] obj = cp.GetObjValues();
            Console.WriteLine("Configuration cost: " + (int)obj[0] +
                              " Number of Trucks: " + (int)obj[1]);
            for (int i = 0; i < nbTrucks; i++)
            {
                if (cp.GetValue(load[i]) > 0)
                {
                    Console.Write("Truck " + i +
                                  ": Config=" + cp.GetIntValue(truckConfigs[i])
                                  + " Items= ");
                    for (int j = 0; j < nbOrders; j++)
                    {
                        if (cp.GetValue(where[j]) == i)
                        {
                            Console.Write("<" + j + "," + colors[j] + "," + volumes[j] + "> ");
                        }
                    }
                    Console.WriteLine();
                }
            }
        }
コード例 #28
0
ファイル: Steelmill.cs プロジェクト: yzhou364/Cplex_Tutorial
        static void Main(string[] args)
        {
            CP cp = new CP();

            int weightSum = 0;

            for (int o = 0; o < nbOrders; o++)
            {
                weightSum += weight[o];
            }

            IIntVar[] where = new IIntVar[nbOrders];
            for (int o = 0; o < nbOrders; o++)
            {
                where[o] = cp.IntVar(0, nbSlabs - 1);
            }
            IIntVar[] load = new IIntVar[nbSlabs];
            for (int m = 0; m < nbSlabs; m++)
            {
                load[m] = cp.IntVar(0, weightSum);
            }

            // Pack constraint
            cp.Add(cp.Pack(load, where, weight));

            // Color constraints
            for (int m = 0; m < nbSlabs; m++)
            {
                IIntExpr[] colorExpArray = new IIntExpr[nbColors];
                for (int c = 0; c < nbColors; c++)
                {
                    IConstraint orCt = cp.FalseConstraint();
                    for (int o = 0; o < nbOrders; o++)
                    {
                        if (colors[o] == c)
                        {
                            orCt = cp.Or(orCt, cp.Eq(where[o], m));
                        }
                    }
                    colorExpArray[c] = cp.IntExpr(orCt);
                }
                cp.Add(cp.Le(cp.Sum(colorExpArray), 2));
            }

            // Objective function
            int sizeLossValues = capacities[capacities.Length - 1] - capacities[0] + 1;

            int[] lossValues = new int[sizeLossValues];
            lossValues[0] = 0;
            int indexValue = 1;

            for (int q = 1; q < capacities.Length; q++)
            {
                for (int p = capacities[q - 1] + 1; p <= capacities[q]; p++)
                {
                    lossValues[indexValue] = capacities[q] - p;
                    indexValue++;
                }
            }
            IIntExpr obj = cp.Constant(0);

            for (int m = 0; m < nbSlabs; m++)
            {
                obj = cp.Sum(obj, cp.Element(lossValues, load[m]));
            }
            cp.Add(cp.Minimize(obj));

            // - A symmetry breaking constraint that is useful for small instances
            for (int m = 1; m < nbSlabs; m++)
            {
                cp.Add(cp.Ge(load[m - 1], load[m]));
            }

            if (cp.Solve())
            {
                Console.WriteLine("Optimal value: " + cp.GetValue(obj));
                for (int m = 0; m < nbSlabs; m++)
                {
                    int p = 0;
                    for (int o = 0; o < nbOrders; o++)
                    {
                        if (cp.GetValue(where[o]) == m)
                        {
                            ++p;
                        }
                    }
                    if (p == 0)
                    {
                        continue;
                    }
                    Console.Write("Slab " + m + " is used for order");
                    if (p > 1)
                    {
                        Console.Write("s");
                    }
                    Console.Write(" :");
                    for (int o = 0; o < nbOrders; o++)
                    {
                        if (cp.GetValue(where[o]) == m)
                        {
                            Console.Write(" " + o);
                        }
                    }
                    Console.WriteLine();
                }
            }
        }
コード例 #29
0
        static void Main(string[] args)
        {
            try
            {
                int n = 10;
                if (args.Length > 0)
                {
                    n = Int32.Parse(args[0]);
                }
                if ((n % 2) == 1)
                {
                    n++;
                }
                Console.WriteLine("Finding schedule for {0} teams", n);
                int nbWeeks        = 2 * (n - 1);
                int nbGamesPerWeek = n / 2;
                int nbGames        = n * (n - 1);
                CP  cp             = new CP();

                IIntVar[][] games = new IIntVar[nbWeeks][];
                IIntVar[][] home  = new IIntVar[nbWeeks][];
                IIntVar[][] away  = new IIntVar[nbWeeks][];

                for (int i = 0; i < nbWeeks; i++)
                {
                    home[i]  = cp.IntVarArray(nbGamesPerWeek, 0, n - 1);
                    away[i]  = cp.IntVarArray(nbGamesPerWeek, 0, n - 1);
                    games[i] = cp.IntVarArray(nbGamesPerWeek, 0, nbGames - 1);
                }
                //
                // For each play slot, set up correspondance between game id,
                // home team, and away team
                //

                IIntTupleSet gha   = cp.IntTable(3);
                int[]        tuple = new int[3];
                for (int i = 0; i < n; i++)
                {
                    tuple[0] = i;
                    for (int j = 0; j < n; j++)
                    {
                        if (i != j)
                        {
                            tuple[1] = j;
                            tuple[2] = Game(i, j, n);
                            cp.AddTuple(gha, tuple);
                        }
                    }
                }

                for (int i = 0; i < nbWeeks; i++)
                {
                    for (int j = 0; j < nbGamesPerWeek; j++)
                    {
                        IIntVar[] vars = cp.IntVarArray(3);
                        vars[0] = home[i][j];
                        vars[1] = away[i][j];
                        vars[2] = games[i][j];
                        cp.Add(cp.AllowedAssignments(vars, gha));
                    }
                }
                //
                // All teams play each week
                //
                for (int i = 0; i < nbWeeks; i++)
                {
                    IIntVar[] teamsThisWeek = cp.IntVarArray(n);
                    for (int j = 0; j < nbGamesPerWeek; j++)
                    {
                        teamsThisWeek[j] = home[i][j];
                        teamsThisWeek[nbGamesPerWeek + j] = away[i][j];
                    }
                    cp.Add(cp.AllDiff(teamsThisWeek));
                }
                //
                // Dual representation: for each game id, the play slot is maintained
                //
                IIntVar[] weekOfGame = cp.IntVarArray(nbGames, 0, nbWeeks - 1);
                IIntVar[] allGames   = cp.IntVarArray(nbGames);
                IIntVar[] allSlots   = cp.IntVarArray(nbGames, 0, nbGames - 1);
                for (int i = 0; i < nbWeeks; i++)
                {
                    for (int j = 0; j < nbGamesPerWeek; j++)
                    {
                        allGames[i * nbGamesPerWeek + j] = games[i][j];
                    }
                }
                cp.Add(cp.Inverse(allGames, allSlots));
                for (int i = 0; i < nbGames; i++)
                {
                    cp.Add(cp.Eq(weekOfGame[i], cp.Div(allSlots[i], nbGamesPerWeek)));
                }
                //
                // Two half schedules.  Cannot play the same pair twice in the same half.
                // Plus, impose a minimum number of weeks between two games involving
                // the same teams (up to six weeks)
                //
                int mid     = nbWeeks / 2;
                int overlap = 0;
                if (n >= 6)
                {
                    overlap = min(n / 2, 6);
                }
                for (int i = 0; i < n; i++)
                {
                    for (int j = i + 1; j < n; j++)
                    {
                        int g1 = Game(i, j, n);
                        int g2 = Game(j, i, n);
                        cp.Add(cp.Equiv(cp.Ge(weekOfGame[g1], mid), cp.Lt(weekOfGame[g2], mid)));
                        // Six week difference...
                        if (overlap != 0)
                        {
                            cp.Add(cp.Ge(cp.Abs(cp.Diff(weekOfGame[g1], weekOfGame[g2])), overlap));
                        }
                    }
                }

                //
                // Can't have three homes or three aways in a row.
                //
                IIntVar[][] playHome = new IIntVar[n][];
                for (int i = 0; i < n; i++)
                {
                    playHome[i] = cp.IntVarArray(nbWeeks, 0, 1);
                    for (int j = 0; j < nbWeeks; j++)
                    {
                        cp.Add(cp.Eq(playHome[i][j], cp.Count(home[j], i)));
                    }
                    for (int j = 0; j < nbWeeks - 3; j++)
                    {
                        IIntVar[] window = cp.IntVarArray(3);
                        for (int k = j; k < j + 3; k++)
                        {
                            window[k - j] = playHome[i][k];
                        }
                        IIntExpr windowSum = cp.Sum(window);
                        cp.Add(cp.Le(1, windowSum));
                        cp.Add(cp.Le(windowSum, 2));
                    }
                }

                //
                // If we start the season home, we finish away and vice versa.
                //
                for (int i = 0; i < n; i++)
                {
                    cp.Add(cp.Neq(playHome[i][0], playHome[i][nbWeeks - 1]));
                }

                //
                // Objective: minimize the number of `breaks'.  A break is
                //            two consecutive home or away matches for a
                //            particular team
                IIntVar[] teamBreaks = cp.IntVarArray(n, 0, nbWeeks / 2);
                for (int i = 0; i < n; i++)
                {
                    IIntExpr nbreaks = cp.Constant(0);
                    for (int j = 1; j < nbWeeks; j++)
                    {
                        nbreaks = cp.Sum(nbreaks, cp.IntExpr(cp.Eq(playHome[i][j - 1], playHome[i][j])));
                    }
                    cp.Add(cp.Eq(teamBreaks[i], nbreaks));
                }
                IIntVar breaks = cp.IntVar(n - 2, n * (nbWeeks / 2));
                cp.Add(cp.Eq(breaks, cp.Sum(teamBreaks)));
                cp.Add(cp.Minimize(breaks));

                //
                // Catalyzing constraints
                //

                // Each team plays home the same number of times as away
                for (int i = 0; i < n; i++)
                {
                    cp.Add(cp.Eq(cp.Sum(playHome[i]), nbWeeks / 2));
                }

                // Breaks must be even for each team
                for (int i = 0; i < n; i++)
                {
                    cp.Add(cp.Eq(cp.Modulo(teamBreaks[i], 2), 0));
                }

                //
                // Symmetry breaking constraints
                //

                // Teams are interchangeable.  Fix first week.
                // Also breaks reflection symmetry of the whole schedule.
                for (int i = 0; i < nbGamesPerWeek; i++)
                {
                    cp.Add(cp.Eq(home[0][i], i * 2));
                    cp.Add(cp.Eq(away[0][i], i * 2 + 1));
                }

                // Order of games in each week is arbitrary.
                // Break symmetry by forcing an order.
                for (int i = 0; i < nbWeeks; i++)
                {
                    for (int j = 1; j < nbGamesPerWeek; j++)
                    {
                        cp.Add(cp.Gt(games[i][j], games[i][j - 1]));
                    }
                }

                cp.SetParameter(CP.DoubleParam.TimeLimit, 20);
                cp.SetParameter(CP.IntParam.LogPeriod, 10000);
                IVarSelector   varSel = cp.SelectSmallest(cp.VarIndex(allGames));;
                IValueSelector valSel = cp.SelectRandomValue();

                ISearchPhase phase = cp.SearchPhase(allGames,
                                                    cp.IntVarChooser(varSel),
                                                    cp.IntValueChooser(valSel));
                cp.SetSearchPhases(phase);
                cp.StartNewSearch();
                while (cp.Next())
                {
                    Console.WriteLine("Solution at {0}", cp.GetValue(breaks));
                }
                cp.EndSearch();
            }
            catch (ILOG.Concert.Exception e)
            {
                Console.WriteLine("Error {0}", e);
            }
        }
コード例 #30
0
ファイル: Talent.cs プロジェクト: andreasmattas/testcode
    private void BuildModel()
    {
        // Create the decision variables, cost, and the model
        scene = new IIntVar[numScenes];
        for (int s = 0; s < numScenes; s++)
            scene[s] = cp.IntVar(0, numScenes - 1);

        // Expression representing the global cost
        idleCost = cp.IntExpr();

        // Make the slot-based secondary model
        IIntVar[] slot = new IIntVar[numScenes];
        for (int s = 0; s < numScenes; s++)
            slot[s] = cp.IntVar(0, numScenes - 1);
        cp.Add(cp.Inverse(scene, slot));

        // Loop over all actors, building cost
        for (int a = 0; a < numActors; a++)
        {
            // Expression for the waiting time for this actor
            IIntExpr actorWait = cp.IntExpr();

            // Calculate the first and last slots where this actor plays
            List<IIntVar> position = new List<IIntVar>();

            System.Collections.IEnumerator en = actorInScene[a].GetEnumerator();
            while (en.MoveNext())
                position.Add(slot[(int)en.Current]);

            IIntExpr firstSlot = cp.Min(position.ToArray());
            IIntExpr lastSlot = cp.Max(position.ToArray());

            // If an actor is not in a scene, he waits
            // if he is on set when the scene is filmed
            for (int s = 0; s < numScenes; s++)
            {
                if (!actorInScene[a].Contains(s))
                { // not in scene
                    IIntExpr wait = cp.And(cp.Le(firstSlot, slot[s]), cp.Le(
                            slot[s], lastSlot));
                    actorWait = cp.Sum(actorWait, cp.Prod(sceneDuration[s],
                            wait));
                }
            }

            // Accumulate the cost of waiting time for this actor
            idleCost = cp.Sum(idleCost, cp.Prod(actorPay[a], actorWait));
        }
        cp.Add(cp.Minimize(idleCost));
    }