private void InitRCGModel() { SubModel.ClearModel(); h = SubModel.NumVarArray(Data.DS.Count, 0, double.MaxValue); r = SubModel.NumVarArray(Data.RS.Count, 0, double.MaxValue); constraint_sub2 = new IRange[Data.RS.Count]; subObject[0] = new INumExpr[Data.TimeHorizon]; subObject[1] = new INumExpr[Data.TimeHorizon]; #region 生成约束 //第一、四种约束 INumExpr expr1 = SubModel.NumExpr(); foreach (IMDPDecision d in Data.DS) { expr1 = SubModel.Sum(expr1, h[Data.DS.IndexOf(d)]);//SubModel.AddGe(h[aff.DS.IndexOf(d)], 0); } SubModel.AddEq(expr1, 1); //第二、三种约束 foreach (IALPResource re in Data.RS) { constraint_sub2[Data.RS.IndexOf(re)] = SubModel.AddLe(r[Data.RS.IndexOf(re)], (Data.InitialState as IALPState)[re]); INumExpr expr2 = SubModel.NumExpr(); foreach (IALPDecision a in Data.DS) { if (a.UseResource(re)) { expr2 = SubModel.Sum(expr2, h[Data.DS.IndexOf(a)]); } } expr2 = SubModel.Sum(expr2, SubModel.Prod(-1, r[Data.RS.IndexOf(re)])); SubModel.AddLe(expr2, 0); } #endregion #region 初始化目标函数第一部分 //Parallel.For(0, Data.TimeHorizon, t => for (int t = 0; t < Data.TimeHorizon; t++) { int iteration = t; Task ta = factory.StartNew(() => { subObject[0][iteration] = SubModel.NumExpr(); foreach (IMDPDecision a in Data.DS) { subObject[0][iteration] = SubModel.Sum(subObject[0][iteration], SubModel.Prod(Data.Rt(iteration, a), h[Data.DS.IndexOf(a)])); } }, cts.Token); tasks.Add(ta); } #endregion Task.WaitAll(tasks.ToArray()); tasks.Clear(); SubModel.SetOut(null); }
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(); }
// This function creates the following model: // Minimize // obj: x1 + x2 + x3 + x4 + x5 + x6 // Subject To // c1: x1 + x2 + x5 = 8 // c2: x3 + x5 + x6 = 10 // q1: [ -x1^2 + x2^2 + x3^2 ] <= 0 // q2: [ -x4^2 + x5^2 ] <= 0 // Bounds // x2 Free // x3 Free // x5 Free // End // which is a second order cone program in standard form. private static IObjective Createmodel(Cplex cplex, ICollection <INumVar> vars, ICollection <IRange> rngs, IDictionary <INumVar, IRange> cone) { System.Double pinf = System.Double.PositiveInfinity; System.Double ninf = System.Double.NegativeInfinity; INumVar x1 = cplex.NumVar(0, pinf, "x1"); INumVar x2 = cplex.NumVar(ninf, pinf, "x2"); INumVar x3 = cplex.NumVar(ninf, pinf, "x3"); INumVar x4 = cplex.NumVar(0, pinf, "x4"); INumVar x5 = cplex.NumVar(ninf, pinf, "x5"); INumVar x6 = cplex.NumVar(0, pinf, "x6"); IObjective obj = cplex.AddMinimize(cplex.Sum(cplex.Sum(cplex.Sum(x1, x2), cplex.Sum(x3, x4)), cplex.Sum(x5, x6)), "obj"); IRange c1 = cplex.AddEq(cplex.Sum(x1, cplex.Sum(x2, x5)), 8, "c1"); IRange c2 = cplex.AddEq(cplex.Sum(x3, cplex.Sum(x5, x6)), 10, "c2"); IRange q1 = cplex.AddLe(cplex.Sum(cplex.Prod(-1, cplex.Prod(x1, x1)), cplex.Sum(cplex.Prod(x2, x2), cplex.Prod(x3, x3))), 0, "q1"); cone[x1] = q1; cone[x2] = NOT_CONE_HEAD; cone[x3] = NOT_CONE_HEAD; IRange q2 = cplex.AddLe(cplex.Sum(cplex.Prod(-1, cplex.Prod(x4, x4)), cplex.Prod(x5, x5)), 0, "q2"); cone[x4] = q2; cone[x5] = NOT_CONE_HEAD; cone[x6] = NOT_IN_CONE; vars.Add(x1); vars.Add(x2); vars.Add(x3); vars.Add(x4); vars.Add(x5); vars.Add(x6); rngs.Add(c1); rngs.Add(c2); rngs.Add(q1); rngs.Add(q2); return(obj); }
private void InitRCGModel() { SubModel.ClearModel(); h = SubModel.NumVarArray(Data.DS.Count, 0, double.MaxValue); r = SubModel.NumVarArray(Data.RS.Count, 0, double.MaxValue); constraint_sub2 = new IRange[Data.RS.Count]; subObject[0] = new INumExpr[Data.TimeHorizon]; subObject[1] = new INumExpr[Data.TimeHorizon]; #region 生成约束 //第一、四种约束 INumExpr expr1 = SubModel.NumExpr(); foreach (IMDPDecision d in Data.DS) { expr1 = SubModel.Sum(expr1, h[Data.DS.IndexOf(d)]);//SubModel.AddGe(h[aff.DS.IndexOf(d)], 0); } SubModel.AddEq(expr1, 1); //第二、三种约束 foreach (IALPResource re in Data.RS) { constraint_sub2[Data.RS.IndexOf(re)] = SubModel.AddLe(r[Data.RS.IndexOf(re)], (Data.InitialState as IALPState)[re]); INumExpr expr2 = SubModel.NumExpr(); foreach (IALPDecision a in Data.DS) { if (a.UseResource(re)) { expr2 = SubModel.Sum(expr2, h[Data.DS.IndexOf(a)]); } } expr2 = SubModel.Sum(expr2, SubModel.Prod(-1, r[Data.RS.IndexOf(re)])); SubModel.AddLe(expr2, 0); } #endregion #region 初始化目标函数第一部分 Parallel.For(0, Data.TimeHorizon, t => //for (int t = 0; t < Data.TimeHorizon; t++) { subObject[0][t] = SubModel.NumExpr(); foreach (IMDPDecision a in Data.DS) { subObject[0][t] = SubModel.Sum(subObject[0][t], SubModel.Prod(Data.Rt(t, a), h[Data.DS.IndexOf(a)])); } }); #endregion SubModel.SetOut(null); }
public static void Main(string[] args) { try { Cplex cplex = new Cplex(); INumVar[] fused = cplex.BoolVarArray(_nbMachines); INumVar[] x = cplex.NumVarArray(_nbMachines, 0.0, System.Double.MaxValue); // Objective: minimize the sum of fixed and variable costs cplex.AddMinimize(cplex.Sum(cplex.ScalProd(_cost, x), cplex.ScalProd(fused, _fixedCost))); for (int i = 0; i < _nbMachines; i++) { // Constraint: respect capacity constraint on machine 'i' cplex.AddLe(x[i], _capacity[i]); // Constraint: only produce product on machine 'i' if it is 'used' // (to capture fixed cost of using machine 'i') cplex.AddLe(x[i], cplex.Prod(10000, fused[i])); } // Constraint: meet demand cplex.AddEq(cplex.Sum(x), _demand); if (cplex.Solve()) { System.Console.WriteLine("Solution status = " + cplex.GetStatus()); System.Console.WriteLine("Obj " + cplex.ObjValue); double eps = cplex.GetParam(Cplex.Param.MIP.Tolerances.Integrality); for (int i = 0; i < _nbMachines; i++) { if (cplex.GetValue(fused[i]) > eps) { System.Console.WriteLine("E" + i + " is used for " + cplex.GetValue(x[i])); } } System.Console.WriteLine(); System.Console.WriteLine("----------------------------------------"); } cplex.End(); } catch (ILOG.Concert.Exception exc) { System.Console.WriteLine("Concert exception '" + exc + "' caught"); } }
private void AddCplexLEqual(Cplex model, dc_FGPair fg, INumVar slack) { INumExpr fi = fg.f.AddExpression(model); INumExpr gi = fg.g.Minorize(model); model.AddLe(fi, model.Sum(gi, slack)); }
static bool HasTourElimination(Cplex cplex, Data data, IIntVar[][] x) { double[][] sol_x = new double[data.n][]; for (int i = 0; i < data.n; i++) { sol_x[i] = cplex.GetValues(x[i]); } //int shortestLenght = ShortestCicleInSelectedPaths(sol_x); int[] tour = FindSubTour(sol_x); if (tour.Length < data.n) { ILinearNumExpr sumx = cplex.LinearNumExpr(); for (int i = 0; i < tour.Length; i++) { for (int j = i + 1; j < tour.Length; j++) { sumx.AddTerm(1, x[tour[i]][tour[j]]); } } cplex.AddLazyConstraint(cplex.AddLe(cplex.Diff(sumx, (tour.Length + 1)), 0)); return(true); } else { return(false); } }
private void AddIndependentSetsConstraints() { var independentSets = GetIndependentSets(new List <GraphNode>(graph.Nodes)); var sets = independentSets.Values.Where(x => x.Count > 1); foreach (var set in sets) { var numExpr = cplex.NumExpr(); foreach (var node in set) { var curVar = numVars[node.Index - 1]; numExpr = cplex.Sum(numExpr, curVar); } cplex.AddLe(numExpr, 1); } }
public static void Main( string[] args ) { try { string filename = "../../../../examples/data/facility.dat"; if (args.Length > 0) filename = args[0]; ReadData(filename); Cplex cplex = new Cplex(); INumVar[] open = cplex.BoolVarArray(_nbLocations); INumVar[][] supply = new INumVar[_nbClients][]; for(int i = 0; i < _nbClients; i++) supply[i] = cplex.BoolVarArray(_nbLocations); for(int i = 0; i < _nbClients; i++) cplex.AddEq(cplex.Sum(supply[i]), 1); for(int j = 0; j < _nbLocations; j++) { ILinearNumExpr v = cplex.LinearNumExpr(); for(int i = 0; i < _nbClients; i++) v.AddTerm(1.0, supply[i][j]); cplex.AddLe(v, cplex.Prod(_capacity[j], open[j])); } ILinearNumExpr obj = cplex.ScalProd(_fixedCost, open); for(int i = 0; i < _nbClients; i++) obj.Add(cplex.ScalProd(_cost[i], supply[i])); cplex.AddMinimize(obj); if (cplex.Solve()) { System.Console.WriteLine("Solution status = " + cplex.GetStatus()); double tolerance = cplex.GetParam(Cplex.Param.MIP.Tolerances.Integrality); System.Console.WriteLine("Optimal value: " + cplex.ObjValue); for(int j = 0; j < _nbLocations; j++) { if (cplex.GetValue(open[j]) >= 1 - tolerance) { System.Console.Write("Facility " + j +" is open, it serves clients "); for(int i = 0; i < _nbClients; i++) if (cplex.GetValue(supply[i][j]) >= 1 - tolerance) System.Console.Write(" " + i); System.Console.WriteLine(); } } } 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 { Cplex cplex = new Cplex(); INumVar[] inside = cplex.NumVarArray(_nbProds, 10.0, Double.MaxValue); INumVar[] outside = cplex.NumVarArray(_nbProds, 0.0, Double.MaxValue); INumVar costVar = cplex.NumVar(0.0, Double.MaxValue); cplex.AddEq(costVar, cplex.Sum(cplex.ScalProd(inside, _insideCost), cplex.ScalProd(outside, _outsideCost))); IObjective obj = cplex.AddMinimize(costVar); // Must meet demand for each product for (int p = 0; p < _nbProds; p++) { cplex.AddEq(cplex.Sum(inside[p], outside[p]), _demand[p]); } // Must respect capacity constraint for each resource for (int r = 0; r < _nbResources; r++) { cplex.AddLe(cplex.ScalProd(_consumption[r], inside), _capacity[r]); } cplex.Solve(); if (cplex.GetStatus() != Cplex.Status.Optimal) { System.Console.WriteLine("No optimal solution found"); return; } // New constraint: cost must be no more than 10% over minimum double cost = cplex.ObjValue; costVar.UB = 1.1 * cost; // New objective: minimize outside production obj.Expr = cplex.Sum(outside); cplex.Solve(); System.Console.WriteLine("Solution status = " + cplex.GetStatus()); DisplayResults(cplex, costVar, inside, outside); System.Console.WriteLine("----------------------------------------"); cplex.End(); } catch (ILOG.Concert.Exception exc) { System.Console.WriteLine("Concert exception '" + exc + "' caught"); } }
public static void Main( string[] args ) { try { Cplex cplex = new Cplex(); INumVar[] fused = cplex.BoolVarArray(_nbMachines); INumVar[] x = cplex.NumVarArray(_nbMachines, 0.0, System.Double.MaxValue); // Objective: minimize the sum of fixed and variable costs cplex.AddMinimize(cplex.Sum(cplex.ScalProd(_cost, x), cplex.ScalProd(fused, _fixedCost))); for (int i = 0; i < _nbMachines; i++) { // Constraint: respect capacity constraint on machine 'i' cplex.AddLe(x[i], _capacity[i]); // Constraint: only produce product on machine 'i' if it is 'used' // (to capture fixed cost of using machine 'i') cplex.AddLe(x[i], cplex.Prod(10000, fused[i])); } // Constraint: meet demand cplex.AddEq(cplex.Sum(x), _demand); if ( cplex.Solve() ) { System.Console.WriteLine("Solution status = " + cplex.GetStatus()); System.Console.WriteLine("Obj " + cplex.ObjValue); double eps = cplex.GetParam(Cplex.Param.MIP.Tolerances.Integrality); for(int i = 0; i < _nbMachines; i++) if (cplex.GetValue(fused[i]) > eps) System.Console.WriteLine("E" + i + " is used for " + cplex.GetValue(x[i])); System.Console.WriteLine(); System.Console.WriteLine("----------------------------------------"); } cplex.End(); } catch (ILOG.Concert.Exception exc) { System.Console.WriteLine("Concert exception '" + exc + "' caught"); } }
/// <summary> /// Constraints for cargo - location coverage considerations. For example, TEX /// can have at most %55 of the cargo from a location /// </summary> private void Coverage() { for (int i = 0; i < N; i++) { var cargo = _cargoList[i]; for (int j = 0; j < M; j++) { var location = _locationList[j]; if (location.ContainsCargo(cargo)) { var rate = cargo.GetCoverageRate(); var forecast = location.GetForecast(); var constraint = _solver.LinearNumExpr(); constraint.AddTerm(x[i][j], 1); constraint.AddTerm(e[i][j], 1); var rhs = forecast * rate; _solver.AddLe(constraint, rhs); } } } }
public static void Main( string[] args ) { try { Cplex cplex = new Cplex(); INumVar[] inside = cplex.NumVarArray(_nbProds, 10.0, Double.MaxValue); INumVar[] outside = cplex.NumVarArray(_nbProds, 0.0, Double.MaxValue); INumVar costVar = cplex.NumVar(0.0, Double.MaxValue); cplex.AddEq(costVar, cplex.Sum(cplex.ScalProd(inside, _insideCost), cplex.ScalProd(outside, _outsideCost))); IObjective obj = cplex.AddMinimize(costVar); // Must meet demand for each product for(int p = 0; p < _nbProds; p++) cplex.AddEq(cplex.Sum(inside[p], outside[p]), _demand[p]); // Must respect capacity constraint for each resource for(int r = 0; r < _nbResources; r++) cplex.AddLe(cplex.ScalProd(_consumption[r], inside), _capacity[r]); cplex.Solve(); if ( cplex.GetStatus() != Cplex.Status.Optimal ) { System.Console.WriteLine("No optimal solution found"); return; } // New constraint: cost must be no more than 10% over minimum double cost = cplex.ObjValue; costVar.UB = 1.1 * cost; // New objective: minimize outside production obj.Expr = cplex.Sum(outside); cplex.Solve(); System.Console.WriteLine("Solution status = " + cplex.GetStatus()); DisplayResults(cplex, costVar, inside, outside); System.Console.WriteLine("----------------------------------------"); cplex.End(); } catch (ILOG.Concert.Exception exc) { System.Console.WriteLine("Concert exception '" + exc + "' caught"); } }
public static void Main(string[] args) { try { Cplex cplex = new Cplex(); INumVar[] inside = new INumVar[_nbProds]; INumVar[] outside = new INumVar[_nbProds]; IObjective obj = cplex.AddMinimize(); // Must meet demand for each product for (int p = 0; p < _nbProds; p++) { IRange demRange = cplex.AddRange(_demand[p], _demand[p]); inside[p] = cplex.NumVar(cplex.Column(obj, _insideCost[p]).And( cplex.Column(demRange, 1.0)), 0.0, System.Double.MaxValue); outside[p] = cplex.NumVar(cplex.Column(obj, _outsideCost[p]).And( cplex.Column(demRange, 1.0)), 0.0, System.Double.MaxValue); } // Must respect capacity constraint for each resource for (int r = 0; r < _nbResources; r++) { cplex.AddLe(cplex.ScalProd(_consumption[r], inside), _capacity[r]); } cplex.Solve(); if (!cplex.GetStatus().Equals(Cplex.Status.Optimal)) { System.Console.WriteLine("No optimal solution found"); return; } System.Console.WriteLine("Solution status = " + cplex.GetStatus()); DisplayResults(cplex, inside, outside); System.Console.WriteLine("----------------------------------------"); cplex.End(); } catch (ILOG.Concert.Exception exc) { System.Console.WriteLine("Concert exception '" + exc + "' caught"); } }
public static void Main( string[] args ) { try { Cplex cplex = new Cplex(); INumVar[] inside = new INumVar[_nbProds]; INumVar[] outside = new INumVar[_nbProds]; IObjective obj = cplex.AddMinimize(); // Must meet demand for each product for(int p = 0; p < _nbProds; p++) { IRange demRange = cplex.AddRange(_demand[p], _demand[p]); inside[p] = cplex.NumVar(cplex.Column(obj, _insideCost[p]).And( cplex.Column(demRange, 1.0)), 0.0, System.Double.MaxValue); outside[p] = cplex.NumVar(cplex.Column(obj, _outsideCost[p]).And( cplex.Column(demRange, 1.0)), 0.0, System.Double.MaxValue); } // Must respect capacity constraint for each resource for(int r = 0; r < _nbResources; r++) cplex.AddLe(cplex.ScalProd(_consumption[r], inside), _capacity[r]); cplex.Solve(); if ( !cplex.GetStatus().Equals(Cplex.Status.Optimal) ) { System.Console.WriteLine("No optimal solution found"); return; } System.Console.WriteLine("Solution status = " + cplex.GetStatus()); DisplayResults(cplex, inside, outside); System.Console.WriteLine("----------------------------------------"); cplex.End(); } catch (ILOG.Concert.Exception exc) { System.Console.WriteLine("Concert exception '" + exc + "' caught"); } }
public static void Main(string[] args) { try { string filename = "../../../../examples/data/facility.dat"; if (args.Length > 0) { filename = args[0]; } ReadData(filename); Cplex cplex = new Cplex(); INumVar[] open = cplex.BoolVarArray(_nbLocations); INumVar[][] supply = new INumVar[_nbClients][]; for (int i = 0; i < _nbClients; i++) { supply[i] = cplex.BoolVarArray(_nbLocations); } for (int i = 0; i < _nbClients; i++) { cplex.AddEq(cplex.Sum(supply[i]), 1); } for (int j = 0; j < _nbLocations; j++) { ILinearNumExpr v = cplex.LinearNumExpr(); for (int i = 0; i < _nbClients; i++) { v.AddTerm(1.0, supply[i][j]); } cplex.AddLe(v, cplex.Prod(_capacity[j], open[j])); } ILinearNumExpr obj = cplex.ScalProd(_fixedCost, open); for (int i = 0; i < _nbClients; i++) { obj.Add(cplex.ScalProd(_cost[i], supply[i])); } cplex.AddMinimize(obj); if (cplex.Solve()) { System.Console.WriteLine("Solution status = " + cplex.GetStatus()); double tolerance = cplex.GetParam(Cplex.Param.MIP.Tolerances.Integrality); System.Console.WriteLine("Optimal value: " + cplex.ObjValue); for (int j = 0; j < _nbLocations; j++) { if (cplex.GetValue(open[j]) >= 1 - tolerance) { System.Console.Write("Facility " + j + " is open, it serves clients "); for (int i = 0; i < _nbClients; i++) { if (cplex.GetValue(supply[i][j]) >= 1 - tolerance) { System.Console.Write(" " + i); } } System.Console.WriteLine(); } } } 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); } }
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"); } }
private double one_tsp(int dim, int [][] matrix, int [] path) { int[] lo = new int[dim]; for (int i = 0; i < dim; i++) { lo[i] = 1; } Cplex cplex = new Cplex(); NumVarType varType = NumVarType.Bool; INumVar[][] x = new INumVar[dim][]; for (int i = 0; i < dim; i++) { x[i] = cplex.NumVarArray(dim, 0, 1); } for (int i = 0; i < dim; i++) { for (int j = 0; j < dim; j++) { x[i][j] = cplex.BoolVar(); } } for (int j = 0; j < dim; j++) { INumExpr xcolSum = cplex.NumExpr(); for (int i = 0; i < dim; i++) { xcolSum = cplex.Sum(xcolSum, x[i][j]); } cplex.AddEq(lo[j], xcolSum); } varType = NumVarType.Float; INumVar[] u = new INumVar[dim]; for (int j = 0; j < dim; j++) { u[j] = cplex.NumVar(0, 100000); } for (int j = 1; j < dim; j++) { cplex.AddGe(u[j], 0); } for (int i = 1; i < dim; i++) { for (int j = 1; j < dim; j++) { if (i != j) { cplex.AddLe(cplex.Sum(cplex.Diff(u[i], u[j]), cplex.Prod(dim, x[i][j])), dim - 1); } } } for (int i = 0; i < dim; i++) { INumExpr xrowSum = cplex.NumExpr(); for (int j = 0; j < dim; j++) { xrowSum = cplex.Sum(xrowSum, x[i][j]); } cplex.AddEq(lo[i], xrowSum); } INumExpr costSum = cplex.NumExpr(); for (int i = 0; i < dim; i++) { for (int j = 0; j < dim; j++) { costSum = cplex.Sum(costSum, cplex.Prod(x[i][j], matrix[i][j])); } } cplex.AddMinimize(costSum); try { if (cplex.Solve()) { //MessageBox.Show("Solution status = " + cplex.GetStatus()); //MessageBox.Show("cost = " + cplex.ObjValue); int ipath = 0; int depo = -1; for (int i = dim - 1; i >= 0; i--) { for (int j = 0; j < dim; j++) { if (Convert.ToInt16(cplex.GetValue(x[i][j])) == 1) { depo = i; } } } path[ipath] = depo; ipath++; while (depo > -1) { for (int j = 0; j < dim; j++) { if (Convert.ToInt16(cplex.GetValue(x[path[ipath - 1]][j])) == 1) { path[ipath] = j; ipath++; if (j == depo) { depo = -1; } break; } } } return(cplex.ObjValue); } cplex.End(); } catch (ILOG.Concert.Exception ex) { System.Console.WriteLine("Concert Error: " + ex); } return(-1); }
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(); } }
/// <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 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); } }
/// <summary> /// The example's main function. /// </summary> public static void Main(string[] args) { int retval = 0; Cplex cplex = null; try { cplex = new Cplex(); /* ***************************************************************** * * * * S E T U P P R O B L E M * * * * We create the following problem: * * Minimize * * obj: 3x1 - x2 + 3x3 + 2x4 + x5 + 2x6 + 4x7 * * Subject To * * c1: x1 + x2 = 4 * * c2: x1 + x3 >= 3 * * c3: x6 + x7 <= 5 * * c4: -x1 + x7 >= -2 * * q1: [ -x1^2 + x2^2 ] <= 0 * * q2: [ 4.25x3^2 -2x3*x4 + 4.25x4^2 - 2x4*x5 + 4x5^2 ] + 2 x1 <= 9.0 * q3: [ x6^2 - x7^2 ] >= 4 * * Bounds * * 0 <= x1 <= 3 * * x2 Free * * 0 <= x3 <= 0.5 * * x4 Free * * x5 Free * * x7 Free * * End * * * * ***************************************************************** */ INumVar[] x = new INumVar[7]; x[0] = cplex.NumVar(0, 3, "x1"); x[1] = cplex.NumVar(System.Double.NegativeInfinity, System.Double.PositiveInfinity, "x2"); x[2] = cplex.NumVar(0, 0.5, "x3"); x[3] = cplex.NumVar(System.Double.NegativeInfinity, System.Double.PositiveInfinity, "x4"); x[4] = cplex.NumVar(System.Double.NegativeInfinity, System.Double.PositiveInfinity, "x5"); x[5] = cplex.NumVar(0, System.Double.PositiveInfinity, "x6"); x[6] = cplex.NumVar(System.Double.NegativeInfinity, System.Double.PositiveInfinity, "x7"); IRange[] linear = new IRange[4]; linear[0] = cplex.AddEq(cplex.Sum(x[0], x[1]), 4.0, "c1"); linear[1] = cplex.AddGe(cplex.Sum(x[0], x[2]), 3.0, "c2"); linear[2] = cplex.AddLe(cplex.Sum(x[5], x[6]), 5.0, "c3"); linear[3] = cplex.AddGe(cplex.Diff(x[6], x[0]), -2.0, "c4"); IRange[] quad = new IRange[3]; quad[0] = cplex.AddLe(cplex.Sum(cplex.Prod(-1, x[0], x[0]), cplex.Prod(x[1], x[1])), 0.0, "q1"); quad[1] = cplex.AddLe(cplex.Sum(cplex.Prod(4.25, x[2], x[2]), cplex.Prod(-2,x[2],x[3]), cplex.Prod(4.25,x[3],x[3]), cplex.Prod(-2,x[3],x[4]), cplex.Prod(4,x[4],x[4]), cplex.Prod(2,x[0])), 9.0, "q2"); quad[2] = cplex.AddGe(cplex.Sum(cplex.Prod(x[5], x[5]), cplex.Prod(-1, x[6], x[6])), 4.0, "q3"); cplex.AddMinimize(cplex.Sum(cplex.Prod(3.0, x[0]), cplex.Prod(-1.0, x[1]), cplex.Prod(3.0, x[2]), cplex.Prod(2.0, x[3]), cplex.Prod(1.0, x[4]), cplex.Prod(2.0, x[5]), cplex.Prod(4.0, x[6])), "obj"); /* ***************************************************************** * * * * O P T I M I Z E P R O B L E M * * * * ***************************************************************** */ cplex.SetParam(Cplex.Param.Barrier.QCPConvergeTol, 1e-10); cplex.Solve(); /* ***************************************************************** * * * * Q U E R Y S O L U T I O N * * * * ***************************************************************** */ double[] xval = cplex.GetValues(x); double[] slack = cplex.GetSlacks(linear); double[] qslack = cplex.GetSlacks(quad); double[] cpi = cplex.GetReducedCosts(x); double[] rpi = cplex.GetDuals(linear); double[] qpi = getqconstrmultipliers(cplex, xval, ZEROTOL, x, quad); // Also store solution in a dictionary so that we can look up // values by variable and not only by index. IDictionary<INumVar, System.Double> xmap = new Dictionary<INumVar, System.Double>(); for (int j = 0; j < x.Length; ++j) { xmap.Add(x[j], xval[j]); } /* ***************************************************************** * * * * C H E C K K K T C O N D I T I O N S * * * * Here we verify that the optimal solution computed by CPLEX * * (and the qpi[] values computed above) satisfy the KKT * * conditions. * * * * ***************************************************************** */ // Primal feasibility: This example is about duals so we skip this test. // Dual feasibility: We must verify // - for <= constraints (linear or quadratic) the dual // multiplier is non-positive. // - for >= constraints (linear or quadratic) the dual // multiplier is non-negative. for (int i = 0; i < linear.Length; ++i) { if (linear[i].LB <= System.Double.NegativeInfinity) { // <= constraint if (rpi[i] > ZEROTOL) throw new System.SystemException("Dual feasibility test failed for row " + linear[i] + ": " + rpi[i]); } else if (linear[i].UB >= System.Double.PositiveInfinity) { // >= constraint if (rpi[i] < -ZEROTOL) throw new System.SystemException("Dual feasibility test failed for row " + linear[i] + ": " + rpi[i]); } else { // nothing to do for equality constraints } } for (int i = 0; i < quad.Length; ++i) { if (quad[i].LB <= System.Double.NegativeInfinity) { // <= constraint if (qpi[i] > ZEROTOL) throw new System.SystemException("Dual feasibility test failed for quad " + quad[i] + ": " + qpi[i]); } else if (quad[i].UB >= System.Double.PositiveInfinity) { // >= constraint if (qpi[i] < -ZEROTOL) throw new System.SystemException("Dual feasibility test failed for quad " + quad[i] + ": " + qpi[i]); } else { // nothing to do for equality constraints } } // Complementary slackness. // For any constraint the product of primal slack and dual multiplier // must be 0. for (int i = 0; i < linear.Length; ++i) { if (System.Math.Abs(linear[i].UB - linear[i].LB) > ZEROTOL && System.Math.Abs(slack[i] * rpi[i]) > ZEROTOL) throw new System.SystemException("Complementary slackness test failed for row " + linear[i] + ": " + System.Math.Abs(slack[i] * rpi[i])); } for (int i = 0; i < quad.Length; ++i) { if (System.Math.Abs(quad[i].UB - quad[i].LB) > ZEROTOL && System.Math.Abs(qslack[i] * qpi[i]) > ZEROTOL) throw new System.SystemException("Complementary slackness test failed for quad " + quad[i] + ": " + System.Math.Abs(qslack[i] * qpi[i])); } for (int j = 0; j < x.Length; ++j) { if (x[j].UB < System.Double.PositiveInfinity) { double slk = x[j].UB - xval[j]; double dual = cpi[j] < -ZEROTOL ? cpi[j] : 0.0; if (System.Math.Abs(slk * dual) > ZEROTOL) throw new System.SystemException("Complementary slackness test failed for column " + x[j] + ": " + System.Math.Abs(slk * dual)); } if (x[j].LB > System.Double.NegativeInfinity) { double slk = xval[j] - x[j].LB; double dual = cpi[j] > ZEROTOL ? cpi[j] : 0.0; if (System.Math.Abs(slk * dual) > ZEROTOL) throw new System.SystemException("Complementary slackness test failed for column " + x[j] + ": " + System.Math.Abs(slk * dual)); } } // Stationarity. // The difference between objective function and gradient at optimal // solution multiplied by dual multipliers must be 0, i.E., for the // optimal solution x // 0 == c // - sum(r in rows) r'(x)*rpi[r] // - sum(q in quads) q'(x)*qpi[q] // - sum(c in cols) b'(x)*cpi[c] // where r' and q' are the derivatives of a row or quadratic constraint, // x is the optimal solution and rpi[r] and qpi[q] are the dual // multipliers for row r and quadratic constraint q. // b' is the derivative of a bound constraint and cpi[c] the dual bound // multiplier for column c. IDictionary<INumVar, System.Double> kktsum = new Dictionary<INumVar, System.Double>(); for (int j = 0; j < x.Length; ++j) { kktsum.Add(x[j], 0.0); } // Objective function. for (ILinearNumExprEnumerator it = ((ILinearNumExpr)cplex.GetObjective().Expr).GetLinearEnumerator(); it.MoveNext(); /* nothing */) { kktsum[it.NumVar] = it.Value; } // Linear constraints. // The derivative of a linear constraint ax - b (<)= 0 is just a. for (int i = 0; i < linear.Length; ++i) { for (ILinearNumExprEnumerator it = ((ILinearNumExpr)linear[i].Expr).GetLinearEnumerator(); it.MoveNext(); /* nothing */) { kktsum[it.NumVar] = kktsum[it.NumVar] - rpi[i] * it.Value; } } // Quadratic constraints. // The derivative of a constraint xQx + ax - b <= 0 is // Qx + Q'x + a. for (int i = 0; i < quad.Length; ++i) { for (ILinearNumExprEnumerator it = ((ILinearNumExpr)quad[i].Expr).GetLinearEnumerator(); it.MoveNext(); /* nothing */) { kktsum[it.NumVar] = kktsum[it.NumVar] - qpi[i] * it.Value; } for (IQuadNumExprEnumerator it = ((IQuadNumExpr)quad[i].Expr).GetQuadEnumerator(); it.MoveNext(); /* nothing */) { INumVar v1 = it.NumVar1; INumVar v2 = it.NumVar2; kktsum[v1] = kktsum[v1] - qpi[i] * xmap[v2] * it.Value; kktsum[v2] = kktsum[v2] - qpi[i] * xmap[v1] * it.Value; } } // Bounds. // The derivative for lower bounds is -1 and that for upper bounds // is 1. // CPLEX already returns dj with the appropriate sign so there is // no need to distinguish between different bound types here. for (int j = 0; j < x.Length; ++j) { kktsum[x[j]] = kktsum[x[j]] - cpi[j]; } foreach (INumVar v in x) { if (System.Math.Abs(kktsum[v]) > ZEROTOL) throw new System.SystemException("Stationarity test failed at " + v + ": " + System.Math.Abs(kktsum[v])); } // KKT conditions satisfied. Dump out the optimal solutions and // the dual values. System.Console.WriteLine("Optimal solution satisfies KKT conditions."); System.Console.WriteLine(" x[] = " + arrayToString(xval)); System.Console.WriteLine(" cpi[] = " + arrayToString(cpi)); System.Console.WriteLine(" rpi[] = " + arrayToString(rpi)); System.Console.WriteLine(" qpi[] = " + arrayToString(qpi)); } catch (ILOG.Concert.Exception e) { System.Console.WriteLine("IloException: " + e.Message); System.Console.WriteLine(e.StackTrace); retval = -1; } finally { if (cplex != null) cplex.End(); } System.Environment.Exit(retval); }
void solve() { Cplex Model = new Cplex(); // decision variables #region //x1-tjs (first stage t = 1),length of a collection period (in days) at collection point j during time period t //INumVar[][][] X1 = new INumVar[period][][]; //for (int i = 0; i < period; i++) //{ // X1[i] = new INumVar[cpoint][]; // for (int ii = 0; ii < cpoint; ii++) // { // X1[i][ii] = new INumVar[scenario]; // X1[i][ii] = Model.NumVarArray(scenario, 1, 7, NumVarType.Int); // } //} //x2-tpjks ,volume of products returned from collection point j to recycling center k during time period t INumVar[][][][][] X2 = new INumVar[period][][][][]; for (int a = 0; a < period; a++) { X2[a] = new INumVar[ptype][][][]; for (int aa = 0; aa < ptype; aa++) { X2[a][aa] = new INumVar[cpoint][][]; for (int bb = 0; bb < cpoint; bb++) { X2[a][aa][bb] = new INumVar[rcenter][]; for (int cc = 0; cc < rcenter; cc++) { X2[a][aa][bb][cc] = new INumVar[scenario]; X2[a][aa][bb][cc] = Model.NumVarArray(scenario, 0, System.Double.MaxValue, NumVarType.Int); } } } } //x3-tij ,Binary decision variable equals ‘1’ if customer i is allocated to collection point j during time period t and ‘0’ otherwise INumVar[][][] X3 = new INumVar[period][][]; for (int aa = 0; aa < period; aa++) { X3[aa] = new INumVar[customer][]; for (int bb = 0; bb < customer; bb++) { X3[aa][bb] = new INumVar[cpoint]; X3[aa][bb] = Model.NumVarArray(cpoint, 0.0, 1.0, NumVarType.Bool); } } //x4-tj ,Binary decision variable equals ‘1’ if collection point j is rented during time period t and ‘0’ otherwise INumVar[][] X4 = new INumVar[period][]; for (int i = 0; i < period; i++) { X4[i] = new INumVar[cpoint]; X4[i] = Model.NumVarArray(cpoint, 0.0, 1.0, NumVarType.Bool); } //x5-k ,Binary decision variable equals ‘1’ if recycling center k is established and ‘0’ otherwise INumVar[] X5 = new INumVar[rcenter]; X5 = Model.NumVarArray(rcenter, 0, 1, NumVarType.Bool); //x6 maximum capacity level option for recycling center k INumVar[] X6 = new INumVar[rcenter]; X6 = Model.NumVarArray(rcenter, 1, 3, NumVarType.Int); //X7-tjs Auxiliary variable x7 the frequency of recylce during a period //INumVar[][][] X7 = new INumVar[period][][]; //for (int i = 0; i < period; i++) //{ // X7[i] = new INumVar[cpoint][]; // for (int ii = 0; ii < cpoint; ii++) // { // X7[i][ii] = new INumVar[scenario]; // X7[i][ii] = Model.NumVarArray(scenario, 30, wday, NumVarType.Int); // } //} #endregion Double M = 100000; // constraints #region // formulation (4) INumExpr[] expr1 = new INumExpr[1]; for (int aa = 0; aa < period; aa++) { for (int bb = 0; bb < customer; bb++) { expr1[0] = X3[0][0][0]; for (int cc = 0; cc < cpoint; cc++) { expr1[0] = Model.Sum(expr1[0], X3[aa][bb][cc]); } expr1[0] = Model.Sum(expr1[0], Model.Prod(-1.0, X3[0][0][0])); Model.AddEq(expr1[0], 1); } } // formulation (5) INumExpr[] expr2 = new INumExpr[1]; INumExpr[] expr3 = new INumExpr[1]; for (int aa = 0; aa < period; aa++) { for (int bb = 0; bb < cpoint; bb++) { expr2[0] = X3[0][0][0]; expr3[0] = X4[0][0]; for (int cc = 0; cc < customer; cc++) { Model.Sum(expr2[0], X3[aa][cc][bb]); } expr2[0] = Model.Sum(expr2[0], Model.Prod(-1.0, X3[0][0][0])); expr3[0] = Model.Prod(M, X4[aa][bb]); expr3[0] = Model.Sum(expr3[0], Model.Prod(-1.0, X4[0][0])); Model.AddLe(expr2[0], expr3[0]); } } // formulation (6) INumExpr[] expr4 = new INumExpr[1]; INumExpr[] expr5 = new INumExpr[1]; INumExpr[] expr6 = new INumExpr[1]; for (int aa = 0; aa < period; aa++) { for (int cc = 0; cc < scenario; cc++) { for (int bb = 0; bb < cpoint; bb++) { expr5[0] = X3[0][0][0]; for (int dd = 0; dd < customer; dd++) { for (int ee = 0; ee < ptype; ee++) { expr5[0] = Model.Sum(expr5[0], Model.Prod(Model.Prod(r[dd, ee, aa, cc], X3[aa][dd][bb]), vlength)); } } expr5[0] = Model.Sum(expr5[0], Model.Prod(-1.0, X3[0][0][0])); expr6[0] = X2[0][0][0][0][0]; for (int ff = 0; ff < rcenter; ff++) { for (int ee = 0; ee < ptype; ee++) { expr6[0] = Model.Sum(expr6[0], X2[aa][ee][bb][ff][cc]); } } expr6[0] = Model.Sum(expr6[0], Model.Prod(-1.0, X2[0][0][0][0][0])); Model.AddEq(expr5[0], expr6[0]); } } } // formulation (7-1) INumExpr[] expr7 = new INumExpr[1]; for (int aa = 0; aa < period; aa++) { for (int bb = 0; bb < rcenter; bb++) { for (int cc = 0; cc < scenario; cc++) { for (int dd = 0; dd < cpoint; dd++) { expr7[0] = X2[0][0][0][0][0]; for (int ee = 0; ee < ptype; ee++) { expr7[0] = Model.Sum(expr7[0], X2[aa][ee][dd][bb][cc]); } expr7[0] = Model.Sum(expr7[0], Model.Prod(-1.0, X2[0][0][0][0][0])); Model.AddLe(expr7[0], Model.Prod(X5[bb], M)); } } } } // formulation (7-2) INumExpr[] expr71 = new INumExpr[1]; for (int aa = 0; aa < period; aa++) { for (int bb = 0; bb < rcenter; bb++) { for (int cc = 0; cc < scenario; cc++) { for (int dd = 0; dd < cpoint; dd++) { expr71[0] = X2[0][0][0][0][0]; for (int ee = 0; ee < ptype; ee++) { expr71[0] = Model.Sum(expr71[0], X2[aa][ee][dd][bb][cc]); } expr71[0] = Model.Sum(expr71[0], Model.Prod(-1.0, X2[0][0][0][0][0])); Model.AddLe(expr71[0], Model.Sum(Model.Prod(X6[bb], 1000), Model.Prod(Model.Sum(1, Model.Prod(X5[bb], -1)), M))); } } } } // formulation (8) INumExpr[] expr8 = new INumExpr[1]; for (int a = 0; a < period; a++) { expr8[0] = X4[0][0]; for (int b = 0; b < cpoint; b++) { expr8[0] = Model.Sum(expr8[0], X4[a][b]); } expr8[0] = Model.Sum(expr8[0], Model.Prod(-1.0, X4[0][0])); Model.AddGe(expr8[0], 1); } // formulation (9) INumExpr[] expr9 = new INumExpr[1]; expr9[0] = X5[0]; for (int a = 0; a < rcenter; a++) { expr9[0] = Model.Sum(expr9[0], X5[a]); } expr9[0] = Model.Sum(expr9[0], Model.Prod(-1.0, X5[0])); Model.AddGe(expr9[0], 1); // formulation (10) INumExpr[] expr10 = new INumExpr[1]; for (int a = 0; a < period; a++) { for (int b = 0; b < rcenter; b++) { for (int c = 0; c < scenario; c++) { for (int d = 0; d < cpoint; d++) { expr10[0] = X2[0][0][0][0][0]; for (int e = 0; e < ptype; e++) { expr10[0] = Model.Sum(expr10[0], X2[a][e][d][b][c]); } expr10[0] = Model.Sum(expr10[0], Model.Prod(-1.0, X2[0][0][0][0][0])); Model.AddGe(expr10[0], X5[b]); } } } } // formulation (11) for (int a = 0; a < period; a++) { for (int c = 0; c < customer; c++) { for (int b = 0; b < cpoint; b++) { Model.AddLe(Model.Prod(d1[c, b], X3[a][c][b]), l); } } } // formulation (12) for (int a = 0; a < period; a++) { for (int aa = 0; aa < ptype; aa++) { for (int b = 0; b < cpoint; b++) { for (int c = 0; c < rcenter; c++) { for (int d = 0; d < scenario; d++) { Model.AddGe(X2[a][aa][b][c][d], 0); } } } } } // #endregion //formulation (15) //formulation (1) objective function -1 // collection points rent cost INumExpr[] expr11 = new INumExpr[1]; for (int a = 0; a < period; a++) { expr11[0] = X4[0][0]; for (int b = 0; b < cpoint; b++) { expr11[0] = Model.Sum(expr11[0], Model.Prod(X4[a][b], e1[b])); } expr11[0] = Model.Sum(expr11[0], Model.Prod(-1.0, X4[0][0])); } INumExpr[] expr12 = new INumExpr[1]; INumExpr[] expr121 = new INumExpr[1]; for (int a = 0; a < period; a++) { for (int b = 0; b < rcenter; b++) { expr121[0] = X5[0]; for (int c = 0; c < cpoint; c++) { for (int d = 0; d < ptype; d++) { for (int e = 0; e < customer; e++) { expr12[0] = X2[0][0][0][0][0]; for (int f = 0; f < scenario; f++) { expr12[0] = Model.Sum(expr12[0], Model.Prod(Model.Prod(X2[a][d][c][b][f], e2[d, c, b]), wday / vlength)); } expr12[0] = Model.Sum(expr12[0], Model.Prod(-1.0, X2[0][0][0][0][0])); } } } expr121[0] = Model.Sum(expr121[0], Model.Prod(expr12[0], X5[b])); } } INumExpr[] expr13 = new INumExpr[1]; for (int a = 0; a < period; a++) { for (int b = 0; b < rcenter; b++) { expr13[0] = X5[0]; for (int bb = 0; bb < elevel; bb++) { expr13[0] = Model.Sum(expr13[0], Model.Prod(X5[b], e3[b, bb])); } expr13[0] = Model.Sum(expr13[0], Model.Prod(-1.0, X5[0])); } } Model.AddLe(Model.Prod(wday, Model.Sum(expr11[0], expr13[0])), e); //expr12[0], ,) // #endregion // //formulation (1) objective function -1 // #region INumExpr[] expr15 = new INumExpr[1]; expr15[0] = X4[0][0]; for (int i = 0; i < period; i++) { for (int ii = 0; ii < cpoint; ii++) { expr15[0] = Model.Sum(expr15[0], Model.Prod(a[ii], X4[i][ii])); } } expr15[0] = Model.Sum(expr15[0], Model.Prod(-1.0, X4[0][0])); // ok INumExpr[] expr17 = new INumExpr[1]; for (int a = 0; a < period; a++) { for (int aaa = 0; aaa < scenario; aaa++) { for (int bb = 0; bb < cpoint; bb++) { for (int bbb = 0; bbb < customer; bbb++) { expr17[0] = X3[0][0][0]; for (int aa = 0; aa < ptype; aa++) { expr17[0] = Model.Sum(expr17[0], Model.Prod(Model.Prod(r[bbb, aa, a, aaa] * b[aa], X3[a][bbb][bb]), (vlength + 1) * 0.5)); } expr17[0] = Model.Sum(expr17[0], Model.Prod(-1.0, X3[0][0][0])); } } } } INumExpr[] expr18 = new INumExpr[1]; INumExpr[] expr41 = new INumExpr[1]; expr18[0] = X5[0]; for (int a = 0; a < period; a++) { for (int aa = 0; aa < rcenter; aa++) { for (int bb = 0; bb < cpoint; bb++) { for (int b = 0; b < ptype; b++) { for (int aaa = 0; aaa < customer; aaa++) { expr41[0] = X2[0][0][0][0][0]; for (int bbb = 0; bbb < scenario; bbb++) { expr41[0] = Model.Sum(expr41[0], Model.Prod(Model.Prod(X2[a][b][bb][aa][bbb], z[bb, aa, b]), vlength)); } expr41[0] = Model.Sum(expr17[0], Model.Prod(-1.0, X2[0][0][0][0][0])); } } } expr18[0] = Model.Prod(expr41[0], X5[aa]); } } expr18[0] = Model.Sum(expr18[0], Model.Prod(-1.0, X5[0])); INumExpr[] expr19 = new INumExpr[1]; for (int i = 0; i < period; i++) { for (int ii = 0; ii < rcenter; ii++) { for (int iii = 0; iii < elevel; iii++) { expr19[0] = X5[0]; for (int iiii = 0; iiii < capacity; iiii++) { expr19[0] = Model.Sum(expr19[0], Model.Prod(q[ii, iii, iiii], X5[ii])); } } } } expr19[0] = Model.Sum(expr19[0], Model.Prod(-1.0, X5[0])); #endregion INumExpr[] expr21 = new INumExpr[1]; expr21[0] = Model.Prod(Model.Sum(expr15[0], Model.Prod(expr17[0], wday), expr18[0], expr19[0]), lambda); // INumExpr[] expr22 = new INumExpr[1]; expr22[0] = Model.Prod(Model.Sum(expr11[0], expr12[0], expr13[0]), delta); // Model.Prod(Model.Prod(wday, Model.Sum(expr11[0], expr12[0], expr13[0])),delta); Model.AddMinimize(Model.Sum(expr21[0], expr22[0])); // Model.ExportModel("RLND.LP"); if (Model.Solve()) { Console.WriteLine("statue=" + Model.GetStatus()); Console.WriteLine("obj=" + Model.ObjValue); Console.WriteLine("X2的结果"); for (int aa2 = 0; aa2 < period; aa2++) { for (int bb2 = 0; bb2 < ptype; bb2++) { for (int cc = 0; cc < cpoint; cc++) { for (int dd = 0; dd < rcenter; dd++) { for (int ee = 0; ee < scenario; ee++) { Console.WriteLine(Model.GetValue(X2[aa2][bb2][cc][dd][ee])); Console.WriteLine(); } } } } } //for (int a = 0; a < X6.Length; a++) //{ // Console.WriteLine("result[" + a + "] = " + Model.GetValue(X6[a])); //} //Console.WriteLine(); Model.End(); } else { Model.End(); Console.WriteLine(); Console.WriteLine("cannot be solved"); } }
//Handle the resolution method without callbacks static void Loop(Cplex cplex, Instance instance, Stopwatch clock, Process process, double perc, int numb) { int typeSol = 1; //epGap is false when EpGap parameter is at default bool epGap = false; //allEdges is true when all possible links have their upper bound to 1 bool allEdges = true; //Setting EpGap if a valid percentage is specified if (perc >= 0 && perc <= 1) { cplex.SetParam(Cplex.DoubleParam.EpGap, perc); epGap = true; typeSol = 0; } //numb is equal to -1 when all links upper bound are 1 if (numb != -1) { allEdges = false; typeSol = 0; } //Building the maximum # of links that involves each node INumVar[] x = Utility.BuildModel(cplex, instance, numb); //Allocating the correct space to store the optimal solution //Only links from node i to i with i < i are considered instance.BestSol = new double[(instance.NNodes - 1) * instance.NNodes / 2]; //Init buffers int[] relatedComponents = new int[instance.NNodes]; List <ILinearNumExpr> rcExpr = new List <ILinearNumExpr>(); List <int> bufferCoeffRC = new List <int>(); //Temporary variable double[] linksDistances = new double[(instance.NNodes - 1) * instance.NNodes / 2];; do { //When only one related component is found and ehuristics methods are active they are disabled if (rcExpr.Count == 1) { epGap = false; allEdges = true; cplex.SetParam(Cplex.DoubleParam.EpGap, 1e-06); Utility.ResetVariables(x); typeSol = 1; } //Cplex solves the current model cplex.Solve(); //Initializing the arrays used to eliminate the subtour Utility.InitCC(relatedComponents); rcExpr = new List <ILinearNumExpr>(); bufferCoeffRC = new List <int>(); //Init the StreamWriter for the current solution StreamWriter file = new StreamWriter(instance.InputFile + ".dat", false); //Storing the optimal value of the objective function instance.BestLb = cplex.ObjValue; //Blank line Console.WriteLine(); //Printing the optimal solution and the GNUPlot input file for (int i = 0; i < instance.NNodes; i++) { for (int j = i + 1; j < instance.NNodes; j++) { //Retriving the correct index position for the current link inside x int position = Utility.xPos(i, j, instance.NNodes); //Reading the optimal solution for the actual link (i,i) linksDistances[position] = cplex.GetValue(x[position]); //Only links in the optimal solution (coefficient = 1) are printed in the GNUPlot file if (linksDistances[position] >= 0.5) { /* * Current GNUPlot format is: *-- previus link -- *<Blank line> * Xi Yi <index(i)> * Xj Yj <index(i)> *<Blank line> *-- next link -- */ file.WriteLine(instance.Coord[i].X + " " + instance.Coord[i].Y + " " + (i + 1)); file.WriteLine(instance.Coord[j].X + " " + instance.Coord[j].Y + " " + (j + 1) + "\n"); //Updating the model with the current subtours elimination Utility.UpdateCC(cplex, x, rcExpr, bufferCoeffRC, relatedComponents, i, j); } } } //Only when more than one related components are found they are added to the model if (rcExpr.Count > 1) { for (int i = 0; i < rcExpr.Count; i++) { cplex.AddLe(rcExpr[i], bufferCoeffRC[i] - 1); } } //GNUPlot input file needs to be closed file.Close(); //Accessing GNUPlot to read the file if (Program.VERBOSE >= -1) { Utility.PrintGNUPlot(process, instance.InputFile, typeSol, instance.BestLb, -1); } //Blank line cplex.Output().WriteLine(); //Writing the value cplex.Output().WriteLine("xOPT = " + instance.BestLb + "\n"); } while (rcExpr.Count > 1 || epGap || !allEdges); //if there is more then one related components the solution is not optimal instance.BestSol = linksDistances; instance.XBest = instance.BestLb; //Exporting the updated model if (Program.VERBOSE >= -1) { cplex.ExportModel(instance.InputFile + ".lp"); } //Closing Cplex link cplex.End(); //Accessing GNUPlot to read the file if (Program.VERBOSE >= -1) { Utility.PrintGNUPlot(process, instance.InputFile, typeSol, instance.XBest, -1); } }
// The constructor sets up the Cplex instance to solve the worker LP, // and creates the worker LP (i.e., the dual of flow constraints and // capacity constraints of the flow MILP) // // Modeling variables: // forall k in V0, i in V: // u(k,i) = dual variable associated with flow constraint (k,i) // // forall k in V0, forall (i,j) in A: // v(k,i,j) = dual variable associated with capacity constraint (k,i,j) // // Objective: // minimize sum(k in V0) sum((i,j) in A) x(i,j) * v(k,i,j) // - sum(k in V0) u(k,0) + sum(k in V0) u(k,k) // // Constraints: // forall k in V0, forall (i,j) in A: u(k,i) - u(k,j) <= v(k,i,j) // // Nonnegativity on variables v(k,i,j) // forall k in V0, forall (i,j) in A: v(k,i,j) >= 0 // internal WorkerLP(int numNodes) { this.numNodes = numNodes; int i, j, k; // Set up Cplex instance to solve the worker LP cplex = new Cplex(); cplex.SetOut(null); // Turn off the presolve reductions and set the CPLEX optimizer // to solve the worker LP with primal simplex method. cplex.SetParam(Cplex.Param.Preprocessing.Reduce, 0); cplex.SetParam(Cplex.Param.RootAlgorithm, Cplex.Algorithm.Primal); // Create variables v(k,i,j) forall k in V0, (i,j) in A // For simplicity, also dummy variables v(k,i,i) are created. // Those variables are fixed to 0 and do not partecipate to // the constraints. v = new INumVar[numNodes - 1][][]; for (k = 1; k < numNodes; ++k) { v[k - 1] = new INumVar[numNodes][]; for (i = 0; i < numNodes; ++i) { v[k - 1][i] = new INumVar[numNodes]; for (j = 0; j < numNodes; ++j) { v[k - 1][i][j] = cplex.NumVar(0.0, System.Double.MaxValue, "v." + k + "." + i + "." + j); cplex.Add(v[k - 1][i][j]); } v[k - 1][i][i].UB = 0.0; } } // Create variables u(k,i) forall k in V0, i in V u = new INumVar[numNodes - 1][]; for (k = 1; k < numNodes; ++k) { u[k - 1] = new INumVar[numNodes]; for (i = 0; i < numNodes; ++i) { u[k - 1][i] = cplex.NumVar(-System.Double.MaxValue, System.Double.MaxValue, "u." + k + "." + i); cplex.Add(u[k - 1][i]); } } // Initial objective function is empty cplex.AddMinimize(); // Add constraints: // forall k in V0, forall (i,j) in A: u(k,i) - u(k,j) <= v(k,i,j) for (k = 1; k < numNodes; ++k) { for (i = 0; i < numNodes; ++i) { for (j = 0; j < numNodes; ++j) { if (i != j) { ILinearNumExpr expr = cplex.LinearNumExpr(); expr.AddTerm(v[k - 1][i][j], -1.0); expr.AddTerm(u[k - 1][i], 1.0); expr.AddTerm(u[k - 1][j], -1.0); cplex.AddLe(expr, 0.0); } } } } } // END WorkerLP
/// <summary> /// The example's main function. /// </summary> public static void Main(string[] args) { int retval = 0; Cplex cplex = null; try { cplex = new Cplex(); /* ***************************************************************** * * * * S E T U P P R O B L E M * * * * We create the following problem: * * Minimize * * obj: 3x1 - x2 + 3x3 + 2x4 + x5 + 2x6 + 4x7 * * Subject To * * c1: x1 + x2 = 4 * * c2: x1 + x3 >= 3 * * c3: x6 + x7 <= 5 * * c4: -x1 + x7 >= -2 * * q1: [ -x1^2 + x2^2 ] <= 0 * * q2: [ 4.25x3^2 -2x3*x4 + 4.25x4^2 - 2x4*x5 + 4x5^2 ] + 2 x1 <= 9.0 * q3: [ x6^2 - x7^2 ] >= 4 * * Bounds * * 0 <= x1 <= 3 * * x2 Free * * 0 <= x3 <= 0.5 * * x4 Free * * x5 Free * * x7 Free * * End * * * * ***************************************************************** */ INumVar[] x = new INumVar[7]; x[0] = cplex.NumVar(0, 3, "x1"); x[1] = cplex.NumVar(System.Double.NegativeInfinity, System.Double.PositiveInfinity, "x2"); x[2] = cplex.NumVar(0, 0.5, "x3"); x[3] = cplex.NumVar(System.Double.NegativeInfinity, System.Double.PositiveInfinity, "x4"); x[4] = cplex.NumVar(System.Double.NegativeInfinity, System.Double.PositiveInfinity, "x5"); x[5] = cplex.NumVar(0, System.Double.PositiveInfinity, "x6"); x[6] = cplex.NumVar(System.Double.NegativeInfinity, System.Double.PositiveInfinity, "x7"); IRange[] linear = new IRange[4]; linear[0] = cplex.AddEq(cplex.Sum(x[0], x[1]), 4.0, "c1"); linear[1] = cplex.AddGe(cplex.Sum(x[0], x[2]), 3.0, "c2"); linear[2] = cplex.AddLe(cplex.Sum(x[5], x[6]), 5.0, "c3"); linear[3] = cplex.AddGe(cplex.Diff(x[6], x[0]), -2.0, "c4"); IRange[] quad = new IRange[3]; quad[0] = cplex.AddLe(cplex.Sum(cplex.Prod(-1, x[0], x[0]), cplex.Prod(x[1], x[1])), 0.0, "q1"); quad[1] = cplex.AddLe(cplex.Sum(cplex.Prod(4.25, x[2], x[2]), cplex.Prod(-2, x[2], x[3]), cplex.Prod(4.25, x[3], x[3]), cplex.Prod(-2, x[3], x[4]), cplex.Prod(4, x[4], x[4]), cplex.Prod(2, x[0])), 9.0, "q2"); quad[2] = cplex.AddGe(cplex.Sum(cplex.Prod(x[5], x[5]), cplex.Prod(-1, x[6], x[6])), 4.0, "q3"); cplex.AddMinimize(cplex.Sum(cplex.Prod(3.0, x[0]), cplex.Prod(-1.0, x[1]), cplex.Prod(3.0, x[2]), cplex.Prod(2.0, x[3]), cplex.Prod(1.0, x[4]), cplex.Prod(2.0, x[5]), cplex.Prod(4.0, x[6])), "obj"); /* ***************************************************************** * * * * O P T I M I Z E P R O B L E M * * * * ***************************************************************** */ cplex.SetParam(Cplex.Param.Barrier.QCPConvergeTol, 1e-10); cplex.Solve(); /* ***************************************************************** * * * * Q U E R Y S O L U T I O N * * * * ***************************************************************** */ double[] xval = cplex.GetValues(x); double[] slack = cplex.GetSlacks(linear); double[] qslack = cplex.GetSlacks(quad); double[] cpi = cplex.GetReducedCosts(x); double[] rpi = cplex.GetDuals(linear); double[] qpi = getqconstrmultipliers(cplex, xval, ZEROTOL, x, quad); // Also store solution in a dictionary so that we can look up // values by variable and not only by index. IDictionary <INumVar, System.Double> xmap = new Dictionary <INumVar, System.Double>(); for (int j = 0; j < x.Length; ++j) { xmap.Add(x[j], xval[j]); } /* ***************************************************************** * * * * C H E C K K K T C O N D I T I O N S * * * * Here we verify that the optimal solution computed by CPLEX * * (and the qpi[] values computed above) satisfy the KKT * * conditions. * * * * ***************************************************************** */ // Primal feasibility: This example is about duals so we skip this test. // Dual feasibility: We must verify // - for <= constraints (linear or quadratic) the dual // multiplier is non-positive. // - for >= constraints (linear or quadratic) the dual // multiplier is non-negative. for (int i = 0; i < linear.Length; ++i) { if (linear[i].LB <= System.Double.NegativeInfinity) { // <= constraint if (rpi[i] > ZEROTOL) { throw new System.SystemException("Dual feasibility test failed for row " + linear[i] + ": " + rpi[i]); } } else if (linear[i].UB >= System.Double.PositiveInfinity) { // >= constraint if (rpi[i] < -ZEROTOL) { throw new System.SystemException("Dual feasibility test failed for row " + linear[i] + ": " + rpi[i]); } } else { // nothing to do for equality constraints } } for (int i = 0; i < quad.Length; ++i) { if (quad[i].LB <= System.Double.NegativeInfinity) { // <= constraint if (qpi[i] > ZEROTOL) { throw new System.SystemException("Dual feasibility test failed for quad " + quad[i] + ": " + qpi[i]); } } else if (quad[i].UB >= System.Double.PositiveInfinity) { // >= constraint if (qpi[i] < -ZEROTOL) { throw new System.SystemException("Dual feasibility test failed for quad " + quad[i] + ": " + qpi[i]); } } else { // nothing to do for equality constraints } } // Complementary slackness. // For any constraint the product of primal slack and dual multiplier // must be 0. for (int i = 0; i < linear.Length; ++i) { if (System.Math.Abs(linear[i].UB - linear[i].LB) > ZEROTOL && System.Math.Abs(slack[i] * rpi[i]) > ZEROTOL) { throw new System.SystemException("Complementary slackness test failed for row " + linear[i] + ": " + System.Math.Abs(slack[i] * rpi[i])); } } for (int i = 0; i < quad.Length; ++i) { if (System.Math.Abs(quad[i].UB - quad[i].LB) > ZEROTOL && System.Math.Abs(qslack[i] * qpi[i]) > ZEROTOL) { throw new System.SystemException("Complementary slackness test failed for quad " + quad[i] + ": " + System.Math.Abs(qslack[i] * qpi[i])); } } for (int j = 0; j < x.Length; ++j) { if (x[j].UB < System.Double.PositiveInfinity) { double slk = x[j].UB - xval[j]; double dual = cpi[j] < -ZEROTOL ? cpi[j] : 0.0; if (System.Math.Abs(slk * dual) > ZEROTOL) { throw new System.SystemException("Complementary slackness test failed for column " + x[j] + ": " + System.Math.Abs(slk * dual)); } } if (x[j].LB > System.Double.NegativeInfinity) { double slk = xval[j] - x[j].LB; double dual = cpi[j] > ZEROTOL ? cpi[j] : 0.0; if (System.Math.Abs(slk * dual) > ZEROTOL) { throw new System.SystemException("Complementary slackness test failed for column " + x[j] + ": " + System.Math.Abs(slk * dual)); } } } // Stationarity. // The difference between objective function and gradient at optimal // solution multiplied by dual multipliers must be 0, i.E., for the // optimal solution x // 0 == c // - sum(r in rows) r'(x)*rpi[r] // - sum(q in quads) q'(x)*qpi[q] // - sum(c in cols) b'(x)*cpi[c] // where r' and q' are the derivatives of a row or quadratic constraint, // x is the optimal solution and rpi[r] and qpi[q] are the dual // multipliers for row r and quadratic constraint q. // b' is the derivative of a bound constraint and cpi[c] the dual bound // multiplier for column c. IDictionary <INumVar, System.Double> kktsum = new Dictionary <INumVar, System.Double>(); for (int j = 0; j < x.Length; ++j) { kktsum.Add(x[j], 0.0); } // Objective function. for (ILinearNumExprEnumerator it = ((ILinearNumExpr)cplex.GetObjective().Expr).GetLinearEnumerator(); it.MoveNext(); /* nothing */) { kktsum[it.NumVar] = it.Value; } // Linear constraints. // The derivative of a linear constraint ax - b (<)= 0 is just a. for (int i = 0; i < linear.Length; ++i) { for (ILinearNumExprEnumerator it = ((ILinearNumExpr)linear[i].Expr).GetLinearEnumerator(); it.MoveNext(); /* nothing */) { kktsum[it.NumVar] = kktsum[it.NumVar] - rpi[i] * it.Value; } } // Quadratic constraints. // The derivative of a constraint xQx + ax - b <= 0 is // Qx + Q'x + a. for (int i = 0; i < quad.Length; ++i) { for (ILinearNumExprEnumerator it = ((ILinearNumExpr)quad[i].Expr).GetLinearEnumerator(); it.MoveNext(); /* nothing */) { kktsum[it.NumVar] = kktsum[it.NumVar] - qpi[i] * it.Value; } for (IQuadNumExprEnumerator it = ((IQuadNumExpr)quad[i].Expr).GetQuadEnumerator(); it.MoveNext(); /* nothing */) { INumVar v1 = it.NumVar1; INumVar v2 = it.NumVar2; kktsum[v1] = kktsum[v1] - qpi[i] * xmap[v2] * it.Value; kktsum[v2] = kktsum[v2] - qpi[i] * xmap[v1] * it.Value; } } // Bounds. // The derivative for lower bounds is -1 and that for upper bounds // is 1. // CPLEX already returns dj with the appropriate sign so there is // no need to distinguish between different bound types here. for (int j = 0; j < x.Length; ++j) { kktsum[x[j]] = kktsum[x[j]] - cpi[j]; } foreach (INumVar v in x) { if (System.Math.Abs(kktsum[v]) > ZEROTOL) { throw new System.SystemException("Stationarity test failed at " + v + ": " + System.Math.Abs(kktsum[v])); } } // KKT conditions satisfied. Dump out the optimal solutions and // the dual values. System.Console.WriteLine("Optimal solution satisfies KKT conditions."); System.Console.WriteLine(" x[] = " + arrayToString(xval)); System.Console.WriteLine(" cpi[] = " + arrayToString(cpi)); System.Console.WriteLine(" rpi[] = " + arrayToString(rpi)); System.Console.WriteLine(" qpi[] = " + arrayToString(qpi)); } catch (ILOG.Concert.Exception e) { System.Console.WriteLine("IloException: " + e.Message); System.Console.WriteLine(e.StackTrace); retval = -1; } finally { if (cplex != null) { cplex.End(); } } System.Environment.Exit(retval); }
static void Main(string[] args) { double[] Demand = new double[] { 15, 18, 14, 20 }; double[] Capacity = new double[] { 20, 22, 17, 19, 18 }; double[,] ShipCosts = new double[,] { { 4000, 2500, 1200, 2200 }, { 2000, 2600, 1800, 2600 }, { 3000, 3400, 2600, 3100 }, { 2500, 3000, 4100, 3700 }, { 4500, 4000, 3000, 3200 } }; int nWarehouses = Capacity.Length; int nCustomers = Demand.Length; Cplex m = new Cplex(); INumVar[,] Ship = new INumVar[nWarehouses, nCustomers]; for (int i = 0; i < nWarehouses; ++i) for (int j = 0; j < nCustomers; ++j) Ship[i, j] = m.NumVar(0, System.Double.MaxValue, NumVarType.Float, "ship." + i + "." + j); INumVar[] Shortage = new INumVar[nCustomers]; for (int j = 0; j < nCustomers; ++j) Shortage[j] = m.NumVar(0, System.Double.MaxValue, NumVarType.Float, "shortage." + j); INumVar TotalShortage = m.NumVar(0, System.Double.MaxValue, NumVarType.Float, "TotalShortage"); INumVar TotalShippingCost = m.NumVar(0, System.Double.MaxValue, NumVarType.Float, "TotalShippingCost"); IObjective obj = m.AddMinimize(TotalShippingCost); IConstraint[] DemandCon = new IConstraint[nCustomers]; for (int j = 0; j < nCustomers; ++j) { INumExpr lhs = m.LinearNumExpr(0.0); INumExpr rhs = m.LinearNumExpr(Demand[j]); for (int i = 0; i < nWarehouses; ++i) lhs = m.Sum(lhs, Ship[i, j]); lhs = m.Sum(lhs, Shortage[j]); DemandCon[j] = m.AddEq(lhs, rhs, "demand." + j); } IConstraint[] CapacityCon = new IConstraint[nWarehouses]; for (int i = 0; i < nWarehouses; ++i) { INumExpr lhs = m.LinearNumExpr(0.0); for (int j = 0; j < nCustomers; ++j) lhs = m.Sum(lhs, Ship[i, j]); CapacityCon[i] = m.AddLe(lhs, Capacity[i], "capacity." + i); } INumExpr expr = m.Sum(Shortage); IConstraint TotalShortageCon = m.AddEq(expr, TotalShortage, "total_shortage"); expr = m.LinearNumExpr(0.0); for (int i = 0; i < nWarehouses; ++i) for (int j = 0; j < nCustomers; ++j) expr = m.Sum(expr, m.Prod(ShipCosts[i, j], Ship[i, j])); IConstraint TotalShippingCon = m.AddEq(expr, TotalShippingCost, "total_shipping"); m.ExportModel("Facility.lp"); while (true) { Console.WriteLine("\nSolver Output:"); m.Solve(); double OptShortage = m.GetValue(TotalShortage); double OptShipping = m.GetValue(TotalShippingCost); Console.WriteLine("\nFacility Program Output:"); Console.WriteLine("\nTotalShortage = {0}", OptShortage); Console.WriteLine("TotalShippingCost= {0}\n", OptShipping); if (OptShortage < EPS) break; INumVar[] varArr = new INumVar[26]; double[] ubs = new double[26]; double[] lbs = new double[26]; varArr[0] = TotalShortage; varArr[1] = TotalShippingCost; for (int i = 0; i < nWarehouses; ++i) for (int j = 0; j < nCustomers; ++j) varArr[4 * i + j + 2] = Ship[i, j]; for (int j = 0; j < nCustomers; ++j) varArr[j + 22] = Shortage[j]; m.GetObjSA(lbs, ubs, varArr); double ObjectiveBound = ubs[0]; m.SetLinearCoef(obj, ((1 + EPS) * ObjectiveBound), TotalShortage); } // end while for (int i = 0; i < nWarehouses; ++i) for (int j = 0; j < nCustomers; ++j) Console.WriteLine("{0} = {1}", Ship[i, j].Name, m.GetValue(Ship[i, j])); for (int j = 0; j < nCustomers; ++j) Console.WriteLine("{0} = {1}", Shortage[j].Name, m.GetValue(Shortage[j])); Console.WriteLine("{0} = {1}", TotalShortage.Name, m.GetValue(TotalShortage)); Console.WriteLine("{0} = {1}", TotalShippingCost.Name, m.GetValue(TotalShippingCost)); } // end Main
public void AddCapacityConstraint() { theModel.AddLe(theModel.Sum(theModel.ScalProd(TrailerTurns, LoadedMoves), theModel.ScalProd(TrailerTurns, EmptyMoves)), (trailerCapacity * 52), "Capacity"); }
static void Main() { try { string resultFilename = "./ResultFiles/MTSP_MTZ.csv"; string filename = "./DataFiles/Data.dat"; Data data = new Data(filename); double timeFactor = 0; double distanceFactor = 1; double step = 0.1; int routeCounter = 0; File.WriteAllText(resultFilename, ""); do { using (Cplex cplex = new Cplex()) { #region [Decision Variables] IIntVar[][] x = new IIntVar[data.n][]; IIntVar Q = cplex.IntVar(1, 250, "Q"); for (int i = 0; i < data.n; i++) { x[i] = cplex.BoolVarArray(data.n); cplex.Add(x[i]); } #endregion #region [Objective Function] INumExpr obj = cplex.NumExpr(); for (int i = 0; i < data.n; i++) { for (int j = 0; j < data.n; j++) { if (i != j) { obj = cplex.Sum(obj, cplex.Prod( ( (timeFactor * data.timeNormalized[i][j]) + (distanceFactor * data.distanceNormalized[i][j]) ), x[i][j])); } } } cplex.AddMinimize(obj); #endregion #region [Restrictions] for (int j = 0; j < data.n; j++) { ILinearNumExpr sumj = cplex.LinearNumExpr(); for (int i = 0; i < data.n; i++) { if (i != j) { sumj.AddTerm(1, x[i][j]); } } cplex.AddEq(sumj, 1); } for (int i = 0; i < data.n; i++) { ILinearNumExpr sumi = cplex.LinearNumExpr(); for (int j = 0; j < data.n; j++) { if (i != j) { sumi.AddTerm(1, x[i][j]); } } cplex.AddEq(sumi, 1); } #endregion cplex.SetParam(Cplex.DoubleParam.WorkMem, 4000.0); cplex.SetParam(Cplex.Param.MIP.Strategy.File, 2); cplex.SetParam(Cplex.DoubleParam.EpGap, 0.1); cplex.SetParam(Cplex.BooleanParam.MemoryEmphasis, true); cplex.SetParam(Cplex.IntParam.VarSel, 4); SOLVE: Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); if (cplex.Solve()) { stopWatch.Stop(); double[][] sol_x = new double[data.n][]; for (int i = 0; i < data.n; i++) { sol_x[i] = cplex.GetValues(x[i]); } int[] tour = FindSubTour(sol_x); if (tour.Length < data.n) { ILinearNumExpr sumx = cplex.LinearNumExpr(); for (int i = 0; i < tour.Length; i++) { for (int j = 0; j < tour.Length; j++) { sumx.AddTerm(1, x[tour[i]][tour[j]]); } } cplex.AddLazyConstraint(cplex.AddLe(cplex.Diff(sumx, tour.Length), -1)); goto SOLVE; } double timeTotal = 0; double distanceTotal = 0; for (int i = 0; i < data.n; i++) { for (int j = 0; j < data.n; j++) { timeTotal += data.time[i][j] * sol_x[i][j]; distanceTotal += data.distance[i][j] * sol_x[i][j]; } } StreamWriter file = new StreamWriter(resultFilename, true); file.WriteLine($"{timeFactor},{distanceFactor},{stopWatch.Elapsed.TotalSeconds},{cplex.ObjValue},{timeTotal},{distanceTotal}"); file.Close(); StreamWriter fileRouteResult = new StreamWriter($"./ResultFiles/Route-{routeCounter}.txt"); for (int i = 0; i < data.n; i++) { for (int j = 0; j < data.n; j++) { if (sol_x[i][j] == 1) { fileRouteResult.WriteLine($"From city {i} to city {j}"); } } } fileRouteResult.Close(); } cplex.End(); } timeFactor += step; distanceFactor -= step; routeCounter++; } while (timeFactor <= 1); } catch (ILOG.Concert.Exception ex) { StreamWriter errorfile = new StreamWriter("./ErrorLog.txt"); errorfile.WriteLine("Exception Kind: ILOG.Concert.Exception (Concert Error)"); errorfile.WriteLine("Message: " + ex.Message); errorfile.WriteLine("StackTrace: " + ex.StackTrace); errorfile.Close(); } catch (InputDataReader.InputDataReaderException ex) { StreamWriter errorfile = new StreamWriter("./ErrorLog.txt"); errorfile.WriteLine("Exception Kind: InputDataReader.InputDataReaderException (Data Error)"); errorfile.WriteLine("Message: " + ex.Message); errorfile.WriteLine("StackTrace: " + ex.StackTrace); errorfile.Close(); } catch (System.IO.IOException ex) { StreamWriter errorfile = new StreamWriter("./ErrorLog.txt"); errorfile.WriteLine("Exception Kind: System.IO.IOException (IO Error)"); errorfile.WriteLine("Message: " + ex.Message); errorfile.WriteLine("StackTrace: " + ex.StackTrace); errorfile.Close(); } }
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(); }
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); } }
// The constructor sets up the Cplex instance to solve the worker LP, // and creates the worker LP (i.e., the dual of flow constraints and // capacity constraints of the flow MILP) // // Modeling variables: // forall k in V0, i in V: // u(k,i) = dual variable associated with flow constraint (k,i) // // forall k in V0, forall (i,j) in A: // v(k,i,j) = dual variable associated with capacity constraint (k,i,j) // // Objective: // minimize sum(k in V0) sum((i,j) in A) x(i,j) * v(k,i,j) // - sum(k in V0) u(k,0) + sum(k in V0) u(k,k) // // Constraints: // forall k in V0, forall (i,j) in A: u(k,i) - u(k,j) <= v(k,i,j) // // Nonnegativity on variables v(k,i,j) // forall k in V0, forall (i,j) in A: v(k,i,j) >= 0 // internal WorkerLP(int numNodes) { this.numNodes = numNodes; int i, j, k; // Set up Cplex instance to solve the worker LP cplex = new Cplex(); cplex.SetOut(null); // Turn off the presolve reductions and set the CPLEX optimizer // to solve the worker LP with primal simplex method. cplex.SetParam(Cplex.Param.Preprocessing.Reduce, 0); cplex.SetParam(Cplex.Param.RootAlgorithm, Cplex.Algorithm.Primal); // Create variables v(k,i,j) forall k in V0, (i,j) in A // For simplicity, also dummy variables v(k,i,i) are created. // Those variables are fixed to 0 and do not partecipate to // the constraints. v = new INumVar[numNodes-1][][]; for (k = 1; k < numNodes; ++k) { v[k-1] = new INumVar[numNodes][]; for (i = 0; i < numNodes; ++i) { v[k-1][i] = new INumVar[numNodes]; for (j = 0; j < numNodes; ++j) { v[k-1][i][j] = cplex.NumVar(0.0, System.Double.MaxValue, "v." + k + "." + i + "." + j); cplex.Add(v[k-1][i][j]); } v[k-1][i][i].UB = 0.0; } } // Create variables u(k,i) forall k in V0, i in V u = new INumVar[numNodes-1][]; for (k = 1; k < numNodes; ++k) { u[k-1] = new INumVar[numNodes]; for (i = 0; i < numNodes; ++i) { u[k-1][i] = cplex.NumVar(-System.Double.MaxValue, System.Double.MaxValue, "u." + k + "." + i); cplex.Add(u[k-1][i]); } } // Initial objective function is empty cplex.AddMinimize(); // Add constraints: // forall k in V0, forall (i,j) in A: u(k,i) - u(k,j) <= v(k,i,j) for (k = 1; k < numNodes; ++k) { for (i = 0; i < numNodes; ++i) { for (j = 0; j < numNodes; ++j) { if ( i != j ) { ILinearNumExpr expr = cplex.LinearNumExpr(); expr.AddTerm(v[k-1][i][j], -1.0); expr.AddTerm(u[k-1][i], 1.0); expr.AddTerm(u[k-1][j], -1.0); cplex.AddLe(expr, 0.0); } } } } }
private void decomp(int dim, int kts, int[][] dist, List <int> WorkList) { int[] lo = new int[dim]; int dk = dim * kts; for (int i = 0; i < dim; i++) { lo[i] = 1; } Cplex cplex = new Cplex(); NumVarType varType = NumVarType.Bool; INumVar[][] x = new INumVar[dim][]; for (int i = 0; i < dim; i++) { x[i] = cplex.NumVarArray(dk, 0, 1); } for (int i = 0; i < dim; i++) { for (int j = 0; j < dk; j++) { x[i][j] = cplex.BoolVar(); } } //**************************************** //Что тут происходит? for (int j = 0; j < dim; j++) { INumExpr xcolSum = cplex.NumExpr(); for (int k = 0; k < kts; k++) { for (int i = 0; i < dim; i++) { xcolSum = cplex.Sum(xcolSum, x[i][k * dim + j]); } } cplex.AddEq(lo[j], xcolSum); } varType = NumVarType.Float; INumVar[] u = new INumVar[dk]; for (int j = 0; j < dk; j++) { u[j] = cplex.NumVar(0, 100000); } for (int j = 1; j < dk; j++) { cplex.AddGe(u[j], 0); } for (int k = 0; k < kts; k++) { for (int i = 1; i < dim; i++) { for (int j = 1; j < dim; j++) { if (i != j) { if (kts == 1) { cplex.AddLe(cplex.Sum(cplex.Diff(u[k * dim + i], u[k * dim + j]), cplex.Prod(dim, x[i][k * dim + j])), dim - 1); } else { cplex.AddLe(cplex.Sum(cplex.Diff(u[k * dim + i], u[k * dim + j]), cplex.Prod(dim, x[i][k * dim + j])), dim); } } } } } for (int i = 0; i < dim; i++) { INumExpr xrowSum = cplex.NumExpr(); for (int j = 0; j < dk; j++) { xrowSum = cplex.Sum(xrowSum, x[i][j]); } cplex.AddEq(lo[i], xrowSum); } //Условия независимости кластеров if (kts > 1) { int[] a = new int[kts + 1]; for (int k = 1; k < kts; k++) { if (k > 1 && k < kts - 1) { continue; } int p; for (int i = 1; i <= k; i++) { a[i] = i; } p = k; while (p >= 1) { for (int m = 0; m < dim; m++) { INumExpr xcolrowSum = cplex.NumExpr(); for (int j = 1; j <= kts; j++) { bool row = false; for (int i = 1; i <= k; i++) { if (a[i] == j) { row = true; } } if (row) { for (int t = 0; t < dim; t++) { xcolrowSum = cplex.Sum(xcolrowSum, x[m][(j - 1) * dim + t]); } } else { for (int t = 0; t < dim; t++) { xcolrowSum = cplex.Sum(xcolrowSum, x[t][(j - 1) * dim + m]); } } } cplex.AddLe(xcolrowSum, lo[m]); } if (a[k] == kts) { p--; } else { p = k; } if (p >= 1) { for (int i = k; i >= p; i--) { a[i] = a[p] + i - p + 1; } } } } } INumExpr costSum = cplex.NumExpr(); INumExpr[] costSum1 = new INumExpr[kts]; if (kts == 1) { for (int i = 0; i < dim; i++) { for (int j = 0; j < dim; j++) { costSum = cplex.Sum(costSum, cplex.Prod(x[i][j], dist[i][j])); } } cplex.AddMinimize(costSum); } else { for (int k = 0; k < kts; k++) { costSum1[k] = cplex.NumExpr(); for (int i = 0; i < dim; i++) { for (int j = 0; j < dim; j++) { costSum1[k] = cplex.Sum(costSum1[k], cplex.Prod(x[i][k * dim + j], dist[i][j])); } } //cplex.AddLe(costSum1[k], costSum); } costSum = cplex.Max(costSum1); cplex.AddMinimize(costSum); } try { if (cplex.Solve()) { textBox1.Text += "lambda = " + cplex.ObjValue + Environment.NewLine; textBox1.Text += DateTime.Now.ToString() + Environment.NewLine; WorkList.Clear(); int num_clust = 0; for (int k = 0; k < kts; k++) { int dim1 = 0; for (int i = 0; i < dim; i++) { for (int j = 0; j < dim; j++) { if (Convert.ToInt16(cplex.GetValue(x[i][k * dim + j])) == 1) { dim1++; } } } if (dim1 > 0) { num_clust++; for (int i = 0; i < dim; i++) { for (int j = 0; j < dim; j++) { if (Convert.ToInt16(cplex.GetValue(x[i][k * dim + j])) == 1) { WorkList.Add(i); break; } } } WorkList.Add(-1); } } textBox1.Text += DateTime.Now.ToString() + Environment.NewLine; } else { textBox1.Text += "Нет решения" + Environment.NewLine; textBox1.Text += DateTime.Now.ToString() + Environment.NewLine; } cplex.End(); } catch (ILOG.Concert.Exception ex) { textBox1.Text += "Concert Error: " + ex + Environment.NewLine; textBox1.Text += DateTime.Now.ToString() + Environment.NewLine; } }
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(); }
private void button1_Click(object sender, EventArgs e) { int[,] A = new int[, ] { { 1, 1, 1, 1, 0 }, { 1, 1, 0, 1, 1 }, { 0, 1, 1, 1, 1 } }; double[] L = new double[] { 8, 5, 7, 8, 4 }; double G = 10.7; double[] N_Max = new double[] { 2, 2, 2 }; int nbOfWorkers = A.GetLength(0); int nbOfTasks = A.GetLength(1); Cplex cplex = new Cplex(); INumVar[,] X = new INumVar[nbOfWorkers, nbOfTasks]; // C라는 2차원 인덱스가 0이면, 행의 개수을 받겠다 // C라는 2차원 인덱스가 1이면 열의 개수를 받겠다. for (int i = 0; i < A.GetLength(0); i++) { for (int j = 0; j < A.GetLength(1); j++) { X[i, j] = cplex.BoolVar(); } } List <INumVar> D_negative = new List <INumVar>(); for (int i = 0; i < nbOfWorkers; i++) { D_negative.Add(cplex.NumVar(0, double.MaxValue)); } List <INumVar> D_positive = new List <INumVar>(); for (int i = 0; i < nbOfWorkers; i++) { D_positive.Add(cplex.NumVar(0, double.MaxValue)); } //목적함수 ILinearNumExpr objectiveFunction = cplex.LinearNumExpr(); for (int i = 0; i < nbOfWorkers; i++) { objectiveFunction.AddTerm(1, D_negative[i]); } for (int i = 0; i < nbOfWorkers; i++) { objectiveFunction.AddTerm(1, D_positive[i]); // C[i, j], X[i, j] 두개를 곱해서 objectiveFunction 에 넣겠다. } //과제 for (int i = 0; i < nbOfWorkers; i++) { ILinearNumExpr constLeft1 = cplex.LinearNumExpr(); for (int j = 0; j < nbOfTasks; j++) { constLeft1.AddTerm(L[j], X[i, j]); } constLeft1.AddTerm(1, D_negative[i]); constLeft1.AddTerm(-1, D_positive[i]); cplex.AddEq(constLeft1, G); } for (int j = 0; j < nbOfTasks; j++) { ILinearNumExpr constLeft2 = cplex.LinearNumExpr(); for (int i = 0; i < X.GetLength(0); i++) { constLeft2.AddTerm(1, X[i, j]); } cplex.AddEq(constLeft2, 1); } for (int i = 0; i < nbOfWorkers; i++) { for (int j = 0; j < nbOfTasks; j++) { cplex.AddLe(X[i, j], A[i, j]); } } for (int i = 0; i < nbOfWorkers; i++) { ILinearNumExpr constLeft4 = cplex.LinearNumExpr(); for (int j = 0; j < nbOfTasks; j++) { constLeft4.AddTerm(1, X[i, j]); } cplex.AddLe(constLeft4, N_Max[i]); } cplex.AddMinimize(objectiveFunction); cplex.Solve(); string solution = ""; double tolerance = cplex.GetParam(Cplex.Param.MIP.Tolerances.Integrality); //tolerance를 정의함 for (int i = 0; i < A.GetLength(0); i++) { for (int j = 0; j < A.GetLength(1); j++) { if (cplex.GetValue(X[i, j]) >= 1 - tolerance) { solution += "(" + (i + 1).ToString() + " ," + (j + 1).ToString() + ")"; } } } MessageBox.Show("목적함수 값은 =" + cplex.GetObjValue() + "\r\n" + "선택된 변수는 =" + solution); }