} // END WorkerLP // This method creates the master ILP (arc variables x and degree constraints). // // Modeling variables: // forall (i,j) in A: // x(i,j) = 1, if arc (i,j) is selected // = 0, otherwise // // Objective: // minimize sum((i,j) in A) c(i,j) * x(i,j) // // Degree constraints: // forall i in V: sum((i,j) in delta+(i)) x(i,j) = 1 // forall i in V: sum((j,i) in delta-(i)) x(j,i) = 1 // // Binary constraints on arc variables: // forall (i,j) in A: x(i,j) in {0, 1} // internal static void CreateMasterILP(IModeler model, Data data, IIntVar[][] x) { int i, j; int numNodes = data.numNodes; // Create variables x(i,j) for (i,j) in A // For simplicity, also dummy variables x(i,i) are created. // Those variables are fixed to 0 and do not partecipate to // the constraints. for (i = 0; i < numNodes; ++i) { x[i] = new IIntVar[numNodes]; for (j = 0; j < numNodes; ++j) { x[i][j] = model.BoolVar("x." + i + "." + j); model.Add(x[i][j]); } x[i][i].UB = 0; } // Create objective function: minimize sum((i,j) in A ) c(i,j) * x(i,j) ILinearNumExpr objExpr = model.LinearNumExpr(); for (i = 0; i < numNodes; ++i) { objExpr.Add(model.ScalProd(x[i], data.arcCost[i])); } model.AddMinimize(objExpr); // Add the out degree constraints. // forall i in V: sum((i,j) in delta+(i)) x(i,j) = 1 for (i = 0; i < numNodes; ++i) { ILinearNumExpr expr = model.LinearNumExpr(); for (j = 0; j < i; ++j) { expr.AddTerm(x[i][j], 1.0); } for (j = i + 1; j < numNodes; ++j) { expr.AddTerm(x[i][j], 1.0); } model.AddEq(expr, 1.0); } // Add the in degree constraints. // forall i in V: sum((j,i) in delta-(i)) x(j,i) = 1 for (i = 0; i < numNodes; ++i) { ILinearNumExpr expr = model.LinearNumExpr(); for (j = 0; j < i; ++j) { expr.AddTerm(x[j][i], 1.0); } for (j = i + 1; j < numNodes; ++j) { expr.AddTerm(x[j][i], 1.0); } model.AddEq(expr, 1.0); } } // END CreateMasterILP
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); } }