Exemple #1
0
        protected void InitRMPModel()
        {
            cost       = RMPModel.AddMaximize();
            var        = new Dictionary <IALPDecision, INumVar> [Data.TimeHorizon];
            DualValue1 = new double[Data.TimeHorizon][];
            DualValue2 = new double[Data.TimeHorizon];
            lowerbound = new double[Data.TimeHorizon][];
            upperbound = new double[Data.TimeHorizon][];
            #region //////////////生成约束//////////////
            constraint1 = new IRange[Data.TimeHorizon][];
            constraint2 = new IRange[Data.TimeHorizon];
            for (int i = 0; i < Data.TimeHorizon; i++)
            {
                DualValue1[i]  = new double[Data.RS.Count];
                var[i]         = new Dictionary <IALPDecision, INumVar>();
                constraint1[i] = new IRange[Data.RS.Count];
                lowerbound[i]  = new double[Data.RS.Count];
                upperbound[i]  = new double[Data.RS.Count];
                foreach (IALPResource re in Data.RS)
                {
                    constraint1[i][Data.RS.IndexOf(re)] = RMPModel.AddRange(double.MinValue, (Data.InitialState as IALPState)[re]);
                }
                //constraint1[i][0].UB -= 0.3;
                constraint2[i] = RMPModel.AddRange(1, 1);
            }
            #endregion

            RMPModel.SetOut(this.SolverTextWriter);
        }
        private void btn_cutStep_Click(object sender, RoutedEventArgs e)
        {
            mainCanvas.ClearCanvas();

            int[] La = new int[node_cnt * node_cnt];
            for (int i = 0; i < node_cnt; i++)
            {
                int deg = 0;
                for (int j = 0; j < node_cnt; j++)
                {
                    La[i * node_cnt + j] = graph[i, j] ? -1 : 0;
                    deg += graph[i, j] ? 1 : 0;
                }
                La[i * node_cnt + i] = deg;
            }

            Cplex model = new Cplex();

            INumVar[] x   = model.BoolVarArray(node_cnt);
            INumVar[] eij = model.BoolVarArray(node_cnt * node_cnt);
            for (int i = 0; i < node_cnt; i++)
            {
                for (int j = i; j < node_cnt; j++)
                {
                    if (i != j)
                    {
                        model.AddEq(eij[i * node_cnt + j], eij[j * node_cnt + i]);
                    }
                    model.AddLe(eij[i * node_cnt + j], x[i]);
                    model.AddLe(eij[i * node_cnt + j], x[j]);
                    model.AddLe(model.Sum(x[i], x[j]), model.Sum(eij[i * node_cnt + j], eij[i * node_cnt + j], model.Constant(1)));
                }
            }
            model.AddMaximize(model.ScalProd(La, eij));

            if (model.Solve())
            {
                double[] vals = model.GetValues(x);
                int      val  = (int)Math.Round(model.GetObjValue());
                dc_Utility.WriteLine("");
                dc_Utility.WriteLine(dc_Utility.c_stars);
                dc_Utility.WriteLine("Group A size: " + vals.Count(p => p > 0.5));
                dc_Utility.WriteLine("Group B size: " + vals.Count(p => p < 0.5));
                dc_Utility.WriteLine("Max Cut: " + val);
                dc_Utility.WriteLine(dc_Utility.c_stars);
                dc_Utility.WriteLine("");

                for (int i = 0; i < node_cnt; i++)
                {
                    classes[i] = vals[i] > 0.5;
                }
                DrawGraph(true);
            }

            model.Dispose();
        }
        private void InitializeObjFunc()
        {
            var func = cplex.LinearNumExpr();

            foreach (var x in numVars)
            {
                func.AddTerm(1, x);
            }
            cplex.AddMaximize(func);
        }
Exemple #4
0
        private bool RCG(int t, out IALPState temp_s, out IMDPDecision deci_a)
        {
            temp_s = null;
            deci_a = null;

            //System.Console.WriteLine("--------开始生成问题:{0}-----", System.DateTime.Now.Millisecond);
            #region 创建目标函数
            SubModel.Remove(SubModel.GetObjective());
            SubModel.AddMaximize(subObject[1][t]);
            #endregion

            foreach (IALPResource re in Data.RS)
            {
                constraint_sub2[Data.RS.IndexOf(re)].SetBounds(0, (Data.InitialState as IALPState)[re]);
            }

            //System.Console.WriteLine("--------生成问题结束:{0}-----", System.DateTime.Now.Millisecond);
            if (SubModel.Solve())
            {
                //System.Console.WriteLine("--------求解问题结束:{0}-----", System.DateTime.Now.Millisecond);
                //System.Console.WriteLine("RCG({0})求解结束\t目标值为:{1}", t, SubModel.ObjValue<0.001?0: SubModel.ObjValue);
                if (SubModel.ObjValue <= Tolerance)
                {
                    return(true);
                }
                else
                {
                    //print("{0}问题违反程度{1}", t, (SubModel.ObjValue - Tolerance).ToString());
                    #region  用h,r生成一个State
                    for (int _h = 0; _h < h.Count(); _h++)
                    {
                        double temp_h = SubModel.GetValue(h[_h]);
                        if (temp_h == 1)
                        {
                            deci_a = Data.DS[_h];
                            break;
                        }
                    }

                    Dictionary <IALPResource, int> dic = new Dictionary <IALPResource, int>();
                    for (int _r = 0; _r < r.Count(); _r++)
                    {
                        dic.Add(Data.RS[_r], (int)SubModel.GetValue(r[_r]));
                    }
                    temp_s = Data.CreateOrFind(dic);
                    #endregion
                    return(false);
                }
            }
            else
            {
                throw new System.Exception("子问题无解");
            }
        }
Exemple #5
0
        //Affine Funciton Approximation
        public static Cplex Build_CD1_Model(IALPFTMDP aff)
        {
            Cplex model = new Cplex();

            IObjective cost = model.AddMaximize();

            IRange[][] constraint1 = new IRange[aff.TimeHorizon][];
            IRange[]   constraint2 = new IRange[aff.TimeHorizon];

            #region //////////////生成约束//////////////
            for (int i = 0; i < aff.TimeHorizon; i++)
            {
                constraint1[i] = new IRange[aff.RS.Count];
                foreach (IALPResource re in aff.RS)
                {
                    if (i == 0)
                    {
                        constraint1[i][aff.RS.IndexOf(re)] = model.AddRange((aff.InitialState as IALPState)[re], (aff.InitialState as IALPState)[re]);
                    }
                    else
                    {
                        constraint1[i][aff.RS.IndexOf(re)] = model.AddRange(0, 0);
                    }
                }
                constraint2[i] = model.AddRange(1, 1);
            }
            #endregion

            #region //////////////生成变量//////////////
            for (int t = 0; t < aff.TimeHorizon; t++)
            {
                foreach (IALPState s in aff.SS)
                {
                    foreach (IMDPDecision a in aff.GenDecisionSpace(s))
                    {
                        Column col = model.Column(cost, aff.Rt(t, a));
                        foreach (IALPResource re in aff.RS)
                        {
                            col = col.And(model.Column(constraint1[t][aff.RS.IndexOf(re)], (s as IALPState)[re]));
                            if (t < aff.TimeHorizon - 1)
                            {
                                col = col.And(model.Column(constraint1[t + 1][aff.RS.IndexOf(re)], (aff.Qti(t, re, a)) - (s as IALPState)[re]));
                            }
                        }
                        col = col.And(model.Column(constraint2[t], 1));
                        model.NumVar(col, 0, double.MaxValue, NumVarType.Float);
                    }
                }
            }
            #endregion
            return(model);
        }
Exemple #6
0
        public static Cplex BuildDualModel(IFTMDP Ida)
        {
            Cplex model = new Cplex();

            IObjective cost = model.AddMaximize();

            IRange[][] constraint = new IRange[Ida.TimeHorizon][];

            #region //////////////生成约束//////////////
            for (int i = 0; i < Ida.TimeHorizon; i++)
            {
                constraint[i] = new IRange[Ida.SS.Count];
                foreach (IMDPState s in Ida.SS)
                {
                    if (i == 0 && s.Equals(Ida.InitialState))
                    {
                        constraint[i][Ida.SS.IndexOf(s)] = model.AddRange(1, 1);
                    }
                    else
                    {
                        constraint[i][Ida.SS.IndexOf(s)] = model.AddRange(0, 0);
                    }
                }
            }
            #endregion

            #region //////////////生成变量//////////////
            for (int t = 0; t < Ida.TimeHorizon; t++)
            {
                foreach (IMDPState s in Ida.SS)
                {
                    foreach (IMDPDecision a in Ida.GenDecisionSpace(s))
                    {
                        Column col = model.Column(cost, Ida.Reward(t, s, a));
                        col = col.And(model.Column(constraint[t][Ida.SS.IndexOf(s)], 1));    //插入Aj

                        if (t < Ida.TimeHorizon - 1)
                        {
                            foreach (IMDPState k in Ida.GenStateSpace(s, a))
                            {
                                col = col.And(model.Column(constraint[t + 1][Ida.SS.IndexOf(k)], -Ida.Prob(t, s, k, a)));    //插入Aj
                            }
                        }
                        model.NumVar(col, 0, double.MaxValue, NumVarType.Float);
                    }
                }
            }
            #endregion
            model.SetOut(null);
            return(model);
        }
Exemple #7
0
            private void SetTime(int t)
            {
                model.Remove(model.GetObjective());
                cost = model.AddMaximize();

                foreach (IALPDecision a in aff.DS)
                {
                    Column col = model.Column(cost, aff.Rt(t, a));

                    col = col.And(model.Column(constraint, 1));

                    vars[aff.DS.IndexOf(a)] = model.NumVar(col, 0, 1, NumVarType.Int);
                }
            }
Exemple #8
0
        public static Cplex Build_CD3_Model(IALPFTMDP aff)
        {
            Cplex      model = new Cplex();
            IObjective cost  = model.AddMaximize();

            INumVar[][] var = new INumVar[aff.TimeHorizon][];

            #region //////////////生成约束//////////////
            IRange[][] constraint1 = new IRange[aff.TimeHorizon][];
            IRange[]   constraint2 = new IRange[aff.TimeHorizon];
            for (int i = 0; i < aff.TimeHorizon; i++)
            {
                var[i]         = new INumVar[aff.DS.Count];
                constraint1[i] = new IRange[aff.RS.Count];
                foreach (IALPResource re in aff.RS)
                {
                    constraint1[i][aff.RS.IndexOf(re)] = model.AddRange(double.MinValue, (aff.InitialState as IALPState)[re]);
                }
                constraint2[i] = model.AddRange(1, 1);
            }
            #endregion

            #region //////////////生成变量//////////////
            for (int t = 0; t < aff.TimeHorizon; t++)
            {
                foreach (IALPDecision a in aff.DS)
                {
                    //目标函数
                    Column col = model.Column(cost, aff.Rt(t, a));
                    //第一类约束
                    foreach (IALPResource re in aff.RS)
                    {
                        for (int k = t + 1; k < aff.TimeHorizon; k++)
                        {
                            col = col.And(model.Column(constraint1[k][aff.RS.IndexOf(re)], aff.Qti(t, re, a)));
                        }
                        if (a.UseResource(re))
                        {
                            col = col.And(model.Column(constraint1[t][aff.RS.IndexOf(re)], 1));
                        }
                    }
                    //第二类约束
                    col = col.And(model.Column(constraint2[t], 1));
                    var[t][aff.DS.IndexOf(a)] = model.NumVar(col, 0, double.MaxValue, NumVarType.Float);
                }
            }
            #endregion

            return(model);
        }
Exemple #9
0
        private void InitRMPModel()
        {
            RMPModel.ClearModel();
            cost        = RMPModel.AddMaximize();
            constraint1 = new IRange[Data.TimeHorizon][];
            constraint2 = new IRange[Data.TimeHorizon];
            DualValue1  = new double[Data.TimeHorizon][];
            DualValue2  = new double[Data.TimeHorizon];

            #region //////////////生成约束//////////////
            //Parallel.For(0, Data.TimeHorizon, i =>
            for (int i = 0; i < Data.TimeHorizon; i++)
            {
                lock (RMPModel)
                {
                    constraint1[i] = new IRange[Data.RS.Count];
                    DualValue1[i]  = new double[Data.RS.Count];
                    foreach (IALPResource re in Data.RS)
                    {
                        if (i == 0)
                        {
                            constraint1[i][Data.RS.IndexOf(re)] = RMPModel.AddRange((Data.InitialState as IALPState)[re], (Data.InitialState as IALPState)[re]);
                        }
                        else
                        {
                            constraint1[i][Data.RS.IndexOf(re)] = RMPModel.AddRange(0, 0);
                        }
                    }
                    constraint2[i] = RMPModel.AddRange(1, 1);
                }
            }
            #endregion

            //RMPModel.SetParam(Cplex.LongParam.RootAlgorithm, 1);
            RMPModel.SetOut(SolverTextWriter);
        }
Exemple #10
0
        public static Cplex Build_CD2_Model(IALPFTMDP aff)
        {
            Cplex      model = new Cplex();
            IObjective cost  = model.AddMaximize();

            #region //////////////生成约束//////////////
            IRange[][] constraint1 = new IRange[aff.TimeHorizon][];
            IRange[][] constraint2 = new IRange[aff.TimeHorizon][];
            IRange[]   constraint3 = new IRange[aff.TimeHorizon];
            for (int i = 0; i < aff.TimeHorizon; i++)
            {
                constraint1[i] = new IRange[aff.RS.Count];
                constraint2[i] = new IRange[aff.RS.Count];
                foreach (IALPResource re in aff.RS)
                {
                    if (i == 0)
                    {
                        constraint1[i][aff.RS.IndexOf(re)] = model.AddRange((aff.InitialState as IALPState)[re], (aff.InitialState as IALPState)[re]);
                        constraint2[i][aff.RS.IndexOf(re)] = model.AddRange(double.MinValue, 0);
                    }
                    else
                    {
                        constraint1[i][aff.RS.IndexOf(re)] = model.AddRange(0, 0);
                        constraint2[i][aff.RS.IndexOf(re)] = model.AddRange(double.MinValue, 0);
                    }
                }
                constraint3[i] = model.AddRange(1, 1);
            }
            #endregion

            #region //////////////生成变量//////////////
            //生成h
            for (int t = 0; t < aff.TimeHorizon; t++)
            {
                foreach (IALPDecision a in aff.DS)
                {
                    //目标函数
                    Column col = model.Column(cost, aff.Rt(t, a));
                    foreach (IALPResource re in aff.RS)
                    {
                        //第一类约束
                        if (t < aff.TimeHorizon - 1)
                        {
                            col = col.And(model.Column(constraint1[t + 1][aff.RS.IndexOf(re)], aff.Qti(t + 1, re, a)));
                        }
                        //第二类约束
                        if (a.UseResource(re))
                        {
                            col = col.And(model.Column(constraint2[t][aff.RS.IndexOf(re)], 1));
                        }
                    }
                    //第三类约束
                    col = col.And(model.Column(constraint3[t], 1));
                    model.NumVar(col, 0, double.MaxValue, NumVarType.Float);
                }
                foreach (IALPResource r in aff.RS)
                {
                    Column col = model.Column(cost, 0);// cost, aff.Rt(t, a));
                    if (t < aff.TimeHorizon - 1)
                    {
                        col = col.And(model.Column(constraint1[t + 1][aff.RS.IndexOf(r)], -1));
                    }
                    col = col.And(model.Column(constraint1[t][aff.RS.IndexOf(r)], 1));
                    col = col.And(model.Column(constraint2[t][aff.RS.IndexOf(r)], -1));
                    model.NumVar(col, 0, double.MaxValue, NumVarType.Float);
                }
            }
            ///);
            #endregion

            return(model);
        }
Exemple #11
0
        //Piece-Wise Function Approximation
        public static Cplex Build_Dual_PW_Model(IALPFTMDP aff)
        {
            Cplex      model = new Cplex();
            IObjective cost  = model.AddMaximize();

            #region //////////////生成约束//////////////
            IRange[][][] constraint1 = new IRange[aff.TimeHorizon][][];
            IRange[]     constraint2 = new IRange[aff.TimeHorizon];
            for (int i = 0; i < aff.TimeHorizon; i++)
            {
                constraint1[i] = new IRange[aff.RS.Count][];
                foreach (IALPResource re in aff.RS)
                {
                    constraint1[i][aff.RS.IndexOf(re)] = new IRange[(aff.InitialState as IALPState)[re]];
                    for (int k = 1; k < (aff.InitialState as IALPState)[re]; k++)
                    {
                        if (i == 0)
                        {
                            constraint1[i][aff.RS.IndexOf(re)][k - 1] = model.AddRange(1, 1);
                        }
                        else
                        {
                            constraint1[i][aff.RS.IndexOf(re)][k - 1] = model.AddRange(0, 0);
                        }
                    }
                }
                constraint2[i] = model.AddRange(1, 1);
            }
            #endregion

            #region //////////////生成变量//////////////
            //System.Threading.Tasks.Parallel.For(0, aff.TimeHorizon, (t) =>
            for (int t = 0; t < aff.TimeHorizon; t++)
            {
                foreach (IALPState s in aff.SS)
                {
                    foreach (IMDPDecision a in aff.GenDecisionSpace(s))
                    {
                        //目标函数
                        Column col = model.Column(cost, aff.Reward(t, s, a));
                        // System.Console.WriteLine(aff.Reward(t, s, a));
                        //第一类约束
                        foreach (IALPResource re in aff.RS)
                        {
                            for (int k = 1; k < (aff.InitialState as IALPState)[re]; k++)
                            {
                                if (s[re] >= k)
                                {
                                    col = col.And(model.Column(constraint1[t][aff.RS.IndexOf(re)][k - 1], 1));
                                    if (t < aff.TimeHorizon - 1)
                                    {
                                        col = col.And(model.Column(constraint1[t + 1][aff.RS.IndexOf(re)][k - 1], -1));
                                        if (s[re] == k)
                                        {
                                            col = col.And(model.Column(constraint1[t + 1][aff.RS.IndexOf(re)][k - 1], (aff.Qti(t, re, a))));
                                        }
                                    }
                                }
                            }
                        }
                        //第二类约束
                        col = col.And(model.Column(constraint2[t], 1));
                        model.NumVar(col, 0, double.MaxValue, NumVarType.Float);
                    }
                }
            }
            ///);
            #endregion

            model.SetOut(null);
            return(model);
        }
Exemple #12
0
    private void runModel(List <Employee> employees, List <Shift> shifts)
    {
        StreamWriter writer = File.CreateText(@"C:\Users\user\Desktop\cplex log\result9.txt");

        try
        {
            Cplex model = new Cplex();

            model.SetOut(writer);

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

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

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

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

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

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

            model.ExportModel(@"C:\Users\user\Desktop\cplex log\model1.lp");
            bool feasible = model.Solve();
            if (feasible)
            {
                double objVal = model.ObjValue;
                model.Output().WriteLine("Solution value = " + model.ObjValue);
                shifts.ForEach(shift =>
                {
                    ILinearNumExpr sumAssigsExpr = model.LinearNumExpr();
                    employees.ForEach(employee =>
                    {
                        string name = getAssignVarName(employee, shift);
                    });
                    model.AddLe(sumAssigsExpr, shift.shiftNumber, "NoOverAssignConst");
                });
            }
            else
            {
            }
        }
        catch (System.Exception ex)
        {
            Response.ContentType = "application/json; charset=utf-8";
            Response.Write(ex.Message);
            Response.End();
        }
        writer.Close();
    }
Exemple #13
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);
        }
Exemple #14
0
 public void AddObjective()
 {
     theModel.AddMaximize(theModel.Diff(theModel.ScalProd(LaneMargin, LoadedMoves), theModel.ScalProd(LaneCost, EmptyMoves)));
 }
Exemple #15
0
    public static void Main(string[] args)
    {
        try {
            string filename = "../../../../examples/data/steel.dat";
            if (args.Length > 0)
            {
                filename = args[0];
            }
            ReadData(filename);

            Cplex cplex = new Cplex();

            // VARIABLES
            INumVar[][] Make = new INumVar[_nProd][];
            for (int p = 0; p < _nProd; p++)
            {
                Make[p] = cplex.NumVarArray(_nTime, 0.0, System.Double.MaxValue);
            }

            INumVar[][] Inv = new INumVar[_nProd][];
            for (int p = 0; p < _nProd; p++)
            {
                Inv[p] = cplex.NumVarArray(_nTime, 0.0, System.Double.MaxValue);
            }

            INumVar[][] Sell = new INumVar[_nProd][];
            for (int p = 0; p < _nProd; p++)
            {
                Sell[p] = new INumVar[_nTime];
                for (int t = 0; t < _nTime; t++)
                {
                    Sell[p][t] = cplex.NumVar(0.0, _market[p][t]);
                }
            }

            // OBJECTIVE
            ILinearNumExpr TotalRevenue  = cplex.LinearNumExpr();
            ILinearNumExpr TotalProdCost = cplex.LinearNumExpr();
            ILinearNumExpr TotalInvCost  = cplex.LinearNumExpr();

            for (int p = 0; p < _nProd; p++)
            {
                for (int t = 1; t < _nTime; t++)
                {
                    TotalRevenue.AddTerm(_revenue[p][t], Sell[p][t]);
                    TotalProdCost.AddTerm(_prodCost[p], Make[p][t]);
                    TotalInvCost.AddTerm(_invCost[p], Inv[p][t]);
                }
            }

            cplex.AddMaximize(cplex.Diff(TotalRevenue,
                                         cplex.Sum(TotalProdCost, TotalInvCost)));

            // TIME AVAILABILITY CONSTRAINTS

            for (int t = 0; t < _nTime; t++)
            {
                ILinearNumExpr availExpr = cplex.LinearNumExpr();
                for (int p = 0; p < _nProd; p++)
                {
                    availExpr.AddTerm(1.0 / _rate[p], Make[p][t]);
                }
                cplex.AddLe(availExpr, _avail[t]);
            }

            // MATERIAL BALANCE CONSTRAINTS

            for (int p = 0; p < _nProd; p++)
            {
                cplex.AddEq(cplex.Sum(Make[p][0], _inv0[p]),
                            cplex.Sum(Sell[p][0], Inv[p][0]));
                for (int t = 1; t < _nTime; t++)
                {
                    cplex.AddEq(cplex.Sum(Make[p][t], Inv[p][t - 1]),
                                cplex.Sum(Sell[p][t], Inv[p][t]));
                }
            }

            cplex.ExportModel("steel.lp");

            if (cplex.Solve())
            {
                System.Console.WriteLine("Solution status = " + cplex.GetStatus());
                System.Console.WriteLine();
                System.Console.WriteLine("Total Profit = " + cplex.ObjValue);

                System.Console.WriteLine();
                System.Console.WriteLine("\tp\tt\tMake\tInv\tSell");

                for (int p = 0; p < _nProd; p++)
                {
                    for (int t = 0; t < _nTime; t++)
                    {
                        System.Console.WriteLine("\t" + p + "\t" + t + "\t" + cplex.GetValue(Make[p][t]) +
                                                 "\t" + cplex.GetValue(Inv[p][t]) + "\t" + cplex.GetValue(Sell[p][t]));
                    }
                }
            }
            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);
        }
    }
Exemple #16
0
    public static void Main(string[] args)
    {
        try {
         string filename = "../../../../examples/data/steel.dat";
         if ( args.Length > 0 )
            filename = args[0];
         ReadData(filename);

         Cplex cplex = new Cplex();

         // VARIABLES
         INumVar[][] Make = new INumVar[_nProd][];
         for (int p = 0; p < _nProd; p++) {
            Make[p] = cplex.NumVarArray(_nTime, 0.0, System.Double.MaxValue);
         }

         INumVar[][] Inv = new INumVar[_nProd][];
         for (int p = 0; p < _nProd; p++) {
            Inv[p] = cplex.NumVarArray(_nTime, 0.0, System.Double.MaxValue);
         }

         INumVar[][] Sell = new INumVar[_nProd][];
         for (int p = 0; p < _nProd; p++) {
             Sell[p] = new INumVar[_nTime];
            for (int t = 0; t < _nTime; t++) {
               Sell[p][t] = cplex.NumVar(0.0, _market[p][t]);
            }
         }

         // OBJECTIVE
         ILinearNumExpr TotalRevenue  = cplex.LinearNumExpr();
         ILinearNumExpr TotalProdCost = cplex.LinearNumExpr();
         ILinearNumExpr TotalInvCost  = cplex.LinearNumExpr();

         for (int p = 0; p < _nProd; p++) {
            for (int t = 1; t < _nTime; t++) {
               TotalRevenue.AddTerm (_revenue[p][t], Sell[p][t]);
               TotalProdCost.AddTerm(_prodCost[p], Make[p][t]);
               TotalInvCost.AddTerm (_invCost[p], Inv[p][t]);
            }
         }

         cplex.AddMaximize(cplex.Diff(TotalRevenue,
                                      cplex.Sum(TotalProdCost, TotalInvCost)));

         // TIME AVAILABILITY CONSTRAINTS

         for (int t = 0; t < _nTime; t++) {
            ILinearNumExpr availExpr = cplex.LinearNumExpr();
            for (int p = 0; p < _nProd; p++) {
               availExpr.AddTerm(1.0/_rate[p], Make[p][t]);
            }
            cplex.AddLe(availExpr, _avail[t]);
         }

         // MATERIAL BALANCE CONSTRAINTS

         for (int p = 0; p < _nProd; p++) {
            cplex.AddEq(cplex.Sum(Make[p][0], _inv0[p]),
                        cplex.Sum(Sell[p][0], Inv[p][0]));
            for (int t = 1; t < _nTime; t++) {
               cplex.AddEq(cplex.Sum(Make[p][t], Inv[p][t-1]),
                           cplex.Sum(Sell[p][t], Inv[p][t]));
            }
         }

         cplex.ExportModel("steel.lp");

         if ( cplex.Solve() ) {
            System.Console.WriteLine("Solution status = " + cplex.GetStatus());
            System.Console.WriteLine();
            System.Console.WriteLine("Total Profit = " + cplex.ObjValue);

            System.Console.WriteLine();
            System.Console.WriteLine("\tp\tt\tMake\tInv\tSell");

            for (int p = 0; p < _nProd; p++) {
               for (int t = 0; t < _nTime; t++) {
                  System.Console.WriteLine("\t" + p +"\t" + t +"\t" + cplex.GetValue(Make[p][t]) +
                                           "\t" + cplex.GetValue(Inv[p][t]) +"\t" + cplex.GetValue(Sell[p][t]));
               }
            }
         }
         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);
          }
    }
Exemple #17
0
        //A quadratic interger program for graph matching,
        //When tuned with the right similarity function it can represent the GED problem.
        // See Pattern Reocgnition Paper paper On the unification of graph matching and graph edit distance paper.
        //The directed version has not been tested yet
        public override void QAPGMGED()
        {
            //some important variables
            int nbNode1       = graph1.ListNodes.Count;
            int nbNode2       = graph2.ListNodes.Count;
            int nbvar         = nbNode1 * nbNode2; // number of variables
            int nbcontraintes = nbNode1 + nbNode2; // number of constraints

            Graphs.Label nodeepslabel;

            //Adjacency matrices
            MatrixLibrary.Matrix adj1 = graph1.calculateAdjacencyMatrix();
            MatrixLibrary.Matrix adj2 = graph2.calculateAdjacencyMatrix();
            //Similarity matrix
            Double[,] S = new Double[nbvar, nbvar];

            //Creation of the Similarity matrix
            //4 for loops integrated
            int countrow = -1;

            for (int i = 0; i < nbNode1; i++)
            {
                Node nodei = graph1.ListNodes[i];
                for (int k = 0; k < nbNode2; k++)
                {
                    Node nodek = graph2.ListNodes[k];
                    countrow = countrow + 1;
                    int countcol = -1;
                    for (int j = 0; j < nbNode1; j++)
                    {
                        Node nodej = graph1.ListNodes[j];
                        for (int l = 0; l < nbNode2; l++)
                        {
                            Node nodel = graph2.ListNodes[l];
                            countcol = countcol + 1;
                            if (i == j && k == l) // Similarity between nodes
                            {
                                Type   typeLabel = nodei.Label.GetType();
                                object obj       = Activator.CreateInstance(typeLabel);
                                nodeepslabel    = (Graphs.Label)obj;
                                nodeepslabel.Id = ConstantsAC.EPS_ID;

                                double costsub = nodei.Label.dissimilarity(nodek.Label);
                                double costdel = nodei.Label.dissimilarity(nodeepslabel);
                                double costins = nodeepslabel.dissimilarity(nodek.Label);
                                double cost    = costsub - costdel - costins;
                                cost *= -1;

                                S[countrow, countcol] = cost;
                            }
                            else // Similarity between edges
                            {
                                int connect1 = (int)adj1[i, j];
                                int connect2 = (int)adj2[k, l];
                                if (connect1 == 1 && connect2 == 1) // Two edges are connected
                                {
                                    Edge ij = findedge(nodei, nodej);
                                    Edge kl = findedge(nodek, nodel);


                                    Type   typeLabel = ij.Label.GetType();
                                    object obj       = Activator.CreateInstance(typeLabel);
                                    nodeepslabel    = (Graphs.Label)obj;
                                    nodeepslabel.Id = ConstantsAC.EPS_ID;

                                    double costsub = ij.Label.dissimilarity(kl.Label);
                                    double costdel = ij.Label.dissimilarity(nodeepslabel);
                                    double costins = nodeepslabel.dissimilarity(kl.Label);
                                    double cost    = costsub - costdel - costins;
                                    cost *= -1;
                                    //cost *= 0.5;
                                    S[countrow, countcol] = cost;
                                }
                            }
                        }
                    }
                }
            }


            //We compute the constant that represents the
            //deletion and insertion of the nodes and edges

            //deletions of the nodes of g1
            double constante = 0;

            for (int i = 1; i <= nbNode1; i++)
            {
                Type   typeLabel = graph1.ListNodes[i - 1].Label.GetType();
                object obj       = Activator.CreateInstance(typeLabel);
                nodeepslabel    = (Graphs.Label)obj;
                nodeepslabel.Id = ConstantsAC.EPS_ID;
                constante      += (graph1.ListNodes[i - 1].Label).dissimilarity(nodeepslabel);
            }

            //deletions of the edges of g1
            for (int ij = 1; ij <= nbEdge1; ij++)
            {
                Type   typeLabel = graph1.ListEdges[ij - 1].Label.GetType();
                object obj       = Activator.CreateInstance(typeLabel);
                nodeepslabel    = (Graphs.Label)obj;
                nodeepslabel.Id = ConstantsAC.EPS_ID;
                double costEdge = (graph1.ListEdges[ij - 1].Label).dissimilarity(nodeepslabel);
                constante += costEdge;
            }

            //insertions of the nodes of g2
            for (int k = 1; k <= nbNode2; k++)
            {
                Type   typeLabel = graph2.ListNodes[k - 1].Label.GetType();
                object obj       = Activator.CreateInstance(typeLabel);
                nodeepslabel    = (Graphs.Label)obj;
                nodeepslabel.Id = ConstantsAC.EPS_ID;
                constante      += (graph2.ListNodes[k - 1].Label).dissimilarity(nodeepslabel);
            }

            //insertions of the edges of g2
            for (int kl = 1; kl <= nbEdge2; kl++)
            {
                Type   typeLabel = graph2.ListEdges[kl - 1].Label.GetType();
                object obj       = Activator.CreateInstance(typeLabel);
                nodeepslabel    = (Graphs.Label)obj;
                nodeepslabel.Id = ConstantsAC.EPS_ID;
                double costEdge = (graph2.ListEdges[kl - 1].Label).dissimilarity(nodeepslabel);
                constante += costEdge;
            }

            // the number of variables is the number of columns
            int nbCols = nbvar;
            // the number of constraints is the number of rows
            int           nbRows      = nbcontraintes;
            List <string> colNameList = new List <string>();


            //We create the name of the vrariables for all couples of nodes in g1 and g2
            for (int i = 0; i < nbNode1; i++)
            {
                for (int k = 0; k < nbNode2; k++)
                {
                    colNameList.Add("x_" + graph1.ListNodes[i].Id + "," + graph2.ListNodes[k].Id + "");
                }
            }
            try
            {
                cplex = new Cplex();                                         // creation du modèle CPLEX

                this.ilpMatrix = cplex.AddLPMatrix();                        // matrice du pb (initialisée à 0 colonnes et 0 lignes)

                ColumnArray colonnes = cplex.ColumnArray(ilpMatrix, nbCols); // définition des variables-colonnes du pb

                // ajout des variables-colonnes dans la matrice du pb
                // y is a vector
                INumVar[] y = cplex.NumVarArray(colonnes, 0, 1, NumVarType.Bool, colNameList.ToArray());


                #region création fonction objectif

                // CALCUL DES COEFFICIENTS
                // We create the ojective function
                INumExpr[] coeffs_expr = new INumExpr[nbvar * nbvar]; // vecteur des coeffs des coûts des arrêtes

                int count = 0;
                for (int ik = 0; ik < nbvar; ik++)
                {
                    for (int jl = 0; jl < nbvar; jl++)
                    {
                        coeffs_expr[count] = cplex.Prod(y[ik], y[jl]);
                        coeffs_expr[count] = cplex.Prod(S[ik, jl], coeffs_expr[count]);
                        count = count + 1;
                    }
                }
                INumExpr ff = cplex.Sum(coeffs_expr);
                INumExpr gg = cplex.Sum(ff, cplex.Constant(-constante));
                cplex.AddMaximize(gg);
                #endregion


                #region définition des contraintes du pb

                // We create the constraints

                // The sum of x variables by rows

                for (int i = 0; i < nbNode1; i++)
                {
                    INumVar[] sommeLignes = new INumVar[nbNode2];
                    for (int k = 0; k < nbNode2; k++)
                    {
                        string nameVarik = "x_" + i + "," + k;
                        int    indexik   = SolverCPLEX.GetIndexByName(y, nameVarik);
                        sommeLignes[k] = y[indexik];
                    }
                    cplex.AddLe(cplex.Sum(sommeLignes), 1);
                }

                // The sum of x variables by columns
                for (int k = 0; k < nbNode2; k++)
                {
                    INumVar[] sommeLignes = new INumVar[nbNode1];
                    for (int i = 0; i < nbNode1; i++)
                    {
                        string nameVarik = "x_" + i + "," + k;
                        int    indexik   = SolverCPLEX.GetIndexByName(y, nameVarik);
                        sommeLignes[i] = y[indexik];
                    }
                    cplex.AddLe(cplex.Sum(sommeLignes), 1);
                }



                #endregion
            }
            catch (ILOG.Concert.Exception e)
            {
                System.Console.WriteLine("Concert exception `" + e + "` caught");
            }
        }
Exemple #18
0
        static void Main(string[] args)
        {
            // Portfolio asset daily price data:
            var assets = new[] { "A", "B", "C" };
            var prices = new double[][] {
                new double[] { .02, .03, .02, .05 },
                new double[] { .01, .01, .05, .01 },
                new double[] { .1, .05, .04, .02 },
            };
            // Pre-process data
            var covmat = CovarianceMatrix(prices);

            DisplayCovariance(covmat);
            var expReturns = AssetReturns(prices);

            DisplayReturns(assets, expReturns);
            var rho = 0.05;

            // Create LP model

            try
            {
                Cplex cplex = new Cplex();

                // Weights bounded 0 <= weight <= 1.0
                var weights = cplex.NumVarArray(assets.Length, 0, 1.0);

                // x = weights.
                // Expected (mean) return of portfolio: ∑ᵢ x[i]*assetReturn[i]
                var expRet = cplex.ScalProd(expReturns, weights);

                // Portfolio variance : xᵀ∑x (matrix form of bi-linear: ∑ᵢ∑ⱼ x[i]*x[j]*cov(i,j)
                // where ∑ is the covariance matrix m*m of m assets.
                var pvar = cplex.QuadNumExpr();
                for (int i = 0; i < assets.Length; ++i)
                {
                    for (int j = 0; j < assets.Length; ++j)
                    {
                        pvar.AddTerm(covmat[i][j], weights[i], weights[j]);
                    }
                }

                // Objective (maximize): portfolio return  - (Rho/2) * portfolio variance.
                // Where 0 <= Rho <= 1 is the desired risk tolerance.
                var obj = cplex.Diff(expRet, cplex.Prod(rho / 2, pvar));

                cplex.AddMaximize(obj);

                // Subject to:
                // Sum of weights <= 1.0
                cplex.AddEq(cplex.Sum(weights), 1.0);

                // Exports model definition to readable LP format
                cplex.ExportModel(@"c:\users\mike\cplexfin.lp");

                // Solve and print results
                if (cplex.Solve())
                {
                    var w = new double[weights.Length];
                    Console.WriteLine("\nResulting Weights:");
                    for (int i = 0; i < weights.Length; i++)
                    {
                        Console.WriteLine($"{i + 1} : {cplex.GetValue(weights[i]) * 100:0.0}%");
                        w[i] = cplex.GetValue(weights[i]);
                    }
                    var totReturn   = WeightedReturn(w, expReturns);
                    var totVariance = PortfolioVariance(w, covmat);
                    Console.WriteLine($"Total Return: {totReturn:0.00}, Total Variance: {totVariance:0.0000}");
                }

                cplex.End();
            }
            catch (ILOG.Concert.Exception e)
            {
                System.Console.WriteLine("Concert exception caught: " + e);
            }

            Console.WriteLine("Press any key to quit.");
            Console.ReadKey();
        }
Exemple #19
0
        /// <summary>
        /// Getting maximum congruency for naming parameter sets A or B. Linear Programming optimization model.
        /// Eq. (4) and Table II in DOI:10.1109/CEC.2019.8790261
        /// The matrices need to be manually entered here in the script (cTopA, cTopB, cBtmA, cBtmB)
        /// </summary>
        internal static void IdentifyTwoBestParameterSets(string caseSolver)
        {
            Cplex cpl = new Cplex();

            int N = 7;

            //string caseSolver = "ES"; //"SGA" (default), "ES", "PSO", "FIPS"

            int[] cTopA;
            int[] cTopB;
            int[] cBtmA;
            int[] cBtmB;
            switch (caseSolver)
            {
            default:
                cTopA = new int[] { 11, 1, 1, 13, 0, 0, 2 };
                cTopB = new int[] { 0, 5, 3, 0, 5, 5, 5 };
                cBtmA = new int[] { 2, 12, 12, 0, 14, 14, 9 };
                cBtmB = new int[] { 4, 0, 1, 4, 0, 0, 0 };
                break;

            case "ES":
                cTopA = new int[] { 4, 6, 9, 3, 11, 11, 5 };
                cTopB = new int[] { 2, 3, 1, 3, 1, 3, 3 };
                cBtmA = new int[] { 4, 5, 2, 8, 0, 0, 6 };
                cBtmB = new int[] { 3, 1, 3, 2, 5, 3, 2 };
                break;

            case "PSO":
                cTopA = new int[] { 1, 3, 2, 3, 3, 7, 5 };
                cTopB = new int[] { 12, 11, 3, 1, 7, 8, 5 };
                cBtmA = new int[] { 7, 5, 6, 5, 5, 1, 3 };
                cBtmB = new int[] { 0, 1, 9, 11, 5, 4, 7 };
                break;

            case "FIPS":
                cTopA = new int[] { 6, 6, 7, 3, 5, 0, 8 };
                cTopB = new int[] { 4, 6, 6, 9, 5, 9, 1 };
                cBtmA = new int[] { 4, 4, 3, 7, 5, 10, 2 };
                cBtmB = new int[] { 6, 4, 4, 1, 5, 1, 9 };
                break;
            }


            INumVar[]      xTopA = new INumVar[N];
            INumVar[]      xBtmB = new INumVar[N];
            INumVar[]      xTopB = new INumVar[N];
            INumVar[]      xBtmA = new INumVar[N];
            ILinearNumExpr value = cpl.LinearNumExpr();

            for (int n = 0; n < N; n++)
            {
                xTopA[n] = cpl.BoolVar();
                xBtmB[n] = cpl.BoolVar();
                xTopB[n] = cpl.BoolVar();
                xBtmA[n] = cpl.BoolVar();
                cpl.AddEq(cpl.Sum(xTopB[n], xTopA[n]), 1);
                cpl.AddEq(cpl.Sum(xBtmA[n], xBtmB[n]), 1);
                cpl.AddEq(cpl.Sum(xTopA[n], xBtmA[n]), 1);
                cpl.AddEq(cpl.Sum(xTopB[n], xBtmB[n]), 1);
                value.AddTerm(xTopA[n], cTopA[n]);
                value.AddTerm(xTopB[n], cTopB[n]);
                value.AddTerm(xBtmA[n], cBtmA[n]);
                value.AddTerm(xBtmB[n], cBtmB[n]);
            }

            cpl.AddMaximize(value);
            cpl.Solve();

            Console.WriteLine("Parameter Grouping for Solver: {0}", caseSolver);
            for (int n = 0; n < N; n++)
            {
                Console.WriteLine("n: {0}", n);
                Console.WriteLine("xtopA: ;{0};, _____, xTopB: ;{1};", cpl.GetValue(xTopA[n]), cpl.GetValue(xTopB[n]));
                Console.WriteLine("xbtmB: ;{0};, _____, xBtmA: ;{1};", cpl.GetValue(xBtmB[n]), cpl.GetValue(xBtmA[n]));
            }
            Console.WriteLine("cost: {0}", cpl.GetObjValue());
            Console.ReadKey();
        }
        static void Main(string[] args)
        {
            double BinCap = 0;
            var    dict   = InputReader.ReadDataFile(ref BinCap);

            Cplex cplex = new Cplex();
            Dictionary <string, INumVar> dictvariables   = new Dictionary <string, INumVar>();
            Dictionary <string, IRange>  dictconstraints = new Dictionary <string, IRange>();
            IObjective objective = cplex.AddMinimize();

            foreach (var vari in dict.Keys)
            {
                var cname = "C" + vari;
                dictconstraints.Add(cname, cplex.AddRange(1, Int32.MaxValue, cname));
            }

            Dictionary <int, Set> InitialSets = new Dictionary <int, Set>();;

            InitialSets.Add(1, new Set(new List <int> {
                1, 5
            }));
            InitialSets.Add(2, new Set(new List <int> {
                2, 5
            }));
            InitialSets.Add(3, new Set(new List <int> {
                3, 5
            }));
            InitialSets.Add(4, new Set(new List <int> {
                4, 5
            }));

            //Add intial sets to the model
            foreach (var vari in InitialSets)
            {
                var    setID  = vari.Key.ToString();
                Column VarSet = cplex.Column(objective, 1);
                foreach (var members in vari.Value.member)
                {
                    var cname = "C" + members;
                    VarSet = VarSet.And(cplex.Column(dictconstraints[cname], 1));
                }

                dictvariables.Add(setID, cplex.NumVar(VarSet, 0, 1, NumVarType.Float));
            }
            cplex.Solve();
            var duals    = getDuals(cplex, dictconstraints);
            var solution = getSolution(cplex, dictvariables);

            Console.WriteLine("The objective value is {0}", cplex.GetObjValue());

            int piter     = 0;
            int fixediter = 0;
            Dictionary <string, INumVar> Fixedvar = new Dictionary <string, INumVar>();

            while (true)
            {
                //Formulate Pricing Problem
                Cplex      pcplex     = new Cplex();
                IObjective pobjective = pcplex.AddMaximize();
                piter++;
                //Add Bin Capacity Constraint
                IRange Knapsack = pcplex.AddRange(0, BinCap, "Bin");
                Dictionary <string, INumVar> pdictvar = new Dictionary <string, INumVar>();
                foreach (var vari in dict.Keys)
                {
                    var    varname  = vari.ToString();
                    var    objcoeff = duals["C" + varname];
                    Column item     = pcplex.Column(pobjective, objcoeff);
                    item = item.And(pcplex.Column(Knapsack, dict[vari]));
                    pdictvar.Add(varname, pcplex.NumVar(item, 0, 1, NumVarType.Int));
                }

                pcplex.Solve();
                if (pcplex.GetObjValue() > 1)
                {
                    Console.WriteLine("Pricing Iteration: {0} and obj value is {1} ", piter, pcplex.GetObjValue());
                    var        psolution = getSolution(pcplex, pdictvar);
                    List <int> sol       = new List <int>();
                    foreach (var vari in psolution.Keys)
                    {
                        sol.Add(Convert.ToInt32(vari));
                    }
                    InitialSets.Add(InitialSets.Count + 1, new Set(sol));

                    var    setID   = (InitialSets.Count).ToString();
                    Column VarSet1 = cplex.Column(objective, 1);
                    foreach (var members in sol)
                    {
                        var cname = "C" + members;
                        VarSet1 = VarSet1.And(cplex.Column(dictconstraints[cname], 1));
                    }

                    dictvariables.Add(setID, cplex.NumVar(VarSet1, 0, 1, NumVarType.Float));

                    cplex.Solve();
                    Console.WriteLine("The objective value of cplex after adding column  is {0}", cplex.GetObjValue());
                    duals    = getDuals(cplex, dictconstraints);
                    solution = getSolution(cplex, dictvariables);
                }
                else
                {
                    fixediter++;
                    bool fixedsomething = false;
                    //fix variables above 0.5
                    foreach (var val in solution)
                    {
                        if (val.Value > 0.5 && !Fixedvar.ContainsKey(val.Key))
                        {
                            Fixedvar.Add(val.Key, dictvariables[val.Key]);
                            dictvariables[val.Key].LB = 1;
                            fixedsomething            = true;
                        }
                    }
                    if (!fixedsomething)
                    {
                        break;
                    }
                    cplex.Solve();
                    Console.WriteLine("The Fixing iterations is {0}", cplex.GetObjValue());
                    duals = getDuals(cplex, dictconstraints);
                }
            }

            foreach (var vari in Fixedvar.Values)
            {
                vari.LB = 0;
            }
            IConversion IP = cplex.Conversion(dictvariables.Values.ToArray(), NumVarType.Int);

            cplex.Add(IP);
            cplex.SetParam(Cplex.DoubleParam.TiLim, 600);
            cplex.Solve();

            solution = getSolution(cplex, dictvariables);
            Console.WriteLine("The objective value is {0}", cplex.GetObjValue());
        }
Exemple #21
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);
      }
   }
        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}轮求解结束--------------");
            }
Exemple #23
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);
        }
    }
Exemple #24
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();
        }
Exemple #25
0
        static void Main(string[] args)
        {
            try
            {
                graphFile = args[0];
                int   timeLimit = Convert.ToInt32(args[1]);
                Timer myTimer   = new Timer();
                myTimer.Start();
                myTimer.Interval = timeLimit * 1000;
                startTime        = DateTime.Now;
                myTimer.Elapsed += MyTimer_Elapsed;
                MyGraph graph            = new MyGraph(graphFile, "DIMACS");
                int     maxTime          = 100;
                int     targetCliqueSize = graph.NumberNodes;
                //Эвристически найдем хотя бы что-то похожее на максимальную клику (в пределах 5% ошибки - чтобы вернуть, если не успеет обсчитаться основной обход)
                maxClique = FindMaxClique(graph, maxTime, targetCliqueSize);
                int ub = maxClique.Count;
                Bound = ub;
                List <List <int> > clique = new List <List <int> >();
                //Сортируем вершины по числу соседей, будем вызывать алгоритм для тех вершин, у которых количество соседей наибольшее
                Dictionary <int, int> nodeAndNeighbors = new Dictionary <int, int>();
                for (int i = 0; i < graph.NumberNodes; ++i)
                {
                    int numberNeighbors = graph.NumberNeighbors(i);
                    nodeAndNeighbors.Add(i, numberNeighbors);
                }
                //Сортируем вершины по уменьшению количества соседей
                nodeAndNeighbors = nodeAndNeighbors.OrderByDescending(pair => pair.Value).ToDictionary(pair => pair.Key, pair => pair.Value);
                List <int> colors = new List <int>()
                {
                    1
                };
                //Раскраска графа
                int top = (from v in nodeAndNeighbors.Keys.ToList() select v).ToList <int>()[0];
                Dictionary <int, int> colorizedGraph = new Dictionary <int, int>();
                //Раскрасим граф
                colorizedGraph = colorize(nodeAndNeighbors.Keys.ToList <int>(), graph);
                int cntr = 0;
                //Зададим базовую модель
                Cplex       cplex = new Cplex();
                IRange[][]  rng   = new IRange[1][];
                INumVar[][] var   = new INumVar[1][];
                rng[0] = new IRange[graph.NumberNodes * graph.NumberNodes];
                // add the objective function
                double[] objvals = new double[graph.NumberNodes];
                string[] varname = new string[graph.NumberNodes];
                for (int i = 0; i < graph.NumberNodes; i++)
                {
                    objvals[i] = 1.0;
                    varname[i] = "x" + (i + 1);
                }
                INumVar[] x = cplex.NumVarArray(graph.NumberNodes, 0.0, 1.0, varname);
                var[0] = x;
                //Ограничение, что х лежит от нуля до единицы задали при инициализации
                cplex.AddMaximize(cplex.ScalProd(x, objvals));
                //Получим номер максимального цвета = это количество цветов, в которые окрашен граф
                //Будем иметь в виду, что количество цветов - это верхняя оценка на размер клики, а найденная эвристически клика на первом этапе - нижняя оценка.
                int        colorCount     = colorizedGraph.Values.Max();
                List <int> colorizedNodes = new List <int>();
                int        pointer        = 1;
                //Добавим ограничение, что вершины, входящие в один цветовой класс, не связаны между собой
                for (int i = 1; i <= colorCount; ++i)
                {
                    colorizedNodes = (from t in colorizedGraph where t.Value == i select t.Key).ToList <int>();
                    if (colorizedNodes.Count() != 1)
                    {
                        INumExpr[] constraint = new INumExpr[colorizedNodes.Count()];
                        int        counter    = 0;
                        colorizedNodes.ForEach(node =>
                        {
                            constraint[counter] = cplex.Prod(1.0, x[node]);
                            counter++;
                        });
                        rng[0][pointer] = cplex.AddLe(cplex.Sum(constraint), 1.0, "c" + (pointer));
                        pointer++;
                    }
                }
                for (int i = 0; i < graph.NumberNodes; i++)
                {
                    for (int j = i + 1; j < graph.NumberNodes; j++)
                    {
                        if (!graph.AreAdjacent(i, j))
                        {
                            rng[0][pointer] = cplex.AddLe(cplex.Sum(cplex.Prod(1.0, x[i]), cplex.Prod(1.0, x[j])), 1.0, "c" + (pointer));
                            pointer++;
                        }
                    }
                }

                //------------------------------------------------------------------------
                //-----Пробуем решать задачу ровно до тех пор, пока не получим клику------
                //-----Помним про ограничения на размер клики-----------------------------
                int countOfConstraint = colorCount;
                globalClick = maxClique;
                Branching(cplex, x);
                cplex.End();
                ////Максимальная клика, которую можно найти для вершины - это количество различных цветов, в которые окрашены все ее соседи плюс она  сама
                //foreach (KeyValuePair<int,int> pair in nodeAndNeighbors)
                //{
                //        List<int> neighbors = graph.GetNeighbors(pair.Key);
                //        neighbors.Add(pair.Key);
                //        var cols = (from n in colorizedGraph where neighbors.Exists(t => t == n.Key) select n.Value).Distinct().ToList<int>();
                //        if (cols.Count() >= Bound && cols.Count() >= globalClick.Count())
                //        {
                //            clique.Add(new List<int>());
                //            List<int> cur = new List<int>();
                //            RecursiveSearch(pair.Key, ref cur, ref neighbors, graph);
                //            clique[cntr] = cur;
                //            cntr++;
                //        }
                //}
                TimeSpan time = (DateTime.Now - startTime);
                Console.WriteLine("Time to find " + time);
                Console.WriteLine(globalClick.Count());
                Console.WriteLine(String.Join(" ", globalClick));
                WriteResults(time, globalClick, false);
            }
            catch (System.Exception ex)
            {
                Console.WriteLine("Fatal: " + ex.Message);
                Console.WriteLine(ex.StackTrace);
                Console.ReadKey();
            }
        }