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); }
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("子问题无解"); } }
//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); }
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); }
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); } }
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); }
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); }
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); }
//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); }
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(); }
/// <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); }
public void AddObjective() { theModel.AddMaximize(theModel.Diff(theModel.ScalProd(LaneMargin, LoadedMoves), theModel.ScalProd(LaneCost, EmptyMoves))); }
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); } }
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); } }
//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"); } }
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(); }
/// <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()); }
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}轮求解结束--------------"); }
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); } }
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(); }
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(); } }