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); } }
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(); }
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"); } }
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> /// 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) { 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); } }
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(); } }