Beispiel #1
0
        protected void AddConstraint(int t, IALPDecision a)//Add a column into RMP model
        {
            if (constraints[t].ContainsKey(a))
            {
                return;
            }
            INumExpr exp1 = RMPModel.NumExpr();

            if (t < Data.TimeHorizon - 1)
            {
                exp1 = RMPModel.Sum(Var2[t], RMPModel.Prod(-1, Var2[t + 1]));
                foreach (IALPResource re in Data.RS)
                {
                    if (a.UseResource(re))
                    {
                        exp1 = RMPModel.Sum(exp1, Var1[t][Data.RS.IndexOf(re)], RMPModel.Prod(Data.Qti(t, re, a) - 1, Var1[t + 1][Data.RS.IndexOf(re)]));
                    }
                }
            }
            else
            {
                exp1 = RMPModel.Sum(exp1, Var2[t]);
                foreach (IALPResource re in Data.RS)
                {
                    if (a.UseResource(re))
                    {
                        exp1 = RMPModel.Sum(exp1, Var1[t][Data.RS.IndexOf(re)]);
                    }
                }
            }
            constraints[t].Add(a, RMPModel.AddGe(exp1, Data.Rt(t, a)));
        }
Beispiel #2
0
 static void Main(string[] args)
 {
     Cplex m = new Cplex();
     INumVar x1 = m.NumVar(0, System.Double.MaxValue, NumVarType.Float, "food.1");
     INumVar x2 = m.NumVar(0, System.Double.MaxValue, NumVarType.Float, "food.2");
     INumVar x3 = m.NumVar(0, System.Double.MaxValue, NumVarType.Float, "food.3");
     INumVar x4 = m.NumVar(0, System.Double.MaxValue, NumVarType.Float, "food.4");
     INumVar x5 = m.NumVar(0, System.Double.MaxValue, NumVarType.Float, "food.5");
     IObjective obj = m.AddMinimize(m.Sum(
         m.Prod(x1, 20), m.Prod(x2, 10), m.Prod(x3, 31), m.Prod(x4, 11), m.Prod(x5, 12)));
     INumExpr ironLHS = m.Sum(m.Prod(x1, 2), m.Prod(x3, 3), m.Prod(x4, 1), m.Prod(x5, 2));
     IRange con1 = m.AddGe(ironLHS, 21, "nutrient.iron");
     INumExpr calciumLHS = m.Sum(m.Prod(x2, 1), m.Prod(x3, 2), m.Prod(x4, 2), m.Prod(x5, 1));
     IRange con2 = m.AddGe(calciumLHS, 12, "nutrient.calcium");
     Console.WriteLine("**** Solver Output:\n");
     m.Solve();
     m.ExportModel("diet.lp");
     Console.WriteLine("\n**** Diet Program Output:\n");
     Console.WriteLine("Objective Value = {0}", m.GetObjValue());
     Console.WriteLine("{0} = {1}, reduced cost = {2}", x1.Name, m.GetValue(x1), m.GetReducedCost(x1));
     Console.WriteLine("{0} = {1}, reduced cost = {2}", x2.Name, m.GetValue(x2), m.GetReducedCost(x2));
     Console.WriteLine("{0} = {1}, reduced cost = {2}", x3.Name, m.GetValue(x3), m.GetReducedCost(x3));
     Console.WriteLine("{0} = {1}, reduced cost = {2}", x4.Name, m.GetValue(x4), m.GetReducedCost(x4));
     Console.WriteLine("{0} = {1}, reduced cost = {2}", x5.Name, m.GetValue(x5), m.GetReducedCost(x5));
     Console.WriteLine("{0}, slack = {1}, pi = {2}", con1.Name, m.GetSlack(con1), m.GetDual(con1));
     Console.WriteLine("{0}, slack = {1}, pi = {2}", con2.Name, m.GetSlack(con2), m.GetDual(con2));
     m.End();
 }
Beispiel #3
0
        public virtual void StepFoward()
        {
            alpha -= step;
            //TODO:Delete Agg constraint(s)
            foreach (var a in Aggconstraints)
            {
                RMPModel.Remove(a.Value);
            }
            List <IALPDecision> list = Aggconstraints.Keys.ToList();

            Aggconstraints.Clear();
            //TODO:Add DisAgg variables and constraint(s)
            for (int i = alpha + 1; i <= alpha + step; i++)
            {
                constraints.Add(i, new Dictionary <IALPDecision, IRange>());
                Var1.Add(i, RMPModel.NumVarArray(Data.RS.Count, 0, double.MaxValue));
                Var2.Add(i, RMPModel.NumVar(0, double.MaxValue));
                V.Add(i, new double[Data.RS.Count]);
                Sita.Add(i, 0);
            }

            for (int t = alpha + 1; t <= alpha + step; t++)
            {
                if (t < Data.TimeHorizon - 1)
                {
                    foreach (IALPResource re in Data.RS)
                    {
                        INumExpr exp2 = RMPModel.Sum(Var1[t][Data.RS.IndexOf(re)], RMPModel.Prod(-1, Var1[t + 1][Data.RS.IndexOf(re)]));
                        RMPModel.AddGe(exp2, 0);
                    }
                    INumExpr exp3 = RMPModel.Sum(Var2[t], RMPModel.Prod(-1, Var2[t + 1]));
                    RMPModel.AddGe(exp3, 0);
                }
            }
            foreach (IALPResource re in Data.RS)
            {
                INumExpr exp6 = RMPModel.NumExpr();
                exp6 = RMPModel.Sum(AggVar1[Data.RS.IndexOf(re)], RMPModel.Prod(-1, Var1[alpha + 1][Data.RS.IndexOf(re)]));
                RMPModel.AddGe(exp6, 0);
            }

            INumExpr exp4 = RMPModel.NumExpr();

            exp4 = RMPModel.Sum(exp4, AggVar2, RMPModel.Prod(-1, Var2[alpha + 1]));
            RMPModel.AddGe(exp4, 0);

            IALPDecision d = (Data.DS as IALPDecisionSpace).CloseAllDecision() as IALPDecision;

            AddConstraint1(d);
            foreach (IALPDecision de in list)
            {
                AddConstraint1(de);
            }
            for (int t = alpha + 1; t <= alpha + step; t++)
            {
                AddConstraint2(t, d);
            }
        }
Beispiel #4
0
        private void initializeArbitraryBooleanConstraints(Cplex cplex, VariabilityModel vm,
                                                           Dictionary <BinaryOption, INumVar> optsToCplex)
        {
            foreach (string booleanConstraint in vm.BinaryConstraints)
            {
                string[] cnfParts = booleanConstraint.Split('&');

                foreach (string cnfPart in cnfParts)
                {
                    string[]   variables     = cnfPart.Split('|');
                    INumExpr[] logicOrConstr = new INumExpr[variables.Length];

                    for (int i = 0; i < variables.Length; i++)
                    {
                        string var = variables[i].Trim();
                        // In binary domain (1 - x) equals the negation of x
                        if (var.StartsWith("!") || var.StartsWith("-"))
                        {
                            logicOrConstr[i] = cplex.Sum(1, cplex.Negative((optsToCplex[vm.getBinaryOption(var.Substring(1))])));
                        }
                        else
                        {
                            logicOrConstr[i] = optsToCplex[vm.getBinaryOption(var)];
                        }
                    }

                    // Since we use cnf notation, it is enough to check if the sum of a single clause is
                    // greater or equal 1
                    cplex.AddGe(cplex.Sum(logicOrConstr), one);
                }
            }
        }
        public void BuildRMP(List <Pairing> initialPathSet)
        {
            //GetCoverMatrix()

            INumExpr obj_expr = RMP.NumExpr();

            foreach (Pairing path in initialPathSet)
            {
                if (path.Route.Count <= 2)
                {
                    continue;
                }

                ColumnPool.Add(path);
                //create obj function
                INumVar x = RMP.NumVar(0, 1, NumVarType.Float);
                DvarSet.Add(x);
                obj_expr = RMP.Sum(obj_expr, RMP.Prod(path.Cost_with_penalty, x));

                CoverMatrix.Add(path.CoverAaray);
            }
            RMP.AddObjective(ObjectiveSense.Minimize, obj_expr);
            //s.t
            for (int i = 0; i < num_task; i++)
            {
                INumExpr ct = RMP.NumExpr();
                for (int j = 0; j < DvarSet.Count; j++)
                {
                    ct = RMP.Sum(ct,
                                 RMP.Prod(CoverMatrix[j][i], DvarSet[j]));
                }
                constraints[i] = RMP.AddGe(ct, 1);
            }
        }
Beispiel #6
0
        private void FindCliqueInternal()
        {
            CallsCount++;
            if (!cplex.Solve())
            {
                return;
            }
            var objValue = cplex.GetObjValue();

            // this branch won't give us better result than existing one
            if (objValue < upperBound || objValue.Almost(upperBound))
            {
                return;
            }
            var branchingVariable = numVars.FirstOrDefault(var => !cplex.GetValue(var).IsInteger());

            if (branchingVariable == null)
            {
                var values = cplex.GetValues(numVars);
                maxClique  = graph.Nodes.Where((_, i) => values[i].Almost(1)).ToList();
                upperBound = maxClique.Count;
                return;
            }
            var constraint = cplex.AddGe(branchingVariable, 1);

            FindCliqueInternal();
            cplex.Remove(constraint);

            constraint = cplex.AddLe(branchingVariable, 0);
            FindCliqueInternal();
            cplex.Remove(constraint);
        }
Beispiel #7
0
        public static Cplex BuildLPModel(IFTMDP Ida)
        {
            Cplex model = new Cplex();

            INumVar[][] v = new INumVar[Ida.TimeHorizon][];   //V(t,x)
            for (int t = 0; t < Ida.TimeHorizon; t++)
            {
                v[t] = model.NumVarArray(Ida.SS.Count, -double.MaxValue, double.MaxValue);
            }

            IObjective RevenueUB = model.AddMinimize(model.Prod(1, v[0][Ida.SS.IndexOf(Ida.InitialState)]));

            //time->State->Active-> Expression
            for (int t = 0; t < Ida.TimeHorizon; t++)
            {
                foreach (IMDPState s in Ida.SS)
                {
                    foreach (IMDPDecision a in Ida.GenDecisionSpace(s))
                    {
                        INumExpr expr = v[t][Ida.SS.IndexOf(s)];
                        if (t < Ida.TimeHorizon - 1)
                        {
                            foreach (IMDPState k in Ida.GenStateSpace(s, a))
                            {
                                expr = model.Sum(expr,
                                                 model.Prod(-Ida.Prob(t, s, k, a), v[t + 1][Ida.SS.IndexOf(k)]));
                            }
                        }
                        model.AddGe(expr, Ida.Reward(t, s, a));
                    }
                }
            }
            //model.SetOut(null);
            return(model);
        }
        /// <summary>建立最初的RMP
        /// 依据初始解
        /// </summary>
        /// <param name="IS"></param>
        public void Build_RMP(InitialSolution IS)
        {
            initialPath_num    = IS.PathSet.Count;
            trip_num           = TripList.Count;
            realistic_trip_num = NetWork.num_Physical_trip;

            DvarSet  = new List <INumVar>();
            CoefSet  = new List <double>();
            A_Matrix = new List <int[]>();
            PathSet  = new List <Pairing>();

            //virtualVarSet = new List<INumVar>();
            //for (int virtual_x = 0; virtual_x < realistic_trip_num; virtual_x++) {
            //    virtualVarSet.Add(masterModel.NumVar(0, 1, NumVarType.Float));
            //}

            CoefSet  = IS.Coefs;
            A_Matrix = IS.A_Matrix;
            PathSet  = IS.PathSet;

            foreach (var p in PathSet)
            {
                ColumnPool.Add(p);
            }

            int i, j;

            Obj        = masterModel.AddMinimize();
            Constraint = new IRange[realistic_trip_num];
            /**按行建模**/
            //vars and obj function
            for (j = 0; j < initialPath_num; j++)
            {
                INumVar var = masterModel.NumVar(0, 1, NumVarType.Float);
                DvarSet.Add(var);
                Obj.Expr = masterModel.Sum(Obj.Expr, masterModel.Prod(CoefSet[j], DvarSet[j]));
            }
            //constraints
            for (i = 0; i < realistic_trip_num; i++)
            {
                INumExpr expr = masterModel.NumExpr();

                for (j = 0; j < initialPath_num; j++)
                {
                    expr = masterModel.Sum(expr,
                                           masterModel.Prod(A_Matrix[j][i], DvarSet[j]));//在从初始解传值给A_Matrix,已经针对网络复制作了处理
                }

                Constraint[i] = masterModel.AddGe(expr, 1);
            }
        }
Beispiel #9
0
    public static void Main(string[] args)
    {
        try {
            string filename = "../../../../examples/data/rates.dat";
            if (args.Length > 0)
            {
                filename = args[0];
            }
            ReadData(filename);

            Cplex cplex = new Cplex();

            INumVar[] production = new INumVar[_generators];
            for (int j = 0; j < _generators; ++j)
            {
                production[j] = cplex.SemiContVar(_minArray[j], _maxArray[j],
                                                  NumVarType.Float);
            }

            cplex.AddMinimize(cplex.ScalProd(_cost, production));
            cplex.AddGe(cplex.Sum(production), _demand);

            cplex.ExportModel("rates.lp");
            if (cplex.Solve())
            {
                System.Console.WriteLine("Solution status = " + cplex.GetStatus());
                for (int j = 0; j < _generators; ++j)
                {
                    System.Console.WriteLine("   generator " + j + ": " +
                                             cplex.GetValue(production[j]));
                }
                System.Console.WriteLine("Total cost = " + cplex.ObjValue);
            }
            else
            {
                System.Console.WriteLine("No solution");
            }

            cplex.End();
        }
        catch (ILOG.Concert.Exception exc) {
            System.Console.WriteLine("Concert exception '" + exc + "' caught");
        }
        catch (System.IO.IOException exc) {
            System.Console.WriteLine("Error reading file " + args[0] + ": " + exc);
        }
        catch (InputDataReader.InputDataReaderException exc) {
            System.Console.WriteLine(exc);
        }
    }
Beispiel #10
0
    public static void Main( string[] args )
    {
        try {
         string filename = "../../../../examples/data/rates.dat";
         if (args.Length > 0)
            filename = args[0];
         ReadData(filename);

         Cplex cplex = new Cplex();

         INumVar[] production = new INumVar[_generators];
         for (int j = 0; j < _generators; ++j) {
            production[j] = cplex.SemiContVar(_minArray[j], _maxArray[j],
                                              NumVarType.Float);
         }

         cplex.AddMinimize(cplex.ScalProd(_cost, production));
         cplex.AddGe(cplex.Sum(production), _demand);

         cplex.ExportModel("rates.lp");
         if ( cplex.Solve() ) {
            System.Console.WriteLine("Solution status = " + cplex.GetStatus());
            for (int j = 0; j < _generators; ++j) {
               System.Console.WriteLine("   generator " + j + ": " +
                                  cplex.GetValue(production[j]));
            }
            System.Console.WriteLine("Total cost = " + cplex.ObjValue);
         }
         else
            System.Console.WriteLine("No solution");

         cplex.End();
          }
          catch (ILOG.Concert.Exception exc) {
         System.Console.WriteLine("Concert exception '" + exc + "' caught");
          }
          catch (System.IO.IOException exc) {
         System.Console.WriteLine("Error reading file " + args[0] + ": " + exc);
          }
          catch (InputDataReader.InputDataReaderException exc) {
         System.Console.WriteLine(exc);
          }
    }
Beispiel #11
0
        void AddRestricaoDemandaMinima(EntradaViewModel entrada)
        {
            entrada.Produtos.ForEach(produto =>
            {
                foreach (var diaSemana in Enum.GetValues(typeof(DiaDaSemana)))
                {
                    var produtoHR = produto.GetNomeVariavel((DiaDaSemana)diaSemana, false);
                    var produtoHE = produto.GetNomeVariavel((DiaDaSemana)diaSemana, true);
                    var demanda   = produto.Demanda[(DiaDaSemana)diaSemana];
                    var equacao   = _cplex.Prod(
                        produto.GetTaxaUnidadeHora(),
                        _variaveis[0][_varArray[produtoHR]],
                        _variaveis[0][_varArray[produtoHE]]
                        );

                    var restricao = _cplex.AddGe(equacao, demanda, $"RestricaoProducaoMinima_{produto.GetNomeLimpo()}_{diaSemana}");
                    _restricoesList.Add(restricao);
                }
            });
        }
Beispiel #12
0
        /// <summary>
        /// Capacity constraints for each cargo
        /// </summary>
        private void Capacity()
        {
            for (int i = 0; i < N; i++)
            {
                var cargo = _cargoList[i];

                var ub = cargo.GetMaxCapacity();
                _solver.AddLe(yR[i], ub);

                var lb         = cargo.GetMinCapacity();
                var constraint = _solver.LinearNumExpr();
                constraint.AddTerm(yR[i], 1);
                constraint.AddTerm(yE[i], 1);
                constraint.AddTerm(m[i], 1);
                _solver.AddGe(constraint, lb);

                var excessCap = cargo.GetExcessCapacity();
                _solver.AddLe(yE[i], excessCap);
            }
        }
Beispiel #13
0
        private void decomp(int dim, int kts, int[][] dist, List <int> WorkList)
        {
            int[] lo = new int[dim];
            int   dk = dim * kts;

            for (int i = 0; i < dim; i++)
            {
                lo[i] = 1;
            }

            Cplex      cplex   = new Cplex();
            NumVarType varType = NumVarType.Bool;

            INumVar[][] x = new INumVar[dim][];
            for (int i = 0; i < dim; i++)
            {
                x[i] = cplex.NumVarArray(dk, 0, 1);
            }

            for (int i = 0; i < dim; i++)
            {
                for (int j = 0; j < dk; j++)
                {
                    x[i][j] = cplex.BoolVar();
                }
            }

            //****************************************
            //Что тут происходит?
            for (int j = 0; j < dim; j++)
            {
                INumExpr xcolSum = cplex.NumExpr();
                for (int k = 0; k < kts; k++)
                {
                    for (int i = 0; i < dim; i++)
                    {
                        xcolSum = cplex.Sum(xcolSum, x[i][k * dim + j]);
                    }
                }
                cplex.AddEq(lo[j], xcolSum);
            }

            varType = NumVarType.Float;
            INumVar[] u = new INumVar[dk];
            for (int j = 0; j < dk; j++)
            {
                u[j] = cplex.NumVar(0, 100000);
            }

            for (int j = 1; j < dk; j++)
            {
                cplex.AddGe(u[j], 0);
            }

            for (int k = 0; k < kts; k++)
            {
                for (int i = 1; i < dim; i++)
                {
                    for (int j = 1; j < dim; j++)
                    {
                        if (i != j)
                        {
                            if (kts == 1)
                            {
                                cplex.AddLe(cplex.Sum(cplex.Diff(u[k * dim + i], u[k * dim + j]), cplex.Prod(dim, x[i][k * dim + j])), dim - 1);
                            }
                            else
                            {
                                cplex.AddLe(cplex.Sum(cplex.Diff(u[k * dim + i], u[k * dim + j]), cplex.Prod(dim, x[i][k * dim + j])), dim);
                            }
                        }
                    }
                }
            }

            for (int i = 0; i < dim; i++)
            {
                INumExpr xrowSum = cplex.NumExpr();
                for (int j = 0; j < dk; j++)
                {
                    xrowSum = cplex.Sum(xrowSum, x[i][j]);
                }
                cplex.AddEq(lo[i], xrowSum);
            }

            //Условия независимости кластеров
            if (kts > 1)
            {
                int[] a = new int[kts + 1];
                for (int k = 1; k < kts; k++)
                {
                    if (k > 1 && k < kts - 1)
                    {
                        continue;
                    }
                    int p;
                    for (int i = 1; i <= k; i++)
                    {
                        a[i] = i;
                    }
                    p = k;
                    while (p >= 1)
                    {
                        for (int m = 0; m < dim; m++)
                        {
                            INumExpr xcolrowSum = cplex.NumExpr();
                            for (int j = 1; j <= kts; j++)
                            {
                                bool row = false;
                                for (int i = 1; i <= k; i++)
                                {
                                    if (a[i] == j)
                                    {
                                        row = true;
                                    }
                                }
                                if (row)
                                {
                                    for (int t = 0; t < dim; t++)
                                    {
                                        xcolrowSum = cplex.Sum(xcolrowSum, x[m][(j - 1) * dim + t]);
                                    }
                                }
                                else
                                {
                                    for (int t = 0; t < dim; t++)
                                    {
                                        xcolrowSum = cplex.Sum(xcolrowSum, x[t][(j - 1) * dim + m]);
                                    }
                                }
                            }
                            cplex.AddLe(xcolrowSum, lo[m]);
                        }
                        if (a[k] == kts)
                        {
                            p--;
                        }
                        else
                        {
                            p = k;
                        }
                        if (p >= 1)
                        {
                            for (int i = k; i >= p; i--)
                            {
                                a[i] = a[p] + i - p + 1;
                            }
                        }
                    }
                }
            }

            INumExpr costSum = cplex.NumExpr();

            INumExpr[] costSum1 = new INumExpr[kts];

            if (kts == 1)
            {
                for (int i = 0; i < dim; i++)
                {
                    for (int j = 0; j < dim; j++)
                    {
                        costSum = cplex.Sum(costSum, cplex.Prod(x[i][j], dist[i][j]));
                    }
                }
                cplex.AddMinimize(costSum);
            }
            else
            {
                for (int k = 0; k < kts; k++)
                {
                    costSum1[k] = cplex.NumExpr();
                    for (int i = 0; i < dim; i++)
                    {
                        for (int j = 0; j < dim; j++)
                        {
                            costSum1[k] = cplex.Sum(costSum1[k], cplex.Prod(x[i][k * dim + j], dist[i][j]));
                        }
                    }
                    //cplex.AddLe(costSum1[k], costSum);
                }
                costSum = cplex.Max(costSum1);
                cplex.AddMinimize(costSum);
            }

            try
            {
                if (cplex.Solve())
                {
                    textBox1.Text += "lambda = " + cplex.ObjValue + Environment.NewLine;
                    textBox1.Text += DateTime.Now.ToString() + Environment.NewLine;

                    WorkList.Clear();
                    int num_clust = 0;
                    for (int k = 0; k < kts; k++)
                    {
                        int dim1 = 0;
                        for (int i = 0; i < dim; i++)
                        {
                            for (int j = 0; j < dim; j++)
                            {
                                if (Convert.ToInt16(cplex.GetValue(x[i][k * dim + j])) == 1)
                                {
                                    dim1++;
                                }
                            }
                        }

                        if (dim1 > 0)
                        {
                            num_clust++;
                            for (int i = 0; i < dim; i++)
                            {
                                for (int j = 0; j < dim; j++)
                                {
                                    if (Convert.ToInt16(cplex.GetValue(x[i][k * dim + j])) == 1)
                                    {
                                        WorkList.Add(i);
                                        break;
                                    }
                                }
                            }

                            WorkList.Add(-1);
                        }
                    }
                    textBox1.Text += DateTime.Now.ToString() + Environment.NewLine;
                }
                else
                {
                    textBox1.Text += "Нет решения" + Environment.NewLine;
                    textBox1.Text += DateTime.Now.ToString() + Environment.NewLine;
                }
                cplex.End();
            }
            catch (ILOG.Concert.Exception ex)
            {
                textBox1.Text += "Concert Error: " + ex + Environment.NewLine;
                textBox1.Text += DateTime.Now.ToString() + Environment.NewLine;
            }
        }
Beispiel #14
0
    public static void Main(string[] args)
    {
        int nMonths   = cost.Length;
        int nProducts = cost[0].Length;

        try {
            Cplex cplex = new Cplex();

            INumVar[]   produce = cplex.NumVarArray(nMonths, 0, System.Double.MaxValue);
            INumVar[][] use     = new INumVar[nMonths][];
            INumVar[][] buy     = new INumVar[nMonths][];
            INumVar[][] store   = new INumVar[nMonths][];

            for (int i = 0; i < nMonths; i++)
            {
                use[i]   = cplex.NumVarArray(nProducts, 0.0, System.Double.MaxValue);
                buy[i]   = cplex.NumVarArray(nProducts, 0.0, System.Double.MaxValue);
                store[i] = cplex.NumVarArray(nProducts, 0.0, 1000.0);
            }

            for (int p = 0; p < nProducts; p++)
            {
                store[nMonths - 1][p].LB = 500.0;
                store[nMonths - 1][p].UB = 500.0;
            }

            INumExpr profit = cplex.NumExpr();
            for (int i = 0; i < nMonths; i++)
            {
                // Not more than 200 tons of vegetable oil can be refined
                cplex.AddLe(cplex.Sum(use[i][v1], use[i][v2]), 200.0);

                // Not more than 250 tons of non-vegetable oil can be refined
                cplex.AddLe(cplex.Sum(use[i][o1], use[i][o2], use[i][o3]), 250.0);

                // Constraints on food composition
                cplex.AddLe(cplex.Prod(3.0, produce[i]),
                            cplex.Sum(cplex.Prod(8.8, use[i][v1]),
                                      cplex.Prod(6.1, use[i][v2]),
                                      cplex.Prod(2.0, use[i][o1]),
                                      cplex.Prod(4.2, use[i][o2]),
                                      cplex.Prod(5.0, use[i][o3])));
                cplex.AddGe(cplex.Prod(6.0, produce[i]),
                            cplex.Sum(cplex.Prod(8.8, use[i][v1]),
                                      cplex.Prod(6.1, use[i][v2]),
                                      cplex.Prod(2.0, use[i][o1]),
                                      cplex.Prod(4.2, use[i][o2]),
                                      cplex.Prod(5.0, use[i][o3])));
                cplex.AddEq(produce[i], cplex.Sum(use[i]));

                // Raw oil can be stored for later use
                if (i == 0)
                {
                    for (int p = 0; p < nProducts; p++)
                    {
                        cplex.AddEq(cplex.Sum(500.0, buy[i][p]),
                                    cplex.Sum(use[i][p], store[i][p]));
                    }
                }
                else
                {
                    for (int p = 0; p < nProducts; p++)
                    {
                        cplex.AddEq(cplex.Sum(store[i - 1][p], buy[i][p]),
                                    cplex.Sum(use[i][p], store[i][p]));
                    }
                }

                // Logical constraints:
                // The food cannot use more than 3 oils
                // (or at least two oils must not be used)
                cplex.AddGe(cplex.Sum(cplex.Eq(use[i][v1], 0),
                                      cplex.Eq(use[i][v2], 0),
                                      cplex.Eq(use[i][o1], 0),
                                      cplex.Eq(use[i][o2], 0),
                                      cplex.Eq(use[i][o3], 0)), 2);

                // When an oil is used, the quantity must be at least 20 tons
                for (int p = 0; p < nProducts; p++)
                {
                    cplex.Add(cplex.Or(cplex.Eq(use[i][p], 0),
                                       cplex.Ge(use[i][p], 20)));
                }

                // If products v1 or v2 are used, then product o3 is also used
                cplex.Add(cplex.IfThen(cplex.Or(cplex.Ge(use[i][v1], 20),
                                                cplex.Ge(use[i][v2], 20)),
                                       cplex.Ge(use[i][o3], 20)));

                // Objective function
                profit = cplex.Sum(profit, cplex.Prod(150, produce[i]));
                profit = cplex.Diff(profit, cplex.ScalProd(cost[i], buy[i]));
                profit = cplex.Diff(profit, cplex.Prod(5, cplex.Sum(store[i])));
            }

            cplex.AddMaximize(profit);

            if (cplex.Solve())
            {
                System.Console.WriteLine("Solution status = " + cplex.GetStatus());
                System.Console.WriteLine(" Maximum profit = " + cplex.ObjValue);
                for (int i = 0; i < nMonths; i++)
                {
                    System.Console.WriteLine(" Month {0}", i);

                    System.Console.Write("  . buy   ");
                    for (int p = 0; p < nProducts; p++)
                    {
                        System.Console.Write("{0,8:F2} ", cplex.GetValue(buy[i][p]));
                    }
                    System.Console.WriteLine();

                    System.Console.Write("  . use   ");
                    for (int p = 0; p < nProducts; p++)
                    {
                        System.Console.Write("{0,8:F2} ", cplex.GetValue(use[i][p]));
                    }
                    System.Console.WriteLine();

                    System.Console.Write("  . store ");
                    for (int p = 0; p < nProducts; p++)
                    {
                        System.Console.Write("{0,8:F2} ", cplex.GetValue(store[i][p]));
                    }
                    System.Console.WriteLine();
                }
            }
            cplex.End();
        }
        catch (ILOG.Concert.Exception e) {
            System.Console.WriteLine("Concert exception caught: " + e);
        }
    }
Beispiel #15
0
    /// <summary>
    /// The example's main function.
    /// </summary>
    public static void Main(string[] args)
    {
        int retval = 0;
        Cplex cplex = null;
        try
        {
            cplex = new Cplex();

            /* ***************************************************************** *
             *                                                                   *
             *    S E T U P   P R O B L E M                                      *
             *                                                                   *
             *  We create the following problem:                                 *
             * Minimize                                                          *
             *  obj: 3x1 - x2 + 3x3 + 2x4 + x5 + 2x6 + 4x7                       *
             * Subject To                                                        *
             *  c1: x1 + x2 = 4                                                  *
             *  c2: x1 + x3 >= 3                                                 *
             *  c3: x6 + x7 <= 5                                                 *
             *  c4: -x1 + x7 >= -2                                               *
             *  q1: [ -x1^2 + x2^2 ] <= 0                                        *
             *  q2: [ 4.25x3^2 -2x3*x4 + 4.25x4^2 - 2x4*x5 + 4x5^2  ] + 2 x1 <= 9.0
             *  q3: [ x6^2 - x7^2 ] >= 4                                         *
             * Bounds                                                            *
             *  0 <= x1 <= 3                                                     *
             *  x2 Free                                                          *
             *  0 <= x3 <= 0.5                                                   *
             *  x4 Free                                                          *
             *  x5 Free                                                          *
             *  x7 Free                                                          *
             * End                                                               *
             *                                                                   *
             * ***************************************************************** */

            INumVar[] x = new INumVar[7];
            x[0] = cplex.NumVar(0, 3, "x1");
            x[1] = cplex.NumVar(System.Double.NegativeInfinity, System.Double.PositiveInfinity, "x2");
            x[2] = cplex.NumVar(0, 0.5, "x3");
            x[3] = cplex.NumVar(System.Double.NegativeInfinity, System.Double.PositiveInfinity, "x4");
            x[4] = cplex.NumVar(System.Double.NegativeInfinity, System.Double.PositiveInfinity, "x5");
            x[5] = cplex.NumVar(0, System.Double.PositiveInfinity, "x6");
            x[6] = cplex.NumVar(System.Double.NegativeInfinity, System.Double.PositiveInfinity, "x7");

            IRange[] linear = new IRange[4];
            linear[0] = cplex.AddEq(cplex.Sum(x[0], x[1]), 4.0, "c1");
            linear[1] = cplex.AddGe(cplex.Sum(x[0], x[2]), 3.0, "c2");
            linear[2] = cplex.AddLe(cplex.Sum(x[5], x[6]), 5.0, "c3");
            linear[3] = cplex.AddGe(cplex.Diff(x[6], x[0]), -2.0, "c4");

            IRange[] quad = new IRange[3];
            quad[0] = cplex.AddLe(cplex.Sum(cplex.Prod(-1, x[0], x[0]),
                                            cplex.Prod(x[1], x[1])), 0.0, "q1");
            quad[1] = cplex.AddLe(cplex.Sum(cplex.Prod(4.25, x[2], x[2]),
                cplex.Prod(-2,x[2],x[3]),
                cplex.Prod(4.25,x[3],x[3]),
                cplex.Prod(-2,x[3],x[4]),
                cplex.Prod(4,x[4],x[4]),
                cplex.Prod(2,x[0])), 9.0, "q2");
            quad[2] = cplex.AddGe(cplex.Sum(cplex.Prod(x[5], x[5]),
                                            cplex.Prod(-1, x[6], x[6])), 4.0, "q3");

            cplex.AddMinimize(cplex.Sum(cplex.Prod(3.0, x[0]),
                                        cplex.Prod(-1.0, x[1]),
                                        cplex.Prod(3.0, x[2]),
                                        cplex.Prod(2.0, x[3]),
                                        cplex.Prod(1.0, x[4]),
                                        cplex.Prod(2.0, x[5]),
                                        cplex.Prod(4.0, x[6])), "obj");

            /* ***************************************************************** *
             *                                                                   *
             *    O P T I M I Z E   P R O B L E M                                *
             *                                                                   *
             * ***************************************************************** */
            cplex.SetParam(Cplex.Param.Barrier.QCPConvergeTol, 1e-10);
            cplex.Solve();

            /* ***************************************************************** *
             *                                                                   *
             *    Q U E R Y   S O L U T I O N                                    *
             *                                                                   *
             * ***************************************************************** */
            double[] xval = cplex.GetValues(x);
            double[] slack = cplex.GetSlacks(linear);
            double[] qslack = cplex.GetSlacks(quad);
            double[] cpi = cplex.GetReducedCosts(x);
            double[] rpi = cplex.GetDuals(linear);
            double[] qpi = getqconstrmultipliers(cplex, xval, ZEROTOL, x, quad);
            // Also store solution in a dictionary so that we can look up
            // values by variable and not only by index.
            IDictionary<INumVar, System.Double> xmap = new Dictionary<INumVar, System.Double>();
            for (int j = 0; j < x.Length; ++j)
            {
                xmap.Add(x[j], xval[j]);
            }

            /* ***************************************************************** *
             *                                                                   *
             *    C H E C K   K K T   C O N D I T I O N S                        *
             *                                                                   *
             *    Here we verify that the optimal solution computed by CPLEX     *
             *    (and the qpi[] values computed above) satisfy the KKT          *
             *    conditions.                                                    *
             *                                                                   *
             * ***************************************************************** */

            // Primal feasibility: This example is about duals so we skip this test.

            // Dual feasibility: We must verify
            // - for <= constraints (linear or quadratic) the dual
            //   multiplier is non-positive.
            // - for >= constraints (linear or quadratic) the dual
            //   multiplier is non-negative.
            for (int i = 0; i < linear.Length; ++i)
            {
                if (linear[i].LB <= System.Double.NegativeInfinity)
                {
                    // <= constraint
                    if (rpi[i] > ZEROTOL)
                        throw new System.SystemException("Dual feasibility test failed for row " + linear[i]
                                                   + ": " + rpi[i]);
                }
                else if (linear[i].UB >= System.Double.PositiveInfinity)
                {
                    // >= constraint
                    if (rpi[i] < -ZEROTOL)
                        throw new System.SystemException("Dual feasibility test failed for row " + linear[i]
                                                   + ": " + rpi[i]);
                }
                else
                {
                    // nothing to do for equality constraints
                }
            }
            for (int i = 0; i < quad.Length; ++i)
            {
                if (quad[i].LB <= System.Double.NegativeInfinity)
                {
                    // <= constraint
                    if (qpi[i] > ZEROTOL)
                        throw new System.SystemException("Dual feasibility test failed for quad " + quad[i]
                                                   + ": " + qpi[i]);
                }
                else if (quad[i].UB >= System.Double.PositiveInfinity)
                {
                    // >= constraint
                    if (qpi[i] < -ZEROTOL)
                        throw new System.SystemException("Dual feasibility test failed for quad " + quad[i]
                                                   + ": " + qpi[i]);
                }
                else
                {
                    // nothing to do for equality constraints
                }
            }

            // Complementary slackness.
            // For any constraint the product of primal slack and dual multiplier
            // must be 0.
            for (int i = 0; i < linear.Length; ++i)
            {
                if (System.Math.Abs(linear[i].UB - linear[i].LB) > ZEROTOL &&
                     System.Math.Abs(slack[i] * rpi[i]) > ZEROTOL)
                    throw new System.SystemException("Complementary slackness test failed for row " + linear[i]
                                               + ": " + System.Math.Abs(slack[i] * rpi[i]));
            }
            for (int i = 0; i < quad.Length; ++i)
            {
                if (System.Math.Abs(quad[i].UB - quad[i].LB) > ZEROTOL &&
                     System.Math.Abs(qslack[i] * qpi[i]) > ZEROTOL)
                    throw new System.SystemException("Complementary slackness test failed for quad " + quad[i]
                                               + ": " + System.Math.Abs(qslack[i] * qpi[i]));
            }
            for (int j = 0; j < x.Length; ++j)
            {
                if (x[j].UB < System.Double.PositiveInfinity)
                {
                    double slk = x[j].UB - xval[j];
                    double dual = cpi[j] < -ZEROTOL ? cpi[j] : 0.0;
                    if (System.Math.Abs(slk * dual) > ZEROTOL)
                        throw new System.SystemException("Complementary slackness test failed for column " + x[j]
                                                   + ": " + System.Math.Abs(slk * dual));
                }
                if (x[j].LB > System.Double.NegativeInfinity)
                {
                    double slk = xval[j] - x[j].LB;
                    double dual = cpi[j] > ZEROTOL ? cpi[j] : 0.0;
                    if (System.Math.Abs(slk * dual) > ZEROTOL)
                        throw new System.SystemException("Complementary slackness test failed for column " + x[j]
                                                   + ": " + System.Math.Abs(slk * dual));
                }
            }

            // Stationarity.
            // The difference between objective function and gradient at optimal
            // solution multiplied by dual multipliers must be 0, i.E., for the
            // optimal solution x
            // 0 == c
            //      - sum(r in rows)  r'(x)*rpi[r]
            //      - sum(q in quads) q'(x)*qpi[q]
            //      - sum(c in cols)  b'(x)*cpi[c]
            // where r' and q' are the derivatives of a row or quadratic constraint,
            // x is the optimal solution and rpi[r] and qpi[q] are the dual
            // multipliers for row r and quadratic constraint q.
            // b' is the derivative of a bound constraint and cpi[c] the dual bound
            // multiplier for column c.
            IDictionary<INumVar, System.Double> kktsum = new Dictionary<INumVar, System.Double>();
            for (int j = 0; j < x.Length; ++j)
            {
                kktsum.Add(x[j], 0.0);
            }

            // Objective function.
            for (ILinearNumExprEnumerator it = ((ILinearNumExpr)cplex.GetObjective().Expr).GetLinearEnumerator();
                 it.MoveNext(); /* nothing */)
            {
                kktsum[it.NumVar] = it.Value;
            }

            // Linear constraints.
            // The derivative of a linear constraint ax - b (<)= 0 is just a.
            for (int i = 0; i < linear.Length; ++i)
            {
                for (ILinearNumExprEnumerator it = ((ILinearNumExpr)linear[i].Expr).GetLinearEnumerator();
                     it.MoveNext(); /* nothing */)
                {
                    kktsum[it.NumVar] = kktsum[it.NumVar] - rpi[i] * it.Value;
                }
            }

            // Quadratic constraints.
            // The derivative of a constraint xQx + ax - b <= 0 is
            // Qx + Q'x + a.
            for (int i = 0; i < quad.Length; ++i)
            {
                for (ILinearNumExprEnumerator it = ((ILinearNumExpr)quad[i].Expr).GetLinearEnumerator();
                     it.MoveNext(); /* nothing */)
                {
                    kktsum[it.NumVar] = kktsum[it.NumVar] - qpi[i] * it.Value;
                }
                for (IQuadNumExprEnumerator it = ((IQuadNumExpr)quad[i].Expr).GetQuadEnumerator();
                     it.MoveNext(); /* nothing */)
                {
                    INumVar v1 = it.NumVar1;
                    INumVar v2 = it.NumVar2;
                    kktsum[v1] = kktsum[v1] - qpi[i] * xmap[v2] * it.Value;
                    kktsum[v2] = kktsum[v2] - qpi[i] * xmap[v1] * it.Value;
                }
            }

            // Bounds.
            // The derivative for lower bounds is -1 and that for upper bounds
            // is 1.
            // CPLEX already returns dj with the appropriate sign so there is
            // no need to distinguish between different bound types here.
            for (int j = 0; j < x.Length; ++j)
            {
                kktsum[x[j]] = kktsum[x[j]] - cpi[j];
            }

            foreach (INumVar v in x)
            {
                if (System.Math.Abs(kktsum[v]) > ZEROTOL)
                    throw new System.SystemException("Stationarity test failed at " + v
                        + ": " + System.Math.Abs(kktsum[v]));
            }

            // KKT conditions satisfied. Dump out the optimal solutions and
            // the dual values.
            System.Console.WriteLine("Optimal solution satisfies KKT conditions.");
            System.Console.WriteLine("   x[] = " + arrayToString(xval));
            System.Console.WriteLine(" cpi[] = " + arrayToString(cpi));
            System.Console.WriteLine(" rpi[] = " + arrayToString(rpi));
            System.Console.WriteLine(" qpi[] = " + arrayToString(qpi));
        }
        catch (ILOG.Concert.Exception e)
        {
            System.Console.WriteLine("IloException: " + e.Message);
            System.Console.WriteLine(e.StackTrace);
            retval = -1;
        }
        finally
        {
            if (cplex != null)
                cplex.End();
        }
        System.Environment.Exit(retval);
    }
Beispiel #16
0
        /// <summary>建立最初的RMP
        /// 依据初始解
        /// </summary>
        /// <param name="IS"></param>
        public void Build_RMP(InitialSolution IS)//主问题的建模
        {
            initialPath_num    = IS.PathSet.Count;
            trip_num           = TripList.Count;
            realistic_trip_num = NetWork.num_Physical_trip;

            DvarSet       = new List <INumVar>(); //x
            CoefSet       = new List <double>();  //cij
            AccumuWorkSet = new List <double>();  //每条交路累计工作时间
            ObjCoefSet    = new List <double>();
            A_Matrix      = new List <int[]>();   //aij
            PathSet       = new List <Pairing>(); //列池
            //int n = 196;//n代表的是整个高一车队每天所需要的乘务员和乘务长的总和


            CoefSet       = IS.Coefs;//IS初始解
            AccumuWorkSet = IS.AccumuWorkSet;
            A_Matrix      = IS.A_Matrix;
            PathSet       = IS.PathSet;
            ObjCoefSet    = IS.ObjCoefs;

            //for(int k = 0 ; k < IS.Coefs.Count ; k++)
            //{
            //    ObjCoefSet.Add(Network.GetObjCoef(IS.AccumuWorkSet[k] , IS.Coefs[k]));
            //}

            foreach (var p in PathSet)
            {
                ColumnPool.Add(p);
            }

            int i, j;

            masterModel = new Cplex();
            Obj         = masterModel.AddMinimize();
            Constraint  = new IRange[realistic_trip_num];//这种I打头的都是cplex里面的东西
            /**按行建模**/
            //vars and obj function
            for (j = 0; j < initialPath_num; j++)                                               //定义决策变量和目标函数
            {
                INumVar var = masterModel.NumVar(0, 1, NumVarType.Float);                       //INumVar-cplex里面的,定义决策变量。后面括号中的意思是定义var是0-1之间的浮点值
                DvarSet.Add(var);
                Obj.Expr = masterModel.Sum(Obj.Expr, masterModel.Prod(CoefSet[j], DvarSet[j])); //后面的小括号里面是一个cij*xj,大括号里面的是累计,包括之前的expr
            }
            //constraints
            for (i = 0; i < realistic_trip_num; i++) //对每一行    这部分的内容是aij*xj>=n
            {
                INumExpr expr = masterModel.NumExpr();

                for (j = 0; j < initialPath_num; j++) //对每一列
                {
                    expr = masterModel.Sum(expr,
                                           masterModel.Prod(A_Matrix[j][i], DvarSet[j])); //在从初始解传值给A_Matrix,已经针对网络复制作了处理
                }//小括号路里aij*xj

                Constraint[i] = masterModel.AddGe(expr, NUMBER_CREW); //约束list addge表示返回一个大于等于n的数
            }

            for (j = 0; j < initialPath_num; j++)//对每一列
            {
                INumExpr expr = masterModel.NumExpr();
                expr = masterModel.Sum(expr, DvarSet[j]);//在从初始解传值给A_Matrix,已经针对网络复制作了处理
            }


            //这里怎样使约束expr的值等于1????????????????????????????????????????????????
        }
Beispiel #17
0
   public static void Main (string[] args) {
      int nMonths   = cost.Length;
      int nProducts = cost[0].Length;

      try {
         Cplex cplex = new Cplex();

         INumVar[]   produce = cplex.NumVarArray(nMonths, 0, System.Double.MaxValue);
         INumVar[][] use   = new INumVar[nMonths][];
         INumVar[][] buy   = new INumVar[nMonths][];
         INumVar[][] store = new INumVar[nMonths][];

         for (int i = 0; i < nMonths; i++) {
            use[i]   = cplex.NumVarArray(nProducts, 0.0, System.Double.MaxValue);
            buy[i]   = cplex.NumVarArray(nProducts, 0.0, System.Double.MaxValue);
            store[i] = cplex.NumVarArray(nProducts, 0.0, 1000.0);
         }

         for (int p = 0; p < nProducts; p++) {
           store[nMonths-1][p].LB = 500.0;
           store[nMonths-1][p].UB = 500.0;
         }

         INumExpr profit = cplex.NumExpr();
         for (int i = 0; i < nMonths; i++) {
            // Not more than 200 tons of vegetable oil can be refined
            cplex.AddLe(cplex.Sum(use[i][v1], use[i][v2]), 200.0);

            // Not more than 250 tons of non-vegetable oil can be refined
            cplex.AddLe(cplex.Sum(use[i][o1], use[i][o2], use[i][o3]), 250.0);

            // Constraints on food composition
            cplex.AddLe(cplex.Prod(3.0,produce[i]),
                        cplex.Sum(cplex.Prod(8.8, use[i][v1]),
                                  cplex.Prod(6.1, use[i][v2]),
                                  cplex.Prod(2.0, use[i][o1]),
                                  cplex.Prod(4.2, use[i][o2]),
                                  cplex.Prod(5.0, use[i][o3])));
            cplex.AddGe(cplex.Prod(6.0, produce[i]),
                        cplex.Sum(cplex.Prod(8.8, use[i][v1]),
                                  cplex.Prod(6.1, use[i][v2]),
                                  cplex.Prod(2.0, use[i][o1]),
                                  cplex.Prod(4.2, use[i][o2]),
                                  cplex.Prod(5.0, use[i][o3])));
            cplex.AddEq(produce[i], cplex.Sum(use[i]));

            // Raw oil can be stored for later use
            if (i == 0) {
               for (int p = 0; p < nProducts; p++)
                  cplex.AddEq(cplex.Sum(500.0, buy[i][p]),
                              cplex.Sum(use[i][p], store[i][p]));
            }
            else {
               for (int p = 0; p < nProducts; p++)
                 cplex.AddEq(cplex.Sum(store[i-1][p], buy[i][p]),
                             cplex.Sum(use[i][p], store[i][p]));
            }

            // Logical constraints:
            // The food cannot use more than 3 oils
            // (or at least two oils must not be used)
            cplex.AddGe(cplex.Sum(cplex.Eq(use[i][v1], 0),
                                  cplex.Eq(use[i][v2], 0),
                                  cplex.Eq(use[i][o1], 0),
                                  cplex.Eq(use[i][o2], 0),
                                  cplex.Eq(use[i][o3], 0)), 2);

            // When an oil is used, the quantity must be at least 20 tons
            for (int p = 0; p < nProducts; p++)
               cplex.Add(cplex.Or(cplex.Eq(use[i][p],  0),
                                  cplex.Ge(use[i][p], 20)));

            // If products v1 or v2 are used, then product o3 is also used
            cplex.Add(cplex.IfThen(cplex.Or(cplex.Ge(use[i][v1], 20),
                                            cplex.Ge(use[i][v2], 20)),
                                   cplex.Ge(use[i][o3], 20)));

            // Objective function
            profit = cplex.Sum (profit, cplex.Prod(150, produce[i]));
            profit = cplex.Diff(profit, cplex.ScalProd(cost[i], buy[i]));
            profit = cplex.Diff(profit, cplex.Prod(5, cplex.Sum(store[i])));
         }

         cplex.AddMaximize(profit);

         if ( cplex.Solve() ) {
            System.Console.WriteLine("Solution status = " + cplex.GetStatus());
            System.Console.WriteLine(" Maximum profit = " + cplex.ObjValue);
            for (int i = 0; i < nMonths; i++) {
               System.Console.WriteLine(" Month {0}", i);

               System.Console.Write("  . buy   ");
               for (int p = 0; p < nProducts; p++)
                  System.Console.Write("{0,8:F2} ", cplex.GetValue(buy[i][p]));
               System.Console.WriteLine();

               System.Console.Write("  . use   ");
               for (int p = 0; p < nProducts; p++)
                  System.Console.Write("{0,8:F2} ", cplex.GetValue(use[i][p]));
               System.Console.WriteLine();

               System.Console.Write("  . store ");
               for (int p = 0; p < nProducts; p++)
                  System.Console.Write("{0,8:F2} ", cplex.GetValue(store[i][p]));
               System.Console.WriteLine();
            }
         }
         cplex.End();
      }
      catch (ILOG.Concert.Exception e) {
         System.Console.WriteLine("Concert exception caught: " + e);
      }
   }
Beispiel #18
0
        static void Main(string[] args)
        {
            double[]   price        = { 170.0, 170.0, 170.0 };
            double[]   priceStorage = { 10.0, 10.0, 10.0 };
            double[]   hardness     = { 8.4, 6.2, 2.0 };
            double[]   hardness3    = { 3, 3, 3 };
            double[]   hardness6    = { 6, 6, 6 };
            double[][] oilCost      = new double[2][];
            oilCost[0] = new double[3] {
                1.159550009798596e+02, 1.018115866059220e+02, 1.128780935294160e+02
            };
            oilCost[1] = new double[3] {
                100, 1.067537671189185e+02, 1.098041326934309e+02
            };

            //oilCost = GenerateRandomVector();

            INumVar[][] oilStore   = new INumVar[3][];
            INumVar[][] oilBuy     = new INumVar[2][];
            INumVar[][] oilProduce = new INumVar[2][]; // [month][A-C]
            Cplex       cplex      = new Cplex();

            for (int i = 0; i < 2; i++) // Initialize oilBuy and oilProduce
            {
                oilBuy[i]     = new INumVar[3];
                oilProduce[i] = new INumVar[3];
            }
            for (int i = 0; i < 3; i++) // Initialize oilStore
            {
                oilStore[i] = new INumVar[3];
                for (int j = 0; j < 3; j++)
                {
                    oilStore[i][j] = cplex.NumVar(0, 800); // Ograniczenia na pojemność magazynu
                }
            }
            for (int i = 0; i < 2; i++)     // Ograniczenia na miesiące
            {
                for (int j = 0; j < 3; j++) // Ograniczenia na możliwości rafinacji
                {
                    if (j != 2)
                    {
                        oilProduce[i][j] = cplex.NumVar(0, 220); // Rafinacja roślinnego
                    }
                    else
                    {
                        oilProduce[i][j] = cplex.NumVar(0, 270); // Rafinacja nie-roślinnego
                    }
                    oilBuy[i][j] = cplex.NumVar(0, 1070);
                }
                cplex.AddRange(0, cplex.Sum(oilProduce[i][0], oilProduce[i][1]), 220);
                cplex.AddGe(cplex.ScalProd(hardness, oilProduce[i]), cplex.ScalProd(hardness3, oilProduce[i]));     // Hardness greater than 3
                cplex.AddLe(cplex.ScalProd(hardness, oilProduce[i]), cplex.ScalProd(hardness6, oilProduce[i]));     // Hardness less than 6
            }
            for (int i = 0; i < 3; i++)                                                                             // Ograniczenia na oleje
            {
                cplex.AddEq(oilStore[0][i], 200.0);                                                                 // Ograniczenie na stan magazynu w grudniu
                cplex.AddEq(oilStore[2][i], 200.0);                                                                 // Ograniczenie na stan magazynu w lutym
                cplex.AddEq(oilStore[1][i], cplex.Sum(cplex.Diff(oilBuy[0][i], oilProduce[0][i]), oilStore[0][i])); // (Kupowane + zmagazynowane - produkowane) w tym miesiacu = zmagazynowane w nastepnym miesiacu
                cplex.AddEq(oilStore[2][i], cplex.Sum(cplex.Diff(oilBuy[1][i], oilProduce[1][i]), oilStore[1][i]));
            }

            // Funkcja Celu: zyski ze sprzedaży - koszta magazynowania - koszta kupowania materiału do produkcji
            cplex.AddMaximize(
                cplex.Diff(
                    cplex.Diff(
                        cplex.Sum(
                            cplex.ScalProd(price, oilProduce[0]),
                            cplex.ScalProd(price, oilProduce[1])),
                        cplex.Sum(
                            cplex.ScalProd(priceStorage, oilStore[1]),
                            cplex.ScalProd(priceStorage, oilStore[2]))),
                    cplex.Sum(
                        cplex.ScalProd(oilCost[0], oilBuy[0]),
                        cplex.ScalProd(oilCost[1], oilBuy[1]))));


            if (cplex.Solve())
            {
                System.Console.WriteLine();
                System.Console.WriteLine("Solution status = " + cplex.GetStatus());
                System.Console.WriteLine();
                System.Console.WriteLine("  = " + cplex.ObjValue);
                Console.WriteLine();
                for (int i = 0; i < 2; i++)
                {
                    for (int j = 0; j < 3; j++)
                    {
                        Console.WriteLine(" oilCost[" + i + "][" + j + "] = " + oilCost[i][j]);
                    }
                }

                Console.WriteLine();
                for (int j = 0; j < 2; j++)
                {
                    double hardnessTotal = 0;
                    double sum           = 0;
                    for (int i = 0; i < 3; i++)
                    {
                        System.Console.WriteLine(" oilProduce[" + j + "][" + i + "] = " + cplex.GetValue(oilProduce[j][i]));
                        hardnessTotal += cplex.GetValue(oilProduce[j][i]) * hardness[i];
                        sum           += cplex.GetValue(oilProduce[j][i]);
                    }
                    System.Console.WriteLine(" hardnessTotal[" + j + "] = " + hardnessTotal / sum);
                    Console.WriteLine();
                }

                for (int j = 0; j < 2; j++)
                {
                    for (int i = 0; i < 3; i++)
                    {
                        System.Console.WriteLine(" oilBuy[" + j + "][" + i + "] = " + cplex.GetValue(oilBuy[j][i]));
                    }
                }
                Console.WriteLine();
                for (int j = 0; j < 3; j++)
                {
                    for (int i = 0; i < 3; i++)
                    {
                        System.Console.WriteLine(" oilStore[" + j + "][" + i + "] = " + cplex.GetValue(oilStore[j][i]));
                    }
                }

                System.Console.WriteLine();
            }
            Console.ReadKey();
        }
Beispiel #19
0
    /// <summary>
    /// The example's main function.
    /// </summary>
    public static void Main(string[] args)
    {
        int   retval = 0;
        Cplex cplex  = null;

        try
        {
            cplex = new Cplex();

            /* ***************************************************************** *
            *                                                                   *
            *    S E T U P   P R O B L E M                                      *
            *                                                                   *
            *  We create the following problem:                                 *
            * Minimize                                                          *
            *  obj: 3x1 - x2 + 3x3 + 2x4 + x5 + 2x6 + 4x7                       *
            * Subject To                                                        *
            *  c1: x1 + x2 = 4                                                  *
            *  c2: x1 + x3 >= 3                                                 *
            *  c3: x6 + x7 <= 5                                                 *
            *  c4: -x1 + x7 >= -2                                               *
            *  q1: [ -x1^2 + x2^2 ] <= 0                                        *
            *  q2: [ 4.25x3^2 -2x3*x4 + 4.25x4^2 - 2x4*x5 + 4x5^2  ] + 2 x1 <= 9.0
            *  q3: [ x6^2 - x7^2 ] >= 4                                         *
            * Bounds                                                            *
            *  0 <= x1 <= 3                                                     *
            *  x2 Free                                                          *
            *  0 <= x3 <= 0.5                                                   *
            *  x4 Free                                                          *
            *  x5 Free                                                          *
            *  x7 Free                                                          *
            * End                                                               *
            *                                                                   *
            * ***************************************************************** */

            INumVar[] x = new INumVar[7];
            x[0] = cplex.NumVar(0, 3, "x1");
            x[1] = cplex.NumVar(System.Double.NegativeInfinity, System.Double.PositiveInfinity, "x2");
            x[2] = cplex.NumVar(0, 0.5, "x3");
            x[3] = cplex.NumVar(System.Double.NegativeInfinity, System.Double.PositiveInfinity, "x4");
            x[4] = cplex.NumVar(System.Double.NegativeInfinity, System.Double.PositiveInfinity, "x5");
            x[5] = cplex.NumVar(0, System.Double.PositiveInfinity, "x6");
            x[6] = cplex.NumVar(System.Double.NegativeInfinity, System.Double.PositiveInfinity, "x7");

            IRange[] linear = new IRange[4];
            linear[0] = cplex.AddEq(cplex.Sum(x[0], x[1]), 4.0, "c1");
            linear[1] = cplex.AddGe(cplex.Sum(x[0], x[2]), 3.0, "c2");
            linear[2] = cplex.AddLe(cplex.Sum(x[5], x[6]), 5.0, "c3");
            linear[3] = cplex.AddGe(cplex.Diff(x[6], x[0]), -2.0, "c4");

            IRange[] quad = new IRange[3];
            quad[0] = cplex.AddLe(cplex.Sum(cplex.Prod(-1, x[0], x[0]),
                                            cplex.Prod(x[1], x[1])), 0.0, "q1");
            quad[1] = cplex.AddLe(cplex.Sum(cplex.Prod(4.25, x[2], x[2]),
                                            cplex.Prod(-2, x[2], x[3]),
                                            cplex.Prod(4.25, x[3], x[3]),
                                            cplex.Prod(-2, x[3], x[4]),
                                            cplex.Prod(4, x[4], x[4]),
                                            cplex.Prod(2, x[0])), 9.0, "q2");
            quad[2] = cplex.AddGe(cplex.Sum(cplex.Prod(x[5], x[5]),
                                            cplex.Prod(-1, x[6], x[6])), 4.0, "q3");

            cplex.AddMinimize(cplex.Sum(cplex.Prod(3.0, x[0]),
                                        cplex.Prod(-1.0, x[1]),
                                        cplex.Prod(3.0, x[2]),
                                        cplex.Prod(2.0, x[3]),
                                        cplex.Prod(1.0, x[4]),
                                        cplex.Prod(2.0, x[5]),
                                        cplex.Prod(4.0, x[6])), "obj");

            /* ***************************************************************** *
            *                                                                   *
            *    O P T I M I Z E   P R O B L E M                                *
            *                                                                   *
            * ***************************************************************** */
            cplex.SetParam(Cplex.Param.Barrier.QCPConvergeTol, 1e-10);
            cplex.Solve();

            /* ***************************************************************** *
            *                                                                   *
            *    Q U E R Y   S O L U T I O N                                    *
            *                                                                   *
            * ***************************************************************** */
            double[] xval   = cplex.GetValues(x);
            double[] slack  = cplex.GetSlacks(linear);
            double[] qslack = cplex.GetSlacks(quad);
            double[] cpi    = cplex.GetReducedCosts(x);
            double[] rpi    = cplex.GetDuals(linear);
            double[] qpi    = getqconstrmultipliers(cplex, xval, ZEROTOL, x, quad);
            // Also store solution in a dictionary so that we can look up
            // values by variable and not only by index.
            IDictionary <INumVar, System.Double> xmap = new Dictionary <INumVar, System.Double>();
            for (int j = 0; j < x.Length; ++j)
            {
                xmap.Add(x[j], xval[j]);
            }

            /* ***************************************************************** *
            *                                                                   *
            *    C H E C K   K K T   C O N D I T I O N S                        *
            *                                                                   *
            *    Here we verify that the optimal solution computed by CPLEX     *
            *    (and the qpi[] values computed above) satisfy the KKT          *
            *    conditions.                                                    *
            *                                                                   *
            * ***************************************************************** */

            // Primal feasibility: This example is about duals so we skip this test.

            // Dual feasibility: We must verify
            // - for <= constraints (linear or quadratic) the dual
            //   multiplier is non-positive.
            // - for >= constraints (linear or quadratic) the dual
            //   multiplier is non-negative.
            for (int i = 0; i < linear.Length; ++i)
            {
                if (linear[i].LB <= System.Double.NegativeInfinity)
                {
                    // <= constraint
                    if (rpi[i] > ZEROTOL)
                    {
                        throw new System.SystemException("Dual feasibility test failed for row " + linear[i]
                                                         + ": " + rpi[i]);
                    }
                }
                else if (linear[i].UB >= System.Double.PositiveInfinity)
                {
                    // >= constraint
                    if (rpi[i] < -ZEROTOL)
                    {
                        throw new System.SystemException("Dual feasibility test failed for row " + linear[i]
                                                         + ": " + rpi[i]);
                    }
                }
                else
                {
                    // nothing to do for equality constraints
                }
            }
            for (int i = 0; i < quad.Length; ++i)
            {
                if (quad[i].LB <= System.Double.NegativeInfinity)
                {
                    // <= constraint
                    if (qpi[i] > ZEROTOL)
                    {
                        throw new System.SystemException("Dual feasibility test failed for quad " + quad[i]
                                                         + ": " + qpi[i]);
                    }
                }
                else if (quad[i].UB >= System.Double.PositiveInfinity)
                {
                    // >= constraint
                    if (qpi[i] < -ZEROTOL)
                    {
                        throw new System.SystemException("Dual feasibility test failed for quad " + quad[i]
                                                         + ": " + qpi[i]);
                    }
                }
                else
                {
                    // nothing to do for equality constraints
                }
            }

            // Complementary slackness.
            // For any constraint the product of primal slack and dual multiplier
            // must be 0.
            for (int i = 0; i < linear.Length; ++i)
            {
                if (System.Math.Abs(linear[i].UB - linear[i].LB) > ZEROTOL &&
                    System.Math.Abs(slack[i] * rpi[i]) > ZEROTOL)
                {
                    throw new System.SystemException("Complementary slackness test failed for row " + linear[i]
                                                     + ": " + System.Math.Abs(slack[i] * rpi[i]));
                }
            }
            for (int i = 0; i < quad.Length; ++i)
            {
                if (System.Math.Abs(quad[i].UB - quad[i].LB) > ZEROTOL &&
                    System.Math.Abs(qslack[i] * qpi[i]) > ZEROTOL)
                {
                    throw new System.SystemException("Complementary slackness test failed for quad " + quad[i]
                                                     + ": " + System.Math.Abs(qslack[i] * qpi[i]));
                }
            }
            for (int j = 0; j < x.Length; ++j)
            {
                if (x[j].UB < System.Double.PositiveInfinity)
                {
                    double slk  = x[j].UB - xval[j];
                    double dual = cpi[j] < -ZEROTOL ? cpi[j] : 0.0;
                    if (System.Math.Abs(slk * dual) > ZEROTOL)
                    {
                        throw new System.SystemException("Complementary slackness test failed for column " + x[j]
                                                         + ": " + System.Math.Abs(slk * dual));
                    }
                }
                if (x[j].LB > System.Double.NegativeInfinity)
                {
                    double slk  = xval[j] - x[j].LB;
                    double dual = cpi[j] > ZEROTOL ? cpi[j] : 0.0;
                    if (System.Math.Abs(slk * dual) > ZEROTOL)
                    {
                        throw new System.SystemException("Complementary slackness test failed for column " + x[j]
                                                         + ": " + System.Math.Abs(slk * dual));
                    }
                }
            }

            // Stationarity.
            // The difference between objective function and gradient at optimal
            // solution multiplied by dual multipliers must be 0, i.E., for the
            // optimal solution x
            // 0 == c
            //      - sum(r in rows)  r'(x)*rpi[r]
            //      - sum(q in quads) q'(x)*qpi[q]
            //      - sum(c in cols)  b'(x)*cpi[c]
            // where r' and q' are the derivatives of a row or quadratic constraint,
            // x is the optimal solution and rpi[r] and qpi[q] are the dual
            // multipliers for row r and quadratic constraint q.
            // b' is the derivative of a bound constraint and cpi[c] the dual bound
            // multiplier for column c.
            IDictionary <INumVar, System.Double> kktsum = new Dictionary <INumVar, System.Double>();
            for (int j = 0; j < x.Length; ++j)
            {
                kktsum.Add(x[j], 0.0);
            }

            // Objective function.
            for (ILinearNumExprEnumerator it = ((ILinearNumExpr)cplex.GetObjective().Expr).GetLinearEnumerator();
                 it.MoveNext(); /* nothing */)
            {
                kktsum[it.NumVar] = it.Value;
            }

            // Linear constraints.
            // The derivative of a linear constraint ax - b (<)= 0 is just a.
            for (int i = 0; i < linear.Length; ++i)
            {
                for (ILinearNumExprEnumerator it = ((ILinearNumExpr)linear[i].Expr).GetLinearEnumerator();
                     it.MoveNext(); /* nothing */)
                {
                    kktsum[it.NumVar] = kktsum[it.NumVar] - rpi[i] * it.Value;
                }
            }

            // Quadratic constraints.
            // The derivative of a constraint xQx + ax - b <= 0 is
            // Qx + Q'x + a.
            for (int i = 0; i < quad.Length; ++i)
            {
                for (ILinearNumExprEnumerator it = ((ILinearNumExpr)quad[i].Expr).GetLinearEnumerator();
                     it.MoveNext(); /* nothing */)
                {
                    kktsum[it.NumVar] = kktsum[it.NumVar] - qpi[i] * it.Value;
                }
                for (IQuadNumExprEnumerator it = ((IQuadNumExpr)quad[i].Expr).GetQuadEnumerator();
                     it.MoveNext(); /* nothing */)
                {
                    INumVar v1 = it.NumVar1;
                    INumVar v2 = it.NumVar2;
                    kktsum[v1] = kktsum[v1] - qpi[i] * xmap[v2] * it.Value;
                    kktsum[v2] = kktsum[v2] - qpi[i] * xmap[v1] * it.Value;
                }
            }

            // Bounds.
            // The derivative for lower bounds is -1 and that for upper bounds
            // is 1.
            // CPLEX already returns dj with the appropriate sign so there is
            // no need to distinguish between different bound types here.
            for (int j = 0; j < x.Length; ++j)
            {
                kktsum[x[j]] = kktsum[x[j]] - cpi[j];
            }

            foreach (INumVar v in x)
            {
                if (System.Math.Abs(kktsum[v]) > ZEROTOL)
                {
                    throw new System.SystemException("Stationarity test failed at " + v
                                                     + ": " + System.Math.Abs(kktsum[v]));
                }
            }

            // KKT conditions satisfied. Dump out the optimal solutions and
            // the dual values.
            System.Console.WriteLine("Optimal solution satisfies KKT conditions.");
            System.Console.WriteLine("   x[] = " + arrayToString(xval));
            System.Console.WriteLine(" cpi[] = " + arrayToString(cpi));
            System.Console.WriteLine(" rpi[] = " + arrayToString(rpi));
            System.Console.WriteLine(" qpi[] = " + arrayToString(qpi));
        }
        catch (ILOG.Concert.Exception e)
        {
            System.Console.WriteLine("IloException: " + e.Message);
            System.Console.WriteLine(e.StackTrace);
            retval = -1;
        }
        finally
        {
            if (cplex != null)
            {
                cplex.End();
            }
        }
        System.Environment.Exit(retval);
    }
Beispiel #20
0
        void solve()
        {
            Cplex Model = new Cplex();

            // decision variables
            #region
            //x1-tjs (first stage t = 1),length of a collection period (in days) at collection point j during time period t
            //INumVar[][][] X1 = new INumVar[period][][];
            //for (int i = 0; i < period; i++)
            //{
            //    X1[i] = new INumVar[cpoint][];
            //    for (int ii = 0; ii < cpoint; ii++)
            //    {
            //        X1[i][ii] = new INumVar[scenario];
            //        X1[i][ii] = Model.NumVarArray(scenario, 1, 7, NumVarType.Int);
            //    }
            //}

            //x2-tpjks ,volume of products returned from collection point j to recycling center k during time period t
            INumVar[][][][][] X2 = new INumVar[period][][][][];
            for (int a = 0; a < period; a++)
            {
                X2[a] = new INumVar[ptype][][][];
                for (int aa = 0; aa < ptype; aa++)
                {
                    X2[a][aa] = new INumVar[cpoint][][];
                    for (int bb = 0; bb < cpoint; bb++)
                    {
                        X2[a][aa][bb] = new INumVar[rcenter][];
                        for (int cc = 0; cc < rcenter; cc++)
                        {
                            X2[a][aa][bb][cc] = new INumVar[scenario];
                            X2[a][aa][bb][cc] = Model.NumVarArray(scenario, 0, System.Double.MaxValue, NumVarType.Int);
                        }
                    }
                }
            }

            //x3-tij ,Binary decision variable equals ‘1’ if customer i is allocated to collection point j during time period t and ‘0’ otherwise
            INumVar[][][] X3 = new INumVar[period][][];
            for (int aa = 0; aa < period; aa++)
            {
                X3[aa] = new INumVar[customer][];
                for (int bb = 0; bb < customer; bb++)
                {
                    X3[aa][bb] = new INumVar[cpoint];
                    X3[aa][bb] = Model.NumVarArray(cpoint, 0.0, 1.0, NumVarType.Bool);
                }
            }


            //x4-tj ,Binary decision variable equals ‘1’ if collection point j is rented during time period t and ‘0’ otherwise
            INumVar[][] X4 = new INumVar[period][];
            for (int i = 0; i < period; i++)
            {
                X4[i] = new INumVar[cpoint];
                X4[i] = Model.NumVarArray(cpoint, 0.0, 1.0, NumVarType.Bool);
            }

            //x5-k ,Binary decision variable equals ‘1’ if recycling center k is established and ‘0’ otherwise
            INumVar[] X5 = new INumVar[rcenter];
            X5 = Model.NumVarArray(rcenter, 0, 1, NumVarType.Bool);

            //x6 maximum capacity level option for recycling center k
            INumVar[] X6 = new INumVar[rcenter];
            X6 = Model.NumVarArray(rcenter, 1, 3, NumVarType.Int);

            //X7-tjs Auxiliary variable  x7 the frequency of recylce during a period
            //INumVar[][][] X7 = new INumVar[period][][];
            //for (int i = 0; i < period; i++)
            //{
            //    X7[i] = new INumVar[cpoint][];
            //    for (int ii = 0; ii < cpoint; ii++)
            //    {
            //        X7[i][ii] = new INumVar[scenario];
            //        X7[i][ii] = Model.NumVarArray(scenario, 30, wday, NumVarType.Int);
            //    }
            //}

            #endregion

            Double M = 100000;

            // constraints
            #region
            // formulation (4)
            INumExpr[] expr1 = new INumExpr[1];

            for (int aa = 0; aa < period; aa++)
            {
                for (int bb = 0; bb < customer; bb++)
                {
                    expr1[0] = X3[0][0][0];
                    for (int cc = 0; cc < cpoint; cc++)
                    {
                        expr1[0] = Model.Sum(expr1[0], X3[aa][bb][cc]);
                    }
                    expr1[0] = Model.Sum(expr1[0], Model.Prod(-1.0, X3[0][0][0]));
                    Model.AddEq(expr1[0], 1);
                }
            }


            // formulation (5)
            INumExpr[] expr2 = new INumExpr[1];
            INumExpr[] expr3 = new INumExpr[1];
            for (int aa = 0; aa < period; aa++)
            {
                for (int bb = 0; bb < cpoint; bb++)
                {
                    expr2[0] = X3[0][0][0];
                    expr3[0] = X4[0][0];
                    for (int cc = 0; cc < customer; cc++)
                    {
                        Model.Sum(expr2[0], X3[aa][cc][bb]);
                    }
                    expr2[0] = Model.Sum(expr2[0], Model.Prod(-1.0, X3[0][0][0]));
                    expr3[0] = Model.Prod(M, X4[aa][bb]);
                    expr3[0] = Model.Sum(expr3[0], Model.Prod(-1.0, X4[0][0]));
                    Model.AddLe(expr2[0], expr3[0]);
                }
            }

            // formulation (6)
            INumExpr[] expr4 = new INumExpr[1];
            INumExpr[] expr5 = new INumExpr[1];
            INumExpr[] expr6 = new INumExpr[1];
            for (int aa = 0; aa < period; aa++)
            {
                for (int cc = 0; cc < scenario; cc++)
                {
                    for (int bb = 0; bb < cpoint; bb++)
                    {
                        expr5[0] = X3[0][0][0];
                        for (int dd = 0; dd < customer; dd++)
                        {
                            for (int ee = 0; ee < ptype; ee++)
                            {
                                expr5[0] = Model.Sum(expr5[0], Model.Prod(Model.Prod(r[dd, ee, aa, cc], X3[aa][dd][bb]), vlength));
                            }
                        }
                        expr5[0] = Model.Sum(expr5[0], Model.Prod(-1.0, X3[0][0][0]));

                        expr6[0] = X2[0][0][0][0][0];
                        for (int ff = 0; ff < rcenter; ff++)
                        {
                            for (int ee = 0; ee < ptype; ee++)
                            {
                                expr6[0] = Model.Sum(expr6[0], X2[aa][ee][bb][ff][cc]);
                            }
                        }
                        expr6[0] = Model.Sum(expr6[0], Model.Prod(-1.0, X2[0][0][0][0][0]));
                        Model.AddEq(expr5[0], expr6[0]);
                    }
                }
            }

            // formulation (7-1)
            INumExpr[] expr7 = new INumExpr[1];
            for (int aa = 0; aa < period; aa++)
            {
                for (int bb = 0; bb < rcenter; bb++)
                {
                    for (int cc = 0; cc < scenario; cc++)
                    {
                        for (int dd = 0; dd < cpoint; dd++)
                        {
                            expr7[0] = X2[0][0][0][0][0];
                            for (int ee = 0; ee < ptype; ee++)
                            {
                                expr7[0] = Model.Sum(expr7[0], X2[aa][ee][dd][bb][cc]);
                            }
                            expr7[0] = Model.Sum(expr7[0], Model.Prod(-1.0, X2[0][0][0][0][0]));
                            Model.AddLe(expr7[0], Model.Prod(X5[bb], M));
                        }
                    }
                }
            }

            // formulation (7-2)
            INumExpr[] expr71 = new INumExpr[1];
            for (int aa = 0; aa < period; aa++)
            {
                for (int bb = 0; bb < rcenter; bb++)
                {
                    for (int cc = 0; cc < scenario; cc++)
                    {
                        for (int dd = 0; dd < cpoint; dd++)
                        {
                            expr71[0] = X2[0][0][0][0][0];
                            for (int ee = 0; ee < ptype; ee++)
                            {
                                expr71[0] = Model.Sum(expr71[0], X2[aa][ee][dd][bb][cc]);
                            }
                            expr71[0] = Model.Sum(expr71[0], Model.Prod(-1.0, X2[0][0][0][0][0]));
                            Model.AddLe(expr71[0], Model.Sum(Model.Prod(X6[bb], 1000), Model.Prod(Model.Sum(1, Model.Prod(X5[bb], -1)), M)));
                        }
                    }
                }
            }

            // formulation (8)
            INumExpr[] expr8 = new INumExpr[1];
            for (int a = 0; a < period; a++)
            {
                expr8[0] = X4[0][0];
                for (int b = 0; b < cpoint; b++)
                {
                    expr8[0] = Model.Sum(expr8[0], X4[a][b]);
                }
                expr8[0] = Model.Sum(expr8[0], Model.Prod(-1.0, X4[0][0]));
                Model.AddGe(expr8[0], 1);
            }

            // formulation (9)
            INumExpr[] expr9 = new INumExpr[1];
            expr9[0] = X5[0];
            for (int a = 0; a < rcenter; a++)
            {
                expr9[0] = Model.Sum(expr9[0], X5[a]);
            }
            expr9[0] = Model.Sum(expr9[0], Model.Prod(-1.0, X5[0]));
            Model.AddGe(expr9[0], 1);

            // formulation (10)
            INumExpr[] expr10 = new INumExpr[1];
            for (int a = 0; a < period; a++)
            {
                for (int b = 0; b < rcenter; b++)
                {
                    for (int c = 0; c < scenario; c++)
                    {
                        for (int d = 0; d < cpoint; d++)
                        {
                            expr10[0] = X2[0][0][0][0][0];
                            for (int e = 0; e < ptype; e++)
                            {
                                expr10[0] = Model.Sum(expr10[0], X2[a][e][d][b][c]);
                            }
                            expr10[0] = Model.Sum(expr10[0], Model.Prod(-1.0, X2[0][0][0][0][0]));
                            Model.AddGe(expr10[0], X5[b]);
                        }
                    }
                }
            }


            // formulation (11)
            for (int a = 0; a < period; a++)
            {
                for (int c = 0; c < customer; c++)
                {
                    for (int b = 0; b < cpoint; b++)
                    {
                        Model.AddLe(Model.Prod(d1[c, b], X3[a][c][b]), l);
                    }
                }
            }

            // formulation (12)
            for (int a = 0; a < period; a++)
            {
                for (int aa = 0; aa < ptype; aa++)
                {
                    for (int b = 0; b < cpoint; b++)
                    {
                        for (int c = 0; c < rcenter; c++)
                        {
                            for (int d = 0; d < scenario; d++)
                            {
                                Model.AddGe(X2[a][aa][b][c][d], 0);
                            }
                        }
                    }
                }
            }



            // #endregion
            //formulation (15)  //formulation (1)  objective function -1
            // collection points rent cost

            INumExpr[] expr11 = new INumExpr[1];
            for (int a = 0; a < period; a++)
            {
                expr11[0] = X4[0][0];
                for (int b = 0; b < cpoint; b++)
                {
                    expr11[0] = Model.Sum(expr11[0], Model.Prod(X4[a][b], e1[b]));
                }
                expr11[0] = Model.Sum(expr11[0], Model.Prod(-1.0, X4[0][0]));
            }

            INumExpr[] expr12  = new INumExpr[1];
            INumExpr[] expr121 = new INumExpr[1];

            for (int a = 0; a < period; a++)
            {
                for (int b = 0; b < rcenter; b++)
                {
                    expr121[0] = X5[0];
                    for (int c = 0; c < cpoint; c++)
                    {
                        for (int d = 0; d < ptype; d++)
                        {
                            for (int e = 0; e < customer; e++)
                            {
                                expr12[0] = X2[0][0][0][0][0];
                                for (int f = 0; f < scenario; f++)
                                {
                                    expr12[0] = Model.Sum(expr12[0], Model.Prod(Model.Prod(X2[a][d][c][b][f], e2[d, c, b]), wday / vlength));
                                }
                                expr12[0] = Model.Sum(expr12[0], Model.Prod(-1.0, X2[0][0][0][0][0]));
                            }
                        }
                    }
                    expr121[0] = Model.Sum(expr121[0], Model.Prod(expr12[0], X5[b]));
                }
            }

            INumExpr[] expr13 = new INumExpr[1];
            for (int a = 0; a < period; a++)
            {
                for (int b = 0; b < rcenter; b++)
                {
                    expr13[0] = X5[0];
                    for (int bb = 0; bb < elevel; bb++)
                    {
                        expr13[0] = Model.Sum(expr13[0], Model.Prod(X5[b], e3[b, bb]));
                    }
                    expr13[0] = Model.Sum(expr13[0], Model.Prod(-1.0, X5[0]));
                }
            }


            Model.AddLe(Model.Prod(wday, Model.Sum(expr11[0], expr13[0])), e);  //expr12[0],  ,)
            // #endregion

            // //formulation (1)  objective function -1
            // #region
            INumExpr[] expr15 = new INumExpr[1];
            expr15[0] = X4[0][0];
            for (int i = 0; i < period; i++)
            {
                for (int ii = 0; ii < cpoint; ii++)
                {
                    expr15[0] = Model.Sum(expr15[0], Model.Prod(a[ii], X4[i][ii]));
                }
            }
            expr15[0] = Model.Sum(expr15[0], Model.Prod(-1.0, X4[0][0]));
            // ok


            INumExpr[] expr17 = new INumExpr[1];
            for (int a = 0; a < period; a++)
            {
                for (int aaa = 0; aaa < scenario; aaa++)
                {
                    for (int bb = 0; bb < cpoint; bb++)
                    {
                        for (int bbb = 0; bbb < customer; bbb++)
                        {
                            expr17[0] = X3[0][0][0];
                            for (int aa = 0; aa < ptype; aa++)
                            {
                                expr17[0] = Model.Sum(expr17[0], Model.Prod(Model.Prod(r[bbb, aa, a, aaa] * b[aa], X3[a][bbb][bb]), (vlength + 1) * 0.5));
                            }
                            expr17[0] = Model.Sum(expr17[0], Model.Prod(-1.0, X3[0][0][0]));
                        }
                    }
                }
            }

            INumExpr[] expr18 = new INumExpr[1];
            INumExpr[] expr41 = new INumExpr[1];
            expr18[0] = X5[0];
            for (int a = 0; a < period; a++)
            {
                for (int aa = 0; aa < rcenter; aa++)
                {
                    for (int bb = 0; bb < cpoint; bb++)
                    {
                        for (int b = 0; b < ptype; b++)
                        {
                            for (int aaa = 0; aaa < customer; aaa++)
                            {
                                expr41[0] = X2[0][0][0][0][0];
                                for (int bbb = 0; bbb < scenario; bbb++)
                                {
                                    expr41[0] = Model.Sum(expr41[0], Model.Prod(Model.Prod(X2[a][b][bb][aa][bbb], z[bb, aa, b]), vlength));
                                }
                                expr41[0] = Model.Sum(expr17[0], Model.Prod(-1.0, X2[0][0][0][0][0]));
                            }
                        }
                    }
                    expr18[0] = Model.Prod(expr41[0], X5[aa]);
                }
            }
            expr18[0] = Model.Sum(expr18[0], Model.Prod(-1.0, X5[0]));

            INumExpr[] expr19 = new INumExpr[1];
            for (int i = 0; i < period; i++)
            {
                for (int ii = 0; ii < rcenter; ii++)
                {
                    for (int iii = 0; iii < elevel; iii++)
                    {
                        expr19[0] = X5[0];
                        for (int iiii = 0; iiii < capacity; iiii++)
                        {
                            expr19[0] = Model.Sum(expr19[0], Model.Prod(q[ii, iii, iiii], X5[ii]));
                        }
                    }
                }
            }
            expr19[0] = Model.Sum(expr19[0], Model.Prod(-1.0, X5[0]));



            #endregion
            INumExpr[] expr21 = new INumExpr[1];
            expr21[0] = Model.Prod(Model.Sum(expr15[0], Model.Prod(expr17[0], wday), expr18[0], expr19[0]), lambda); //

            INumExpr[] expr22 = new INumExpr[1];
            expr22[0] = Model.Prod(Model.Sum(expr11[0], expr12[0], expr13[0]), delta); // Model.Prod(Model.Prod(wday, Model.Sum(expr11[0], expr12[0], expr13[0])),delta);

            Model.AddMinimize(Model.Sum(expr21[0], expr22[0]));                        //

            Model.ExportModel("RLND.LP");

            if (Model.Solve())
            {
                Console.WriteLine("statue=" + Model.GetStatus());
                Console.WriteLine("obj=" + Model.ObjValue);
                Console.WriteLine("X2的结果");

                for (int aa2 = 0; aa2 < period; aa2++)
                {
                    for (int bb2 = 0; bb2 < ptype; bb2++)
                    {
                        for (int cc = 0; cc < cpoint; cc++)
                        {
                            for (int dd = 0; dd < rcenter; dd++)
                            {
                                for (int ee = 0; ee < scenario; ee++)
                                {
                                    Console.WriteLine(Model.GetValue(X2[aa2][bb2][cc][dd][ee]));
                                    Console.WriteLine();
                                }
                            }
                        }
                    }
                }

                //for (int a = 0; a < X6.Length; a++)
                //{
                //    Console.WriteLine("result[" + a + "] = " + Model.GetValue(X6[a]));
                //}
                //Console.WriteLine();


                Model.End();
            }
            else
            {
                Model.End();
                Console.WriteLine();
                Console.WriteLine("cannot be solved");
            }
        }
Beispiel #21
0
        /// <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);
        }
Beispiel #22
0
        private double one_tsp(int dim, int [][] matrix, int [] path)
        {
            int[] lo = new int[dim];

            for (int i = 0; i < dim; i++)
            {
                lo[i] = 1;
            }

            Cplex      cplex   = new Cplex();
            NumVarType varType = NumVarType.Bool;

            INumVar[][] x = new INumVar[dim][];
            for (int i = 0; i < dim; i++)
            {
                x[i] = cplex.NumVarArray(dim, 0, 1);
            }

            for (int i = 0; i < dim; i++)
            {
                for (int j = 0; j < dim; j++)
                {
                    x[i][j] = cplex.BoolVar();
                }
            }

            for (int j = 0; j < dim; j++)
            {
                INumExpr xcolSum = cplex.NumExpr();
                for (int i = 0; i < dim; i++)
                {
                    xcolSum = cplex.Sum(xcolSum, x[i][j]);
                }
                cplex.AddEq(lo[j], xcolSum);
            }

            varType = NumVarType.Float;
            INumVar[] u = new INumVar[dim];
            for (int j = 0; j < dim; j++)
            {
                u[j] = cplex.NumVar(0, 100000);
            }

            for (int j = 1; j < dim; j++)
            {
                cplex.AddGe(u[j], 0);
            }

            for (int i = 1; i < dim; i++)
            {
                for (int j = 1; j < dim; j++)
                {
                    if (i != j)
                    {
                        cplex.AddLe(cplex.Sum(cplex.Diff(u[i], u[j]), cplex.Prod(dim, x[i][j])), dim - 1);
                    }
                }
            }

            for (int i = 0; i < dim; i++)
            {
                INumExpr xrowSum = cplex.NumExpr();
                for (int j = 0; j < dim; j++)
                {
                    xrowSum = cplex.Sum(xrowSum, x[i][j]);
                }
                cplex.AddEq(lo[i], xrowSum);
            }

            INumExpr costSum = cplex.NumExpr();

            for (int i = 0; i < dim; i++)
            {
                for (int j = 0; j < dim; j++)
                {
                    costSum = cplex.Sum(costSum, cplex.Prod(x[i][j], matrix[i][j]));
                }
            }
            cplex.AddMinimize(costSum);

            try
            {
                if (cplex.Solve())
                {
                    //MessageBox.Show("Solution status = " + cplex.GetStatus());
                    //MessageBox.Show("cost = " + cplex.ObjValue);
                    int ipath = 0;
                    int depo  = -1;
                    for (int i = dim - 1; i >= 0; i--)
                    {
                        for (int j = 0; j < dim; j++)
                        {
                            if (Convert.ToInt16(cplex.GetValue(x[i][j])) == 1)
                            {
                                depo = i;
                            }
                        }
                    }
                    path[ipath] = depo;
                    ipath++;
                    while (depo > -1)
                    {
                        for (int j = 0; j < dim; j++)
                        {
                            if (Convert.ToInt16(cplex.GetValue(x[path[ipath - 1]][j])) == 1)
                            {
                                path[ipath] = j;
                                ipath++;
                                if (j == depo)
                                {
                                    depo = -1;
                                }
                                break;
                            }
                        }
                    }
                    return(cplex.ObjValue);
                }
                cplex.End();
            }
            catch (ILOG.Concert.Exception ex)
            {
                System.Console.WriteLine("Concert Error: " + ex);
            }
            return(-1);
        }
Beispiel #23
0
        public static Cplex Build_CLP1_Model(IALPFTMDP aff)
        {
            Cplex model = new Cplex();

            INumVar[][] Var1 = new INumVar[aff.TimeHorizon][];
            INumVar[]   Var2 = model.NumVarArray(aff.TimeHorizon, 0, double.MaxValue);

            #region //////////////生成变量//////////////
            for (int i = 0; i < aff.TimeHorizon; i++)
            {
                Var1[i] = model.NumVarArray(aff.RS.Count, 0, double.MaxValue);// new INumVar[aff.DS.Count];
            }
            #endregion

            #region //////////////生成约束//////////////
            for (int t = 0; t < aff.TimeHorizon; t++)
            {
                foreach (IALPDecision a in aff.DS)
                {
                    INumExpr exp1 = model.NumExpr();
                    if (t < aff.TimeHorizon - 1)
                    {
                        exp1 = model.Sum(Var2[t], model.Prod(-1, Var2[t + 1]));
                        foreach (IALPResource re in aff.RS)
                        {
                            if (a.UseResource(re))
                            {
                                exp1 = model.Sum(exp1, Var1[t][aff.RS.IndexOf(re)], model.Prod(aff.Qti(t, re, a) - 1, Var1[t + 1][aff.RS.IndexOf(re)]));
                            }
                        }
                    }
                    else
                    {
                        exp1 = model.Sum(exp1, Var2[t]);
                        foreach (IALPResource re in aff.RS)
                        {
                            if (a.UseResource(re))
                            {
                                exp1 = model.Sum(exp1, Var1[t][aff.RS.IndexOf(re)]);
                            }
                        }
                    }
                    model.AddGe(exp1, aff.Rt(t, a));
                }
                if (t < aff.TimeHorizon - 1)
                {
                    foreach (IALPResource re in aff.RS)
                    {
                        INumExpr exp2 = model.NumExpr();
                        exp2 = model.Sum(Var1[t][aff.RS.IndexOf(re)], model.Prod(-1, Var1[t + 1][aff.RS.IndexOf(re)]));
                        model.AddGe(exp2, 0);
                    }
                    INumExpr exp3 = model.NumExpr();
                    exp3 = model.Sum(exp3, Var2[t], model.Prod(-1, Var2[t + 1]));
                    model.AddGe(exp3, 0);
                }
            }
            #endregion

            #region //////////////生成目标//////////////
            INumExpr exp5 = model.NumExpr();
            exp5 = model.Sum(exp5, Var2[0]);
            foreach (IALPResource re in aff.RS)
            {
                exp5 = model.Sum(exp5, model.Prod((aff.InitialState as IALPState)[re], Var1[0][aff.RS.IndexOf(re)]));
            }
            IObjective cost = model.AddMinimize(exp5);
            #endregion

            return(model);
        }
Beispiel #24
0
        public override void Work()
        {
            //获取求解设置
            decimal terminalFactor = _ctx.GetParameter("TerminalFactor", 0.001m);
            int     iteration      = _ctx.GetParameter("Iteration", 10);
            int     resolution     = _ctx.GetParameter("Resolution", 60);
            decimal initMultipler  = _ctx.GetParameter("InitMultiper", 0.1m);

            string objectiveType = _ctx.GetParameter("ObjectiveType", "");

            // 相对-绝对时间转化器
            DiscreteTimeAdapter adapter
                = new DiscreteTimeAdapter(_ctx.StartTime, _ctx.EndTime, resolution);

            // 路径集
            Dictionary <CustomerArrival, List <TravelPath> > pathDict
                = new Dictionary <CustomerArrival, List <TravelPath> >();

            #region 建立初始网络,搜索可行路径
            //目标函数网络
            var objgraph = ObjectNetworkFactory.Create(objectiveType, _ctx, adapter); //new ObjectTravelHyperNetwork(_ctx, adapter);
            objgraph.Build();

            //基础网络
            var basicGraph = new BasicTravelHyperNetwork(_ctx, adapter);
            basicGraph.Build();

            SubTasks.Clear();
            foreach (CustomerArrival customer in _ctx.Pal)
            {
                Task ta = factory.StartNew(() =>
                {
                    var ori   = (_ctx.Wor.Mar[customer.Customer.MarSegID] as IRailwayMarketSegment).OriSta;
                    var des   = (_ctx.Wor.Mar[customer.Customer.MarSegID] as IRailwayMarketSegment).DesSta;
                    var paths = DepthFirstSearcher.FindAllPaths(basicGraph,
                                                                new TravelHyperNode()
                    {
                        Time = adapter.ConvertToDiscreteTime(customer.ArriveTime), Station = ori, Price = 0
                    },
                                                                new TravelHyperNode()
                    {
                        Time = adapter.Horizon + 1440, Station = des, Price = 0
                    });
                    pathDict.Add(customer, new List <TravelPath>());
                    foreach (var path in paths)
                    {
                        pathDict[customer].Add(new TravelPath(basicGraph, path));
                    }
                });
                SubTasks.Add(ta);
            }
            Task.WaitAll(SubTasks.ToArray());
            #endregion

            #region 构建对偶问题 with CPLEX
            Cplex model = new Cplex();
            model.SetOut(null);
            INumVar theta = model.NumVar(double.MinValue, double.MaxValue); //θ

            model.AddMaximize(theta);

            Dictionary <IServiceSegment, INumVar> dual_rho = _ctx.Wor.RailwayTimeTable.Trains
                                                             .SelectMany(i => i.ServiceSegments).ToDictionary(i => i, i =>
                                                                                                              model.NumVar(0, double.MaxValue));

            Dictionary <CustomerArrival, Dictionary <TravelPath, INumVar> > dual_mu =
                new Dictionary <CustomerArrival, Dictionary <TravelPath, INumVar> >();
            foreach (CustomerArrival customer in _ctx.Pal)
            {
                dual_mu.Add(customer, new Dictionary <TravelPath, INumVar>());
                foreach (var path in pathDict[customer])
                {
                    dual_mu[customer].Add(path, model.NumVar(0, double.MaxValue));
                }
            }

            Dictionary <IEdge <TravelHyperNode>, INumVar> dual_lambda =
                new Dictionary <IEdge <TravelHyperNode>, INumVar>();
            foreach (CustomerArrival customer in _ctx.Pal)
            {
                foreach (var path in pathDict[customer])
                {
                    if (!dual_lambda.ContainsKey(path.ReservationArc))
                    {
                        dual_lambda.Add(path.ReservationArc, model.NumVar(0, double.MaxValue));
                    }
                }
            }
            #endregion

            #region 变量与乘子
            //决策变量 x
            Dictionary <CustomerArrival, TravelPath> x
                = new Dictionary <CustomerArrival, TravelPath>();
            foreach (CustomerArrival customer in _ctx.Pal)
            {
                x.Add(customer, new TravelPath());
            }

            //决策变量 w
            Dictionary <ITrainTrip, Dictionary <IRailwayStation, PricePath> > w
                = new Dictionary <ITrainTrip, Dictionary <IRailwayStation, PricePath> >();
            foreach (var train in _ctx.Wor.RailwayTimeTable.Trains)
            {
                w.Add(train, new Dictionary <IRailwayStation, PricePath>());
                foreach (var sta in _ctx.Wor.Net.StationCollection)
                {
                    w[train].Add(sta, null);
                }
            }

            //辅助变量 y
            //记录每条弧在当前w的取值下是否可行(available),值为true = 可行;false = 不可行
            //超出了y记录的reservation arc 不会有人走
            Dictionary <IEdge <TravelHyperNode>, bool> y
                = new Dictionary <IEdge <TravelHyperNode>, bool>();
            foreach (var p in pathDict.Values.SelectMany(i => i))
            {
                if (p.ReservationArc != null && !y.ContainsKey(p.ReservationArc))
                {
                    y.Add(p.ReservationArc, false);
                }
            }

            //拉格朗日乘子 rho
            Dictionary <IServiceSegment, decimal> LM_rho = _ctx.Wor.RailwayTimeTable.Trains
                                                           .SelectMany(i => i.ServiceSegments).ToDictionary(i => i, i => initMultipler);

            //拉格朗日乘子 rho 迭代方向
            Dictionary <IServiceSegment, decimal> Grad_rho = _ctx.Wor.RailwayTimeTable.Trains
                                                             .SelectMany(i => i.ServiceSegments).ToDictionary(i => i, i => initMultipler);


            //拉格朗日乘子 mu
            Dictionary <CustomerArrival, Dictionary <TravelPath, decimal> > LM_mu
                = new Dictionary <CustomerArrival, Dictionary <TravelPath, decimal> >();
            foreach (CustomerArrival customer in _ctx.Pal)
            {
                LM_mu.Add(customer, new Dictionary <TravelPath, decimal>());
                foreach (var path in pathDict[customer])
                {
                    LM_mu[customer].Add(path, initMultipler);
                }
            }
            //拉格朗日乘子 mu 迭代方向
            Dictionary <CustomerArrival, Dictionary <TravelPath, decimal> > Grad_mu
                = new Dictionary <CustomerArrival, Dictionary <TravelPath, decimal> >();
            foreach (CustomerArrival customer in _ctx.Pal)
            {
                Grad_mu.Add(customer, new Dictionary <TravelPath, decimal>());
                foreach (var path in pathDict[customer])
                {
                    Grad_mu[customer].Add(path, initMultipler);
                }
            }

            //拉格朗日乘子 lambda
            Dictionary <IEdge <TravelHyperNode>, decimal> LM_lambda = new Dictionary <IEdge <TravelHyperNode>, decimal>();
            //WARNING: 这里缺少了没有旅客选择的reservation arc
            foreach (CustomerArrival customer in _ctx.Pal)
            {
                foreach (var path in pathDict[customer])
                {
                    if (!LM_lambda.ContainsKey(path.ReservationArc))
                    {
                        LM_lambda.Add(path.ReservationArc, initMultipler);
                    }
                }
            }

            //拉格朗日乘子 lambda 迭代方向
            Dictionary <IEdge <TravelHyperNode>, decimal> Grad_lambda = new Dictionary <IEdge <TravelHyperNode>, decimal>();
            foreach (CustomerArrival customer in _ctx.Pal)
            {
                foreach (var path in pathDict[customer])
                {
                    if (!Grad_lambda.ContainsKey(path.ReservationArc))
                    {
                        Grad_lambda.Add(path.ReservationArc, initMultipler);
                    }
                }
            }

            #endregion

            decimal bigM1      = pathDict.Max(i => i.Value.Max(j => basicGraph.GetPathCost(j)));
            decimal bigM2      = _ctx.Pal.Count();
            decimal bigM       = Math.Max(bigM1, bigM2);
            decimal lowerBound = decimal.MinValue;
            decimal upperBound = decimal.MaxValue;
            bool    flag       = false;//对偶问题有解

            PrintIterationInfo($"Iteration Number, Lower Bound, Upper Bound, Best Lower Bound, Best Upper Bound, Total Gap(%) ");

            for (int iter = 0; iter < iteration; iter++)
            {
                Log($"--------------第{iter}轮求解开始--------------");

                bool hasFeasibleSolution = true;

                #region 求解LR问题
                SubTasks.Clear();
                foreach (CustomerArrival customer in _ctx.Pal)// 求解x
                {
                    Task ta = factory.StartNew(() =>
                    {
                        var graph = new LRxTravelHyperNetwork(_ctx, adapter, objgraph, customer, pathDict, LM_rho, LM_mu, LM_lambda);
                        graph.Build();
                        var ori = (_ctx.Wor.Mar[customer.Customer.MarSegID] as IRailwayMarketSegment).OriSta;
                        var des = (_ctx.Wor.Mar[customer.Customer.MarSegID] as IRailwayMarketSegment).DesSta;
                        DijkstraShortestPaths <DirectedWeightedSparseGraph <TravelHyperNode>, TravelHyperNode> dijkstra
                            = new DijkstraShortestPaths <DirectedWeightedSparseGraph <TravelHyperNode>, TravelHyperNode>(graph, new TravelHyperNode()
                        {
                            Time    = adapter.ConvertToDiscreteTime(customer.ArriveTime),
                            Station = ori,
                            Price   = 0
                        });    //考虑该旅客到达时间
                        x[customer] = new TravelPath(graph, dijkstra.ShortestPathTo(
                                                         new TravelHyperNode()
                        {
                            Time    = adapter.Horizon + 1440,
                            Station = des,
                            Price   = 0
                        }));
                    });
                    SubTasks.Add(ta);
                }
                foreach (var train in _ctx.Wor.RailwayTimeTable.Trains)
                {
                    foreach (IRailwayStation station in _ctx.Wor.Net.StationCollection)// 求解w
                    {
                        Task ta = factory.StartNew(() =>
                        {
                            var graph = DpnAlgorithm.BuildLRwGraph(_ctx, adapter, train, station, pathDict, basicGraph.LinkTrainDict, LM_mu, LM_lambda);
                            DijkstraShortestPaths <DirectedWeightedSparseGraph <string>, string> dijkstra
                                         = new DijkstraShortestPaths <DirectedWeightedSparseGraph <string>, string>(graph, "Start");//考虑该旅客到达时间
                            var nodepath = dijkstra.ShortestPathTo("End");
                            if (nodepath == null)
                            {
                                throw new System.Exception("No path found");
                            }
                            else
                            {
                                w[train][station] = new PricePath(graph, nodepath);
                            }
                        });
                        SubTasks.Add(ta);
                    }
                }
                Task.WaitAll(SubTasks.ToArray());

                foreach (var edge in y.Keys.ToArray())//更新y
                {
                    var sta   = edge.Source.Station;
                    var train = basicGraph.GetTrainByReservationLink(edge);
                    y[edge] = w[train][sta].GetWrapPoints(edge.Destination.Price, edge.Source.Time).Any();
                }
                #endregion

                #region 计算拉格朗日函数值作为下界

                decimal templowerBound       = 0m;
                decimal templowerBound_part1 = 0m;
                decimal templowerBound_part2 = 0m;
                decimal templowerBound_part3 = 0m;
                decimal templowerBound_part4 = 0m;
                Dictionary <CustomerArrival, decimal> lbValueDic
                    = new Dictionary <CustomerArrival, decimal>();
                //1 计算在基础网络中的路径cost
                foreach (CustomerArrival customer in _ctx.Pal)
                {
                    lbValueDic.Add(customer, objgraph.GetPathCost(x[customer]));
                    templowerBound_part1 += lbValueDic[customer];
                }

                //2计算BRUE项
                templowerBound_part2 += _ctx.Pal.Sum(c => pathDict[c].Sum(p =>
                {
                    decimal secondItem = 0m;
                    secondItem        += basicGraph.GetPathCost(x[c]) - basicGraph.GetPathCost(p) - _ctx.SitaDic[c.Customer.MarSegID];
                    secondItem        -= (p.ReservationArc != null && y[p.ReservationArc]) ? 0 : bigM;
                    return(secondItem * LM_mu[c][p]);
                }));

                //3计算In-train Capacity项
                Dictionary <IServiceSegment, int> ServiceDic = _ctx.Wor.RailwayTimeTable
                                                               .Trains.SelectMany(i => i.ServiceSegments)
                                                               .ToDictionary(i => i, i => 0);//当前service segment使用情况

                foreach (var p in x.Values)
                {
                    foreach (IServiceSegment seg in p.GetSegments(basicGraph))
                    {
                        ServiceDic[seg] += 1;
                    }
                }
                foreach (var train in _ctx.Wor.RailwayTimeTable.Trains)
                {
                    foreach (var seg in train.ServiceSegments)
                    {
                        templowerBound_part3 += LM_rho[seg] * (ServiceDic[seg] - train.Carriage.Chairs.Count());
                    }
                }

                //4 计算reservation constraint 项
                Dictionary <IEdge <TravelHyperNode>, int> reservationDic
                    = new Dictionary <IEdge <TravelHyperNode>, int>();
                foreach (var p in x.Values)
                {
                    if (reservationDic.ContainsKey(p.ReservationArc))
                    {
                        reservationDic[p.ReservationArc] += 1;
                    }
                    else
                    {
                        reservationDic.Add(p.ReservationArc, 1);
                    }
                }
                foreach (var pair in y.Keys)
                {
                    //y是所有的reservation 的集合 reservationDic 是已经使用的reservation 集合
                    var res = reservationDic.Keys.FirstOrDefault(i => i.Source == pair.Source && i.Destination == pair.Destination);
                    templowerBound_part4 += LM_lambda[pair] * ((res != null ? reservationDic[res] : 0) - (y[pair] ? bigM : 0));
                }

                templowerBound = templowerBound_part1 + templowerBound_part2 + templowerBound_part3 + templowerBound_part4;

                //Log($"Lower Bound = { Math.Round(templowerBound, 2)}," +
                //   $"({ Math.Round(templowerBound_part1, 2) }" +
                //   $"+{ Math.Round(templowerBound_part2, 2)}" +
                //   $"+{ Math.Round(templowerBound_part3, 2)}" +
                //   $"+{ Math.Round(templowerBound_part4, 2)})");

                PrintLBSolution(DpnAlgorithm.GetTravelPathString(_ctx, adapter, objgraph, x, lbValueDic));
                #endregion

                #region 更新乘子
                if (flag)
                {
                    decimal LagLowerBound = Convert.ToDecimal(model.GetValue(theta));
                    Log($"LagLower Bound = { LagLowerBound }");
                    Log($"Lower Bound = { templowerBound }");
                    lowerBound = Math.Max(lowerBound, templowerBound);

                    decimal lagGap = LagLowerBound - templowerBound;

                    if (lagGap <= 0)//判断拉格朗日对偶问题是否达到最优
                    {
                        Log($"求解终止:对偶函数已最优。");
                        break;
                    }
                    else
                    {
                        /* 更新乘子值 */
                        foreach (var pair in dual_rho)
                        {
                            LM_rho[pair.Key] = Convert.ToDecimal(model.GetValue(pair.Value));
                        }
                        foreach (var pair in dual_lambda)
                        {
                            LM_lambda[pair.Key] = Convert.ToDecimal(model.GetValue(pair.Value));
                        }
                        foreach (CustomerArrival customer in _ctx.Pal)
                        {
                            foreach (var path in pathDict[customer])
                            {
                                LM_mu[customer][path] = Convert.ToDecimal(model.GetValue(dual_mu[customer][path]));
                            }
                        }
                    }
                }
                else /* 如果对偶问题无可行解,通过次梯度的方式更新乘子 */
                {
                    //decimal step = 1.618m / (iter + 1);
                    //foreach (CustomerArrival c in _ctx.Pal)//更新mu
                    //{
                    //    foreach (TravelPath p in pathDict[c])
                    //    {
                    //        Grad_mu[c][p] = basicGraph.GetPathCost(x[c]) - basicGraph.GetPathCost(p) - _ctx.SitaDic[c.Customer.MarSegID]
                    //            - ((p.ReservationArc != null && y[p.ReservationArc]) ? 0 : bigM);
                    //        LM_mu[c][p] = Math.Max(0, LM_mu[c][p] + step * Grad_mu[c][p]);
                    //    }
                    //}
                    //foreach (var pair in y.Keys) //更新lambda
                    //{
                    //    var res = reservationDic.Keys.FirstOrDefault(i => i.Source == pair.Source && i.Destination == pair.Destination);
                    //    Grad_lambda[pair] = ((res != null ? reservationDic[res] : 0) - (y[pair] ? bigM : 0));
                    //    LM_lambda[pair] = Math.Max(0, LM_lambda[pair] + step * Grad_lambda[pair]);
                    //}
                    //foreach (var train in _ctx.Wor.RailwayTimeTable.Trains)//更新rho
                    //{
                    //    foreach (var seg in train.ServiceSegments)
                    //    {
                    //        Grad_rho[seg] = ServiceDic[seg] - train.Carriage.Chairs.Count();
                    //        LM_rho[seg] = Math.Max(0, LM_rho[seg] + step * Grad_rho[seg]);
                    //    }
                    //}
                }

                #endregion

                #region 求解拉格朗日对偶问题

                /* 求解 几何乘子 */
                // 增加 一个约束
                INumExpr exp = model.NumExpr();

                //2 计算BRUE项
                foreach (var c in _ctx.Pal)
                {
                    foreach (var p in pathDict[c])
                    {
                        decimal secondItem = 0m;
                        secondItem += basicGraph.GetPathCost(x[c]) - basicGraph.GetPathCost(p) - _ctx.SitaDic[c.Customer.MarSegID];
                        secondItem -= (p.ReservationArc != null && y[p.ReservationArc]) ? 0 : bigM;
                        exp         = model.Sum(exp, model.Prod(Convert.ToDouble(secondItem), dual_mu[c][p]));
                    }
                }

                //3计算In-train Capacity项 (这里直接用了计算下界时候的 Service_dic
                foreach (var train in _ctx.Wor.RailwayTimeTable.Trains)
                {
                    foreach (var seg in train.ServiceSegments)
                    {
                        exp = model.Sum(exp, model.Prod(Convert.ToDouble(ServiceDic[seg]
                                                                         - train.Carriage.Chairs.Count()), dual_rho[seg]));
                    }
                }

                //4 计算reservation constraint 项 (这里直接用了计算下界时候的 reservationDic
                foreach (var pair in y.Keys)
                {
                    var res = reservationDic.Keys.FirstOrDefault(i => i.Source == pair.Source &&
                                                                 i.Destination == pair.Destination);
                    exp = model.Sum(exp, model.Prod(Convert.ToDouble(((res != null ? reservationDic[res] : 0)
                                                                      - (y[pair] ? bigM : 0))), dual_lambda[pair]));
                }

                model.AddGe(model.Sum(Convert.ToDouble(templowerBound_part1), exp), theta);

                /* Trust-Region */
                //var trExpr = model.Add()

                flag = model.Solve();
                Log($"Is Dual Problem Feasible: { flag }");

                #endregion

                #region 通过一个启发式规则计算上界(按照w模拟到达)

                var pathcost     = lbValueDic.ToDictionary(i => i.Key, i => i.Value);
                var x_least      = x.ToDictionary(i => i.Key, i => i.Value);//当前w下每个旅客的最短路径
                var x_upperbound = x.ToDictionary(i => i.Key, i => i.Value);
                var x_controlled = x.ToDictionary(i => i.Key, i => i.Value);

                #region 1-构建当前y下的最优x值
                SubTasks.Clear();
                foreach (CustomerArrival customer in _ctx.Pal)// 求解x
                {
                    Task ta = factory.StartNew(() =>
                    {
                        var controlledLRxgraph = new ControlledLRxTravelHyperNetwork(
                            _ctx, adapter, objgraph, customer, pathDict, LM_rho, LM_mu, LM_lambda, y);
                        controlledLRxgraph.Build();
                        var ori = (_ctx.Wor.Mar[customer.Customer.MarSegID] as IRailwayMarketSegment).OriSta;
                        var des = (_ctx.Wor.Mar[customer.Customer.MarSegID] as IRailwayMarketSegment).DesSta;

                        TravelHyperNode startNode = new TravelHyperNode()
                        {
                            Time    = adapter.ConvertToDiscreteTime(customer.ArriveTime),
                            Station = ori,
                            Price   = 0
                        };
                        TravelHyperNode endNode = new TravelHyperNode()
                        {
                            Time    = adapter.Horizon + 1440,
                            Station = des,
                            Price   = 0
                        };

                        DijkstraShortestPaths <DirectedWeightedSparseGraph <TravelHyperNode>, TravelHyperNode> dijkstra
                            = new DijkstraShortestPaths <DirectedWeightedSparseGraph <TravelHyperNode>, TravelHyperNode>
                                  (controlledLRxgraph, startNode);//考虑该旅客到达时间

                        if (!dijkstra.HasPathTo(endNode))
                        {
                            throw new System.Exception("没有路径!");
                        }
                        else
                        {
                            x_controlled[customer] = new TravelPath(controlledLRxgraph, dijkstra.ShortestPathTo(endNode));
                        }
                    });
                    SubTasks.Add(ta);
                }
                Task.WaitAll(SubTasks.ToArray());
                #endregion

                # region 2-构建当前y下的出行最小值
                var solutiongraph = new ControlledTravelHyperNetwork(_ctx, adapter, y);
                solutiongraph.Build();
                Parallel.ForEach(_ctx.Pal, customer =>                //foreach (var customer in _ctx.Pal)//求此网络下每个旅客的最短路径
                {
                    var ori = (_ctx.Wor.Mar[customer.Customer.MarSegID] as IRailwayMarketSegment).OriSta;
                    var des = (_ctx.Wor.Mar[customer.Customer.MarSegID] as IRailwayMarketSegment).DesSta;

                    TravelHyperNode startNode = new TravelHyperNode()
                    {
                        Time    = adapter.ConvertToDiscreteTime(customer.ArriveTime),
                        Station = ori,
                        Price   = 0
                    };

                    TravelHyperNode endNode = new TravelHyperNode()
                    {
                        Time    = adapter.Horizon + 1440,
                        Station = des,
                        Price   = 0
                    };

                    DijkstraShortestPaths <DirectedWeightedSparseGraph <TravelHyperNode>, TravelHyperNode> dijkstra
                        = new DijkstraShortestPaths <DirectedWeightedSparseGraph <TravelHyperNode>, TravelHyperNode>
                              (solutiongraph, startNode);

                    if (!dijkstra.HasPathTo(endNode))
                    {
                        throw new System.Exception("没有路径!");
                    }
                    else
                    {
                        x_least[customer] = new TravelPath(solutiongraph, dijkstra.ShortestPathTo(endNode));
                    }
                });
                #endregion

                #region 3-修复可行解
                var solutiongraphTemp = new SimNetwork(_ctx, adapter, y);//建立仿真网络
                solutiongraphTemp.Build();
                foreach (var customer in _ctx.Pal)
                {
                    x_upperbound[customer] = x_controlled[customer];
                    TravelPath path = x_controlled[customer];

                    if (!solutiongraphTemp.IsPathFeasible(path) ||
                        solutiongraphTemp.GetPathCost(path) > solutiongraph.GetPathCost(x_least[customer]) + _ctx.SitaDic[customer.Customer.MarSegID])//如果违反了容量约束或者BRUE约束
                    {
                        var ori = (_ctx.Wor.Mar[customer.Customer.MarSegID] as IRailwayMarketSegment).OriSta;
                        var des = (_ctx.Wor.Mar[customer.Customer.MarSegID] as IRailwayMarketSegment).DesSta;
                        DijkstraShortestPaths <DirectedWeightedSparseGraph <TravelHyperNode>, TravelHyperNode> dijkstra
                            = new DijkstraShortestPaths <DirectedWeightedSparseGraph <TravelHyperNode>, TravelHyperNode>(solutiongraphTemp, new TravelHyperNode()
                        {
                            Time    = adapter.ConvertToDiscreteTime(customer.ArriveTime),
                            Station = ori,
                            Price   = 0
                        });

                        //重新查找路径,如果存在路径
                        if (dijkstra.HasPathTo(new TravelHyperNode()
                        {
                            Time = adapter.Horizon + 1440,
                            Station = des,
                            Price = 0
                        }))
                        {
                            x_upperbound[customer] = new TravelPath(solutiongraphTemp, dijkstra.ShortestPathTo(new TravelHyperNode()
                            {
                                Time    = adapter.Horizon + 1440,
                                Station = des,
                                Price   = 0
                            }));
                            if (solutiongraphTemp.GetPathCost(x_upperbound[customer]) <= //满足BRUE约束
                                solutiongraph.GetPathCost(x_least[customer]) + _ctx.SitaDic[customer.Customer.MarSegID])
                            {
                                path = x_upperbound[customer];
                            }
                            else
                            {
                                hasFeasibleSolution = false;
                                break;
                            }
                        }
                        else
                        {
                            hasFeasibleSolution = false;
                            break;
                        }
                    }

                    pathcost[customer] = objgraph.GetPathCost(path);

                    //加载路径
                    foreach (var seg in path.GetSegments(basicGraph))
                    {
                        solutiongraphTemp.AddUsage(seg, 1);
                    }
                }
                var tempUpperbound = _ctx.Pal.Sum(c => objgraph.GetPathCost(x_upperbound[c]));
                #endregion

                //如果有最优解再更新上界
                bool hasBetterUpperbound = tempUpperbound < upperBound;
                if (hasFeasibleSolution)
                {
                    upperBound = Math.Min(upperBound, tempUpperbound);
                }
                Log($"Upper Bound = {  Math.Round(tempUpperbound, 2) },找到可行解 : { hasFeasibleSolution.ToString()}");
                #endregion

                #region  Terminatation 判定
                Log($"Upper Bound = { tempUpperbound }");
                decimal absoluteGap = 0;
                string  gapStr      = "";
                //如果上限是无穷,那么此时gap也是无穷
                if (upperBound == decimal.MaxValue || lowerBound == decimal.MinValue)
                {
                    absoluteGap = decimal.MaxValue;
                    gapStr      = $"+∞";
                }
                else
                {
                    absoluteGap = upperBound - lowerBound;
                    gapStr      = $"{ Math.Round(absoluteGap, 2)}";
                }


                if (absoluteGap < terminalFactor && absoluteGap > 0)
                {
                    Log($"求解终止:Gap以满足终止条件,Gap={ absoluteGap }");
                    break;
                }

                Log($"Total Gap = { gapStr }");
                #endregion

                #region 输出信息

                //SendMessage($"#Iteration Number, Lower Bound, Upper Bound, Best Lower Bound, Best Upper Bound, Total Gap(%) ");
                PrintIterationInfo($"#{iter},{ Math.Round(templowerBound) },{ Math.Round(tempUpperbound) },{ Math.Round(lowerBound)}" +
                                   $",{ Math.Round(upperBound) },{ gapStr }");

                string ss = "###,";
                foreach (var s in LM_rho)
                {
                    ss += ($"{s.Key.ToString()}:{ s.Value.ToString() },");
                }
                PrintIterationInfo(ss);

                if (hasFeasibleSolution && hasBetterUpperbound)
                {
                    ObjValue = pathcost.Sum(i => i.Value);
                    PrintSolution(
                        DpnAlgorithm.GetTravelPathString(_ctx, adapter, solutiongraph, x_upperbound, pathcost),
                        DpnAlgorithm.GetPricingPathString(_ctx, adapter, w));
                }

                #endregion

                Log($"--------------第{iter}轮求解结束--------------");
            }
Beispiel #25
0
    static void Main(string[] args)
    {
        try {
            string filename = "../../../../examples/data/etsp.dat";
            if (args.Length > 0)
            {
                filename = args[0];
            }

            Data  data  = new Data(filename);
            Cplex cplex = new Cplex();

            // Create start variables
            INumVar[][] s = new INumVar[data.nJobs][];
            for (int j = 0; j < data.nJobs; j++)
            {
                s[j] = cplex.NumVarArray(data.nResources, 0.0, Horizon);
            }

            // State precedence constraints
            for (int j = 0; j < data.nJobs; j++)
            {
                for (int i = 1; i < data.nResources; i++)
                {
                    cplex.AddGe(s[j][i], cplex.Sum(s[j][i - 1], data.duration[j][i - 1]));
                }
            }

            // State disjunctive constraints for each resource
            for (int i = 0; i < data.nResources; i++)
            {
                int end = data.nJobs - 1;
                for (int j = 0; j < end; j++)
                {
                    int a = data.activityOnResource[i][j];
                    for (int k = j + 1; k < data.nJobs; k++)
                    {
                        int b = data.activityOnResource[i][k];
                        cplex.Add(cplex.Or(
                                      cplex.Ge(s[j][a], cplex.Sum(s[k][b], data.duration[k][b])),
                                      cplex.Ge(s[k][b], cplex.Sum(s[j][a], data.duration[j][a]))
                                      ));
                    }
                }
            }

            // The cost is the sum of earliness or tardiness costs of each job
            int      last    = data.nResources - 1;
            INumExpr costSum = cplex.NumExpr();
            for (int j = 0; j < data.nJobs; j++)
            {
                double[] points = { data.dueDate[j] };
                double[] slopes = { -data.earlinessCost[j],
                                    data.tardinessCost[j] };
                costSum = cplex.Sum(costSum,
                                    cplex.PiecewiseLinear(
                                        cplex.Sum(s[j][last], data.duration[j][last]),
                                        points, slopes, data.dueDate[j], 0)
                                    );
            }
            cplex.AddMinimize(costSum);

            cplex.SetParam(Cplex.Param.Emphasis.MIP, 4);

            if (cplex.Solve())
            {
                System.Console.WriteLine("Solution status = " + cplex.GetStatus());
                System.Console.WriteLine(" Optimal Value = " + cplex.ObjValue);
            }
            cplex.End();
        }
        catch (ILOG.Concert.Exception e) {
            System.Console.WriteLine("Concert exception caught: " + e);
        }
        catch (InputDataReader.InputDataReaderException ex) {
            System.Console.WriteLine("Data Error: " + ex);
        }
        catch (System.IO.IOException ex) {
            System.Console.WriteLine("IO Error: " + ex);
        }
    }
Beispiel #26
0
    static void Main(string[] args)
    {
        try {
         string filename = "../../../../examples/data/etsp.dat";
         if ( args.Length > 0)
            filename = args[0];

         Data  data  = new Data(filename);
         Cplex cplex = new Cplex();

         // Create start variables
         INumVar[][] s = new INumVar[data.nJobs][];
         for (int j = 0; j < data.nJobs; j++)
            s[j] = cplex.NumVarArray(data.nResources, 0.0, Horizon);

         // State precedence constraints
         for (int j = 0; j < data.nJobs; j++) {
            for (int i = 1; i < data.nResources; i++)
               cplex.AddGe(s[j][i], cplex.Sum(s[j][i-1], data.duration[j][i-1]));
         }

         // State disjunctive constraints for each resource
         for (int i = 0; i < data.nResources; i++) {
            int end = data.nJobs - 1;
            for (int j = 0; j < end; j++) {
               int a = data.activityOnResource[i][j];
               for (int k = j + 1; k < data.nJobs; k++) {
                  int b = data.activityOnResource[i][k];
                  cplex.Add(cplex.Or(
                     cplex.Ge(s[j][a], cplex.Sum(s[k][b], data.duration[k][b])),
                     cplex.Ge(s[k][b], cplex.Sum(s[j][a], data.duration[j][a]))
                  ));
               }
            }
         }

         // The cost is the sum of earliness or tardiness costs of each job
         int last = data.nResources - 1;
         INumExpr costSum = cplex.NumExpr();
         for (int j = 0; j < data.nJobs; j++) {
            double[] points = { data.dueDate[j] };
            double[] slopes = { -data.earlinessCost[j],
                                data.tardinessCost[j] };
            costSum = cplex.Sum(costSum,
               cplex.PiecewiseLinear(
                  cplex.Sum(s[j][last], data.duration[j][last]),
                  points, slopes, data.dueDate[j], 0)
            );
         }
         cplex.AddMinimize(costSum);

         cplex.SetParam(Cplex.Param.Emphasis.MIP, 4);

         if ( cplex.Solve() ) {
           System.Console.WriteLine("Solution status = " + cplex.GetStatus());
           System.Console.WriteLine(" Optimal Value = " + cplex.ObjValue);
         }
         cplex.End();
          }
          catch (ILOG.Concert.Exception e) {
         System.Console.WriteLine("Concert exception caught: " + e);
          }
          catch (InputDataReader.InputDataReaderException ex) {
         System.Console.WriteLine("Data Error: " + ex);
          }
          catch (System.IO.IOException ex) {
         System.Console.WriteLine("IO Error: " + ex);
          }
    }