From 335cf3df3dbdaee1d71d44e87147cd171531fc23 Mon Sep 17 00:00:00 2001 From: Mizux Seiha Date: Mon, 26 Oct 2020 18:36:17 +0100 Subject: [PATCH] format all C# files --- .clang-format | 3 + .github/workflows/clang_format.yml | 2 +- examples/contrib/3_jugs_regular.cs | 160 +- examples/contrib/a_puzzle.cs | 178 +- examples/contrib/a_round_of_golf.cs | 92 +- examples/contrib/all_interval.cs | 38 +- examples/contrib/alldifferent_except_0.cs | 33 +- examples/contrib/assignment.cs | 68 +- examples/contrib/broken_weights.cs | 69 +- examples/contrib/bus_schedule.cs | 37 +- examples/contrib/circuit.cs | 37 +- examples/contrib/circuit2.cs | 45 +- examples/contrib/coins3.cs | 34 +- examples/contrib/coins_grid.cs | 39 +- examples/contrib/combinatorial_auction2.cs | 48 +- examples/contrib/contiguity_regular.cs | 99 +- examples/contrib/contiguity_transition.cs | 47 +- examples/contrib/costas_array.cs | 89 +- examples/contrib/covering_opl.cs | 67 +- examples/contrib/crew.cs | 167 +- examples/contrib/crossword.cs | 154 +- examples/contrib/crypta.cs | 54 +- examples/contrib/crypto.cs | 135 +- examples/contrib/csdiet.cs | 53 +- examples/contrib/curious_set_of_integers.cs | 47 +- examples/contrib/debruijn.cs | 90 +- examples/contrib/discrete_tomography.cs | 89 +- examples/contrib/divisible_by_9_through_1.cs | 76 +- examples/contrib/dudeney.cs | 59 +- examples/contrib/einav_puzzle2.cs | 157 +- examples/contrib/eq10.cs | 71 +- examples/contrib/eq20.cs | 127 +- examples/contrib/fill_a_pix.cs | 120 +- examples/contrib/furniture_moving.cs | 74 +- .../contrib/furniture_moving_intervals.cs | 62 +- examples/contrib/futoshiki.cs | 112 +- examples/contrib/golomb_ruler.cs | 49 +- examples/contrib/grocery.cs | 37 +- examples/contrib/hidato_table.cs | 162 +- examples/contrib/just_forgotten.cs | 59 +- examples/contrib/kakuro.cs | 135 +- examples/contrib/kenken2.cs | 114 +- examples/contrib/killer_sudoku.cs | 148 +- examples/contrib/labeled_dice.cs | 73 +- examples/contrib/langford.cs | 43 +- examples/contrib/least_diff.cs | 30 +- examples/contrib/lectures.cs | 94 +- examples/contrib/magic_sequence.cs | 33 +- examples/contrib/magic_square.cs | 43 +- examples/contrib/magic_square_and_cards.cs | 50 +- examples/contrib/map.cs | 32 +- examples/contrib/map2.cs | 52 +- examples/contrib/marathon2.cs | 68 +- examples/contrib/max_flow_taha.cs | 99 +- examples/contrib/max_flow_winston1.cs | 99 +- examples/contrib/minesweeper.cs | 116 +- examples/contrib/mr_smith.cs | 39 +- examples/contrib/nontransitive_dice.cs | 106 +- examples/contrib/nqueens.cs | 29 +- examples/contrib/nurse_rostering_regular.cs | 160 +- .../contrib/nurse_rostering_transition.cs | 104 +- examples/contrib/olympic.cs | 53 +- examples/contrib/organize_day.cs | 67 +- examples/contrib/organize_day_intervals.cs | 54 +- examples/contrib/p_median.cs | 69 +- examples/contrib/pandigital_numbers.cs | 90 +- examples/contrib/partition.cs | 39 +- examples/contrib/perfect_square_sequence.cs | 62 +- examples/contrib/photo_problem.cs | 78 +- examples/contrib/place_number_puzzle.cs | 75 +- examples/contrib/post_office_problem2.cs | 40 +- examples/contrib/quasigroup_completion.cs | 102 +- examples/contrib/regex.cs | 106 +- examples/contrib/rogo2.cs | 149 +- examples/contrib/scheduling_speakers.cs | 42 +- examples/contrib/secret_santa.cs | 46 +- examples/contrib/secret_santa2.cs | 139 +- examples/contrib/send_more_money.cs | 28 +- examples/contrib/send_more_money2.cs | 33 +- examples/contrib/send_most_money.cs | 46 +- examples/contrib/seseman.cs | 54 +- examples/contrib/set_covering.cs | 44 +- examples/contrib/set_covering2.cs | 46 +- examples/contrib/set_covering3.cs | 50 +- examples/contrib/set_covering4.cs | 57 +- examples/contrib/set_covering_deployment.cs | 65 +- examples/contrib/set_covering_skiena.cs | 64 +- examples/contrib/set_partition.cs | 136 +- examples/contrib/sicherman_dice.cs | 52 +- examples/contrib/ski_assignment.cs | 26 +- examples/contrib/stable_marriage.cs | 176 +- examples/contrib/strimko2.cs | 73 +- examples/contrib/subset_sum.cs | 35 +- examples/contrib/sudoku.cs | 75 +- examples/contrib/survo_puzzle.cs | 112 +- examples/contrib/to_num.cs | 33 +- examples/contrib/traffic_lights.cs | 80 +- examples/contrib/volsay.cs | 18 +- examples/contrib/volsay2.cs | 35 +- examples/contrib/volsay3.cs | 59 +- examples/contrib/wedding_optimal_chart.cs | 125 +- examples/contrib/who_killed_agatha.cs | 65 +- examples/contrib/word_square.cs | 86 +- examples/contrib/xkcd.cs | 21 +- examples/contrib/young_tableaux.cs | 60 +- examples/contrib/zebra.cs | 118 +- examples/dotnet/BalanceGroupSat.cs | 341 ++- examples/dotnet/GateSchedulingSat.cs | 73 +- examples/dotnet/JobshopFt06Sat.cs | 83 +- examples/dotnet/JobshopSat.cs | 130 +- examples/dotnet/NetworkRoutingSat.cs | 2029 ++++++++--------- examples/dotnet/NursesSat.cs | 112 +- examples/dotnet/ShiftSchedulingSat.cs | 872 ++++--- examples/dotnet/SpeakerSchedulingSat.cs | 179 +- examples/dotnet/TaskSchedulingSat.cs | 55 +- examples/dotnet/cscvrptw.cs | 97 +- examples/dotnet/csflow.cs | 58 +- examples/dotnet/csintegerprogramming.cs | 25 +- examples/dotnet/csknapsack.cs | 39 +- examples/dotnet/cslinearprogramming.cs | 27 +- examples/dotnet/csls_api.cs | 94 +- examples/dotnet/csrabbitspheasants.cs | 33 +- examples/dotnet/cstsp.cs | 27 +- examples/tests/ConstraintSolverTests.cs | 1306 ++++++----- examples/tests/LinearSolverTests.cs | 47 +- examples/tests/RoutingSolverTests.cs | 24 +- examples/tests/SatSolverTests.cs | 329 ++- examples/tests/issue18.cs | 5 +- examples/tests/issue22.cs | 91 +- examples/tests/issue33.cs | 376 +-- ortools/algorithms/samples/Knapsack.cs | 36 +- .../csharp/IntArrayHelper.cs | 20 +- .../csharp/IntVarArrayHelper.cs | 620 ++--- .../csharp/IntervalVarArrayHelper.cs | 29 +- .../csharp/NetDecisionBuilder.cs | 286 +-- .../constraint_solver/csharp/SolverHelper.cs | 908 ++++---- .../constraint_solver/csharp/ValCstPair.cs | 517 ++--- .../samples/SimpleCpProgram.cs | 10 +- .../samples/SimpleRoutingProgram.cs | 22 +- ortools/constraint_solver/samples/Tsp.cs | 51 +- .../samples/TspCircuitBoard.cs | 136 +- .../constraint_solver/samples/TspCities.cs | 64 +- .../samples/TspDistanceMatrix.cs | 87 +- ortools/constraint_solver/samples/Vrp.cs | 88 +- .../constraint_solver/samples/VrpCapacity.cs | 113 +- .../constraint_solver/samples/VrpDropNodes.cs | 112 +- .../samples/VrpGlobalSpan.cs | 95 +- .../samples/VrpInitialRoutes.cs | 108 +- .../samples/VrpPickupDelivery.cs | 125 +- .../samples/VrpPickupDeliveryFifo.cs | 123 +- .../samples/VrpPickupDeliveryLifo.cs | 123 +- .../constraint_solver/samples/VrpResources.cs | 153 +- .../samples/VrpStartsEnds.cs | 95 +- .../samples/VrpTimeWindows.cs | 135 +- .../samples/VrpWithTimeLimit.cs | 55 +- ortools/dotnet/CreateSigningKey/Program.cs | 28 +- ortools/graph/samples/SimpleMaxFlowProgram.cs | 26 +- .../graph/samples/SimpleMinCostFlowProgram.cs | 56 +- .../linear_solver/csharp/LinearConstraint.cs | 232 +- ortools/linear_solver/csharp/LinearExpr.cs | 498 ++-- ortools/linear_solver/csharp/SolverHelper.cs | 334 ++- .../linear_solver/csharp/VariableHelper.cs | 353 ++- .../linear_solver/samples/AssignmentMip.cs | 58 +- .../linear_solver/samples/BinPackingMip.cs | 56 +- .../samples/LinearProgrammingExample.cs | 92 +- ortools/linear_solver/samples/MipVarArray.cs | 57 +- .../samples/MultipleKnapsackMip.cs | 56 +- .../linear_solver/samples/SimpleLpProgram.cs | 6 +- .../linear_solver/samples/SimpleMipProgram.cs | 18 +- ortools/sat/csharp/Constraints.cs | 59 +- ortools/sat/csharp/CpModel.cs | 446 ++-- ortools/sat/csharp/CpSolver.cs | 126 +- ortools/sat/csharp/IntegerExpressions.cs | 508 ++--- ortools/sat/csharp/IntervalVariables.cs | 113 +- ortools/sat/csharp/SearchHelpers.cs | 66 +- ortools/sat/samples/AssignmentSat.cs | 47 +- ortools/sat/samples/BinPackingProblemSat.cs | 77 +- ortools/sat/samples/BoolOrSampleSat.cs | 8 +- ortools/sat/samples/ChannelingSampleSat.cs | 24 +- ortools/sat/samples/CpIsFunSat.cs | 34 +- .../EarlinessTardinessCostSampleSat.cs | 26 +- ortools/sat/samples/IntervalSampleSat.cs | 6 +- ortools/sat/samples/LiteralSampleSat.cs | 6 +- ortools/sat/samples/NoOverlapSampleSat.cs | 15 +- .../sat/samples/OptionalIntervalSampleSat.cs | 6 +- ortools/sat/samples/RabbitsAndPheasantsSat.cs | 13 +- ortools/sat/samples/RankingSampleSat.cs | 64 +- ortools/sat/samples/ReifiedSampleSat.cs | 12 +- .../samples/SearchForAllSolutionsSampleSat.cs | 31 +- ortools/sat/samples/SimpleSatProgram.cs | 9 +- .../sat/samples/SolutionHintingSampleSat.cs | 31 +- ...eAndPrintIntermediateSolutionsSampleSat.cs | 31 +- .../samples/SolveWithTimeLimitSampleSat.cs | 9 +- ortools/sat/samples/StepFunctionSampleSat.cs | 44 +- .../samples/StopAfterNSolutionsSampleSat.cs | 40 +- ortools/util/csharp/NestedArrayHelper.cs | 71 +- ortools/util/csharp/ProtoHelper.cs | 22 +- 197 files changed, 10040 insertions(+), 12226 deletions(-) diff --git a/.clang-format b/.clang-format index 5f71237007..4513b0b224 100644 --- a/.clang-format +++ b/.clang-format @@ -4,4 +4,7 @@ BasedOnStyle: Google --- Language: Java BasedOnStyle: Google +--- +Language: CSharp +BasedOnStyle: Google ... diff --git a/.github/workflows/clang_format.yml b/.github/workflows/clang_format.yml index 70d14f8cc6..089fa51672 100644 --- a/.github/workflows/clang_format.yml +++ b/.github/workflows/clang_format.yml @@ -21,4 +21,4 @@ jobs: run: docker run --rm --init -v $(pwd):/repo linter:latest clang-format --help - name: Check current commit - run: docker run --rm --init -v $(pwd):/repo -w /repo linter:latest sh -c "git diff --diff-filter=d --name-only FETCH_HEAD | grep '\.c$\|\.h$\|\.cc$\|\.java$' | xargs clang-format --verbose --style=file --dry-run --Werror " + run: docker run --rm --init -v $(pwd):/repo -w /repo linter:latest sh -c "git diff --diff-filter=d --name-only FETCH_HEAD | grep '\.c$\|\.h$\|\.cc$\|\.java$\|\.cs$' | xargs clang-format --verbose --style=file --dry-run --Werror " diff --git a/examples/contrib/3_jugs_regular.cs b/examples/contrib/3_jugs_regular.cs index e9febc5f34..7bd612b44a 100644 --- a/examples/contrib/3_jugs_regular.cs +++ b/examples/contrib/3_jugs_regular.cs @@ -19,10 +19,7 @@ using System.Linq; using System.Diagnostics; using Google.OrTools.ConstraintSolver; -public class ThreeJugsRegular -{ - - +public class ThreeJugsRegular { /* * Global constraint regular * @@ -45,16 +42,8 @@ public class ThreeJugsRegular * F : accepting states * */ - static void MyRegular(Solver solver, - IntVar[] x, - int Q, - int S, - int[,] d, - int q0, - int[] F) { - - - + static void MyRegular(Solver solver, IntVar[] x, int Q, int S, int[, ] d, + int q0, int[] F) { Debug.Assert(Q > 0, "regular: 'Q' must be greater than zero"); Debug.Assert(S > 0, "regular: 'S' must be greater than zero"); @@ -62,22 +51,25 @@ public class ThreeJugsRegular // each possible input; each extra transition is from state zero // to state zero. This allows us to continue even if we hit a // non-accepted input. - int[][] d2 = new int[Q+1][]; - for(int i = 0; i <= Q; i++) { + int[][] d2 = new int [Q + 1] + []; + for (int i = 0; i <= Q; i++) { int[] row = new int[S]; - for(int j = 0; j < S; j++) { + for (int j = 0; j < S; j++) { if (i == 0) { row[j] = 0; } else { - row[j] = d[i-1,j]; + row[j] = d[i - 1, j]; } } d2[i] = row; } - int[] d2_flatten = (from i in Enumerable.Range(0, Q+1) - from j in Enumerable.Range(0, S) - select d2[i][j]).ToArray(); + int[] d2_flatten = + (from i in Enumerable.Range(0, Q + 1) from j in Enumerable.Range(0, S) + select d2 [i] + [j]) + .ToArray(); // If x has index set m..n, then a[m-1] holds the initial state // (q0), and a[i+1] holds the state we're in after processing @@ -86,25 +78,21 @@ public class ThreeJugsRegular int m = 0; int n = x.Length; - IntVar[] a = solver.MakeIntVarArray(n+1-m, 0,Q+1, "a"); + IntVar[] a = solver.MakeIntVarArray(n + 1 - m, 0, Q + 1, "a"); // Check that the final state is in F - solver.Add(a[a.Length-1].Member(F)); + solver.Add(a [a.Length - 1] + .Member(F)); // First state is q0 solver.Add(a[m] == q0); - for(int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { solver.Add(x[i] >= 1); solver.Add(x[i] <= S); // Determine a[i+1]: a[i+1] == d2[a[i], x[i]] - solver.Add(a[i+1] == d2_flatten.Element(((a[i]*S)+(x[i]-1)))); - + solver.Add(a[i + 1] == d2_flatten.Element(((a[i] * S) + (x[i] - 1)))); } - } - - - /** * * 3 jugs problem using regular constraint in Google CP Solver. @@ -127,18 +115,17 @@ public class ThreeJugsRegular * Also see http://www.hakank.org/or-tools/3_jugs_regular.py * */ - private static bool Solve(int n) - { + private static bool Solve(int n) { Solver solver = new Solver("ThreeJugProblem"); // // Data // - + // the DFA (for regular) int n_states = 14; int input_max = 15; - int initial_state = 1; // state 0 is for the failing state + int initial_state = 1; // state 0 is for the failing state int[] accepting_states = {15}; // @@ -170,36 +157,37 @@ public class ThreeJugsRegular // However, the DFA is easy to create from adjacency lists. // int[][] states = { - new int[] {2,9}, // state 1 - new int[] {3}, // state 2 - new int[] {4, 9}, // state 3 - new int[] {5}, // state 4 - new int[] {6,9}, // state 5 - new int[] {7}, // state 6 - new int[] {8,9}, // state 7 - new int[] {15}, // state 8 - new int[] {10}, // state 9 - new int[] {11}, // state 10 - new int[] {12}, // state 11 - new int[] {13}, // state 12 - new int[] {14}, // state 13 - new int[] {15} // state 14 + new int[]{2, 9}, // state 1 + new int[]{3}, // state 2 + new int[]{4, 9}, // state 3 + new int[]{5}, // state 4 + new int[]{6, 9}, // state 5 + new int[]{7}, // state 6 + new int[]{8, 9}, // state 7 + new int[]{15}, // state 8 + new int[]{10}, // state 9 + new int[]{11}, // state 10 + new int[]{12}, // state 11 + new int[]{13}, // state 12 + new int[]{14}, // state 13 + new int[]{15} // state 14 }; - - int[,] transition_fn = new int[n_states,input_max]; - for(int i = 0; i < n_states; i++) { - for(int j = 1; j <= input_max; j++) { + + int[, ] transition_fn = new int[n_states, input_max]; + for (int i = 0; i < n_states; i++) { + for (int j = 1; j <= input_max; j++) { bool in_states = false; - for(int s = 0; s < states[i].Length; s++) { - if (j == states[i][s]) { + for (int s = 0; s < states[i].Length; s++) { + if (j == states [i] + [s]) { in_states = true; break; } } if (in_states) { - transition_fn[i,j-1] = j; + transition_fn[i, j - 1] = j; } else { - transition_fn[i,j-1] = 0; + transition_fn[i, j - 1] = 0; } } } @@ -209,21 +197,21 @@ public class ThreeJugsRegular // the solution. // string[] nodes = { - "8,0,0", // 1 start - "5,0,3", // 2 - "5,3,0", // 3 - "2,3,3", // 4 - "2,5,1", // 5 - "7,0,1", // 6 - "7,1,0", // 7 - "4,1,3", // 8 - "3,5,0", // 9 - "3,2,3", // 10 - "6,2,0", // 11 - "6,0,2", // 12 - "1,5,2", // 13 - "1,4,3", // 14 - "4,4,0" // 15 goal + "8,0,0", // 1 start + "5,0,3", // 2 + "5,3,0", // 3 + "2,3,3", // 4 + "2,5,1", // 5 + "7,0,1", // 6 + "7,1,0", // 7 + "4,1,3", // 8 + "3,5,0", // 9 + "3,2,3", // 10 + "6,2,0", // 11 + "6,0,2", // 12 + "1,5,2", // 13 + "1,4,3", // 14 + "4,4,0" // 15 goal }; // @@ -233,35 +221,33 @@ public class ThreeJugsRegular // Note: We use 1..2 (instead of 0..1) and subtract 1 in the solution IntVar[] x = solver.MakeIntVarArray(n, 1, input_max, "x"); - // // Constraints // - MyRegular(solver, x, n_states, input_max, transition_fn, - initial_state, accepting_states); - - + MyRegular(solver, x, n_states, input_max, transition_fn, initial_state, + accepting_states); // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); bool found = false; while (solver.NextSolution()) { - Console.WriteLine("\nFound a solution of length {0}", n+1); + Console.WriteLine("\nFound a solution of length {0}", n + 1); int[] x_val = new int[n]; x_val[0] = 1; Console.WriteLine("{0} -> {1}", nodes[0], nodes[x_val[0]]); - for(int i = 1; i < n; i++) { + for (int i = 1; i < n; i++) { // Note: here we subtract 1 to get 0..1 - int val = (int)x[i].Value()-1; + int val = (int) x [i] + .Value() - + 1; x_val[i] = val; - Console.WriteLine("{0} -> {1}", nodes[x_val[i-1]], nodes[x_val[i]]); + Console.WriteLine("{0} -> {1}", nodes[x_val[i - 1]], nodes[x_val[i]]); } Console.WriteLine(); @@ -269,21 +255,17 @@ public class ThreeJugsRegular Console.WriteLine("WallTime: {0}ms", solver.WallTime()); Console.WriteLine("Failures: {0}", solver.Failures()); Console.WriteLine("Branches: {0} ", solver.Branches()); - - found = true; + found = true; } solver.EndSearch(); return found; - } - public static void Main(String[] args) - { - - for(int n = 1; n < 15; n++) { + public static void Main(String[] args) { + for (int n = 1; n < 15; n++) { bool found = Solve(n); if (found) { break; diff --git a/examples/contrib/a_puzzle.cs b/examples/contrib/a_puzzle.cs index edbb511b80..43fee86dba 100644 --- a/examples/contrib/a_puzzle.cs +++ b/examples/contrib/a_puzzle.cs @@ -17,8 +17,7 @@ using System; using System.Linq; using Google.OrTools.ConstraintSolver; -public class APuzzle -{ +public class APuzzle { /** * * From "God plays dice" @@ -84,13 +83,11 @@ public class APuzzle * * */ - private static void Solve(int p = 1) - { + private static void Solve(int p = 1) { Solver solver = new Solver("APuzzle"); Console.WriteLine("\nSolving p{0}", p); - // // Data // @@ -99,22 +96,21 @@ public class APuzzle // // Decision variables // - IntVar x0 = solver.MakeIntVar(0, n-1, "x0"); - IntVar x1 = solver.MakeIntVar(0, n-1, "x1"); - IntVar x2 = solver.MakeIntVar(0, n-1, "x2"); - IntVar x3 = solver.MakeIntVar(0, n-1, "x3"); - IntVar x4 = solver.MakeIntVar(0, n-1, "x4"); - IntVar x5 = solver.MakeIntVar(0, n-1, "x5"); - IntVar x6 = solver.MakeIntVar(0, n-1, "x6"); - IntVar x7 = solver.MakeIntVar(0, n-1, "x7"); - IntVar x8 = solver.MakeIntVar(0, n-1, "x8"); - IntVar x9 = solver.MakeIntVar(0, n-1, "x9"); + IntVar x0 = solver.MakeIntVar(0, n - 1, "x0"); + IntVar x1 = solver.MakeIntVar(0, n - 1, "x1"); + IntVar x2 = solver.MakeIntVar(0, n - 1, "x2"); + IntVar x3 = solver.MakeIntVar(0, n - 1, "x3"); + IntVar x4 = solver.MakeIntVar(0, n - 1, "x4"); + IntVar x5 = solver.MakeIntVar(0, n - 1, "x5"); + IntVar x6 = solver.MakeIntVar(0, n - 1, "x6"); + IntVar x7 = solver.MakeIntVar(0, n - 1, "x7"); + IntVar x8 = solver.MakeIntVar(0, n - 1, "x8"); + IntVar x9 = solver.MakeIntVar(0, n - 1, "x9"); - IntVar[] all = {x0,x1,x2,x3,x4,x5,x6,x7,x8,x9}; + IntVar[] all = {x0, x1, x2, x3, x4, x5, x6, x7, x8, x9}; // The unknown, i.e. 2581 = x - IntVar x = solver.MakeIntVar(0, n-1, "x"); - + IntVar x = solver.MakeIntVar(0, n - 1, "x"); // // Constraints @@ -126,120 +122,90 @@ public class APuzzle // - using a a matrix and Sum of each row if (p == 1) { - // Problem 1 - solver.Add(x8+x8+x0+x9 == 6); - solver.Add(x7+x1+x1+x1 == 0); - solver.Add(x2+x1+x7+x2 == 0); - solver.Add(x6+x6+x6+x6 == 4); - solver.Add(x1+x1+x1+x1 == 0); - solver.Add(x3+x2+x1+x3 == 0); - solver.Add(x7+x6+x6+x2 == 2); - solver.Add(x9+x3+x1+x2 == 1); - solver.Add(x0+x0+x0+x0 == 4); - solver.Add(x2+x2+x2+x2 == 0); - solver.Add(x3+x3+x3+x3 == 0); - solver.Add(x5+x5+x5+x5 == 0); - solver.Add(x8+x1+x9+x3 == 3); - solver.Add(x8+x0+x9+x6 == 5); - solver.Add(x7+x7+x7+x7 == 0); - solver.Add(x9+x9+x9+x9 == 4); - solver.Add(x7+x7+x5+x6 == 1); - solver.Add(x6+x8+x5+x5 == 3); - solver.Add(x9+x8+x8+x1 == 5); - solver.Add(x5+x5+x3+x1 == 0); + solver.Add(x8 + x8 + x0 + x9 == 6); + solver.Add(x7 + x1 + x1 + x1 == 0); + solver.Add(x2 + x1 + x7 + x2 == 0); + solver.Add(x6 + x6 + x6 + x6 == 4); + solver.Add(x1 + x1 + x1 + x1 == 0); + solver.Add(x3 + x2 + x1 + x3 == 0); + solver.Add(x7 + x6 + x6 + x2 == 2); + solver.Add(x9 + x3 + x1 + x2 == 1); + solver.Add(x0 + x0 + x0 + x0 == 4); + solver.Add(x2 + x2 + x2 + x2 == 0); + solver.Add(x3 + x3 + x3 + x3 == 0); + solver.Add(x5 + x5 + x5 + x5 == 0); + solver.Add(x8 + x1 + x9 + x3 == 3); + solver.Add(x8 + x0 + x9 + x6 == 5); + solver.Add(x7 + x7 + x7 + x7 == 0); + solver.Add(x9 + x9 + x9 + x9 == 4); + solver.Add(x7 + x7 + x5 + x6 == 1); + solver.Add(x6 + x8 + x5 + x5 == 3); + solver.Add(x9 + x8 + x8 + x1 == 5); + solver.Add(x5 + x5 + x3 + x1 == 0); // The unknown - solver.Add(x2+x5+x8+x1 == x); + solver.Add(x2 + x5 + x8 + x1 == x); } else if (p == 2) { - // Another representation of Problem 1 - int[,] problem1 = { - {8,8,0,9, 6}, - {7,1,1,1, 0}, - {2,1,7,2, 0}, - {6,6,6,6, 4}, - {1,1,1,1, 0}, - {3,2,1,3, 0}, - {7,6,6,2, 2}, - {9,3,1,2, 1}, - {0,0,0,0, 4}, - {2,2,2,2, 0}, - {3,3,3,3, 0}, - {5,5,5,5, 0}, - {8,1,9,3, 3}, - {8,0,9,6, 5}, - {7,7,7,7, 0}, - {9,9,9,9, 4}, - {7,7,5,6, 1}, - {6,8,5,5, 3}, - {9,8,8,1, 5}, - {5,5,3,1, 0} - }; + int[, ] problem1 = { + {8, 8, 0, 9, 6}, {7, 1, 1, 1, 0}, {2, 1, 7, 2, 0}, {6, 6, 6, 6, 4}, + {1, 1, 1, 1, 0}, {3, 2, 1, 3, 0}, {7, 6, 6, 2, 2}, {9, 3, 1, 2, 1}, + {0, 0, 0, 0, 4}, {2, 2, 2, 2, 0}, {3, 3, 3, 3, 0}, {5, 5, 5, 5, 0}, + {8, 1, 9, 3, 3}, {8, 0, 9, 6, 5}, {7, 7, 7, 7, 0}, {9, 9, 9, 9, 4}, + {7, 7, 5, 6, 1}, {6, 8, 5, 5, 3}, {9, 8, 8, 1, 5}, {5, 5, 3, 1, 0}}; - for(int i = 0; i < problem1.GetLength(0); i++) { - solver.Add( (from j in Enumerable.Range(0, 4) - select all[problem1[i,j]] - ).ToArray().Sum() == problem1[i,4] ); + for (int i = 0; i < problem1.GetLength(0); i++) { + solver.Add((from j in Enumerable.Range(0, 4) select all[problem1[i, j]]) + .ToArray() + .Sum() == problem1[i, 4]); } - solver.Add(all[2]+all[5]+all[8]+all[1] == x); + solver.Add(all[2] + all[5] + all[8] + all[1] == x); } else if (p == 3) { - // Problem 2 - solver.Add(x8+x8+x0+x9 == 6); - solver.Add(x7+x6+x6+x2 == 2); - solver.Add(x9+x3+x1+x2 == 1); - solver.Add(x8+x1+x9+x3 == 3); - solver.Add(x8+x0+x9+x6 == 5); - solver.Add(x7+x7+x5+x6 == 1); - solver.Add(x6+x8+x5+x5 == 3); - solver.Add(x9+x8+x8+x1 == 5); + solver.Add(x8 + x8 + x0 + x9 == 6); + solver.Add(x7 + x6 + x6 + x2 == 2); + solver.Add(x9 + x3 + x1 + x2 == 1); + solver.Add(x8 + x1 + x9 + x3 == 3); + solver.Add(x8 + x0 + x9 + x6 == 5); + solver.Add(x7 + x7 + x5 + x6 == 1); + solver.Add(x6 + x8 + x5 + x5 == 3); + solver.Add(x9 + x8 + x8 + x1 == 5); // The unknown - solver.Add(x2+x5+x8+x1 == x); + solver.Add(x2 + x5 + x8 + x1 == x); } else { - // Another representation of Problem 2 - int[,] problem2 = { - {8,8,0,9, 6}, - {7,6,6,2, 2}, - {9,3,1,2, 1}, - {8,1,9,3, 3}, - {8,0,9,6, 5}, - {7,7,5,6, 1}, - {6,8,5,5, 3}, - {9,8,8,1, 5} - }; + int[, ] problem2 = {{8, 8, 0, 9, 6}, {7, 6, 6, 2, 2}, {9, 3, 1, 2, 1}, + {8, 1, 9, 3, 3}, {8, 0, 9, 6, 5}, {7, 7, 5, 6, 1}, + {6, 8, 5, 5, 3}, {9, 8, 8, 1, 5}}; - for(int i = 0; i < problem2.GetLength(0); i++) { - solver.Add( (from j in Enumerable.Range(0, 4) - select all[problem2[i,j]] - ).ToArray().Sum() == problem2[i,4] ); + for (int i = 0; i < problem2.GetLength(0); i++) { + solver.Add((from j in Enumerable.Range(0, 4) select all[problem2[i, j]]) + .ToArray() + .Sum() == problem2[i, 4]); } - - solver.Add(all[2]+all[5]+all[8]+all[1] == x); + solver.Add(all[2] + all[5] + all[8] + all[1] == x); } - - // // Search // - DecisionBuilder db = solver.MakePhase(all, - Solver.INT_VAR_DEFAULT, - Solver.INT_VALUE_DEFAULT); - + DecisionBuilder db = + solver.MakePhase(all, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { Console.Write("x: {0} x0..x9: ", x.Value()); - for(int i = 0; i < n; i++) { - Console.Write(all[i].Value() + " "); + for (int i = 0; i < n; i++) { + Console.Write(all [i] + .Value() + + " "); } Console.WriteLine(); } @@ -250,12 +216,10 @@ public class APuzzle Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - for(int p = 1; p <= 4; p++) { + public static void Main(String[] args) { + for (int p = 1; p <= 4; p++) { Solve(p); } } diff --git a/examples/contrib/a_round_of_golf.cs b/examples/contrib/a_round_of_golf.cs index fb1316d125..d39bdd2b26 100644 --- a/examples/contrib/a_round_of_golf.cs +++ b/examples/contrib/a_round_of_golf.cs @@ -20,10 +20,7 @@ using System.Linq; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; - -public class ARoundOfGolf -{ - +public class ARoundOfGolf { /** * * A Round of Golf puzzle (Dell Logic Puzzles) in Google CP Solver. @@ -38,21 +35,20 @@ public class ARoundOfGolf * Stars: 1 * * When the Sunny Hills Country Club golf course isn't in use by club members, - * of course, it's open to the club's employees. Recently, Jack and three other - * workers at the golf course got together on their day off to play a round of - * eighteen holes of golf. - * Afterward, all four, including Mr. Green, went to the clubhouse to total - * their scorecards. Each man works at a different job (one is a short-order - * cook), and each shot a different score in the game. No one scored below - * 70 or above 85 strokes. From the clues below, can you discover each man's - * full name, job and golf score? + * of course, it's open to the club's employees. Recently, Jack and three + * other workers at the golf course got together on their day off to play a + * round of eighteen holes of golf. Afterward, all four, including Mr. Green, + * went to the clubhouse to total their scorecards. Each man works at a + * different job (one is a short-order cook), and each shot a different score + * in the game. No one scored below 70 or above 85 strokes. From the clues + * below, can you discover each man's full name, job and golf score? * - * 1. Bill, who is not the maintenance man, plays golf often and had the lowest - * score of the foursome. - * 2. Mr. Clubb, who isn't Paul, hit several balls into the woods and scored ten - * strokes more than the pro-shop clerk. - * 3. In some order, Frank and the caddy scored four and seven more strokes than - * Mr. Sands. + * 1. Bill, who is not the maintenance man, plays golf often and had the + * lowest score of the foursome. + * 2. Mr. Clubb, who isn't Paul, hit several balls into the woods and scored + * ten strokes more than the pro-shop clerk. + * 3. In some order, Frank and the caddy scored four and seven more strokes + * than Mr. Sands. * 4. Mr. Carter thought his score of 78 was one of his better games, even * though Frank's score was lower. * 5. None of the four scored exactly 81 strokes. @@ -63,41 +59,40 @@ public class ARoundOfGolf * See http://www.hakank.org/google_or_tools/a_round_of_golf.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("ARoundOfGolf"); // number of speakers int n = 4; - int Jack = 0; - int Bill = 1; - int Paul = 2; + int Jack = 0; + int Bill = 1; + int Paul = 2; int Frank = 3; // // Decision variables // - IntVar[] last_name = solver.MakeIntVarArray(n, 0, n-1, "last_name"); + IntVar[] last_name = solver.MakeIntVarArray(n, 0, n - 1, "last_name"); // IntVar Green = last_name[0]; // not used - IntVar Clubb = last_name[1]; - IntVar Sands = last_name[2]; + IntVar Clubb = last_name[1]; + IntVar Sands = last_name[2]; IntVar Carter = last_name[3]; - IntVar[] job = solver.MakeIntVarArray(n, 0, n-1, "job"); + IntVar[] job = solver.MakeIntVarArray(n, 0, n - 1, "job"); // IntVar cook = job[0]; // not used IntVar maintenance_man = job[1]; - IntVar clerk = job[2]; - IntVar caddy = job[3]; + IntVar clerk = job[2]; + IntVar caddy = job[3]; - IntVar[] score = solver.MakeIntVarArray(n, 70, 85, "score"); + IntVar[] score = solver.MakeIntVarArray(n, 70, 85, "score"); // for search - IntVar[] all = new IntVar[n*3]; - for(int i = 0; i < n; i++) { + IntVar[] all = new IntVar[n * 3]; + for (int i = 0; i < n; i++) { all[i] = last_name[i]; - all[i+n] = job[i]; - all[i+2*n] = score[i]; + all[i + n] = job[i]; + all[i + 2 * n] = score[i]; } // @@ -129,7 +124,7 @@ public class ARoundOfGolf IntVar b3_a_2 = score.Element(caddy) == score.Element(Sands) + 7; IntVar b3_b_1 = score.Element(Sands) + 7 == score[Frank]; IntVar b3_b_2 = score.Element(caddy) == score.Element(Sands) + 4; - solver.Add( (b3_a_1*b3_a_2) + (b3_b_1*b3_b_2) == 1); + solver.Add((b3_a_1 * b3_a_2) + (b3_b_1 * b3_b_2) == 1); // 4. Mr. Carter thought his score of 78 was one of his better games, // even though Frank's score was lower. @@ -138,32 +133,32 @@ public class ARoundOfGolf solver.Add(score[Frank] < score.Element(Carter)); // 5. None of the four scored exactly 81 strokes. - for(int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { solver.Add(score[i] != 81); } // // Search // - DecisionBuilder db = solver.MakePhase(all, - Solver.INT_VAR_DEFAULT, - Solver.INT_VALUE_DEFAULT); + DecisionBuilder db = + solver.MakePhase(all, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { Console.WriteLine( "Last name: " + - String.Join(", ", (from i in last_name - select i.Value().ToString()).ToArray())); + String.Join( + ", ", + (from i in last_name select i.Value().ToString()).ToArray())); Console.WriteLine( "Job : " + - String.Join(", ", (from i in job - select i.Value().ToString()).ToArray())); + String.Join(", ", + (from i in job select i.Value().ToString()).ToArray())); Console.WriteLine( "Score : " + - String.Join(", ", (from i in score - select i.Value().ToString()).ToArray())); + String.Join(", ", + (from i in score select i.Value().ToString()).ToArray())); } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); @@ -172,12 +167,7 @@ public class ARoundOfGolf Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/all_interval.cs b/examples/contrib/all_interval.cs index 793db46ac0..bf1cd8ac39 100644 --- a/examples/contrib/all_interval.cs +++ b/examples/contrib/all_interval.cs @@ -19,26 +19,21 @@ using System.IO; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; - -public class AllInterval -{ - +public class AllInterval { /** * * Implements the all interval problem. * See http://www.hakank.org/google_or_tools/all_interval.py * */ - private static void Solve(int n=12) - { + private static void Solve(int n = 12) { Solver solver = new Solver("AllInterval"); - // // Decision variables // - IntVar[] x = solver.MakeIntVarArray(n, 0, n-1, "x"); - IntVar[] diffs = solver.MakeIntVarArray(n-1, 1, n-1, "diffs"); + IntVar[] x = solver.MakeIntVarArray(n, 0, n - 1, "x"); + IntVar[] diffs = solver.MakeIntVarArray(n - 1, 1, n - 1, "diffs"); // // Constraints @@ -46,34 +41,34 @@ public class AllInterval solver.Add(x.AllDifferent()); solver.Add(diffs.AllDifferent()); - for(int k = 0; k < n - 1; k++) { + for (int k = 0; k < n - 1; k++) { // solver.Add(diffs[k] == (x[k + 1] - x[k]).Abs()); - solver.Add(diffs[k] == (x[k + 1] - x[k].Abs())); + solver.Add(diffs[k] == (x[k + 1] - x [k] + .Abs())); } - // symmetry breaking solver.Add(x[0] < x[n - 1]); solver.Add(diffs[0] < diffs[1]); - // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); while (solver.NextSolution()) { Console.Write("x: "); - for(int i = 0; i < n; i++) { - Console.Write("{0} ", x[i].Value()); + for (int i = 0; i < n; i++) { + Console.Write("{0} ", x [i] + .Value()); } Console.Write(" diffs: "); - for(int i = 0; i < n-1; i++) { - Console.Write("{0} ", diffs[i].Value()); + for (int i = 0; i < n - 1; i++) { + Console.Write("{0} ", diffs [i] + .Value()); } Console.WriteLine(); } @@ -84,12 +79,9 @@ public class AllInterval Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - public static void Main(String[] args) - { + public static void Main(String[] args) { int n = 12; if (args.Length > 0) { n = Convert.ToInt32(args[0]); diff --git a/examples/contrib/alldifferent_except_0.cs b/examples/contrib/alldifferent_except_0.cs index cbe0c6a13e..00982d439e 100644 --- a/examples/contrib/alldifferent_except_0.cs +++ b/examples/contrib/alldifferent_except_0.cs @@ -16,24 +16,19 @@ using System; using Google.OrTools.ConstraintSolver; - -public class AllDifferentExcept0Test -{ - +public class AllDifferentExcept0Test { // // Decomposition of alldifferent_except_0 // public static void AllDifferentExcept0(Solver solver, IntVar[] a) { - int n = a.Length; - for(int i = 0; i < n; i++) { - for(int j = 0; j < i; j++) { + for (int i = 0; i < n; i++) { + for (int j = 0; j < i; j++) { solver.Add((a[i] != 0) * (a[j] != 0) <= (a[i] != a[j])); } } } - /** * * Decomposition of alldifferent_except_0 @@ -42,8 +37,7 @@ public class AllDifferentExcept0Test * * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("AllDifferentExcept0"); // @@ -54,7 +48,7 @@ public class AllDifferentExcept0Test // // Decision variables // - IntVar[] x = solver.MakeIntVarArray(n, 0, n - 1 , "x"); + IntVar[] x = solver.MakeIntVarArray(n, 0, n - 1, "x"); // // Constraints @@ -63,25 +57,24 @@ public class AllDifferentExcept0Test // we also require at least 2 0's IntVar[] z_tmp = new IntVar[n]; - for(int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { z_tmp[i] = x[i] == 0; } IntVar z = z_tmp.Sum().VarWithName("z"); solver.Add(z == 2); - // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { Console.Write("z: {0} x: ", z.Value()); - for(int i = 0; i < n; i++) { - Console.Write("{0} ", x[i].Value()); + for (int i = 0; i < n; i++) { + Console.Write("{0} ", x [i] + .Value()); } Console.WriteLine(); @@ -93,11 +86,7 @@ public class AllDifferentExcept0Test Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/assignment.cs b/examples/contrib/assignment.cs index 17d9e0821d..a8956b5269 100644 --- a/examples/contrib/assignment.cs +++ b/examples/contrib/assignment.cs @@ -20,9 +20,7 @@ using System.Linq; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; -public class Assignment -{ - +public class Assignment { /** * * Assignment problem @@ -34,9 +32,7 @@ public class Assignment * See See http://www.hakank.org/or-tools/assignment.py * */ - private static void Solve() - { - + private static void Solve() { Solver solver = new Solver("Assignment"); // @@ -48,18 +44,13 @@ public class Assignment // interesting int rows = 4; int cols = 5; - int[,] cost = { - {14, 5, 8, 7, 15}, - { 2, 12, 6, 5, 3}, - { 7, 8, 3, 9, 7}, - { 2, 4, 6, 10, 1} - }; - + int[, ] cost = { + {14, 5, 8, 7, 15}, {2, 12, 6, 5, 3}, {7, 8, 3, 9, 7}, {2, 4, 6, 10, 1}}; // // Decision variables // - IntVar[,] x = solver.MakeBoolVarMatrix(rows, cols, "x"); + IntVar[, ] x = solver.MakeBoolVarMatrix(rows, cols, "x"); IntVar[] x_flat = x.Flatten(); // @@ -68,57 +59,62 @@ public class Assignment // Exacly one assignment per row (task), // i.e. all rows must be assigned with one worker - for(int i = 0; i < rows; i++) { - solver.Add((from j in Enumerable.Range(0, cols) - select x[i,j]).ToArray().Sum() == 1); + for (int i = 0; i < rows; i++) { + solver.Add((from j in Enumerable.Range(0, cols) select x[i, j]) + .ToArray() + .Sum() == 1); } // At most one assignments per column (worker) - for(int j = 0; j < cols; j++) { - solver.Add((from i in Enumerable.Range(0, rows) - select x[i,j]).ToArray().Sum() <= 1); + for (int j = 0; j < cols; j++) { + solver.Add((from i in Enumerable.Range(0, rows) select x[i, j]) + .ToArray() + .Sum() <= 1); } // Total cost - IntVar total_cost = (from i in Enumerable.Range(0, rows) - from j in Enumerable.Range(0, cols) - select (cost[i,j] * x[i,j])).ToArray().Sum().Var(); + IntVar total_cost = + (from i in Enumerable.Range(0, rows) from j in Enumerable.Range(0, cols) + select(cost[i, j] * x[i, j])) + .ToArray() + .Sum() + .Var(); // // objective // OptimizeVar objective = total_cost.Minimize(1); - // // Search // - DecisionBuilder db = solver.MakePhase(x_flat, - Solver.INT_VAR_DEFAULT, + DecisionBuilder db = solver.MakePhase(x_flat, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db, objective); while (solver.NextSolution()) { Console.WriteLine("total_cost: {0}", total_cost.Value()); - for(int i = 0; i < rows; i++) { - for(int j = 0; j < cols; j++) { - Console.Write(x[i,j].Value() + " "); + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + Console.Write(x [i, j] + .Value() + + " "); } Console.WriteLine(); } Console.WriteLine(); Console.WriteLine("Assignments:"); - for(int i = 0; i < rows; i++) { + for (int i = 0; i < rows; i++) { Console.Write("Task " + i); - for(int j = 0; j < cols; j++) { - if (x[i,j].Value() == 1) { + for (int j = 0; j < cols; j++) { + if (x [i, j] + .Value() == 1) { Console.WriteLine(" is done by " + j); } } } Console.WriteLine(); - } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); @@ -127,11 +123,7 @@ public class Assignment Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/broken_weights.cs b/examples/contrib/broken_weights.cs index ff05dbb9a6..34a3e39811 100644 --- a/examples/contrib/broken_weights.cs +++ b/examples/contrib/broken_weights.cs @@ -17,10 +17,7 @@ using System; using System.Linq; using Google.OrTools.ConstraintSolver; - -public class BrokenWeights -{ - +public class BrokenWeights { /** * * Broken weights problem. @@ -49,46 +46,40 @@ public class BrokenWeights * Also see http://www.hakank.org/or-tools/broken_weights.py * */ - private static void Solve(int m=40, int n=4) - { + private static void Solve(int m = 40, int n = 4) { Solver solver = new Solver("BrokenWeights"); Console.WriteLine("Total weight (m): {0}", m); Console.WriteLine("Number of pieces (n): {0}", n); Console.WriteLine(); - // // Decision variables // - IntVar[] weights = solver.MakeIntVarArray(n, 1, m , "weights"); - IntVar[,] x = new IntVar[m, n]; + IntVar[] weights = solver.MakeIntVarArray(n, 1, m, "weights"); + IntVar[, ] x = new IntVar[m, n]; // Note: in x_flat we insert the weights array before x - IntVar[] x_flat = new IntVar[m*n + n]; - for(int j = 0; j < n; j++) { + IntVar[] x_flat = new IntVar[m * n + n]; + for (int j = 0; j < n; j++) { x_flat[j] = weights[j]; } - for(int i = 0; i < m; i++) { - for(int j = 0; j < n; j++) { - x[i,j] = solver.MakeIntVar(-1, 1, "x["+i+","+j+"]"); - x_flat[n+i*n+j] = x[i,j]; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + x[i, j] = solver.MakeIntVar(-1, 1, "x[" + i + "," + j + "]"); + x_flat[n + i * n + j] = x[i, j]; } } - - // // Constraints // - // symmetry breaking - for(int j = 1; j < n; j++) { - solver.Add(weights[j-1] < weights[j]); + for (int j = 1; j < n; j++) { + solver.Add(weights[j - 1] < weights[j]); } - solver.Add(weights.Sum() == m); // Check that all weights from 1 to n (default 40) can be made. @@ -98,41 +89,42 @@ public class BrokenWeights // -1, 0, or 1 of the weights, assuming that // -1 is the weights on the left and 1 is on the right. // - for(int i = 0; i < m; i++) { - solver.Add( (from j in Enumerable.Range(0, n) - select weights[j] * x[i,j]).ToArray().Sum() == i+1); + for (int i = 0; i < m; i++) { + solver.Add((from j in Enumerable.Range(0, n) select weights[j] * x[i, j]) + .ToArray() + .Sum() == i + 1); } - // // The objective is to minimize the last weight. // - OptimizeVar obj = weights[n-1].Minimize(1); - + OptimizeVar obj = weights [n - 1] + .Minimize(1); // // Search // - DecisionBuilder db = solver.MakePhase(x_flat, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(x_flat, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db, obj); while (solver.NextSolution()) { Console.Write("weights: "); - for(int i = 0; i < n; i++) { - Console.Write("{0,3} ", weights[i].Value()); + for (int i = 0; i < n; i++) { + Console.Write("{0,3} ", weights [i] + .Value()); } Console.WriteLine(); - for(int i = 0; i < 10+n*4; i++) { + for (int i = 0; i < 10 + n * 4; i++) { Console.Write("-"); } Console.WriteLine(); - for(int i = 0; i < m; i++) { - Console.Write("weight {0,2}:", i+1); - for(int j = 0; j < n; j++) { - Console.Write("{0,3} ", x[i,j].Value()); + for (int i = 0; i < m; i++) { + Console.Write("weight {0,2}:", i + 1); + for (int j = 0; j < n; j++) { + Console.Write("{0,3} ", x [i, j] + .Value()); } Console.WriteLine(); } @@ -145,12 +137,9 @@ public class BrokenWeights Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - + public static void Main(String[] args) { int m = 40; int n = 4; diff --git a/examples/contrib/bus_schedule.cs b/examples/contrib/bus_schedule.cs index 5b23e569e3..b711bbb3a4 100644 --- a/examples/contrib/bus_schedule.cs +++ b/examples/contrib/bus_schedule.cs @@ -20,10 +20,7 @@ using System.Linq; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; -public class BusSchedule -{ - - +public class BusSchedule { /** * * Bus scheduling. @@ -31,15 +28,13 @@ public class BusSchedule * Minimize number of buses in timeslots. * * Problem from Taha "Introduction to Operations Research", page 58. - * + * * This is a slightly more general model than Taha's. * * Also see, http://www.hakank.org/or-tools/bus_schedule.py * */ - private static long Solve(long num_buses_check = 0) - { - + private static long Solve(long num_buses_check = 0) { Solver solver = new Solver("BusSchedule"); // @@ -63,44 +58,40 @@ public class BusSchedule // // Meet the demands for this and the next time slot. - for(int i = 0; i < time_slots - 1; i++) { - solver.Add(x[i]+x[i+1] >= demands[i]); + for (int i = 0; i < time_slots - 1; i++) { + solver.Add(x[i] + x[i + 1] >= demands[i]); } // The demand "around the clock" - solver.Add(x[time_slots-1] + x[0] - demands[time_slots-1] == 0); + solver.Add(x[time_slots - 1] + x[0] - demands[time_slots - 1] == 0); // For showing all solutions of minimal number of buses if (num_buses_check > 0) { solver.Add(num_buses == num_buses_check); } - // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); if (num_buses_check == 0) { - // Minimize num_buses OptimizeVar obj = num_buses.Minimize(1); solver.NewSearch(db, obj); } else { - solver.NewSearch(db); - } long result = 0; while (solver.NextSolution()) { result = num_buses.Value(); Console.Write("x: "); - for(int i = 0; i < time_slots; i++) { - Console.Write("{0,2} ", x[i].Value()); + for (int i = 0; i < time_slots; i++) { + Console.Write("{0,2} ", x [i] + .Value()); } Console.WriteLine("num_buses: " + num_buses.Value()); } @@ -113,19 +104,13 @@ public class BusSchedule solver.EndSearch(); return result; - } - - - public static void Main(String[] args) - { - + public static void Main(String[] args) { Console.WriteLine("Check for minimum number of buses: "); long num_buses = Solve(); Console.WriteLine("\n... got {0} as minimal value.", num_buses); Console.WriteLine("\nAll solutions: ", num_buses); num_buses = Solve(num_buses); - } } diff --git a/examples/contrib/circuit.cs b/examples/contrib/circuit.cs index c4026c2159..304264d37a 100644 --- a/examples/contrib/circuit.cs +++ b/examples/contrib/circuit.cs @@ -19,11 +19,7 @@ using System.IO; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; - -public class CircuitTest -{ - - +public class CircuitTest { /** * circuit(solver, x) * @@ -34,7 +30,6 @@ public class CircuitTest * since C# is 0-based. */ public static void circuit(Solver solver, IntVar[] x) { - int n = x.Length; IntVar[] z = solver.MakeIntVarArray(n, 0, n - 1, "z"); @@ -43,18 +38,17 @@ public class CircuitTest // put the orbit of x[0] in z[0..n-1] solver.Add(z[0] == x[0]); - for(int i = 1; i < n-1; i++) { - solver.Add(z[i] == x.Element(z[i-1])); + for (int i = 1; i < n - 1; i++) { + solver.Add(z[i] == x.Element(z[i - 1])); } // z may not be 0 for i < n-1 - for(int i = 1; i < n - 1; i++) { + for (int i = 1; i < n - 1; i++) { solver.Add(z[i] != 0); } // when i = n-1 it must be 0 solver.Add(z[n - 1] == 0); - } /** @@ -63,35 +57,31 @@ public class CircuitTest * See http://www.hakank.org/google_or_tools/circuit.py * */ - private static void Solve(int n = 5) - { + private static void Solve(int n = 5) { Solver solver = new Solver("Circuit"); - // // Decision variables // - IntVar[] x = solver.MakeIntVarArray(n, 0, n-1, "x"); + IntVar[] x = solver.MakeIntVarArray(n, 0, n - 1, "x"); // // Constraints // circuit(solver, x); - // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.INT_VAR_DEFAULT, - Solver.INT_VALUE_DEFAULT); - + DecisionBuilder db = + solver.MakePhase(x, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { - for(int i = 0; i < n; i++) { - Console.Write("{0} ", x[i].Value()); + for (int i = 0; i < n; i++) { + Console.Write("{0} ", x [i] + .Value()); } Console.WriteLine(); } @@ -102,12 +92,9 @@ public class CircuitTest Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - public static void Main(String[] args) - { + public static void Main(String[] args) { int n = 5; if (args.Length > 0) { n = Convert.ToInt32(args[0]); diff --git a/examples/contrib/circuit2.cs b/examples/contrib/circuit2.cs index 4e2ed0a26b..139787a2e0 100644 --- a/examples/contrib/circuit2.cs +++ b/examples/contrib/circuit2.cs @@ -19,11 +19,7 @@ using System.IO; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; - -public class CircuitTest2 -{ - - +public class CircuitTest2 { /** * circuit(solver, x, z) * @@ -36,7 +32,6 @@ public class CircuitTest2 * since C# is 0-based. */ public static void circuit(Solver solver, IntVar[] x, IntVar[] z) { - int n = x.Length; solver.Add(x.AllDifferent()); @@ -44,18 +39,17 @@ public class CircuitTest2 // put the orbit of x[0] in z[0..n-1] solver.Add(z[0] == x[0]); - for(int i = 1; i < n-1; i++) { - solver.Add(z[i] == x.Element(z[i-1])); + for (int i = 1; i < n - 1; i++) { + solver.Add(z[i] == x.Element(z[i - 1])); } // z may not be 0 for i < n-1 - for(int i = 1; i < n - 1; i++) { + for (int i = 1; i < n - 1; i++) { solver.Add(z[i] != 0); } // when i = n-1 it must be 0 solver.Add(z[n - 1] == 0); - } /** @@ -67,42 +61,38 @@ public class CircuitTest2 * Thus the extracted path is 0 -> 3 -> 2 -> 4 -> 1 -> 0 * */ - private static void Solve(int n = 5) - { + private static void Solve(int n = 5) { Solver solver = new Solver("CircuitTest2"); - // // Decision variables // - IntVar[] x = solver.MakeIntVarArray(n, 0, n-1, "x"); - IntVar[] path = solver.MakeIntVarArray(n, 0, n-1, "path"); + IntVar[] x = solver.MakeIntVarArray(n, 0, n - 1, "x"); + IntVar[] path = solver.MakeIntVarArray(n, 0, n - 1, "path"); // // Constraints // circuit(solver, x, path); - - // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.INT_VAR_DEFAULT, - Solver.INT_VALUE_DEFAULT); - + DecisionBuilder db = + solver.MakePhase(x, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { Console.Write("x : "); - for(int i = 0; i < n; i++) { - Console.Write("{0} ", x[i].Value()); + for (int i = 0; i < n; i++) { + Console.Write("{0} ", x [i] + .Value()); } Console.Write("\npath: "); - for(int i = 0; i < n; i++) { - Console.Write("{0} ", path[i].Value()); + for (int i = 0; i < n; i++) { + Console.Write("{0} ", path [i] + .Value()); } Console.WriteLine("\n"); } @@ -113,12 +103,9 @@ public class CircuitTest2 Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - public static void Main(String[] args) - { + public static void Main(String[] args) { int n = 5; if (args.Length > 0) { n = Convert.ToInt32(args[0]); diff --git a/examples/contrib/coins3.cs b/examples/contrib/coins3.cs index de242f192d..79cfe4a6a7 100644 --- a/examples/contrib/coins3.cs +++ b/examples/contrib/coins3.cs @@ -19,10 +19,7 @@ using System.Collections.Generic; using System.Linq; using Google.OrTools.ConstraintSolver; - -public class Coins3 -{ - +public class Coins3 { /** * * Coin application. @@ -37,18 +34,16 @@ public class Coins3 * euro cents, of denomination 1, 2, 5, 10, 20, 50 * """ - * Also see http://www.hakank.org/or-tools/coins3.py + * Also see http://www.hakank.org/or-tools/coins3.py * */ - private static void Solve() - { - + private static void Solve() { Solver solver = new Solver("Coins3"); // // Data // - int n = 6; // number of different coins + int n = 6; // number of different coins int[] variables = {1, 2, 5, 10, 25, 50}; IEnumerable RANGE = Enumerable.Range(0, n); @@ -59,20 +54,18 @@ public class Coins3 IntVar[] x = solver.MakeIntVarArray(n, 0, 99, "x"); IntVar num_coins = x.Sum().VarWithName("num_coins"); - // // Constraints // // Check that all changes from 1 to 99 can be made. - for(int j = 1; j < 100; j++) { + for (int j = 1; j < 100; j++) { IntVar[] tmp = solver.MakeIntVarArray(n, 0, 99, "tmp"); solver.Add(tmp.ScalProd(variables) == j); - foreach(int i in RANGE) { + foreach (int i in RANGE) { solver.Add(tmp[i] <= x[i]); } - } // @@ -83,8 +76,7 @@ public class Coins3 // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.CHOOSE_MIN_SIZE_LOWEST_MAX, + DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_MIN_SIZE_LOWEST_MAX, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db, obj); @@ -92,8 +84,10 @@ public class Coins3 while (solver.NextSolution()) { Console.WriteLine("num_coins: {0}", num_coins.Value()); Console.Write("x: "); - foreach(int i in RANGE) { - Console.Write(x[i].Value() + " "); + foreach (int i in RANGE) { + Console.Write(x [i] + .Value() + + " "); } Console.WriteLine(); } @@ -104,11 +98,7 @@ public class Coins3 Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/coins_grid.cs b/examples/contrib/coins_grid.cs index 06eb73548f..8be6ed29e3 100644 --- a/examples/contrib/coins_grid.cs +++ b/examples/contrib/coins_grid.cs @@ -16,23 +16,20 @@ using System; using Google.OrTools.ConstraintSolver; -public class CoinsGrid -{ - +public class CoinsGrid { /** * * Solves the Coins Grid problm. * See http://www.hakank.org/google_or_tools/coins_grid.py * */ - private static void Solve(int n = 31, int c = 14) - { + private static void Solve(int n = 31, int c = 14) { Solver solver = new Solver("CoinsGrid"); // // Decision variables // - IntVar[,] x = solver.MakeIntVarMatrix(n, n, 0, 1 , "x"); + IntVar[, ] x = solver.MakeIntVarMatrix(n, n, 0, 1, "x"); IntVar[] x_flat = x.Flatten(); // @@ -40,12 +37,12 @@ public class CoinsGrid // // sum row/columns == c - for(int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { IntVar[] row = new IntVar[n]; IntVar[] col = new IntVar[n]; - for(int j = 0; j < n; j++) { - row[j] = x[i,j]; - col[j] = x[j,i]; + for (int j = 0; j < n; j++) { + row[j] = x[i, j]; + col[j] = x[j, i]; } solver.Add(row.Sum() == c); solver.Add(col.Sum() == c); @@ -53,9 +50,9 @@ public class CoinsGrid // quadratic horizonal distance IntVar[] obj_tmp = new IntVar[n * n]; - for(int i = 0; i < n; i++) { - for(int j = 0; j < n; j++) { - obj_tmp[i * n + j] = (x[i,j] * (i - j) * (i - j)).Var(); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + obj_tmp[i * n + j] = (x[i, j] * (i - j) * (i - j)).Var(); } } IntVar obj_var = obj_tmp.Sum().Var(); @@ -68,17 +65,18 @@ public class CoinsGrid // // Search // - DecisionBuilder db = solver.MakePhase(x_flat, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(x_flat, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MAX_VALUE); solver.NewSearch(db, obj); while (solver.NextSolution()) { Console.WriteLine("obj: " + obj_var.Value()); - for(int i = 0; i < n; i++) { - for(int j = 0; j < n; j++) { - Console.Write(x[i,j].Value() + " "); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + Console.Write(x [i, j] + .Value() + + " "); } Console.WriteLine(); } @@ -91,11 +89,9 @@ public class CoinsGrid Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { + public static void Main(String[] args) { int n = 31; int c = 14; @@ -107,7 +103,6 @@ public class CoinsGrid c = Convert.ToInt32(args[1]); } - Solve(n, c); } } diff --git a/examples/contrib/combinatorial_auction2.cs b/examples/contrib/combinatorial_auction2.cs index c85d2acec1..887ab179b0 100644 --- a/examples/contrib/combinatorial_auction2.cs +++ b/examples/contrib/combinatorial_auction2.cs @@ -19,8 +19,7 @@ using System.Collections; using System.Collections.Generic; using Google.OrTools.ConstraintSolver; -public class CombinatorialAuction2 -{ +public class CombinatorialAuction2 { /** * * Combinatorial auction. @@ -35,8 +34,7 @@ public class CombinatorialAuction2 * http://www.hakank.org/numberjack/combinatorial_auction.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("CombinatorialAuction2"); // @@ -46,15 +44,15 @@ public class CombinatorialAuction2 // the items for each bid int[][] items = { - new int[] {0,1}, // A,B - new int[] {0,2}, // A, C - new int[] {1,3}, // B,D - new int[] {1,2,3}, // B,C,D - new int[] {0} // A + new int[]{0, 1}, // A,B + new int[]{0, 2}, // A, C + new int[]{1, 3}, // B,D + new int[]{1, 2, 3}, // B,C,D + new int[]{0} // A }; - int[] bid_ids = {0,1,2,3}; - int[] bid_amount = {10,20,30,40,14}; + int[] bid_ids = {0, 1, 2, 3}; + int[] bid_amount = {10, 20, 30, 40, 14}; // // Decision variables @@ -66,20 +64,15 @@ public class CombinatorialAuction2 // Constraints // - foreach(int bid_id in bid_ids) { - + foreach (int bid_id in bid_ids) { var tmp2 = (from item in Enumerable.Range(0, n) - from i in Enumerable.Range(0, items[item].Length) - where items[item][i] == bid_id - select x[item]); + from i in Enumerable.Range(0, items[item].Length) + where items [item] + [i] == bid_id select x[item]); solver.Add(tmp2.ToArray().Sum() <= 1); - } - - - // // Objective // @@ -88,16 +81,17 @@ public class CombinatorialAuction2 // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db, obj); while (solver.NextSolution()) { Console.Write("z: {0,2} x: ", z.Value()); - for(int i = 0; i < n; i++) { - Console.Write(x[i].Value() + " "); + for (int i = 0; i < n; i++) { + Console.Write(x [i] + .Value() + + " "); } Console.WriteLine(); } @@ -108,11 +102,7 @@ public class CombinatorialAuction2 Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/contiguity_regular.cs b/examples/contrib/contiguity_regular.cs index a22cc5c290..0ec9d752f1 100644 --- a/examples/contrib/contiguity_regular.cs +++ b/examples/contrib/contiguity_regular.cs @@ -19,10 +19,7 @@ using System.Linq; using System.Diagnostics; using Google.OrTools.ConstraintSolver; -public class ContiguityRegular -{ - - +public class ContiguityRegular { /* * Global constraint regular * @@ -45,16 +42,8 @@ public class ContiguityRegular * F : accepting states * */ - static void MyRegular(Solver solver, - IntVar[] x, - int Q, - int S, - int[,] d, - int q0, - int[] F) { - - - + static void MyRegular(Solver solver, IntVar[] x, int Q, int S, int[, ] d, + int q0, int[] F) { Debug.Assert(Q > 0, "regular: 'Q' must be greater than zero"); Debug.Assert(S > 0, "regular: 'S' must be greater than zero"); @@ -62,22 +51,25 @@ public class ContiguityRegular // each possible input; each extra transition is from state zero // to state zero. This allows us to continue even if we hit a // non-accepted input. - int[][] d2 = new int[Q+1][]; - for(int i = 0; i <= Q; i++) { + int[][] d2 = new int [Q + 1] + []; + for (int i = 0; i <= Q; i++) { int[] row = new int[S]; - for(int j = 0; j < S; j++) { + for (int j = 0; j < S; j++) { if (i == 0) { row[j] = 0; } else { - row[j] = d[i-1,j]; + row[j] = d[i - 1, j]; } } d2[i] = row; } - int[] d2_flatten = (from i in Enumerable.Range(0, Q+1) - from j in Enumerable.Range(0, S) - select d2[i][j]).ToArray(); + int[] d2_flatten = + (from i in Enumerable.Range(0, Q + 1) from j in Enumerable.Range(0, S) + select d2 [i] + [j]) + .ToArray(); // If x has index set m..n, then a[m-1] holds the initial state // (q0), and a[i+1] holds the state we're in after processing @@ -86,50 +78,43 @@ public class ContiguityRegular int m = 0; int n = x.Length; - IntVar[] a = solver.MakeIntVarArray(n+1-m, 0,Q+1, "a"); + IntVar[] a = solver.MakeIntVarArray(n + 1 - m, 0, Q + 1, "a"); // Check that the final state is in F - solver.Add(a[a.Length-1].Member(F)); + solver.Add(a [a.Length - 1] + .Member(F)); // First state is q0 solver.Add(a[m] == q0); - for(int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { solver.Add(x[i] >= 1); solver.Add(x[i] <= S); // Determine a[i+1]: a[i+1] == d2[a[i], x[i]] - solver.Add(a[i+1] == d2_flatten.Element(((a[i]*S)+(x[i]-1)))); - + solver.Add(a[i + 1] == d2_flatten.Element(((a[i] * S) + (x[i] - 1)))); } - } - static void MyContiguity(Solver solver, IntVar[] x) { - // the DFA (for regular) int n_states = 3; int input_max = 2; - int initial_state = 1; // note: state 0 is used for the failing state - // in MyRegular + int initial_state = 1; // note: state 0 is used for the failing state + // in MyRegular // all states are accepting states - int[] accepting_states = {1,2,3}; + int[] accepting_states = {1, 2, 3}; // The regular expression 0*1*0* - int[,] transition_fn = - { - {1,2}, // state 1 (start): input 0 -> state 1, input 1 -> state 2 i.e. 0* - {3,2}, // state 2: 1* - {3,0}, // state 3: 0* - }; - - MyRegular(solver, x, n_states, input_max, transition_fn, - initial_state, accepting_states); - - + int[, ] transition_fn = { + {1, + 2}, // state 1 (start): input 0 -> state 1, input 1 -> state 2 i.e. 0* + {3, 2}, // state 2: 1* + {3, 0}, // state 3: 0* + }; + MyRegular(solver, x, n_states, input_max, transition_fn, initial_state, + accepting_states); } - /** * * Global constraint contiguity using regular @@ -152,15 +137,13 @@ public class ContiguityRegular * Also see http://www.hakank.org/or-tools/contiguity_regular.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("ContiguityRegular"); // // Data // - int n = 7; // length of the array - + int n = 7; // length of the array // // Decision variables @@ -169,26 +152,26 @@ public class ContiguityRegular // Note: We use 1..2 (instead of 0..1) and subtract 1 in the solution IntVar[] reg_input = solver.MakeIntVarArray(n, 1, 2, "reg_input"); - // // Constraints // MyContiguity(solver, reg_input); - // // Search // - DecisionBuilder db = solver.MakePhase(reg_input, - Solver.CHOOSE_FIRST_UNBOUND, - Solver.ASSIGN_MIN_VALUE); + DecisionBuilder db = solver.MakePhase( + reg_input, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); while (solver.NextSolution()) { - for(int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { // Note: here we subtract 1 to get 0..1 - Console.Write((reg_input[i].Value()-1) + " "); + Console.Write((reg_input [i] + .Value() - + 1) + + " "); } Console.WriteLine(); } @@ -199,11 +182,7 @@ public class ContiguityRegular Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/contiguity_transition.cs b/examples/contrib/contiguity_transition.cs index 3cb90d486d..9a8ea34d5a 100644 --- a/examples/contrib/contiguity_transition.cs +++ b/examples/contrib/contiguity_transition.cs @@ -19,35 +19,25 @@ using System.Linq; using System.Diagnostics; using Google.OrTools.ConstraintSolver; -public class ContiguityRegular -{ - +public class ContiguityRegular { static void MyContiguity(Solver solver, IntVar[] x) { - // the DFA (for regular) int initial_state = 1; // all states are accepting states - int[] accepting_states = {1,2,3}; + int[] accepting_states = {1, 2, 3}; // The regular expression 0*1*0* {state, input, next state} - long[][] transition_tuples = { - new long[] {1, 0, 1}, - new long[] {1, 1, 2}, - new long[] {2, 0, 3}, - new long[] {2, 1, 2}, - new long[] {3, 0, 3} - }; + long[][] transition_tuples = {new long[]{1, 0, 1}, new long[]{1, 1, 2}, + new long[]{2, 0, 3}, new long[]{2, 1, 2}, + new long[]{3, 0, 3}}; IntTupleSet result = new IntTupleSet(3); result.InsertAll(transition_tuples); - solver.Add(x.Transition(result, - initial_state, - accepting_states)); + solver.Add(x.Transition(result, initial_state, accepting_states)); } - /** * * Global constraint contiguity using Transition @@ -70,15 +60,13 @@ public class ContiguityRegular * Also see http://www.hakank.org/or-tools/contiguity_regular.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("ContiguityRegular"); // // Data // - int n = 7; // length of the array - + int n = 7; // length of the array // // Decision variables @@ -86,25 +74,24 @@ public class ContiguityRegular IntVar[] reg_input = solver.MakeIntVarArray(n, 0, 1, "reg_input"); - // // Constraints // MyContiguity(solver, reg_input); - // // Search // - DecisionBuilder db = solver.MakePhase(reg_input, - Solver.CHOOSE_FIRST_UNBOUND, - Solver.ASSIGN_MIN_VALUE); + DecisionBuilder db = solver.MakePhase( + reg_input, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); while (solver.NextSolution()) { - for(int i = 0; i < n; i++) { - Console.Write((reg_input[i].Value()) + " "); + for (int i = 0; i < n; i++) { + Console.Write((reg_input [i] + .Value()) + + " "); } Console.WriteLine(); } @@ -115,11 +102,7 @@ public class ContiguityRegular Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/costas_array.cs b/examples/contrib/costas_array.cs index 060e72c46c..af85b3a5e2 100644 --- a/examples/contrib/costas_array.cs +++ b/examples/contrib/costas_array.cs @@ -20,13 +20,11 @@ using System.Linq; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; -public class CostasArray -{ - +public class CostasArray { /** * * Costas array - * + * * From http://mathworld.wolfram.com/CostasArray.html: * """ * An order-n Costas array is a permutation on {1,...,n} such @@ -36,15 +34,13 @@ public class CostasArray * and {4}. Since each row contains no duplications, the permutation * is therefore a Costas array. * """ - * + * * Also see * http://en.wikipedia.org/wiki/Costas_array * http://hakank.org/or-tools/costas_array.py * */ - private static void Solve(int n = 6) - { - + private static void Solve(int n = 6) { Solver solver = new Solver("CostasArray"); // @@ -56,19 +52,19 @@ public class CostasArray // Decision variables // IntVar[] costas = solver.MakeIntVarArray(n, 1, n, "costas"); - IntVar[,] differences = solver.MakeIntVarMatrix(n, n, -n+1, n-1, - "differences"); + IntVar[, ] differences = + solver.MakeIntVarMatrix(n, n, -n + 1, n - 1, "differences"); // // Constraints // - + // Fix the values in the lower triangle in the // difference matrix to -n+1. This removes variants // of the difference matrix for the the same Costas array. - for(int i = 0; i < n; i++) { - for(int j = 0; j <= i; j++ ) { - solver.Add(differences[i,j] == -n+1); + for (int i = 0; i < n; i++) { + for (int j = 0; j <= i; j++) { + solver.Add(differences[i, j] == -n + 1); } } @@ -77,75 +73,69 @@ public class CostasArray // solver.Add(costas.AllDifferent()); - // "How do the positions in the Costas array relate // to the elements of the distance triangle." - for(int i = 0; i < n; i++) { - for(int j = 0; j < n; j++) { + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { if (i < j) { - solver.Add( differences[i,j] - (costas[j] - costas[j-i-1]) == 0); + solver.Add(differences[i, j] - (costas[j] - costas[j - i - 1]) == 0); } } } - // "All entries in a particular row of the difference // triangle must be distint." - for(int i = 0; i < n-2; i++) { - IntVar[] tmp = ( - from j in Enumerable.Range(0, n) - where j > i - select differences[i,j]).ToArray(); + for (int i = 0; i < n - 2; i++) { + IntVar[] tmp = (from j in Enumerable.Range(0, n) + where j > i select differences[i, j]) + .ToArray(); solver.Add(tmp.AllDifferent()); - } - + // // "All the following are redundant - only here to speed up search." // // "We can never place a 'token' in the same row as any other." - for(int i = 0; i < n; i++) { - for(int j = 0; j < n; j++) { + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { if (i < j) { - solver.Add(differences[i,j] != 0); - solver.Add(differences[i,j] != 0); + solver.Add(differences[i, j] != 0); + solver.Add(differences[i, j] != 0); } } } - for(int k = 2; k < n; k++) { - for(int l = 2; l < n; l++) { + for (int k = 2; k < n; k++) { + for (int l = 2; l < n; l++) { if (k < l) { - solver.Add( - (differences[k-2,l-1] + differences[k,l]) - - (differences[k-1,l-1] + differences[k-1,l]) == 0 - ); + solver.Add((differences[k - 2, l - 1] + differences[k, l]) - + (differences[k - 1, l - 1] + differences[k - 1, l]) == + 0); } } } - // // Search // - DecisionBuilder db = solver.MakePhase(costas, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(costas, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); - solver.NewSearch(db); while (solver.NextSolution()) { Console.Write("costas: "); - for(int i = 0; i < n; i++) { - Console.Write("{0} ", costas[i].Value()); + for (int i = 0; i < n; i++) { + Console.Write("{0} ", costas [i] + .Value()); } Console.WriteLine("\ndifferences:"); - for(int i = 0; i < n; i++) { - for(int j = 0; j < n; j++) { - long v = differences[i,j].Value(); - if (v == -n+1) { + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + long v = differences [i, j] + .Value(); + if (v == -n + 1) { Console.Write(" "); } else { Console.Write("{0,2} ", v); @@ -162,13 +152,9 @@ public class CostasArray Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - - public static void Main(String[] args) - { + public static void Main(String[] args) { int n = 6; if (args.Length > 0) { @@ -176,6 +162,5 @@ public class CostasArray } Solve(n); - } } diff --git a/examples/contrib/covering_opl.cs b/examples/contrib/covering_opl.cs index 39da44748b..bd3070f981 100644 --- a/examples/contrib/covering_opl.cs +++ b/examples/contrib/covering_opl.cs @@ -19,18 +19,14 @@ using System.IO; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; -public class SetCoveringOPL -{ - +public class SetCoveringOPL { /** * * Solves a set covering problem. * See See http://www.hakank.org/or-tools/set_covering_opl.py * */ - private static void Solve() - { - + private static void Solve() { Solver solver = new Solver("SetCoveringOPL"); // @@ -41,28 +37,25 @@ public class SetCoveringOPL // Which worker is qualified for each task. // Note: This is 1-based and will be made 0-base below. - int[][] qualified = { - new int[] { 1, 9, 19, 22, 25, 28, 31 }, - new int[] { 2, 12, 15, 19, 21, 23, 27, 29, 30, 31, 32 }, - new int[] { 3, 10, 19, 24, 26, 30, 32 }, - new int[] { 4, 21, 25, 28, 32 }, - new int[] { 5, 11, 16, 22, 23, 27, 31 }, - new int[] { 6, 20, 24, 26, 30, 32 }, - new int[] { 7, 12, 17, 25, 30, 31 } , - new int[] { 8, 17, 20, 22, 23 }, - new int[] { 9, 13, 14, 26, 29, 30, 31 }, - new int[] { 10, 21, 25, 31, 32 }, - new int[] { 14, 15, 18, 23, 24, 27, 30, 32 }, - new int[] { 18, 19, 22, 24, 26, 29, 31 }, - new int[] { 11, 20, 25, 28, 30, 32 }, - new int[] { 16, 19, 23, 31 }, - new int[] { 9, 18, 26, 28, 31, 32 } - }; + int[][] qualified = {new int[]{1, 9, 19, 22, 25, 28, 31}, + new int[]{2, 12, 15, 19, 21, 23, 27, 29, 30, 31, 32}, + new int[]{3, 10, 19, 24, 26, 30, 32}, + new int[]{4, 21, 25, 28, 32}, + new int[]{5, 11, 16, 22, 23, 27, 31}, + new int[]{6, 20, 24, 26, 30, 32}, + new int[]{7, 12, 17, 25, 30, 31}, + new int[]{8, 17, 20, 22, 23}, + new int[]{9, 13, 14, 26, 29, 30, 31}, + new int[]{10, 21, 25, 31, 32}, + new int[]{14, 15, 18, 23, 24, 27, 30, 32}, + new int[]{18, 19, 22, 24, 26, 29, 31}, + new int[]{11, 20, 25, 28, 30, 32}, + new int[]{16, 19, 23, 31}, + new int[]{9, 18, 26, 28, 31, 32}}; int[] cost = {1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 8, 9}; - // // Decision variables // @@ -73,29 +66,29 @@ public class SetCoveringOPL // Constraints // - for(int j = 0; j < num_tasks; j++) { + for (int j = 0; j < num_tasks; j++) { // Sum the cost for hiring the qualified workers // (also, make 0-base). int len = qualified[j].Length; IntVar[] tmp = new IntVar[len]; - for(int c = 0; c < len; c++) { - tmp[c] = hire[qualified[j][c] - 1]; + for (int c = 0; c < len; c++) { + tmp[c] = hire [qualified [j] + [c] + - 1] + ; } solver.Add(tmp.Sum() >= 1); } - // // objective // OptimizeVar objective = total_cost.Minimize(1); - // // Search // - DecisionBuilder db = solver.MakePhase(hire, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(hire, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db, objective); @@ -103,13 +96,13 @@ public class SetCoveringOPL while (solver.NextSolution()) { Console.WriteLine("Cost: " + total_cost.Value()); Console.Write("Hire: "); - for(int i = 0; i < num_workers; i++) { - if (hire[i].Value() == 1) { + for (int i = 0; i < num_workers; i++) { + if (hire [i] + .Value() == 1) { Console.Write(i + " "); } } Console.WriteLine("\n"); - } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); @@ -118,11 +111,7 @@ public class SetCoveringOPL Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/crew.cs b/examples/contrib/crew.cs index 27965dafdf..72992567b6 100644 --- a/examples/contrib/crew.cs +++ b/examples/contrib/crew.cs @@ -20,10 +20,7 @@ using System.Linq; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; - -public class Crew -{ - +public class Crew { /** * * Crew allocation problem in Google CP Solver. @@ -41,65 +38,46 @@ public class Crew * Also see http://www.hakank.org/or-tools/crew.pl * */ - private static void Solve(int sols = 1, int minimize = 0) - { + private static void Solve(int sols = 1, int minimize = 0) { Solver solver = new Solver("Crew"); // // Data // - string[] names = {"Tom", - "David", - "Jeremy", - "Ron", - "Joe", - "Bill", - "Fred", - "Bob", - "Mario", - "Ed", - "Carol", - "Janet", - "Tracy", - "Marilyn", - "Carolyn", - "Cathy", - "Inez", - "Jean", - "Heather", - "Juliet"}; + string[] names = {"Tom", "David", "Jeremy", "Ron", "Joe", + "Bill", "Fred", "Bob", "Mario", "Ed", + "Carol", "Janet", "Tracy", "Marilyn", "Carolyn", + "Cathy", "Inez", "Jean", "Heather", "Juliet"}; int num_persons = names.Length; - // // Attributes of the crew // - int[,] attributes = { - // steward, hostess, french, spanish, german - {1,0,0,0,1}, // Tom = 0 - {1,0,0,0,0}, // David = 1 - {1,0,0,0,1}, // Jeremy = 2 - {1,0,0,0,0}, // Ron = 3 - {1,0,0,1,0}, // Joe = 4 - {1,0,1,1,0}, // Bill = 5 - {1,0,0,1,0}, // Fred = 6 - {1,0,0,0,0}, // Bob = 7 - {1,0,0,1,1}, // Mario = 8 - {1,0,0,0,0}, // Ed = 9 - {0,1,0,0,0}, // Carol = 10 - {0,1,0,0,0}, // Janet = 11 - {0,1,0,0,0}, // Tracy = 12 - {0,1,0,1,1}, // Marilyn = 13 - {0,1,0,0,0}, // Carolyn = 14 - {0,1,0,0,0}, // Cathy = 15 - {0,1,1,1,1}, // Inez = 16 - {0,1,1,0,0}, // Jean = 17 - {0,1,0,1,1}, // Heather = 18 - {0,1,1,0,0} // Juliet = 19 + int[, ] attributes = { + // steward, hostess, french, spanish, german + {1, 0, 0, 0, 1}, // Tom = 0 + {1, 0, 0, 0, 0}, // David = 1 + {1, 0, 0, 0, 1}, // Jeremy = 2 + {1, 0, 0, 0, 0}, // Ron = 3 + {1, 0, 0, 1, 0}, // Joe = 4 + {1, 0, 1, 1, 0}, // Bill = 5 + {1, 0, 0, 1, 0}, // Fred = 6 + {1, 0, 0, 0, 0}, // Bob = 7 + {1, 0, 0, 1, 1}, // Mario = 8 + {1, 0, 0, 0, 0}, // Ed = 9 + {0, 1, 0, 0, 0}, // Carol = 10 + {0, 1, 0, 0, 0}, // Janet = 11 + {0, 1, 0, 0, 0}, // Tracy = 12 + {0, 1, 0, 1, 1}, // Marilyn = 13 + {0, 1, 0, 0, 0}, // Carolyn = 14 + {0, 1, 0, 0, 0}, // Cathy = 15 + {0, 1, 1, 1, 1}, // Inez = 16 + {0, 1, 1, 0, 0}, // Jean = 17 + {0, 1, 0, 1, 1}, // Heather = 18 + {0, 1, 1, 0, 0} // Juliet = 19 }; - // // Required number of crew members. // @@ -111,27 +89,22 @@ public class Crew // spanish : How many Spanish speaking employees are required // german : How many German speaking employees are required // - int[,] required_crew = { - {4,1,1,1,1,1}, // Flight 1 - {5,1,1,1,1,1}, // Flight 2 - {5,1,1,1,1,1}, // .. - {6,2,2,1,1,1}, - {7,3,3,1,1,1}, - {4,1,1,1,1,1}, - {5,1,1,1,1,1}, - {6,1,1,1,1,1}, - {6,2,2,1,1,1}, // ... - {7,3,3,1,1,1} // Flight 10 - }; + int[, ] required_crew = { + {4, 1, 1, 1, 1, 1}, // Flight 1 + {5, 1, 1, 1, 1, 1}, // Flight 2 + {5, 1, 1, 1, 1, 1}, // .. + {6, 2, 2, 1, 1, 1}, {7, 3, 3, 1, 1, 1}, {4, 1, 1, 1, 1, 1}, + {5, 1, 1, 1, 1, 1}, {6, 1, 1, 1, 1, 1}, {6, 2, 2, 1, 1, 1}, // ... + {7, 3, 3, 1, 1, 1} // Flight 10 + }; int num_flights = required_crew.GetLength(0); - // // Decision variables // - IntVar[,] crew = solver.MakeIntVarMatrix(num_flights, num_persons, - 0, 1, "crew"); + IntVar[, ] crew = + solver.MakeIntVarMatrix(num_flights, num_persons, 0, 1, "crew"); IntVar[] crew_flat = crew.Flatten(); // number of working persons @@ -143,37 +116,37 @@ public class Crew // number of working persons IntVar[] nw = new IntVar[num_persons]; - for(int p = 0; p < num_persons; p++) { + for (int p = 0; p < num_persons; p++) { IntVar[] tmp = new IntVar[num_flights]; - for(int f = 0; f < num_flights; f++) { - tmp[f] = crew[f,p]; + for (int f = 0; f < num_flights; f++) { + tmp[f] = crew[f, p]; } nw[p] = tmp.Sum() > 0; } solver.Add(nw.Sum() == num_working); - for(int f = 0; f < num_flights; f++) { + for (int f = 0; f < num_flights; f++) { // size of crew IntVar[] tmp = new IntVar[num_persons]; - for(int p = 0; p < num_persons; p++) { - tmp[p] = crew[f,p]; + for (int p = 0; p < num_persons; p++) { + tmp[p] = crew[f, p]; } - solver.Add(tmp.Sum() == required_crew[f,0]); + solver.Add(tmp.Sum() == required_crew[f, 0]); // attributes and requirements - for(int a = 0; a < 5; a++) { + for (int a = 0; a < 5; a++) { IntVar[] tmp2 = new IntVar[num_persons]; - for(int p = 0; p < num_persons; p++) { - tmp2[p] = (crew[f,p]*attributes[p,a]).Var(); + for (int p = 0; p < num_persons; p++) { + tmp2[p] = (crew[f, p] * attributes[p, a]).Var(); } - solver.Add(tmp2.Sum() >= required_crew[f,a+1]); + solver.Add(tmp2.Sum() >= required_crew[f, a + 1]); } } // after a flight, break for at least two flights - for(int f = 0; f < num_flights - 2; f++) { - for(int i = 0; i < num_persons; i++) { - solver.Add(crew[f,i] + crew[f+1,i] + crew[f+2,i] <= 1); + for (int f = 0; f < num_flights - 2; f++) { + for (int i = 0; i < num_persons; i++) { + solver.Add(crew[f, i] + crew[f + 1, i] + crew[f + 2, i] <= 1); } } @@ -188,13 +161,11 @@ public class Crew } */ - // // Search // - DecisionBuilder db = solver.MakePhase(crew_flat, - Solver.CHOOSE_FIRST_UNBOUND, - Solver.ASSIGN_MIN_VALUE); + DecisionBuilder db = solver.MakePhase( + crew_flat, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); if (minimize > 0) { OptimizeVar obj = num_working.Minimize(1); @@ -209,17 +180,20 @@ public class Crew Console.WriteLine("Solution #{0}", num_solutions); Console.WriteLine("Number working: {0}", num_working.Value()); - for(int f = 0; f < num_flights; f++) { - for(int p = 0; p < num_persons; p++) { - Console.Write(crew[f,p].Value() + " "); + for (int f = 0; f < num_flights; f++) { + for (int p = 0; p < num_persons; p++) { + Console.Write(crew [f, p] + .Value() + + " "); } Console.WriteLine(); } Console.WriteLine("\nFlights: "); - for(int f = 0; f < num_flights; f++) { + for (int f = 0; f < num_flights; f++) { Console.Write("Flight #{0}: ", f); - for(int p = 0; p < num_persons; p++) { - if (crew[f, p].Value() == 1) { + for (int p = 0; p < num_persons; p++) { + if (crew [f, p] + .Value() == 1) { Console.Write(names[p] + " "); } } @@ -227,10 +201,11 @@ public class Crew } Console.WriteLine("\nCrew:"); - for(int p = 0; p < num_persons; p++) { + for (int p = 0; p < num_persons; p++) { Console.Write("{0,-10}", names[p]); - for(int f = 0; f < num_flights; f++) { - if (crew[f,p].Value() == 1) { + for (int f = 0; f < num_flights; f++) { + if (crew [f, p] + .Value() == 1) { Console.Write(f + " "); } } @@ -242,7 +217,6 @@ public class Crew if (num_solutions >= sols) { break; } - } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); @@ -251,14 +225,11 @@ public class Crew Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - public static void Main(String[] args) - { + public static void Main(String[] args) { int n = 1; - int min = 0; // > 0 -> minimize num_working + int min = 0; // > 0 -> minimize num_working if (args.Length > 0) { n = Convert.ToInt32(args[0]); } diff --git a/examples/contrib/crossword.cs b/examples/contrib/crossword.cs index 4c5e5ee2b8..db5111dfdc 100644 --- a/examples/contrib/crossword.cs +++ b/examples/contrib/crossword.cs @@ -19,15 +19,11 @@ using System.IO; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; - // Note: During compilation, there are a couple of // warnings about assigned but never used variables. // It's the characters a..z so it's quite benign. - -public class Crossword -{ - +public class Crossword { /** * * Solving a simple crossword. @@ -35,59 +31,78 @@ public class Crossword * * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("Crossword"); // // data // - String[] alpha = {"_","a","b","c","d","e","f", - "g","h","i","j","k","l","m", - "n","o","p","q","r","s","t", - "u","v","w","x","y","z"}; + String[] alpha = {"_", "a", "b", "c", "d", "e", "f", "g", "h", + "i", "j", "k", "l", "m", "n", "o", "p", "q", + "r", "s", "t", "u", "v", "w", "x", "y", "z"}; - int a=1; int b=2; int c=3; int d=4; int e=5; int f=6; - int g=7; int h=8; int i=9; int j=10; int k=11; int l=12; - int m=13; int n=14; int o=15; int p=16; int q=17; int r=18; - int s=19; int t=20; int u=21; int v=22; int w=23; int x=24; - int y=25; int z=26; + int a = 1; + int b = 2; + int c = 3; + int d = 4; + int e = 5; + int f = 6; + int g = 7; + int h = 8; + int i = 9; + int j = 10; + int k = 11; + int l = 12; + int m = 13; + int n = 14; + int o = 15; + int p = 16; + int q = 17; + int r = 18; + int s = 19; + int t = 20; + int u = 21; + int v = 22; + int w = 23; + int x = 24; + int y = 25; + int z = 26; const int num_words = 15; int word_len = 5; - int[,] AA = {{h, o, s, e, s}, // HOSES - {l, a, s, e, r}, // LASER - {s, a, i, l, s}, // SAILS - {s, h, e, e, t}, // SHEET - {s, t, e, e, r}, // STEER - {h, e, e, l, 0}, // HEEL - {h, i, k, e, 0}, // HIKE - {k, e, e, l, 0}, // KEEL - {k, n, o, t, 0}, // KNOT - {l, i, n, e, 0}, // LINE - {a, f, t, 0, 0}, // AFT - {a, l, e, 0, 0}, // ALE - {e, e, l, 0, 0}, // EEL - {l, e, e, 0, 0}, // LEE - {t, i, e, 0, 0}}; // TIE + int[, ] AA = {{h, o, s, e, s}, // HOSES + {l, a, s, e, r}, // LASER + {s, a, i, l, s}, // SAILS + {s, h, e, e, t}, // SHEET + {s, t, e, e, r}, // STEER + {h, e, e, l, 0}, // HEEL + {h, i, k, e, 0}, // HIKE + {k, e, e, l, 0}, // KEEL + {k, n, o, t, 0}, // KNOT + {l, i, n, e, 0}, // LINE + {a, f, t, 0, 0}, // AFT + {a, l, e, 0, 0}, // ALE + {e, e, l, 0, 0}, // EEL + {l, e, e, 0, 0}, // LEE + {t, i, e, 0, 0}}; // TIE int num_overlapping = 12; - int[,] overlapping = {{0, 2, 1, 0}, // s - {0, 4, 2, 0}, // s + int[, ] overlapping = {{0, 2, 1, 0}, // s + {0, 4, 2, 0}, // s - {3, 1, 1, 2}, // i - {3, 2, 4, 0}, // k - {3, 3, 2, 2}, // e + {3, 1, 1, 2}, // i + {3, 2, 4, 0}, // k + {3, 3, 2, 2}, // e - {6, 0, 1, 3}, // l - {6, 1, 4, 1}, // e - {6, 2, 2, 3}, // e + {6, 0, 1, 3}, // l + {6, 1, 4, 1}, // e + {6, 2, 2, 3}, // e - {7, 0, 5, 1}, // l - {7, 2, 1, 4}, // s - {7, 3, 4, 2}, // e - {7, 4, 2, 4}}; // r + {7, 0, 5, 1}, // l + {7, 2, 1, 4}, // s + {7, 3, 4, 2}, // e + {7, 4, 2, 4}}; // r int N = 8; @@ -95,33 +110,28 @@ public class Crossword // Decision variables // // for labeling on A and E - IntVar[,] A = solver.MakeIntVarMatrix(num_words, word_len, - 0, 26, "A"); + IntVar[, ] A = solver.MakeIntVarMatrix(num_words, word_len, 0, 26, "A"); IntVar[] A_flat = A.Flatten(); IntVar[] all = new IntVar[(num_words * word_len) + N]; - for(int I = 0; I < num_words; I++) { - for(int J = 0; J < word_len; J++) { - all[I * word_len + J] = A[I,J]; + for (int I = 0; I < num_words; I++) { + for (int J = 0; J < word_len; J++) { + all[I * word_len + J] = A[I, J]; } } - - IntVar[] E = solver.MakeIntVarArray(N, 0, num_words, "E"); - for(int I = 0; I < N; I++) { + for (int I = 0; I < N; I++) { all[num_words * word_len + I] = E[I]; } - - // // Constraints // solver.Add(E.AllDifferent()); - for(int I = 0; I < num_words; I++) { - for(int J = 0; J < word_len; J++) { - solver.Add(A[I,J] == AA[I,J]); + for (int I = 0; I < num_words; I++) { + for (int J = 0; J < word_len; J++) { + solver.Add(A[I, J] == AA[I, J]); } } @@ -139,30 +149,30 @@ public class Crossword // == // solver.Element(A_flat,E[overlapping[I][2]]*word_len+overlapping[I][3])) // - for(int I = 0; I < num_overlapping; I++) { + for (int I = 0; I < num_overlapping; I++) { solver.Add( - A_flat.Element(E[overlapping[I,0]] * word_len + overlapping[I,1]) == - A_flat.Element(E[overlapping[I,2]] * word_len + overlapping[I,3])); + A_flat.Element(E[overlapping[I, 0]] * word_len + overlapping[I, 1]) == + A_flat.Element(E[overlapping[I, 2]] * word_len + overlapping[I, 3])); } - - // // Search // - DecisionBuilder db = solver.MakePhase(all, - Solver.INT_VAR_DEFAULT, - Solver.INT_VALUE_DEFAULT); + DecisionBuilder db = + solver.MakePhase(all, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { Console.WriteLine("E: "); - for(int ee = 0; ee < N; ee++) { - int e_val = (int)E[ee].Value(); + for (int ee = 0; ee < N; ee++) { + int e_val = (int) E [ee] + .Value(); Console.Write(ee + ": (" + e_val + ") "); - for(int ii = 0; ii < word_len; ii++) { - Console.Write(alpha[(int)A[ee,ii].Value()]); + for (int ii = 0; ii < word_len; ii++) { + Console.Write(alpha [(int) A [ee, ii] + .Value()] + ); } Console.WriteLine(); } @@ -176,13 +186,7 @@ public class Crossword Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/crypta.cs b/examples/contrib/crypta.cs index eb6d9f45fa..ec13f35f2f 100644 --- a/examples/contrib/crypta.cs +++ b/examples/contrib/crypta.cs @@ -16,12 +16,11 @@ using System; using Google.OrTools.ConstraintSolver; -public class Crypta -{ +public class Crypta { /** * * Cryptarithmetic puzzle. - * + * * Prolog benchmark problem GNU Prolog (crypta.pl) * """ * Name : crypta.pl @@ -42,8 +41,7 @@ public class Crypta * Also see http://hakank.org/or-tools/crypta.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("Crypta"); // @@ -60,12 +58,11 @@ public class Crypta IntVar I = solver.MakeIntVar(0, 9, "I"); IntVar J = solver.MakeIntVar(0, 9, "J"); - IntVar[] LD = new IntVar[] {A,B,C,D,E,F,G,H,I,J}; - + IntVar[] LD = new IntVar[]{A, B, C, D, E, F, G, H, I, J}; + IntVar Sr1 = solver.MakeIntVar(0, 1, "Sr1"); IntVar Sr2 = solver.MakeIntVar(0, 1, "Sr2"); - // // Constraints // @@ -74,32 +71,35 @@ public class Crypta solver.Add(D >= 1); solver.Add(G >= 1); - solver.Add((A+10*E+100*J+1000*B+10000*B+100000*E+1000000*F+ - E+10*J+100*E+1000*F+10000*G+100000*A+1000000*F) == - (F+10*E+100*E+1000*H+10000*I+100000*F+1000000*B+10000000*Sr1)); + solver.Add((A + 10 * E + 100 * J + 1000 * B + 10000 * B + 100000 * E + + 1000000 * F + E + 10 * J + 100 * E + 1000 * F + 10000 * G + + 100000 * A + 1000000 * F) == + (F + 10 * E + 100 * E + 1000 * H + 10000 * I + 100000 * F + + 1000000 * B + 10000000 * Sr1)); + solver.Add((C + 10 * F + 100 * H + 1000 * A + 10000 * I + 100000 * I + + 1000000 * J + F + 10 * I + 100 * B + 1000 * D + 10000 * I + + 100000 * D + 1000000 * C + Sr1) == + (J + 10 * F + 100 * A + 1000 * F + 10000 * H + 100000 * D + + 1000000 * D + 10000000 * Sr2)); - solver.Add((C+10*F+100*H+1000*A+10000*I+100000*I+1000000*J+ - F+10*I+100*B+1000*D+10000*I+100000*D+1000000*C+Sr1) == - (J+10*F+100*A+1000*F+10000*H+100000*D+1000000*D+10000000*Sr2)); - - - solver.Add((A+10*J+100*J+1000*I+10000*A+100000*B+ - B+10*A+100*G+1000*F+10000*H+100000*D+Sr2) == - (C+10*A+100*G+1000*E+10000*J+100000*G)); + solver.Add((A + 10 * J + 100 * J + 1000 * I + 10000 * A + 100000 * B + B + + 10 * A + 100 * G + 1000 * F + 10000 * H + 100000 * D + Sr2) == + (C + 10 * A + 100 * G + 1000 * E + 10000 * J + 100000 * G)); // // Search // - DecisionBuilder db = solver.MakePhase(LD, - Solver.INT_VAR_DEFAULT, - Solver.INT_VALUE_DEFAULT); + DecisionBuilder db = + solver.MakePhase(LD, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { - for(int i = 0; i < 10; i++) { - Console.Write(LD[i].ToString() + " "); + for (int i = 0; i < 10; i++) { + Console.Write(LD [i] + .ToString() + + " "); } Console.WriteLine(); } @@ -109,11 +109,7 @@ public class Crypta Console.WriteLine("Branches: " + solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/crypto.cs b/examples/contrib/crypto.cs index 6d31677209..7526bb3574 100644 --- a/examples/contrib/crypto.cs +++ b/examples/contrib/crypto.cs @@ -16,12 +16,11 @@ using System; using Google.OrTools.ConstraintSolver; -public class Crypto -{ +public class Crypto { /** * * Crypto problem. - * + * * This is the standard benchmark "crypto" problem. * * From GLPK:s model cryto.mod. @@ -52,33 +51,31 @@ public class Crypto * Also see http://hakank.org/or-tools/crypto.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("Crypto"); int num_letters = 26; - int BALLET = 45; - int CELLO = 43; - int CONCERT = 74; - int FLUTE = 30; - int FUGUE = 50; - int GLEE = 66; - int JAZZ = 58; - int LYRE = 47; - int OBOE = 53; - int OPERA = 65; - int POLKA = 59; - int QUARTET = 50; - int SAXOPHONE = 134; - int SCALE = 51; - int SOLO = 37; - int SONG = 61; - int SOPRANO = 82; - int THEME = 72; - int VIOLIN = 100; - int WALTZ = 34; - + int BALLET = 45; + int CELLO = 43; + int CONCERT = 74; + int FLUTE = 30; + int FUGUE = 50; + int GLEE = 66; + int JAZZ = 58; + int LYRE = 47; + int OBOE = 53; + int OPERA = 65; + int POLKA = 59; + int QUARTET = 50; + int SAXOPHONE = 134; + int SCALE = 51; + int SOLO = 37; + int SONG = 61; + int SOPRANO = 82; + int THEME = 72; + int VIOLIN = 100; + int WALTZ = 34; // // Decision variables @@ -86,53 +83,71 @@ public class Crypto IntVar[] LD = solver.MakeIntVarArray(num_letters, 1, num_letters, "LD"); // Note D is not used in the constraints below - IntVar A = LD[0]; IntVar B = LD[1]; IntVar C = LD[2]; // IntVar D = LD[3]; - IntVar E = LD[4]; IntVar F = LD[5]; IntVar G = LD[6]; IntVar H = LD[7]; - IntVar I = LD[8]; IntVar J = LD[9]; IntVar K = LD[10]; IntVar L = LD[11]; - IntVar M = LD[12]; IntVar N = LD[13]; IntVar O = LD[14]; IntVar P = LD[15]; - IntVar Q = LD[16]; IntVar R = LD[17]; IntVar S = LD[18]; IntVar T = LD[19]; - IntVar U = LD[20]; IntVar V = LD[21]; IntVar W = LD[22]; IntVar X = LD[23]; - IntVar Y = LD[24]; IntVar Z = LD[25]; + IntVar A = LD[0]; + IntVar B = LD[1]; + IntVar C = LD[2]; // IntVar D = LD[3]; + IntVar E = LD[4]; + IntVar F = LD[5]; + IntVar G = LD[6]; + IntVar H = LD[7]; + IntVar I = LD[8]; + IntVar J = LD[9]; + IntVar K = LD[10]; + IntVar L = LD[11]; + IntVar M = LD[12]; + IntVar N = LD[13]; + IntVar O = LD[14]; + IntVar P = LD[15]; + IntVar Q = LD[16]; + IntVar R = LD[17]; + IntVar S = LD[18]; + IntVar T = LD[19]; + IntVar U = LD[20]; + IntVar V = LD[21]; + IntVar W = LD[22]; + IntVar X = LD[23]; + IntVar Y = LD[24]; + IntVar Z = LD[25]; // // Constraints // solver.Add(LD.AllDifferent()); - solver.Add( B + A + L + L + E + T == BALLET); - solver.Add( C + E + L + L + O == CELLO); - solver.Add( C + O + N + C + E + R + T == CONCERT); - solver.Add( F + L + U + T + E == FLUTE); - solver.Add( F + U + G + U + E == FUGUE); - solver.Add( G + L + E + E == GLEE); - solver.Add( J + A + Z + Z == JAZZ); - solver.Add( L + Y + R + E == LYRE); - solver.Add( O + B + O + E == OBOE); - solver.Add( O + P + E + R + A == OPERA); - solver.Add( P + O + L + K + A == POLKA); - solver.Add( Q + U + A + R + T + E + T == QUARTET); + solver.Add(B + A + L + L + E + T == BALLET); + solver.Add(C + E + L + L + O == CELLO); + solver.Add(C + O + N + C + E + R + T == CONCERT); + solver.Add(F + L + U + T + E == FLUTE); + solver.Add(F + U + G + U + E == FUGUE); + solver.Add(G + L + E + E == GLEE); + solver.Add(J + A + Z + Z == JAZZ); + solver.Add(L + Y + R + E == LYRE); + solver.Add(O + B + O + E == OBOE); + solver.Add(O + P + E + R + A == OPERA); + solver.Add(P + O + L + K + A == POLKA); + solver.Add(Q + U + A + R + T + E + T == QUARTET); solver.Add(S + A + X + O + P + H + O + N + E == SAXOPHONE); - solver.Add( S + C + A + L + E == SCALE); - solver.Add( S + O + L + O == SOLO); - solver.Add( S + O + N + G == SONG); - solver.Add( S + O + P + R + A + N + O == SOPRANO); - solver.Add( T + H + E + M + E == THEME); - solver.Add( V + I + O + L + I + N == VIOLIN); - solver.Add( W + A + L + T + Z == WALTZ); - + solver.Add(S + C + A + L + E == SCALE); + solver.Add(S + O + L + O == SOLO); + solver.Add(S + O + N + G == SONG); + solver.Add(S + O + P + R + A + N + O == SOPRANO); + solver.Add(T + H + E + M + E == THEME); + solver.Add(V + I + O + L + I + N == VIOLIN); + solver.Add(W + A + L + T + Z == WALTZ); // // Search // - DecisionBuilder db = solver.MakePhase(LD, - Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, + DecisionBuilder db = solver.MakePhase(LD, Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, Solver.ASSIGN_CENTER_VALUE); solver.NewSearch(db); String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; while (solver.NextSolution()) { - for(int i = 0; i < num_letters; i++) { - Console.WriteLine("{0}: {1,2}", str[i], LD[i].Value()); + for (int i = 0; i < num_letters; i++) { + Console.WriteLine("{0}: {1,2}", str[i], + LD [i] + .Value()); } Console.WriteLine(); } @@ -142,11 +157,7 @@ public class Crypto Console.WriteLine("Branches: " + solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/csdiet.cs b/examples/contrib/csdiet.cs index f8d993ff25..7de1a2b923 100644 --- a/examples/contrib/csdiet.cs +++ b/examples/contrib/csdiet.cs @@ -16,8 +16,7 @@ using System; using Google.OrTools.ConstraintSolver; -public class Diet -{ +public class Diet { /** * * Solves the Diet problem @@ -25,24 +24,21 @@ public class Diet * See http://www.hakank.org/google_or_tools/diet1.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("Diet"); int n = 4; - int[] price = { 50, 20, 30, 80}; // in cents + int[] price = {50, 20, 30, 80}; // in cents // requirements for each nutrition type - int[] limits = {500, 6, 10, 8}; + int[] limits = {500, 6, 10, 8}; string[] products = {"A", "B", "C", "D"}; // nutritions for each product - int[] calories = {400, 200, 150, 500}; + int[] calories = {400, 200, 150, 500}; int[] chocolate = {3, 2, 0, 0}; - int[] sugar = {2, 2, 4, 4}; - int[] fat = {2, 4, 1, 5}; - - + int[] sugar = {2, 2, 4, 4}; + int[] fat = {2, 4, 1, 5}; // // Decision variables @@ -50,19 +46,17 @@ public class Diet IntVar[] x = solver.MakeIntVarArray(n, 0, 100, "x"); IntVar cost = x.ScalProd(price).Var(); - - // // Constraints // - - // solver.Add(solver.MakeScalProdGreaterOrEqual(x, calories, limits[0])); - solver.Add(x.ScalProd(calories) >= limits[0]); - solver.Add(x.ScalProd(chocolate) >= limits[1]); - solver.Add(x.ScalProd(sugar) >= limits[2]); - solver.Add(x.ScalProd(fat) >= limits[3]); - // + // solver.Add(solver.MakeScalProdGreaterOrEqual(x, calories, limits[0])); + solver.Add(x.ScalProd(calories) >= limits[0]); + solver.Add(x.ScalProd(chocolate) >= limits[1]); + solver.Add(x.ScalProd(sugar) >= limits[2]); + solver.Add(x.ScalProd(fat) >= limits[3]); + + // // Objective // OptimizeVar obj = cost.Minimize(1); @@ -70,18 +64,19 @@ public class Diet // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.CHOOSE_PATH, - Solver.ASSIGN_MIN_VALUE); + DecisionBuilder db = + solver.MakePhase(x, Solver.CHOOSE_PATH, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db, obj); while (solver.NextSolution()) { Console.WriteLine("cost: {0}", cost.Value()); Console.WriteLine("Products: "); - for(int i = 0; i < n; i++) { - Console.WriteLine("{0}: {1}", products[i], x[i].Value()); + for (int i = 0; i < n; i++) { + Console.WriteLine("{0}: {1}", products[i], + x [i] + .Value()); } - + Console.WriteLine(); } @@ -91,11 +86,7 @@ public class Diet Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/curious_set_of_integers.cs b/examples/contrib/curious_set_of_integers.cs index 6e223c3baa..992440ab90 100644 --- a/examples/contrib/curious_set_of_integers.cs +++ b/examples/contrib/curious_set_of_integers.cs @@ -20,17 +20,13 @@ using System.Linq; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; -public class CuriousSetOfIntegers -{ - - +public class CuriousSetOfIntegers { public static void Decreasing(Solver solver, IntVar[] x) { - for(int i = 0; i < x.Length - 1; i++) { - solver.Add(x[i] <= x[i+1]); + for (int i = 0; i < x.Length - 1; i++) { + solver.Add(x[i] <= x[i + 1]); } } - /** * * Crypto problem in Google CP Solver. @@ -46,9 +42,7 @@ public class CuriousSetOfIntegers * Also see, http://www.hakank.org/or-tools/curious_set_of_integers.py * */ - private static void Solve() - { - + private static void Solve() { Solver solver = new Solver("CuriousSetOfIntegers"); // @@ -67,8 +61,8 @@ public class CuriousSetOfIntegers // solver.Add(x.AllDifferent()); - for(int i = 0; i < n - 1; i++) { - for(int j = i + 1; j < n; j++) { + for (int i = 0; i < n - 1; i++) { + for (int j = i + 1; j < n; j++) { IntVar p = solver.MakeIntVar(0, max_val); solver.Add((p.Square() - 1) - (x[i] * x[j]) == 0); } @@ -79,25 +73,26 @@ public class CuriousSetOfIntegers // This is the original problem // Which is the fifth number? - int[] v = {1,3,8,120}; - IntVar[] b = (from i in Enumerable.Range(0, n) - select x[i].IsMember(v)).ToArray(); + int[] v = {1, 3, 8, 120}; + IntVar[] b = (from i in Enumerable + .Range(0, n) select x [i] + .IsMember(v)) + .ToArray(); solver.Add(b.Sum() == 4); - // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, + DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, Solver.ASSIGN_MIN_VALUE); - solver.NewSearch(db); while (solver.NextSolution()) { - for(int i = 0; i < n; i++) { - Console.Write(x[i].Value() + " "); + for (int i = 0; i < n; i++) { + Console.Write(x [i] + .Value() + + " "); } Console.WriteLine(); } @@ -108,15 +103,7 @@ public class CuriousSetOfIntegers Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - - public static void Main(String[] args) - { - - Solve(); - - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/debruijn.cs b/examples/contrib/debruijn.cs index adc232e3b3..6776e50338 100644 --- a/examples/contrib/debruijn.cs +++ b/examples/contrib/debruijn.cs @@ -16,10 +16,7 @@ using System; using Google.OrTools.ConstraintSolver; -public class DeBruijn -{ - - +public class DeBruijn { /** * * ToNum(solver, a, num, base) @@ -31,53 +28,48 @@ public class DeBruijn int len = a.Length; IntVar[] tmp = new IntVar[len]; - for(int i = 0; i < len; i++) { - tmp[i] = (a[i]*(int)Math.Pow(bbase,(len-i-1))).Var(); + for (int i = 0; i < len; i++) { + tmp[i] = (a[i] * (int) Math.Pow(bbase, (len - i - 1))).Var(); } - return tmp.Sum() == num; + return tmp.Sum() == num; } - - /** * * Implements "arbitrary" de Bruijn sequences. * See http://www.hakank.org/or-tools/debruijn_binary.py * */ - private static void Solve(int bbase, int n, int m) - { + private static void Solve(int bbase, int n, int m) { Solver solver = new Solver("DeBruijn"); - // Ensure that the number of each digit in bin_code is // the same. Nice feature, but it can slow things down... - bool check_same_gcc = false; // true; + bool check_same_gcc = false; // true; // // Decision variables // - IntVar[] x = solver.MakeIntVarArray(m, 0, (int)Math.Pow(bbase, n) - 1, "x"); - IntVar[,] binary = solver.MakeIntVarMatrix(m, n, 0, bbase - 1, "binary"); + IntVar[] x = + solver.MakeIntVarArray(m, 0, (int) Math.Pow(bbase, n) - 1, "x"); + IntVar[, ] binary = solver.MakeIntVarMatrix(m, n, 0, bbase - 1, "binary"); // this is the de Bruijn sequence - IntVar[] bin_code = - solver.MakeIntVarArray(m, 0, bbase - 1, "bin_code"); + IntVar[] bin_code = solver.MakeIntVarArray(m, 0, bbase - 1, "bin_code"); // occurences of each number in bin_code IntVar[] gcc = solver.MakeIntVarArray(bbase, 0, m, "gcc"); // for the branching IntVar[] all = new IntVar[2 * m + bbase]; - for(int i = 0; i < m; i++) { + for (int i = 0; i < m; i++) { all[i] = x[i]; all[m + i] = bin_code[i]; } - for(int i = 0; i < bbase; i++) { + for (int i = 0; i < bbase; i++) { all[2 * m + i] = gcc[i]; } - // // Constraints // @@ -85,10 +77,10 @@ public class DeBruijn solver.Add(x.AllDifferent()); // converts x <-> binary - for(int i = 0; i < m; i++) { + for (int i = 0; i < m; i++) { IntVar[] t = new IntVar[n]; - for(int j = 0; j < n; j++) { - t[j] = binary[i,j]; + for (int j = 0; j < n; j++) { + t[j] = binary[i, j]; } solver.Add(ToNum(t, x[i], bbase)); } @@ -96,30 +88,28 @@ public class DeBruijn // the de Bruijn condition: // the first elements in binary[i] is the same as the last // elements in binary[i-1] - for(int i = 1; i < m; i++) { - for(int j = 1; j < n; j++) { - solver.Add(binary[i - 1,j] == binary[i,j - 1]); + for (int i = 1; i < m; i++) { + for (int j = 1; j < n; j++) { + solver.Add(binary[i - 1, j] == binary[i, j - 1]); } } // ... and around the corner - for(int j = 1; j < n; j++) { - solver.Add(binary[m - 1,j] == binary[0,j - 1]); + for (int j = 1; j < n; j++) { + solver.Add(binary[m - 1, j] == binary[0, j - 1]); } // converts binary -> bin_code (de Bruijn sequence) - for(int i = 0; i < m; i++) { - solver.Add(bin_code[i] == binary[i,0]); - + for (int i = 0; i < m; i++) { + solver.Add(bin_code[i] == binary[i, 0]); } - // extra: ensure that all the numbers in the de Bruijn sequence // (bin_code) has the same occurrences (if check_same_gcc is True // and mathematically possible) solver.Add(bin_code.Distribute(gcc)); if (check_same_gcc && m % bbase == 0) { - for(int i = 1; i < bbase; i++) { + for (int i = 1; i < bbase; i++) { solver.Add(gcc[i] == gcc[i - 1]); } } @@ -128,34 +118,37 @@ public class DeBruijn // the minimum value of x should be first // solver.Add(x[0] == x.Min()); - // // Search // - DecisionBuilder db = solver.MakePhase(all, - Solver.CHOOSE_MIN_SIZE_LOWEST_MAX, - Solver.ASSIGN_MIN_VALUE); + DecisionBuilder db = solver.MakePhase( + all, Solver.CHOOSE_MIN_SIZE_LOWEST_MAX, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); while (solver.NextSolution()) { Console.Write("x: "); - for(int i = 0; i < m; i++) { - Console.Write(x[i].Value() + " "); + for (int i = 0; i < m; i++) { + Console.Write(x [i] + .Value() + + " "); } Console.Write("\nde Bruijn sequence:"); - for(int i = 0; i < m; i++) { - Console.Write(bin_code[i].Value() + " "); + for (int i = 0; i < m; i++) { + Console.Write(bin_code [i] + .Value() + + " "); } Console.Write("\ngcc: "); - for(int i = 0; i < bbase; i++) { - Console.Write(gcc[i].Value() + " "); + for (int i = 0; i < bbase; i++) { + Console.Write(gcc [i] + .Value() + + " "); } Console.WriteLine("\n"); - // for debugging etc: show the full binary table /* Console.Write("binary:"); @@ -167,7 +160,6 @@ public class DeBruijn } Console.WriteLine(); */ - } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); @@ -176,14 +168,12 @@ public class DeBruijn Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { + public static void Main(String[] args) { int bbase = 2; - int n = 3; - int m = 8; + int n = 3; + int m = 8; if (args.Length > 0) { bbase = Convert.ToInt32(args[0]); diff --git a/examples/contrib/discrete_tomography.cs b/examples/contrib/discrete_tomography.cs index 713a4639cf..4c9e843911 100644 --- a/examples/contrib/discrete_tomography.cs +++ b/examples/contrib/discrete_tomography.cs @@ -20,31 +20,28 @@ using System.Linq; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; -public class DiscreteTomography -{ - +public class DiscreteTomography { // default problem - static int[] default_rowsums = {0,0,8,2,6,4,5,3,7,0,0}; - static int[] default_colsums = {0,0,7,1,6,3,4,5,2,7,0,0}; + static int[] default_rowsums = {0, 0, 8, 2, 6, 4, 5, 3, 7, 0, 0}; + static int[] default_colsums = {0, 0, 7, 1, 6, 3, 4, 5, 2, 7, 0, 0}; static int[] rowsums2; static int[] colsums2; - /** * * Discrete tomography - * + * * Problem from http://eclipse.crosscoreop.com/examples/tomo.ecl.txt * """ * This is a little 'tomography' problem, taken from an old issue * of Scientific American. - * + * * A matrix which contains zeroes and ones gets "x-rayed" vertically and * horizontally, giving the total number of ones in each row and column. * The problem is to reconstruct the contents of the matrix from this * information. Sample run: - * + * * ?- go. * 0 0 7 1 6 3 4 5 2 7 0 0 * 0 @@ -65,9 +62,7 @@ public class DiscreteTomography * See http://www.hakank.org/or-tools/discrete_tomography.py * */ - private static void Solve(int[] rowsums, int[] colsums) - { - + private static void Solve(int[] rowsums, int[] colsums) { Solver solver = new Solver("DiscreteTomography"); // @@ -77,54 +72,52 @@ public class DiscreteTomography int c = colsums.Length; Console.Write("rowsums: "); - for(int i = 0; i < r; i++) { + for (int i = 0; i < r; i++) { Console.Write(rowsums[i] + " "); } Console.Write("\ncolsums: "); - for(int j = 0; j < c; j++) { + for (int j = 0; j < c; j++) { Console.Write(colsums[j] + " "); } Console.WriteLine("\n"); - // // Decision variables // - IntVar[,] x = solver.MakeIntVarMatrix(r, c, 0, 1, "x"); + IntVar[, ] x = solver.MakeIntVarMatrix(r, c, 0, 1, "x"); IntVar[] x_flat = x.Flatten(); - // // Constraints // // row sums - for(int i = 0; i < r; i++) { - var tmp = from j in Enumerable.Range(0, c) select x[i,j]; + for (int i = 0; i < r; i++) { + var tmp = from j in Enumerable.Range(0, c) select x[i, j]; solver.Add(tmp.ToArray().Sum() == rowsums[i]); } // cols sums - for(int j = 0; j < c; j++) { - var tmp = from i in Enumerable.Range(0, r) select x[i,j]; + for (int j = 0; j < c; j++) { + var tmp = from i in Enumerable.Range(0, r) select x[i, j]; solver.Add(tmp.ToArray().Sum() == colsums[j]); } - // // Search // - DecisionBuilder db = solver.MakePhase(x_flat, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(x_flat, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); - solver.NewSearch(db); while (solver.NextSolution()) { - for(int i = 0; i < r; i++) { - for(int j = 0; j < c; j++) { - Console.Write("{0} ", x[i,j].Value() == 1 ? "#" : "." ); + for (int i = 0; i < r; i++) { + for (int j = 0; j < c; j++) { + Console.Write("{0} ", x [i, j] + .Value() == 1 + ? "#" + : "."); } Console.WriteLine(); } @@ -137,10 +130,8 @@ public class DiscreteTomography Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - /** * * Reads a discrete tomography file. @@ -149,7 +140,7 @@ public class DiscreteTomography * % a comment which also is ignored * rowsums separated by [,\s] * colsums separated by [,\s] - * + * * e.g. * """ * 0,0,8,2,6,4,5,3,7,0,0 @@ -160,17 +151,16 @@ public class DiscreteTomography * */ private static void readFile(String file) { - Console.WriteLine("readFile(" + file + ")"); - + TextReader inr = new StreamReader(file); String str; int lineCount = 0; - while ((str = inr.ReadLine()) != null && str.Length > 0) { + while ((str = inr.ReadLine()) != null && str.Length > 0) { str = str.Trim(); - + // ignore comments - if(str.StartsWith("#") || str.StartsWith("%")) { + if (str.StartsWith("#") || str.StartsWith("%")) { continue; } @@ -180,37 +170,32 @@ public class DiscreteTomography colsums2 = ConvLine(str); break; } - - lineCount++; - - } // end while - - inr.Close(); - - } // end readFile + lineCount++; + + } // end while + + inr.Close(); + + } // end readFile private static int[] ConvLine(String str) { String[] tmp = Regex.Split(str, "[,\\s]+"); int len = tmp.Length; int[] sums = new int[len]; - for(int i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { sums[i] = Convert.ToInt32(tmp[i]); } - - return sums; + return sums; } - public static void Main(String[] args) - { - - if(args.Length > 0) { + public static void Main(String[] args) { + if (args.Length > 0) { readFile(args[0]); Solve(rowsums2, colsums2); } else { Solve(default_rowsums, default_colsums); } - } } diff --git a/examples/contrib/divisible_by_9_through_1.cs b/examples/contrib/divisible_by_9_through_1.cs index ffa00fe6c2..bde7046590 100644 --- a/examples/contrib/divisible_by_9_through_1.cs +++ b/examples/contrib/divisible_by_9_through_1.cs @@ -19,10 +19,7 @@ using System.IO; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; -public class DivisibleBy9Through1 -{ - - +public class DivisibleBy9Through1 { /** * * A simple propagator for modulo constraint. @@ -35,13 +32,12 @@ public class DivisibleBy9Through1 * */ public static void MyMod(Solver solver, IntVar x, IntVar y, IntVar r) { - long lbx = x.Min(); long ubx = x.Max(); long ubx_neg = -ubx; long lbx_neg = -lbx; - int min_x = (int)Math.Min(lbx, ubx_neg); - int max_x = (int)Math.Max(ubx, lbx_neg); + int min_x = (int) Math.Min(lbx, ubx_neg); + int max_x = (int) Math.Max(ubx, lbx_neg); IntVar d = solver.MakeIntVar(min_x, max_x, "d"); @@ -49,7 +45,7 @@ public class DivisibleBy9Through1 solver.Add(r >= 0); // x*r >= 0 - solver.Add( x*r >= 0); + solver.Add(x * r >= 0); // -abs(y) < r solver.Add(-y.Abs() < r); @@ -64,11 +60,9 @@ public class DivisibleBy9Through1 solver.Add(d <= max_x); // x == y*d+r - solver.Add(x - (y*d + r) == 0); - + solver.Add(x - (y * d + r) == 0); } - /** * * ToNum(solver, a, num, base) @@ -80,10 +74,10 @@ public class DivisibleBy9Through1 int len = a.Length; IntVar[] tmp = new IntVar[len]; - for(int i = 0; i < len; i++) { - tmp[i] = (a[i]*(int)Math.Pow(bbase,(len-i-1))).Var(); + for (int i = 0; i < len; i++) { + tmp[i] = (a[i] * (int) Math.Pow(bbase, (len - i - 1))).Var(); } - return tmp.Sum() == num; + return tmp.Sum() == num; } /** @@ -92,16 +86,14 @@ public class DivisibleBy9Through1 * See http://www.hakank.org/google_or_tools/divisible_by_9_through_1.py * */ - private static void Solve(int bbase) - { - + private static void Solve(int bbase) { Solver solver = new Solver("DivisibleBy9Through1"); - - int m = (int)Math.Pow(bbase,(bbase-1)) - 1; + int m = (int) Math.Pow(bbase, (bbase - 1)) - 1; int n = bbase - 1; - String[] digits_str = {"_","0","1","2","3","4","5","6","7","8","9"}; + String[] digits_str = {"_", "0", "1", "2", "3", "4", + "5", "6", "7", "8", "9"}; Console.WriteLine("base: " + bbase); @@ -114,54 +106,58 @@ public class DivisibleBy9Through1 // the numbers. t[0] contains the answe IntVar[] t = solver.MakeIntVarArray(n, 0, m, "t"); - // // Constraints // - solver.Add(x.AllDifferent()); + solver.Add(x.AllDifferent()); // Ensure the divisibility of base .. 1 IntVar zero = solver.MakeIntConst(0); - for(int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { int mm = bbase - i - 1; IntVar[] tt = new IntVar[mm]; - for(int j = 0; j < mm; j++) { + for (int j = 0; j < mm; j++) { tt[j] = x[j]; } solver.Add(ToNum(tt, t[i], bbase)); MyMod(solver, t[i], solver.MakeIntConst(mm), zero); - } // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.INT_VAR_DEFAULT, - Solver.INT_VALUE_DEFAULT); + DecisionBuilder db = + solver.MakePhase(x, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { Console.Write("x: "); - for(int i = 0; i < n; i++) { - Console.Write(x[i].Value() + " "); + for (int i = 0; i < n; i++) { + Console.Write(x [i] + .Value() + + " "); } Console.WriteLine("\nt: "); - for(int i = 0; i < n; i++) { - Console.Write(t[i].Value() + " "); + for (int i = 0; i < n; i++) { + Console.Write(t [i] + .Value() + + " "); } Console.WriteLine("\n"); if (bbase != 10) { - Console.Write("Number base 10: " + t[0].Value()); + Console.Write("Number base 10: " + t [0] + .Value()); Console.Write(" Base " + bbase + ": "); - for(int i = 0; i < n; i++) { - Console.Write(digits_str[(int)x[i].Value() + 1]); + for (int i = 0; i < n; i++) { + Console.Write(digits_str [(int) x [i] + .Value() + + 1] + ); } Console.WriteLine("\n"); - } } @@ -171,18 +167,16 @@ public class DivisibleBy9Through1 Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - + public static void Main(String[] args) { int bbase = 10; if (args.Length > 0) { bbase = Convert.ToInt32(args[0]); if (bbase > 12) { // Though base = 12 has no solution... - Console.WriteLine("Sorry, max relevant base is 12. Setting base to 12."); + Console.WriteLine( + "Sorry, max relevant base is 12. Setting base to 12."); bbase = 10; } } diff --git a/examples/contrib/dudeney.cs b/examples/contrib/dudeney.cs index 0ed1ca0d03..1c52a1b817 100644 --- a/examples/contrib/dudeney.cs +++ b/examples/contrib/dudeney.cs @@ -20,21 +20,17 @@ using System.Linq; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; -public class DudeneyNumbers -{ - - +public class DudeneyNumbers { private static Constraint ToNum(IntVar[] a, IntVar num, int bbase) { int len = a.Length; IntVar[] tmp = new IntVar[len]; - for(int i = 0; i < len; i++) { - tmp[i] = (a[i]*(int)Math.Pow(bbase,(len-i-1))).Var(); + for (int i = 0; i < len; i++) { + tmp[i] = (a[i] * (int) Math.Pow(bbase, (len - i - 1))).Var(); } - return tmp.Sum() == num; + return tmp.Sum() == num; } - /** * * Dudeney numbers @@ -43,12 +39,12 @@ public class DudeneyNumbers * http://cp-is-fun.blogspot.com/2010/09/test-python.html * """ * I discovered yesterday Dudeney Numbers - * A Dudeney Numbers is a positive integer that is a perfect cube such that the sum - * of its decimal digits is equal to the cube root of the number. There are only six - * Dudeney Numbers and those are very easy to find with CP. - * I made my first experience with google cp solver so find these numbers (model below) - * and must say that I found it very convenient to build CP models in python! - * When you take a close look at the line: + * A Dudeney Numbers is a positive integer that is a perfect cube such that + * the sum of its decimal digits is equal to the cube root of the number. + * There are only six Dudeney Numbers and those are very easy to find with CP. + * I made my first experience with google cp solver so find these numbers + * (model below) and must say that I found it very convenient to build CP + * models in python! When you take a close look at the line: * solver.Add(sum([10**(n-i-1)*x[i] for i in range(n)]) == nb) * It is difficult to argue that it is very far from dedicated * optimization languages! @@ -57,9 +53,7 @@ public class DudeneyNumbers * Also see: http://en.wikipedia.org/wiki/Dudeney_number * */ - private static void Solve() - { - + private static void Solve() { Solver solver = new Solver("DudeneyNumbers"); // @@ -71,30 +65,29 @@ public class DudeneyNumbers // Decision variables // IntVar[] x = solver.MakeIntVarArray(n, 0, 9, "x"); - IntVar nb = solver.MakeIntVar(3, (int)Math.Pow(10,n), "nb"); - IntVar s = solver.MakeIntVar(1,9*n+1,"s"); + IntVar nb = solver.MakeIntVar(3, (int) Math.Pow(10, n), "nb"); + IntVar s = solver.MakeIntVar(1, 9 * n + 1, "s"); // // Constraints // - solver.Add(nb == s*s*s); + solver.Add(nb == s * s * s); solver.Add(x.Sum() == s); // solver.Add(ToNum(x, nb, 10)); // alternative - solver.Add((from i in Enumerable.Range(0, n) - select (x[i]*(int)Math.Pow(10,n-i-1)).Var()). - ToArray().Sum() == nb); - + solver.Add((from i in Enumerable + .Range(0, n) select(x[i] * (int) Math.Pow(10, n - i - 1)) + .Var()) + .ToArray() + .Sum() == nb); // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.INT_VAR_DEFAULT, - Solver.INT_VALUE_DEFAULT); - + DecisionBuilder db = + solver.MakePhase(x, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); @@ -108,15 +101,7 @@ public class DudeneyNumbers Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - - public static void Main(String[] args) - { - - Solve(); - - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/einav_puzzle2.cs b/examples/contrib/einav_puzzle2.cs index 7390755e8b..2536a33560 100644 --- a/examples/contrib/einav_puzzle2.cs +++ b/examples/contrib/einav_puzzle2.cs @@ -19,8 +19,7 @@ using System.Collections.Generic; using System.Linq; using Google.OrTools.ConstraintSolver; -public class EinavPuzzle2 -{ +public class EinavPuzzle2 { /** * * A programming puzzle from Einav. @@ -60,15 +59,14 @@ public class EinavPuzzle2 * """ * * Note: - * This is a port of Larent Perrons's Python version of my own einav_puzzle.py. - * He removed some of the decision variables and made it more efficient. - * Thanks! + * This is a port of Larent Perrons's Python version of my own + * einav_puzzle.py. He removed some of the decision variables and made it more + * efficient. Thanks! * * Also see http://www.hakank.org/or-tools/einav_puzzle2.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("EinavPuzzle2"); // @@ -84,40 +82,36 @@ public class EinavPuzzle2 // {-17, -12, -14} // }; - // Full problem int rows = 27; int cols = 9; - int[,] data = { - {33,30,10,-6,18,-7,-11,23,-6}, - {16,-19,9,-26,-8,-19,-8,-21,-14}, - {17,12,-14,31,-30,13,-13,19,16}, - {-6,-11,1,17,-12,-4,-7,14,-21}, - {18,-31,34,-22,17,-19,20,24,6}, - {33,-18,17,-15,31,-5,3,27,-3}, - {-18,-20,-18,31,6,4,-2,-12,24}, - {27,14,4,-29,-3,5,-29,8,-12}, - {-15,-7,-23,23,-9,-8,6,8,-12}, - {33,-23,-19,-4,-8,-7,11,-12,31}, - {-20,19,-15,-30,11,32,7,14,-5}, - {-23,18,-32,-2,-31,-7,8,24,16}, - {32,-4,-10,-14,-6,-1,0,23,23}, - {25,0,-23,22,12,28,-27,15,4}, - {-30,-13,-16,-3,-3,-32,-3,27,-31}, - {22,1,26,4,-2,-13,26,17,14}, - {-9,-18,3,-20,-27,-32,-11,27,13}, - {-17,33,-7,19,-32,13,-31,-2,-24}, - {-31,27,-31,-29,15,2,29,-15,33}, - {-18,-23,15,28,0,30,-4,12,-32}, - {-3,34,27,-25,-18,26,1,34,26}, - {-21,-31,-10,-13,-30,-17,-12,-26,31}, - {23,-31,-19,21,-17,-10,2,-23,23}, - {-3,6,0,-3,-32,0,-10,-25,14}, - {-19,9,14,-27,20,15,-5,-27,18}, - {11,-6,24,7,-17,26,20,-31,-25}, - {-25,4,-16,30,33,23,-4,-4,23} - }; - + int[, ] data = {{33, 30, 10, -6, 18, -7, -11, 23, -6}, + {16, -19, 9, -26, -8, -19, -8, -21, -14}, + {17, 12, -14, 31, -30, 13, -13, 19, 16}, + {-6, -11, 1, 17, -12, -4, -7, 14, -21}, + {18, -31, 34, -22, 17, -19, 20, 24, 6}, + {33, -18, 17, -15, 31, -5, 3, 27, -3}, + {-18, -20, -18, 31, 6, 4, -2, -12, 24}, + {27, 14, 4, -29, -3, 5, -29, 8, -12}, + {-15, -7, -23, 23, -9, -8, 6, 8, -12}, + {33, -23, -19, -4, -8, -7, 11, -12, 31}, + {-20, 19, -15, -30, 11, 32, 7, 14, -5}, + {-23, 18, -32, -2, -31, -7, 8, 24, 16}, + {32, -4, -10, -14, -6, -1, 0, 23, 23}, + {25, 0, -23, 22, 12, 28, -27, 15, 4}, + {-30, -13, -16, -3, -3, -32, -3, 27, -31}, + {22, 1, 26, 4, -2, -13, 26, 17, 14}, + {-9, -18, 3, -20, -27, -32, -11, 27, 13}, + {-17, 33, -7, 19, -32, 13, -31, -2, -24}, + {-31, 27, -31, -29, 15, 2, 29, -15, 33}, + {-18, -23, 15, 28, 0, 30, -4, 12, -32}, + {-3, 34, 27, -25, -18, 26, 1, 34, 26}, + {-21, -31, -10, -13, -30, -17, -12, -26, 31}, + {23, -31, -19, 21, -17, -10, 2, -23, 23}, + {-3, 6, 0, -3, -32, 0, -10, -25, 14}, + {-19, 9, 14, -27, 20, 15, -5, -27, 18}, + {11, -6, 24, 7, -17, 26, 20, -31, -25}, + {-25, 4, -16, 30, 33, 23, -4, -4, 23}}; IEnumerable ROWS = Enumerable.Range(0, rows); IEnumerable COLS = Enumerable.Range(0, cols); @@ -125,15 +119,15 @@ public class EinavPuzzle2 // // Decision variables // - IntVar[,] x = solver.MakeIntVarMatrix(rows, cols, -100, 100, "x"); + IntVar[, ] x = solver.MakeIntVarMatrix(rows, cols, -100, 100, "x"); IntVar[] x_flat = x.Flatten(); - int[] signs_domain = {-1,1}; + int[] signs_domain = {-1, 1}; // This don't work at the moment... - IntVar[] row_signs = solver.MakeIntVarArray(rows, signs_domain, "row_signs"); - IntVar[] col_signs = solver.MakeIntVarArray(cols, signs_domain, "col_signs"); - - + IntVar[] row_signs = + solver.MakeIntVarArray(rows, signs_domain, "row_signs"); + IntVar[] col_signs = + solver.MakeIntVarArray(cols, signs_domain, "col_signs"); // To optimize IntVar total_sum = x_flat.Sum().VarWithName("total_sum"); @@ -141,39 +135,41 @@ public class EinavPuzzle2 // // Constraints // - foreach(int i in ROWS) { - foreach(int j in COLS) { - solver.Add(x[i,j] == data[i,j] * row_signs[i] * col_signs[j]); + foreach (int i in ROWS) { + foreach (int j in COLS) { + solver.Add(x[i, j] == data[i, j] * row_signs[i] * col_signs[j]); } } // row sums - IntVar[] row_sums = (from i in ROWS - select (from j in COLS - select x[i,j] - ).ToArray().Sum().Var()).ToArray(); + IntVar[] row_sums = (from i in ROWS select(from j in COLS select x[i, j]) + .ToArray() + .Sum() + .Var()) + .ToArray(); - foreach(int i in ROWS) { - row_sums[i].SetMin(0); + foreach (int i in ROWS) { + row_sums [i] + .SetMin(0); } // col sums - IntVar[] col_sums = (from j in COLS - select (from i in ROWS - select x[i,j] - ).ToArray().Sum().Var()).ToArray(); + IntVar[] col_sums = (from j in COLS select(from i in ROWS select x[i, j]) + .ToArray() + .Sum() + .Var()) + .ToArray(); - foreach(int j in COLS) { - col_sums[j].SetMin(0); + foreach (int j in COLS) { + col_sums [j] + .SetMin(0); } - // // Objective // OptimizeVar obj = total_sum.Minimize(1); - // // Search // @@ -184,28 +180,37 @@ public class EinavPuzzle2 solver.NewSearch(db, obj); while (solver.NextSolution()) { - Console.WriteLine("Sum: {0}",total_sum.Value()); + Console.WriteLine("Sum: {0}", total_sum.Value()); Console.Write("row_sums: "); - foreach(int i in ROWS) { - Console.Write(row_sums[i].Value() + " "); + foreach (int i in ROWS) { + Console.Write(row_sums [i] + .Value() + + " "); } Console.Write("\nrow_signs: "); - foreach(int i in ROWS) { - Console.Write(row_signs[i].Value() + " "); + foreach (int i in ROWS) { + Console.Write(row_signs [i] + .Value() + + " "); } Console.Write("\ncol_sums: "); - foreach(int j in COLS) { - Console.Write(col_sums[j].Value() + " "); + foreach (int j in COLS) { + Console.Write(col_sums [j] + .Value() + + " "); } Console.Write("\ncol_signs: "); - foreach(int j in COLS) { - Console.Write(col_signs[j].Value() + " "); + foreach (int j in COLS) { + Console.Write(col_signs [j] + .Value() + + " "); } Console.WriteLine("\n"); - foreach(int i in ROWS) { - foreach(int j in COLS) { - Console.Write("{0,3} ", x[i,j].Value()); + foreach (int i in ROWS) { + foreach (int j in COLS) { + Console.Write("{0,3} ", x [i, j] + .Value()); } Console.WriteLine(); } @@ -218,11 +223,7 @@ public class EinavPuzzle2 Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/eq10.cs b/examples/contrib/eq10.cs index e91bb60492..393ea228eb 100644 --- a/examples/contrib/eq10.cs +++ b/examples/contrib/eq10.cs @@ -16,8 +16,7 @@ using System; using Google.OrTools.ConstraintSolver; -public class Eq10 -{ +public class Eq10 { /** * * Eq 10 in Google CP Solver. @@ -27,8 +26,7 @@ public class Eq10 * Also see http://hakank.org/or-tools/eq10.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("Eq10"); int n = 7; @@ -44,54 +42,59 @@ public class Eq10 IntVar X6 = solver.MakeIntVar(0, 10, "X6"); IntVar X7 = solver.MakeIntVar(0, 10, "X7"); - IntVar[] X = {X1,X2,X3,X4,X5,X6,X7}; - + IntVar[] X = {X1, X2, X3, X4, X5, X6, X7}; // // Constraints // - solver.Add(0+98527*X1+34588*X2+5872*X3+59422*X5+65159*X7 - == 1547604+30704*X4+29649*X6); + solver.Add(0 + 98527 * X1 + 34588 * X2 + 5872 * X3 + 59422 * X5 + + 65159 * X7 == + 1547604 + 30704 * X4 + 29649 * X6); - solver.Add(0+98957*X2+83634*X3+69966*X4+62038*X5+37164*X6+85413*X7 - == 1823553+93989*X1); + solver.Add(0 + 98957 * X2 + 83634 * X3 + 69966 * X4 + 62038 * X5 + + 37164 * X6 + 85413 * X7 == + 1823553 + 93989 * X1); - solver.Add(900032+10949*X1+77761*X2+67052*X5 - == 0+80197*X3+61944*X4+92964*X6+44550*X7); + solver.Add(900032 + 10949 * X1 + 77761 * X2 + 67052 * X5 == + 0 + 80197 * X3 + 61944 * X4 + 92964 * X6 + 44550 * X7); - solver.Add(0+73947*X1+84391*X3+81310*X5 - == 1164380+96253*X2+44247*X4+70582*X6+33054*X7); + solver.Add(0 + 73947 * X1 + 84391 * X3 + 81310 * X5 == + 1164380 + 96253 * X2 + 44247 * X4 + 70582 * X6 + 33054 * X7); - solver.Add(0+13057*X3+42253*X4+77527*X5+96552*X7 - == 1185471+60152*X1+21103*X2+97932*X6); + solver.Add(0 + 13057 * X3 + 42253 * X4 + 77527 * X5 + 96552 * X7 == + 1185471 + 60152 * X1 + 21103 * X2 + 97932 * X6); - solver.Add(1394152+66920*X1+55679*X4 - == 0+64234*X2+65337*X3+45581*X5+67707*X6+98038*X7); + solver.Add(1394152 + 66920 * X1 + 55679 * X4 == + 0 + 64234 * X2 + 65337 * X3 + 45581 * X5 + 67707 * X6 + + 98038 * X7); - solver.Add(0+68550*X1+27886*X2+31716*X3+73597*X4+38835*X7 - == 279091+88963*X5+76391*X6); + solver.Add(0 + 68550 * X1 + 27886 * X2 + 31716 * X3 + 73597 * X4 + + 38835 * X7 == + 279091 + 88963 * X5 + 76391 * X6); - solver.Add(0+76132*X2+71860*X3+22770*X4+68211*X5+78587*X6 - == 480923+48224*X1+82817*X7); + solver.Add(0 + 76132 * X2 + 71860 * X3 + 22770 * X4 + 68211 * X5 + + 78587 * X6 == + 480923 + 48224 * X1 + 82817 * X7); - solver.Add(519878+94198*X2+87234*X3+37498*X4 - == 0+71583*X1+25728*X5+25495*X6+70023*X7); + solver.Add(519878 + 94198 * X2 + 87234 * X3 + 37498 * X4 == + 0 + 71583 * X1 + 25728 * X5 + 25495 * X6 + 70023 * X7); - solver.Add(361921+78693*X1+38592*X5+38478*X6 - == 0+94129*X2+43188*X3+82528*X4+69025*X7); + solver.Add(361921 + 78693 * X1 + 38592 * X5 + 38478 * X6 == + 0 + 94129 * X2 + 43188 * X3 + 82528 * X4 + 69025 * X7); // // Search // - DecisionBuilder db = solver.MakePhase(X, - Solver.INT_VAR_DEFAULT, - Solver.INT_VALUE_DEFAULT); + DecisionBuilder db = + solver.MakePhase(X, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { - for(int i = 0; i < n; i++) { - Console.Write(X[i].ToString() + " "); + for (int i = 0; i < n; i++) { + Console.Write(X [i] + .ToString() + + " "); } Console.WriteLine(); } @@ -102,11 +105,7 @@ public class Eq10 Console.WriteLine("Branches: " + solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/eq20.cs b/examples/contrib/eq20.cs index 147768944d..848f669b5f 100644 --- a/examples/contrib/eq20.cs +++ b/examples/contrib/eq20.cs @@ -16,8 +16,7 @@ using System; using Google.OrTools.ConstraintSolver; -public class Eq20 -{ +public class Eq20 { /** * * Eq 20 in Google CP Solver. @@ -27,8 +26,7 @@ public class Eq20 * Also see http://hakank.org/or-tools/eq20.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("Eq20"); int n = 7; @@ -44,66 +42,85 @@ public class Eq20 IntVar X5 = solver.MakeIntVar(0, 10, "X5"); IntVar X6 = solver.MakeIntVar(0, 10, "X6"); - IntVar[] X = {X0,X1,X2,X3,X4,X5,X6}; - + IntVar[] X = {X0, X1, X2, X3, X4, X5, X6}; // // Constraints // - solver.Add(-76706*X0 + 98205*X1 + 23445*X2 + 67921*X3 + 24111*X4 + - -48614*X5 + -41906*X6 == 821228); - solver.Add(87059*X0 + -29101*X1 + -5513*X2 + -21219*X3 + 22128*X4 + - 7276*X5 + 57308*X6 == 22167); - solver.Add(-60113*X0 + 29475*X1 + 34421*X2 + -76870*X3 + 62646*X4 + - 29278*X5 + -15212*X6 == 251591); - solver.Add(49149*X0 + 52871*X1 + -7132*X2 + 56728*X3 + -33576*X4 + - -49530*X5 + -62089*X6 == 146074); - solver.Add(-10343*X0 + 87758*X1 + -11782*X2 + 19346*X3 + 70072*X4 + - -36991*X5 + 44529*X6 == 740061); - solver.Add(85176*X0 + -95332*X1 + -1268*X2 + 57898*X3 + 15883*X4 + - 50547*X5 + 83287*X6 == 373854); - solver.Add(-85698*X0 + 29958*X1 + 57308*X2 + 48789*X3 + -78219*X4 + - 4657*X5 + 34539*X6 == 249912); - solver.Add(-67456*X0 + 84750*X1 + -51553*X2 + 21239*X3 + 81675*X4 + - -99395*X5 + -4254*X6 == 277271); - solver.Add(94016*X0 + -82071*X1 + 35961*X2 + 66597*X3 + -30705*X4 + - -44404*X5 + -38304*X6 == 25334); - solver.Add(-60301*X0 + 31227*X1 + 93951*X2 + 73889*X3 + 81526*X4 + - -72702*X5 + 68026*X6 == 1410723); - solver.Add(-16835*X0 + 47385*X1 + 97715*X2 + -12640*X3 + 69028*X4 + - 76212*X5 + -81102*X6 == 1244857); - solver.Add(-43277*X0 + 43525*X1 + 92298*X2 + 58630*X3 + 92590*X4 + - -9372*X5 + -60227*X6 == 1503588); - solver.Add(-64919*X0 + 80460*X1 + 90840*X2 + -59624*X3 + -75542*X4 + - 25145*X5 + -47935*X6 == 18465); - solver.Add(-45086*X0 + 51830*X1 + -4578*X2 + 96120*X3 + 21231*X4 + - 97919*X5 + 65651*X6 == 1198280); - solver.Add(85268*X0 + 54180*X1 + -18810*X2 + -48219*X3 + 6013*X4 + - 78169*X5 + -79785*X6 == 90614); - solver.Add(8874*X0 + -58412*X1 + 73947*X2 + 17147*X3 + 62335*X4 + - 16005*X5 + 8632*X6 == 752447); - solver.Add(71202*X0 + -11119*X1 + 73017*X2 + -38875*X3 + -14413*X4 + - -29234*X5 + 72370*X6 == 129768); - solver.Add(1671*X0 + -34121*X1 + 10763*X2 + 80609*X3 + 42532*X4 + - 93520*X5 + -33488*X6 == 915683); - solver.Add(51637*X0 + 67761*X1 + 95951*X2 + 3834*X3 + -96722*X4 + - 59190*X5 + 15280*X6 == 533909); - solver.Add(-16105*X0 + 62397*X1 + -6704*X2 + 43340*X3 + 95100*X4 + - -68610*X5 + 58301*X6 == 876370); - + solver.Add(-76706 * X0 + 98205 * X1 + 23445 * X2 + 67921 * X3 + 24111 * X4 + + -48614 * X5 + -41906 * X6 == + 821228); + solver.Add(87059 * X0 + -29101 * X1 + -5513 * X2 + -21219 * X3 + + 22128 * X4 + 7276 * X5 + 57308 * X6 == + 22167); + solver.Add(-60113 * X0 + 29475 * X1 + 34421 * X2 + -76870 * X3 + + 62646 * X4 + 29278 * X5 + -15212 * X6 == + 251591); + solver.Add(49149 * X0 + 52871 * X1 + -7132 * X2 + 56728 * X3 + -33576 * X4 + + -49530 * X5 + -62089 * X6 == + 146074); + solver.Add(-10343 * X0 + 87758 * X1 + -11782 * X2 + 19346 * X3 + + 70072 * X4 + -36991 * X5 + 44529 * X6 == + 740061); + solver.Add(85176 * X0 + -95332 * X1 + -1268 * X2 + 57898 * X3 + 15883 * X4 + + 50547 * X5 + 83287 * X6 == + 373854); + solver.Add(-85698 * X0 + 29958 * X1 + 57308 * X2 + 48789 * X3 + + -78219 * X4 + 4657 * X5 + 34539 * X6 == + 249912); + solver.Add(-67456 * X0 + 84750 * X1 + -51553 * X2 + 21239 * X3 + + 81675 * X4 + -99395 * X5 + -4254 * X6 == + 277271); + solver.Add(94016 * X0 + -82071 * X1 + 35961 * X2 + 66597 * X3 + + -30705 * X4 + -44404 * X5 + -38304 * X6 == + 25334); + solver.Add(-60301 * X0 + 31227 * X1 + 93951 * X2 + 73889 * X3 + 81526 * X4 + + -72702 * X5 + 68026 * X6 == + 1410723); + solver.Add(-16835 * X0 + 47385 * X1 + 97715 * X2 + -12640 * X3 + + 69028 * X4 + 76212 * X5 + -81102 * X6 == + 1244857); + solver.Add(-43277 * X0 + 43525 * X1 + 92298 * X2 + 58630 * X3 + 92590 * X4 + + -9372 * X5 + -60227 * X6 == + 1503588); + solver.Add(-64919 * X0 + 80460 * X1 + 90840 * X2 + -59624 * X3 + + -75542 * X4 + 25145 * X5 + -47935 * X6 == + 18465); + solver.Add(-45086 * X0 + 51830 * X1 + -4578 * X2 + 96120 * X3 + 21231 * X4 + + 97919 * X5 + 65651 * X6 == + 1198280); + solver.Add(85268 * X0 + 54180 * X1 + -18810 * X2 + -48219 * X3 + 6013 * X4 + + 78169 * X5 + -79785 * X6 == + 90614); + solver.Add(8874 * X0 + -58412 * X1 + 73947 * X2 + 17147 * X3 + 62335 * X4 + + 16005 * X5 + 8632 * X6 == + 752447); + solver.Add(71202 * X0 + -11119 * X1 + 73017 * X2 + -38875 * X3 + + -14413 * X4 + -29234 * X5 + 72370 * X6 == + 129768); + solver.Add(1671 * X0 + -34121 * X1 + 10763 * X2 + 80609 * X3 + 42532 * X4 + + 93520 * X5 + -33488 * X6 == + 915683); + solver.Add(51637 * X0 + 67761 * X1 + 95951 * X2 + 3834 * X3 + -96722 * X4 + + 59190 * X5 + 15280 * X6 == + 533909); + solver.Add(-16105 * X0 + 62397 * X1 + -6704 * X2 + 43340 * X3 + 95100 * X4 + + -68610 * X5 + 58301 * X6 == + 876370); // // Search // - DecisionBuilder db = solver.MakePhase(X, - Solver.INT_VAR_DEFAULT, - Solver.INT_VALUE_DEFAULT); + DecisionBuilder db = + solver.MakePhase(X, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { - for(int i = 0; i < n; i++) { - Console.Write(X[i].ToString() + " "); + for (int i = 0; i < n; i++) { + Console.Write(X [i] + .ToString() + + " "); } Console.WriteLine(); } @@ -114,11 +131,7 @@ public class Eq20 Console.WriteLine("Branches: " + solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/fill_a_pix.cs b/examples/contrib/fill_a_pix.cs index 83e5c65963..c89439bd44 100644 --- a/examples/contrib/fill_a_pix.cs +++ b/examples/contrib/fill_a_pix.cs @@ -20,10 +20,7 @@ using System.Linq; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; - -public class FillAPix -{ - +public class FillAPix { static int X = -1; // @@ -33,27 +30,23 @@ public class FillAPix // static int default_n = 10; - static int[,] default_puzzle = {{X,X,X,X,X,X,X,X,0,X}, - {X,8,8,X,2,X,0,X,X,X}, - {5,X,8,X,X,X,X,X,X,X}, - {X,X,X,X,X,2,X,X,X,2}, - {1,X,X,X,4,5,6,X,X,X}, - {X,0,X,X,X,7,9,X,X,6}, - {X,X,X,6,X,X,9,X,X,6}, - {X,X,6,6,8,7,8,7,X,5}, - {X,4,X,6,6,6,X,6,X,4}, - {X,X,X,X,X,X,3,X,X,X}}; + static int[, ] default_puzzle = { + {X, X, X, X, X, X, X, X, 0, X}, {X, 8, 8, X, 2, X, 0, X, X, X}, + {5, X, 8, X, X, X, X, X, X, X}, {X, X, X, X, X, 2, X, X, X, 2}, + {1, X, X, X, 4, 5, 6, X, X, X}, {X, 0, X, X, X, 7, 9, X, X, 6}, + {X, X, X, 6, X, X, 9, X, X, 6}, {X, X, 6, 6, 8, 7, 8, 7, X, 5}, + {X, 4, X, 6, 6, 6, X, 6, X, 4}, {X, X, X, X, X, X, 3, X, X, X}}; // for the actual problem static int n; - static int[,] puzzle; - + static int[, ] puzzle; /** * * Fill-a-Pix problem * - * From http://www.conceptispuzzles.com/index.aspx?uri=puzzle/fill-a-pix/basiclogic + * From + * http://www.conceptispuzzles.com/index.aspx?uri=puzzle/fill-a-pix/basiclogic * """ * Each puzzle consists of a grid containing clues in various places. The * object is to reveal a hidden picture by painting the squares around each @@ -76,8 +69,7 @@ public class FillAPix * * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("FillAPix"); // @@ -86,10 +78,10 @@ public class FillAPix int[] S = {-1, 0, 1}; Console.WriteLine("Problem:"); - for(int i = 0; i < n; i++) { - for(int j = 0; j < n; j++) { - if (puzzle[i,j] > X) { - Console.Write(puzzle[i,j] + " "); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + if (puzzle[i, j] > X) { + Console.Write(puzzle[i, j] + " "); } else { Console.Write("X "); } @@ -98,40 +90,31 @@ public class FillAPix } Console.WriteLine(); - // // Decision variables // - IntVar[,] pict = solver.MakeIntVarMatrix(n, n, 0, 1, "pict"); - IntVar[] pict_flat = pict.Flatten(); // for branching + IntVar[, ] pict = solver.MakeIntVarMatrix(n, n, 0, 1, "pict"); + IntVar[] pict_flat = pict.Flatten(); // for branching // // Constraints - // - for(int i = 0; i < n; i++) { - for(int j = 0; j < n; j++) { - if (puzzle[i,j] > X) { - + // + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + if (puzzle[i, j] > X) { // this cell is the sum of all surrounding cells - var tmp = from a in S from b in S where - i + a >= 0 && - j + b >= 0 && - i + a < n && - j + b < n - select(pict[i+a,j+b]); - - solver.Add(tmp.ToArray().Sum() == puzzle[i,j]); + var tmp = from a in S from b in S where i + a >= 0 && j + b >= 0 && + i + a < n && j + b < n select(pict[i + a, j + b]); + solver.Add(tmp.ToArray().Sum() == puzzle[i, j]); } } } - // // Search // - DecisionBuilder db = solver.MakePhase(pict_flat, - Solver.INT_VAR_DEFAULT, + DecisionBuilder db = solver.MakePhase(pict_flat, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); @@ -140,13 +123,16 @@ public class FillAPix while (solver.NextSolution()) { sol++; Console.WriteLine("Solution #{0} ", sol + " "); - for(int i = 0; i < n; i++) { - for(int j = 0; j < n; j++){ - Console.Write(pict[i,j].Value() == 1 ? "#" : " "); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + Console.Write(pict [i, j] + .Value() == 1 + ? "#" + : " "); } Console.WriteLine(); } - + Console.WriteLine(); } @@ -156,10 +142,8 @@ public class FillAPix Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - /** * * Reads a Fill-a-Pix file. @@ -170,9 +154,9 @@ public class FillAPix * < * row number of neighbours lines... * > - * + * * 0..8 means number of neighbours, "." mean unknown (may be a mine) - * + * * Example (from fill_a_pix1.txt): * * 10 @@ -189,51 +173,45 @@ public class FillAPix * */ private static void readFile(String file) { - Console.WriteLine("readFile(" + file + ")"); int lineCount = 0; - + TextReader inr = new StreamReader(file); String str; while ((str = inr.ReadLine()) != null && str.Length > 0) { - str = str.Trim(); - + // ignore comments - if(str.StartsWith("#") || str.StartsWith("%")) { + if (str.StartsWith("#") || str.StartsWith("%")) { continue; } - + Console.WriteLine(str); if (lineCount == 0) { - n = Convert.ToInt32(str); // number of rows - puzzle = new int[n,n]; + n = Convert.ToInt32(str); // number of rows + puzzle = new int[n, n]; } else { // the problem matrix String[] row = Regex.Split(str, ""); - for(int j = 1; j <= n; j++) { + for (int j = 1; j <= n; j++) { String s = row[j]; if (s.Equals(".")) { - puzzle[lineCount-1, j-1] = -1; + puzzle[lineCount - 1, j - 1] = -1; } else { - puzzle[lineCount-1, j-1] = Convert.ToInt32(s); + puzzle[lineCount - 1, j - 1] = Convert.ToInt32(s); } } } - + lineCount++; - - } // end while - + + } // end while + inr.Close(); - - } // end readFile + } // end readFile - - - public static void Main(String[] args) - { + public static void Main(String[] args) { String file = ""; if (args.Length > 0) { file = args[0]; diff --git a/examples/contrib/furniture_moving.cs b/examples/contrib/furniture_moving.cs index 2c96c43f54..6fab63308c 100644 --- a/examples/contrib/furniture_moving.cs +++ b/examples/contrib/furniture_moving.cs @@ -18,9 +18,7 @@ using System.Collections; using System.Linq; using Google.OrTools.ConstraintSolver; -public class FurnitureMoving -{ - +public class FurnitureMoving { /* * Decompositon of cumulative. * @@ -43,22 +41,21 @@ public class FurnitureMoving * * */ - static void MyCumulative(Solver solver, - IntVar[] s, - int[] d, - int[] r, + static void MyCumulative(Solver solver, IntVar[] s, int[] d, int[] r, IntVar b) { - - int[] tasks = (from i in Enumerable.Range(0, s.Length) - where r[i] > 0 && d[i] > 0 - select i).ToArray(); - int times_min = tasks.Min(i => (int)s[i].Min()); + int[] tasks = (from i in Enumerable.Range(0, s.Length) where r[i] > 0 && + d[i] > 0 select i) + .ToArray(); + int times_min = tasks.Min(i =>(int) s [i] + .Min()); int d_max = d.Max(); - int times_max = tasks.Max(i => (int)s[i].Max() + d_max); - for(int t = times_min; t <= times_max; t++) { + int times_max = tasks.Max(i =>(int) s [i] + .Max() + + d_max); + for (int t = times_min; t <= times_max; t++) { ArrayList bb = new ArrayList(); - foreach(int i in tasks) { - bb.Add(((s[i] <= t) * (s[i] + d[i]> t) * r[i]).Var()); + foreach (int i in tasks) { + bb.Add(((s[i] <= t) * (s[i] + d[i] > t) * r[i]).Var()); } solver.Add((bb.ToArray(typeof(IntVar)) as IntVar[]).Sum() <= b); } @@ -68,9 +65,7 @@ public class FurnitureMoving if (b is IntVar) { solver.Add(b <= r.Sum()); } - - } - + } /** * @@ -84,38 +79,36 @@ public class FurnitureMoving * Also see http://www.hakank.org/or-tools/furniture_moving.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("FurnitureMoving"); int n = 4; - int[] duration = {30,10,15,15}; - int[] demand = { 3, 1, 3, 2}; + int[] duration = {30, 10, 15, 15}; + int[] demand = {3, 1, 3, 2}; int upper_limit = 160; - // // Decision variables // - IntVar[] start_times = solver.MakeIntVarArray(n, 0, upper_limit, "start_times"); - IntVar[] end_times = solver.MakeIntVarArray(n, 0, upper_limit * 2, "end_times"); + IntVar[] start_times = + solver.MakeIntVarArray(n, 0, upper_limit, "start_times"); + IntVar[] end_times = + solver.MakeIntVarArray(n, 0, upper_limit * 2, "end_times"); IntVar end_time = solver.MakeIntVar(0, upper_limit * 2, "end_time"); // number of needed resources, to be minimized or constrained - IntVar num_resources = solver.MakeIntVar(0, 10, "num_resources"); - + IntVar num_resources = solver.MakeIntVar(0, 10, "num_resources"); // // Constraints // - for(int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { solver.Add(end_times[i] == start_times[i] + duration[i]); } solver.Add(end_time == end_times.Max()); MyCumulative(solver, start_times, duration, demand, num_resources); - // // Some extra constraints to play with // @@ -128,12 +121,10 @@ public class FurnitureMoving // solver.Add(start_times[i] == 0); // } - // limitation of the number of people // solver.Add(num_resources <= 3); solver.Add(num_resources <= 4); - // // Objective // @@ -144,21 +135,22 @@ public class FurnitureMoving // // Search // - DecisionBuilder db = solver.MakePhase(start_times, - Solver.CHOOSE_FIRST_UNBOUND, - Solver.ASSIGN_MIN_VALUE); + DecisionBuilder db = solver.MakePhase( + start_times, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db, obj); while (solver.NextSolution()) { Console.WriteLine("num_resources: {0} end_time: {1}", num_resources.Value(), end_time.Value()); - for(int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { Console.WriteLine("Task {0,1}: {1,2} -> {2,2} -> {3,2} (demand: {4})", i, - start_times[i].Value(), + start_times [i] + .Value(), duration[i], - end_times[i].Value(), + end_times [i] + .Value(), demand[i]); } Console.WriteLine(); @@ -170,11 +162,7 @@ public class FurnitureMoving Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/furniture_moving_intervals.cs b/examples/contrib/furniture_moving_intervals.cs index 0c5dbdc49e..d06d1c2e68 100644 --- a/examples/contrib/furniture_moving_intervals.cs +++ b/examples/contrib/furniture_moving_intervals.cs @@ -16,8 +16,7 @@ using System.Collections; using System.Linq; using Google.OrTools.ConstraintSolver; -public class FurnitureMovingIntervals -{ +public class FurnitureMovingIntervals { /** * * Moving furnitures (scheduling) problem in Google CP Solver. @@ -27,12 +26,11 @@ public class FurnitureMovingIntervals * Also see http://www.hakank.org/or-tools/furniture_moving.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("FurnitureMovingIntervals"); const int n = 4; - int[] durations = {30,10,15,15}; + int[] durations = {30, 10, 15, 15}; int[] demand = {3, 1, 3, 2}; const int upper_limit = 160; const int max_num_workers = 5; @@ -41,40 +39,34 @@ public class FurnitureMovingIntervals // Decision variables // IntervalVar[] tasks = new IntervalVar[n]; - for (int i = 0; i < n; ++i) - { - tasks[i] = solver.MakeFixedDurationIntervalVar(0, - upper_limit - durations[i], - durations[i], - false, - "task_" + i); + for (int i = 0; i < n; ++i) { + tasks[i] = solver.MakeFixedDurationIntervalVar( + 0, upper_limit - durations[i], durations[i], false, "task_" + i); } // Fillers that span the whole resource and limit the available // number of workers. IntervalVar[] fillers = new IntervalVar[max_num_workers]; - for (int i = 0; i < max_num_workers; ++i) - { - fillers[i] = solver.MakeFixedDurationIntervalVar(0, - 0, - upper_limit, - true, + for (int i = 0; i < max_num_workers; ++i) { + fillers[i] = solver.MakeFixedDurationIntervalVar(0, 0, upper_limit, true, "filler_" + i); } // Number of needed resources, to be minimized or constrained. - IntVar num_workers = solver.MakeIntVar(0, max_num_workers, "num_workers"); + IntVar num_workers = solver.MakeIntVar(0, max_num_workers, "num_workers"); // Links fillers and num_workers. - for (int i = 0; i < max_num_workers; ++i) - { - solver.Add((num_workers > i) + fillers[i].PerformedExpr() == 1); + for (int i = 0; i < max_num_workers; ++i) { + solver.Add((num_workers > i) + fillers [i] + .PerformedExpr() == + 1); } // Creates makespan. IntVar[] ends = new IntVar[n]; - for (int i = 0; i < n; ++i) - { - ends[i] = tasks[i].EndExpr().Var(); + for (int i = 0; i < n; ++i) { + ends[i] = tasks [i] + .EndExpr() + .Var(); } IntVar end_time = ends.Max().VarWithName("end_time"); @@ -83,13 +75,11 @@ public class FurnitureMovingIntervals // IntervalVar[] all_tasks = new IntervalVar[n + max_num_workers]; int[] all_demands = new int[n + max_num_workers]; - for (int i = 0; i < n; ++i) - { + for (int i = 0; i < n; ++i) { all_tasks[i] = tasks[i]; all_demands[i] = demand[i]; } - for (int i = 0; i < max_num_workers; ++i) - { + for (int i = 0; i < max_num_workers; ++i) { all_tasks[i + n] = fillers[i]; all_demands[i + n] = 1; } @@ -107,7 +97,6 @@ public class FurnitureMovingIntervals // solver.Add(tasks[i].StartAt(0)); // } - // limitation of the number of people // solver.Add(num_workers <= 3); solver.Add(num_workers <= 4); @@ -128,8 +117,11 @@ public class FurnitureMovingIntervals while (solver.NextSolution()) { Console.WriteLine(num_workers.ToString() + ", " + end_time.ToString()); - for(int i = 0; i < n; i++) { - Console.WriteLine("{0} (demand:{1})", tasks[i].ToString(), demand[i]); + for (int i = 0; i < n; i++) { + Console.WriteLine("{0} (demand:{1})", + tasks [i] + .ToString(), + demand[i]); } Console.WriteLine(); } @@ -140,11 +132,7 @@ public class FurnitureMovingIntervals Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/futoshiki.cs b/examples/contrib/futoshiki.cs index 9a9b90ebc8..7e8a29b7c0 100644 --- a/examples/contrib/futoshiki.cs +++ b/examples/contrib/futoshiki.cs @@ -19,10 +19,7 @@ using System.Collections.Generic; using System.Linq; using Google.OrTools.ConstraintSolver; - -public class Futoshiki -{ - +public class Futoshiki { /** * * Futoshiki problem. @@ -41,9 +38,7 @@ public class Futoshiki * Also see http://www.hakank.org/or-tools/futoshiki.py * */ - private static void Solve(int[,] values, int[,] lt) - { - + private static void Solve(int[, ] values, int[, ] lt) { Solver solver = new Solver("Futoshiki"); int size = values.GetLength(0); @@ -53,61 +48,54 @@ public class Futoshiki // // Decision variables // - IntVar[,] field = solver.MakeIntVarMatrix(size, size, 1, size, "field"); + IntVar[, ] field = solver.MakeIntVarMatrix(size, size, 1, size, "field"); IntVar[] field_flat = field.Flatten(); // // Constraints // - // set initial values - foreach(int row in RANGE) { - foreach(int col in RANGE) { - if (values[row,col] > 0) { - solver.Add(field[row,col] == values[row,col]); + foreach (int row in RANGE) { + foreach (int col in RANGE) { + if (values[row, col] > 0) { + solver.Add(field[row, col] == values[row, col]); } } } - // all rows have to be different - foreach(int row in RANGE) { - solver.Add((from col in RANGE - select field[row,col]).ToArray().AllDifferent()); + foreach (int row in RANGE) { + solver.Add( + (from col in RANGE select field[row, col]).ToArray().AllDifferent()); } - // all columns have to be different - foreach(int col in RANGE) { - solver.Add((from row in RANGE - select field[row,col]).ToArray().AllDifferent()); + foreach (int col in RANGE) { + solver.Add( + (from row in RANGE select field[row, col]).ToArray().AllDifferent()); } - // all < constraints are satisfied // Also: make 0-based - foreach(int i in NUMQD) { - solver.Add(field[ lt[i,0]-1, lt[i,1]-1 ] < - field[ lt[i,2]-1, lt[i,3]-1 ] ); + foreach (int i in NUMQD) { + solver.Add(field[lt[i, 0] - 1, lt[i, 1] - 1] < + field[lt[i, 2] - 1, lt[i, 3] - 1]); } - - - // // Search // - DecisionBuilder db = solver.MakePhase(field_flat, - Solver.CHOOSE_FIRST_UNBOUND, - Solver.ASSIGN_MIN_VALUE); + DecisionBuilder db = solver.MakePhase( + field_flat, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); while (solver.NextSolution()) { - foreach(int i in RANGE) { - foreach(int j in RANGE) { - Console.Write("{0} ", field[i,j].Value()); + foreach (int i in RANGE) { + foreach (int j in RANGE) { + Console.Write("{0} ", field [i, j] + .Value()); } Console.WriteLine(); } @@ -121,13 +109,9 @@ public class Futoshiki Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - public static void Main(String[] args) - { - + public static void Main(String[] args) { // // Example from Tailor model futoshiki.param/futoshiki.param // Solution: @@ -140,29 +124,17 @@ public class Futoshiki // Futoshiki instance, by Andras Salamon // specify the numbers in the grid // - int[,] values1 = { - {0, 0, 3, 2, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}}; - + int[, ] values1 = {{0, 0, 3, 2, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}}; // [i1,j1, i2,j2] requires that values[i1,j1] < values[i2,j2] // Note: 1-based - int [,] lt1 = { - {1,2, 1,1}, - {1,4, 1,5}, - {2,3, 1,3}, - {3,3, 2,3}, - {3,4, 2,4}, - {2,5, 3,5}, - {3,2, 4,2}, - {4,4, 4,3}, - {5,2, 5,1}, - {5,4, 5,3}, - {5,5, 4,5}}; - + int[, ] lt1 = {{1, 2, 1, 1}, {1, 4, 1, 5}, {2, 3, 1, 3}, {3, 3, 2, 3}, + {3, 4, 2, 4}, {2, 5, 3, 5}, {3, 2, 4, 2}, {4, 4, 4, 3}, + {5, 2, 5, 1}, {5, 4, 5, 3}, {5, 5, 4, 5}}; // // Example from http://en.wikipedia.org/wiki/Futoshiki @@ -173,28 +145,20 @@ public class Futoshiki // 3 5 2 1 4 // 1 2 5 4 3 // - int[,] values2 = { - {0, 0, 0, 0, 0}, - {4, 0, 0, 0, 2}, - {0, 0, 4, 0, 0}, - {0, 0, 0, 0, 4}, - {0, 0, 0, 0, 0}}; + int[, ] values2 = {{0, 0, 0, 0, 0}, + {4, 0, 0, 0, 2}, + {0, 0, 4, 0, 0}, + {0, 0, 0, 0, 4}, + {0, 0, 0, 0, 0}}; // Note: 1-based - int[,] lt2 = { - {1,2, 1,1}, - {1,4, 1,3}, - {1,5, 1,4}, - {4,4, 4,5}, - {5,1, 5,2}, - {5,2, 5,3} - }; + int[, ] lt2 = {{1, 2, 1, 1}, {1, 4, 1, 3}, {1, 5, 1, 4}, + {4, 4, 4, 5}, {5, 1, 5, 2}, {5, 2, 5, 3}}; Console.WriteLine("Problem 1"); Solve(values1, lt1); Console.WriteLine("\nProblem 2"); Solve(values2, lt2); - } } diff --git a/examples/contrib/golomb_ruler.cs b/examples/contrib/golomb_ruler.cs index f7cbb9a8a9..0a5f6903de 100644 --- a/examples/contrib/golomb_ruler.cs +++ b/examples/contrib/golomb_ruler.cs @@ -19,10 +19,7 @@ using System.IO; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; - -public class GolombRuler -{ - +public class GolombRuler { /** * * Golomb Ruler problem. @@ -32,35 +29,29 @@ public class GolombRuler * http://code.google.com/p/or-tools/source/browse/trunk/com/google/ortools/constraintsolver/samples/GolombRuler.java * */ - private static void Solve(int m = 8) - { + private static void Solve(int m = 8) { Solver solver = new Solver("GolombRuler"); - // // Decision variables // - IntVar[] ticks = solver.MakeIntVarArray(m, - 0, - ((m < 31) ? (1 << (m + 1)) - 1 : 9999), - "ticks"); + IntVar[] ticks = solver.MakeIntVarArray( + m, 0, ((m < 31) ? (1 << (m + 1)) - 1 : 9999), "ticks"); IntVar[] diff = new IntVar[(m * m - m) / 2]; - // // Constraints // solver.Add(ticks[0] == 0); - for(int i = 0; i < ticks.Length - 1; i++) { - solver.Add(ticks[i] < ticks[i+1]); + for (int i = 0; i < ticks.Length - 1; i++) { + solver.Add(ticks[i] < ticks[i + 1]); } - for (int k = 0, i = 0; i < m - 1; i++) { for (int j = i + 1; j < m; j++, k++) { - diff[k] = (ticks[j]-ticks[i]).Var(); + diff[k] = (ticks[j] - ticks[i]).Var(); solver.Add(diff[k] >= (j - i) * (j - i + 1) / 2); } } @@ -72,36 +63,33 @@ public class GolombRuler solver.Add(diff[0] < diff[diff.Length - 1]); } - // // Optimization // - OptimizeVar opt = ticks[m - 1].Minimize(1); - + OptimizeVar opt = ticks [m - 1] + .Minimize(1); // // Search // - DecisionBuilder db = solver.MakePhase(ticks, - Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, - Solver.ASSIGN_MIN_VALUE); + DecisionBuilder db = solver.MakePhase( + ticks, Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, Solver.ASSIGN_MIN_VALUE); // We just want the debug info for larger instances. if (m >= 11) { - SearchMonitor log = solver.MakeSearchLog(10000, opt); solver.NewSearch(db, opt, log); } else { - solver.NewSearch(db, opt); } - while (solver.NextSolution()) { - Console.Write("opt: {0} [ ", ticks[m-1].Value()); - for(int i = 0; i < m; i++) { - Console.Write("{0} ", ticks[i].Value()); + Console.Write("opt: {0} [ ", ticks [m - 1] + .Value()); + for (int i = 0; i < m; i++) { + Console.Write("{0} ", ticks [i] + .Value()); } Console.WriteLine("]"); } @@ -112,12 +100,9 @@ public class GolombRuler Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - public static void Main(String[] args) - { + public static void Main(String[] args) { int n = 8; if (args.Length > 0) { n = Convert.ToInt32(args[0]); diff --git a/examples/contrib/grocery.cs b/examples/contrib/grocery.cs index 75d6c1dc0a..293100e79b 100644 --- a/examples/contrib/grocery.cs +++ b/examples/contrib/grocery.cs @@ -16,13 +16,10 @@ using System; using Google.OrTools.ConstraintSolver; - -public class Grocery -{ - +public class Grocery { public static void Decreasing(Solver solver, IntVar[] x) { - for(int i = 0; i < x.Length - 1; i++) { - solver.Add(x[i] <= x[i+1]); + for (int i = 0; i < x.Length - 1; i++) { + solver.Add(x[i] <= x[i + 1]); } } @@ -33,14 +30,13 @@ public class Grocery int len = x.Length; IntVar[] tmp = new IntVar[len]; tmp[0] = x[0]; - for(int i = 1; i < len; i++) { - tmp[i] = (tmp[i-1]*x[i]).Var(); + for (int i = 1; i < len; i++) { + tmp[i] = (tmp[i - 1] * x[i]).Var(); } - return tmp[len-1] == prod; + return tmp[len - 1] == prod; } - /** * * Grocery problem. @@ -57,8 +53,7 @@ public class Grocery * """ * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("Grocery"); int n = 4; @@ -76,8 +71,7 @@ public class Grocery solver.Add(item.Sum() == c); // solver.Add(item[0] * item[1] * item[2] * item[3] == c * 100*100*100); // solver.Add(item.Prod() == c * 100*100*100); - solver.Add(MyProd(item, c * 100*100*100)); - + solver.Add(MyProd(item, c * 100 * 100 * 100)); // Symmetry breaking Decreasing(solver, item); @@ -85,14 +79,15 @@ public class Grocery // // Search // - DecisionBuilder db = solver.MakePhase(item, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(item, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); while (solver.NextSolution()) { - for(int i = 0; i < n; i++) { - Console.Write(item[i].Value() + " "); + for (int i = 0; i < n; i++) { + Console.Write(item [i] + .Value() + + " "); } Console.WriteLine(); } @@ -102,11 +97,7 @@ public class Grocery Console.WriteLine("Branches: " + solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/hidato_table.cs b/examples/contrib/hidato_table.cs index 3bb4554c3e..f56267090c 100644 --- a/examples/contrib/hidato_table.cs +++ b/examples/contrib/hidato_table.cs @@ -18,10 +18,7 @@ using System.Collections; using System.Linq; using Google.OrTools.ConstraintSolver; -public class HidatoTable -{ - - +public class HidatoTable { /* * Build closeness pairs for consecutive numbers. * @@ -35,32 +32,27 @@ public class HidatoTable * rows: the number of rows in the grid * cols: the number of columns in the grid */ - public static IntTupleSet BuildPairs(int rows, int cols) - { + public static IntTupleSet BuildPairs(int rows, int cols) { int[] ix = {-1, 0, 1}; - var result_tmp = (from x in Enumerable.Range(0, rows) - from y in Enumerable.Range(0, cols) - from dx in ix - from dy in ix - where - x + dx >= 0 && - x + dx < rows && - y + dy >= 0 && - y + dy < cols && - (dx != 0 || dy != 0) - select new int[] {x * cols + y, (x + dx) * cols + (y + dy)} - ).ToArray(); + var result_tmp = + (from x in Enumerable.Range(0, rows) from y in Enumerable.Range(0, cols) + from dx in ix from dy in ix where x + + dx >= + 0 && + x + dx < rows && y + dy >= 0 && y + dy < cols && + (dx != 0 || dy != 0) + select new int[]{x * cols + y, (x + dx) * cols + (y + dy)}) + .ToArray(); // Convert to len x 2 matrix int len = result_tmp.Length; IntTupleSet result = new IntTupleSet(2); - foreach(int[] r in result_tmp) { + foreach (int[] r in result_tmp) { result.Insert(r); } return result; } - /** * * Hidato puzzle in Google CP Solver. @@ -79,79 +71,65 @@ public class HidatoTable * based on my (much slower) model hidato.py. * */ - private static void Solve(int model = 1) - { + private static void Solve(int model = 1) { Solver solver = new Solver("HidatoTable"); // // models, a 0 indicates an open cell which number is not yet known. // - int[,] puzzle = null; + int[, ] puzzle = null; if (model == 1) { - // Simple problem // Solution 1: // 6 7 9 // 5 2 8 // 1 4 3 - int[,] puzzle1 = {{6, 0, 9}, - {0, 2, 8}, - {1, 0, 0}}; + int[, ] puzzle1 = {{6, 0, 9}, {0, 2, 8}, {1, 0, 0}}; puzzle = puzzle1; } else if (model == 2) { - - int[,] puzzle2 = {{0, 44, 41, 0, 0, 0, 0}, - {0, 43, 0, 28, 29, 0, 0}, - {0, 1, 0, 0, 0, 33, 0}, - {0, 2, 25, 4, 34, 0, 36}, - {49, 16, 0, 23, 0, 0, 0}, - {0, 19, 0, 0, 12, 7, 0}, - {0, 0, 0, 14, 0, 0, 0}}; + int[, ] puzzle2 = {{0, 44, 41, 0, 0, 0, 0}, {0, 43, 0, 28, 29, 0, 0}, + {0, 1, 0, 0, 0, 33, 0}, {0, 2, 25, 4, 34, 0, 36}, + {49, 16, 0, 23, 0, 0, 0}, {0, 19, 0, 0, 12, 7, 0}, + {0, 0, 0, 14, 0, 0, 0}}; puzzle = puzzle2; } else if (model == 3) { // Problems from the book: // Gyora Bededek: "Hidato: 2000 Pure Logic Puzzles" // Problem 1 (Practice) - int[,] puzzle3 = {{0, 0, 20, 0, 0}, - {0, 0, 0, 16, 18}, - {22, 0, 15, 0, 0}, - {23, 0, 1, 14, 11}, - {0, 25, 0, 0, 12}}; + int[, ] puzzle3 = {{0, 0, 20, 0, 0}, + {0, 0, 0, 16, 18}, + {22, 0, 15, 0, 0}, + {23, 0, 1, 14, 11}, + {0, 25, 0, 0, 12}}; puzzle = puzzle3; } else if (model == 4) { // problem 2 (Practice) - int[,] puzzle4 = {{0, 0, 0, 0, 14}, - {0, 18, 12, 0, 0}, - {0, 0, 17, 4, 5}, - {0, 0, 7, 0, 0}, - {9, 8, 25, 1, 0}}; + int[, ] puzzle4 = {{0, 0, 0, 0, 14}, + {0, 18, 12, 0, 0}, + {0, 0, 17, 4, 5}, + {0, 0, 7, 0, 0}, + {9, 8, 25, 1, 0}}; puzzle = puzzle4; } else if (model == 5) { // problem 3 (Beginner) - int[,] puzzle5 = {{0, 26, 0, 0, 0, 18}, - {0, 0, 27, 0, 0, 19}, - {31, 23, 0, 0, 14, 0}, - {0, 33, 8, 0, 15, 1}, - {0, 0, 0, 5, 0, 0}, - {35, 36, 0, 10, 0, 0}}; + int[, ] puzzle5 = {{0, 26, 0, 0, 0, 18}, {0, 0, 27, 0, 0, 19}, + {31, 23, 0, 0, 14, 0}, {0, 33, 8, 0, 15, 1}, + {0, 0, 0, 5, 0, 0}, {35, 36, 0, 10, 0, 0}}; puzzle = puzzle5; } else if (model == 6) { // Problem 15 (Intermediate) - int[,] puzzle6 = {{64, 0, 0, 0, 0, 0, 0, 0}, - {1, 63, 0, 59, 15, 57, 53, 0}, - {0, 4, 0, 14, 0, 0, 0, 0}, - {3, 0, 11, 0, 20, 19, 0, 50}, - {0, 0, 0, 0, 22, 0, 48, 40}, - {9, 0, 0, 32, 23, 0, 0, 41}, - {27, 0, 0, 0, 36, 0, 46, 0}, - {28, 30, 0, 35, 0, 0, 0, 0}}; + int[, ] puzzle6 = { + {64, 0, 0, 0, 0, 0, 0, 0}, {1, 63, 0, 59, 15, 57, 53, 0}, + {0, 4, 0, 14, 0, 0, 0, 0}, {3, 0, 11, 0, 20, 19, 0, 50}, + {0, 0, 0, 0, 22, 0, 48, 40}, {9, 0, 0, 32, 23, 0, 0, 41}, + {27, 0, 0, 0, 36, 0, 46, 0}, {28, 30, 0, 35, 0, 0, 0, 0}}; puzzle = puzzle6; } @@ -167,8 +145,7 @@ public class HidatoTable // // Decision variables // - IntVar[] positions = solver.MakeIntVarArray(r*c, 0, r * c - 1, "p"); - + IntVar[] positions = solver.MakeIntVarArray(r * c, 0, r * c - 1, "p"); // // Constraints @@ -178,10 +155,10 @@ public class HidatoTable // // Fill in the clues // - for(int i = 0; i < r; i++) { - for(int j = 0; j < c; j++) { - if (puzzle[i,j] > 0) { - solver.Add(positions[puzzle[i,j] - 1] == i * c + j); + for (int i = 0; i < r; i++) { + for (int j = 0; j < c; j++) { + if (puzzle[i, j] > 0) { + solver.Add(positions[puzzle[i, j] - 1] == i * c + j); } } } @@ -189,18 +166,16 @@ public class HidatoTable // Consecutive numbers much touch each other in the grid. // We use an allowed assignment constraint to model it. IntTupleSet close_tuples = BuildPairs(r, c); - for(int k = 1; k < r * c - 1; k++) { - IntVar[] tmp = new IntVar[] {positions[k], positions[k + 1]}; + for (int k = 1; k < r * c - 1; k++) { + IntVar[] tmp = new IntVar[]{positions[k], positions[k + 1]}; solver.Add(tmp.AllowedAssignments(close_tuples)); } - // // Search // - DecisionBuilder db = solver.MakePhase(positions, - Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, - Solver.ASSIGN_MIN_VALUE); + DecisionBuilder db = solver.MakePhase( + positions, Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); @@ -216,49 +191,42 @@ public class HidatoTable Console.WriteLine("Branches: " + solver.Branches()); solver.EndSearch(); - } // Print the current solution - public static void PrintOneSolution(IntVar[] positions, - int rows, - int cols, - int num_solution) - { - + public static void PrintOneSolution(IntVar[] positions, int rows, int cols, + int num_solution) { Console.WriteLine("Solution {0}", num_solution); // Create empty board - int[,] board = new int[rows, cols]; - for(int i = 0; i < rows; i++) { - for(int j = 0; j < cols; j++) { - board[i,j] = 0; + int[, ] board = new int[rows, cols]; + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + board[i, j] = 0; } } // Fill board with solution value - for(int k = 0; k < rows*cols; k++) { - int position = (int)positions[k].Value(); + for (int k = 0; k < rows * cols; k++) { + int position = (int) positions [k] + .Value(); board[position / cols, position % cols] = k + 1; } PrintMatrix(board); - } - // Pretty print of the matrix - public static void PrintMatrix(int[,] game) - { + public static void PrintMatrix(int[, ] game) { int rows = game.GetLength(0); int cols = game.GetLength(1); - for(int i = 0; i < rows; i++) { - for(int j = 0; j < cols; j++) { - if (game[i,j] == 0) { + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + if (game[i, j] == 0) { Console.Write(" ."); } else { - Console.Write(" {0,2}", game[i,j] ); + Console.Write(" {0,2}", game[i, j]); } } Console.WriteLine(); @@ -266,22 +234,16 @@ public class HidatoTable Console.WriteLine(); } - - - public static void Main(String[] args) - { + public static void Main(String[] args) { int model = 1; if (args.Length > 0) { - model = Convert.ToInt32(args[0]); Solve(model); } else { - - for(int m = 1; m <= 6; m++) { + for (int m = 1; m <= 6; m++) { Solve(m); } } - } } diff --git a/examples/contrib/just_forgotten.cs b/examples/contrib/just_forgotten.cs index 6281ec5d5b..d761512fdf 100644 --- a/examples/contrib/just_forgotten.cs +++ b/examples/contrib/just_forgotten.cs @@ -20,12 +20,7 @@ using System.Linq; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; - -public class JustForgotten -{ - - - +public class JustForgotten { /** * * Just forgotten puzzle (Enigma 1517) in Google CP Solver. @@ -52,20 +47,17 @@ public class JustForgotten * Also see http://www.hakank.org/google_or_tools/just_forgotten.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("JustForgotten"); - int rows = 4; int cols = 10; // The four tries - int[,] a = {{9,4,6,2,1,5,7,8,3,0}, - {8,6,0,4,3,9,1,2,5,7}, - {1,6,4,0,2,9,7,8,5,3}, - {6,8,2,4,3,1,9,0,7,5}}; - + int[, ] a = {{9, 4, 6, 2, 1, 5, 7, 8, 3, 0}, + {8, 6, 0, 4, 3, 9, 1, 2, 5, 7}, + {1, 6, 4, 0, 2, 9, 7, 8, 5, 3}, + {6, 8, 2, 4, 3, 1, 9, 0, 7, 5}}; // // Decision variables @@ -76,36 +68,38 @@ public class JustForgotten // Constraints // solver.Add(x.AllDifferent()); - for(int r = 0; r < rows; r++) { - solver.Add( (from c in Enumerable.Range(0, cols) - select x[c] == a[r,c]).ToArray().Sum() == 4); + for (int r = 0; r < rows; r++) { + solver.Add((from c in Enumerable.Range(0, cols) select x[c] == a[r, c]) + .ToArray() + .Sum() == 4); } - - // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.INT_VAR_DEFAULT, - Solver.INT_VALUE_DEFAULT); + DecisionBuilder db = + solver.MakePhase(x, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { Console.WriteLine("Account number:"); - for(int j = 0; j < cols; j++) { - Console.Write(x[j].Value() + " "); + for (int j = 0; j < cols; j++) { + Console.Write(x [j] + .Value() + + " "); } Console.WriteLine("\n"); - Console.WriteLine("The four tries, where '!' represents a correct digit:"); - for(int i = 0; i < rows; i++) { - for(int j = 0; j < cols; j++) { + Console.WriteLine( + "The four tries, where '!' represents a correct digit:"); + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { String c = " "; - if (a[i,j] == x[j].Value()) { + if (a[i, j] == x [j] + .Value()) { c = "!"; } - Console.Write("{0}{1} ", a[i,j], c); + Console.Write("{0}{1} ", a[i, j], c); } Console.WriteLine(); } @@ -118,12 +112,7 @@ public class JustForgotten Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/kakuro.cs b/examples/contrib/kakuro.cs index e7a53b672d..5459886fd2 100644 --- a/examples/contrib/kakuro.cs +++ b/examples/contrib/kakuro.cs @@ -19,35 +19,26 @@ using System.Collections.Generic; using System.Linq; using Google.OrTools.ConstraintSolver; - -public class Kakuro -{ - +public class Kakuro { /** * Ensure that the sum of the segments * in cc == res * */ - public static void calc(Solver solver, - int[] cc, - IntVar[,] x, - int res) - { - + public static void calc(Solver solver, int[] cc, IntVar[, ] x, int res) { // ensure that the values are positive int len = cc.Length / 2; - for(int i = 0; i < len; i++) { - solver.Add(x[cc[i*2]-1,cc[i*2+1]-1] >= 1); + for (int i = 0; i < len; i++) { + solver.Add(x[cc[i * 2] - 1, cc[i * 2 + 1] - 1] >= 1); } // sum the numbers - solver.Add( (from i in Enumerable.Range(0, len) - select x[cc[i*2]-1,cc[i*2+1]-1]) - .ToArray().Sum() == res); + solver.Add((from i in Enumerable.Range(0, len) + select x[cc[i * 2] - 1, cc[i * 2 + 1] - 1]) + .ToArray() + .Sum() == res); } - - /** * * Kakuru puzzle. @@ -85,9 +76,7 @@ public class Kakuro * the problem instance. * */ - private static void Solve() - { - + private static void Solve() { Solver solver = new Solver("Kakuro"); // size of matrix @@ -96,58 +85,47 @@ public class Kakuro // segments: // sum, the segments // Note: this is 1-based - int[][] problem = - { - new int[] {16, 1,1, 1,2}, - new int[] {24, 1,5, 1,6, 1,7}, - new int[] {17, 2,1, 2,2}, - new int[] {29, 2,4, 2,5, 2,6, 2,7}, - new int[] {35, 3,1, 3,2, 3,3, 3,4, 3,5}, - new int[] { 7, 4,2, 4,3}, - new int[] { 8, 4,5, 4,6}, - new int[] {16, 5,3, 5,4, 5,5, 5,6, 5,7}, - new int[] {21, 6,1, 6,2, 6,3, 6,4}, - new int[] { 5, 6,6, 6,7}, - new int[] { 6, 7,1, 7,2, 7,3}, - new int[] { 3, 7,6, 7,7}, + int[][] problem = {new int[]{16, 1, 1, 1, 2}, + new int[]{24, 1, 5, 1, 6, 1, 7}, + new int[]{17, 2, 1, 2, 2}, + new int[]{29, 2, 4, 2, 5, 2, 6, 2, 7}, + new int[]{35, 3, 1, 3, 2, 3, 3, 3, 4, 3, 5}, + new int[]{7, 4, 2, 4, 3}, + new int[]{8, 4, 5, 4, 6}, + new int[]{16, 5, 3, 5, 4, 5, 5, 5, 6, 5, 7}, + new int[]{21, 6, 1, 6, 2, 6, 3, 6, 4}, + new int[]{5, 6, 6, 6, 7}, + new int[]{6, 7, 1, 7, 2, 7, 3}, + new int[]{3, 7, 6, 7, 7}, - new int[] {23, 1,1, 2,1, 3,1}, - new int[] {30, 1,2, 2,2, 3,2, 4,2}, - new int[] {27, 1,5, 2,5, 3,5, 4,5, 5,5}, - new int[] {12, 1,6, 2,6}, - new int[] {16, 1,7, 2,7}, - new int[] {17, 2,4, 3,4}, - new int[] {15, 3,3, 4,3, 5,3, 6,3, 7,3}, - new int[] {12, 4,6, 5,6, 6,6, 7,6}, - new int[] { 7, 5,4, 6,4}, - new int[] { 7, 5,7, 6,7, 7,7}, - new int[] {11, 6,1, 7,1}, - new int[] {10, 6,2, 7,2} + new int[]{23, 1, 1, 2, 1, 3, 1}, + new int[]{30, 1, 2, 2, 2, 3, 2, 4, 2}, + new int[]{27, 1, 5, 2, 5, 3, 5, 4, 5, 5, 5}, + new int[]{12, 1, 6, 2, 6}, + new int[]{16, 1, 7, 2, 7}, + new int[]{17, 2, 4, 3, 4}, + new int[]{15, 3, 3, 4, 3, 5, 3, 6, 3, 7, 3}, + new int[]{12, 4, 6, 5, 6, 6, 6, 7, 6}, + new int[]{7, 5, 4, 6, 4}, + new int[]{7, 5, 7, 6, 7, 7, 7}, + new int[]{11, 6, 1, 7, 1}, + new int[]{10, 6, 2, 7, 2} - }; + }; - - int num_p = 24; // Number of segments + int num_p = 24; // Number of segments // The blanks // Note: 1-based - int[,] blanks = { - {1,3}, {1,4}, - {2,3}, - {3,6}, {3,7}, - {4,1}, {4,4}, {4,7}, - {5,1}, {5,2}, - {6,5}, - {7,4}, {7,5} - }; + int[, ] blanks = {{1, 3}, {1, 4}, {2, 3}, {3, 6}, {3, 7}, {4, 1}, {4, 4}, + {4, 7}, {5, 1}, {5, 2}, {6, 5}, {7, 4}, {7, 5}}; int num_blanks = blanks.GetLength(0); - // // Decision variables // - IntVar[,] x = solver.MakeIntVarMatrix(n, n, 0, 9, "x"); + IntVar[, ] x = solver.MakeIntVarMatrix(n, n, 0, 9, "x"); IntVar[] x_flat = x.Flatten(); // @@ -155,17 +133,17 @@ public class Kakuro // // fill the blanks with 0 - for(int i = 0; i < num_blanks; i++) { - solver.Add(x[blanks[i,0]-1,blanks[i,1]-1]==0); + for (int i = 0; i < num_blanks; i++) { + solver.Add(x[blanks[i, 0] - 1, blanks[i, 1] - 1] == 0); } - for(int i = 0; i < num_p; i++) { + for (int i = 0; i < num_p; i++) { int[] segment = problem[i]; // Remove the sum from the segment - int[] s2 = new int[segment.Length-1]; - for(int j = 1; j < segment.Length; j++) { - s2[j-1] = segment[j]; + int[] s2 = new int[segment.Length - 1]; + for (int j = 1; j < segment.Length; j++) { + s2[j - 1] = segment[j]; } // sum this segment @@ -173,24 +151,25 @@ public class Kakuro // all numbers in this segment must be distinct int len = segment.Length / 2; - solver.Add( (from j in Enumerable.Range(0, len) - select x[s2[j * 2] - 1, s2[j * 2 + 1] - 1]) - .ToArray().AllDifferent()); + solver.Add((from j in Enumerable.Range(0, len) + select x[s2[j * 2] - 1, s2[j * 2 + 1] - 1]) + .ToArray() + .AllDifferent()); } // // Search // - DecisionBuilder db = solver.MakePhase(x_flat, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(x_flat, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); while (solver.NextSolution()) { - for(int i = 0; i < n; i++) { - for(int j = 0; j < n; j++) { - int v = (int)x[i,j].Value(); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + int v = (int) x [i, j] + .Value(); if (v > 0) { Console.Write(v + " "); } else { @@ -207,13 +186,7 @@ public class Kakuro Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - public static void Main(String[] args) - { - - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/kenken2.cs b/examples/contrib/kenken2.cs index a322f15a38..d5507ab6ab 100644 --- a/examples/contrib/kenken2.cs +++ b/examples/contrib/kenken2.cs @@ -19,28 +19,19 @@ using System.Collections.Generic; using System.Linq; using Google.OrTools.ConstraintSolver; - -public class KenKen2 -{ - +public class KenKen2 { /** * Ensure that the sum of the segments * in cc == res * */ - public static void calc(Solver solver, - int[] cc, - IntVar[,] x, - int res) - { - + public static void calc(Solver solver, int[] cc, IntVar[, ] x, int res) { int ccLen = cc.Length; if (ccLen == 4) { - // for two operands there's // a lot of possible variants - IntVar a = x[cc[0]-1, cc[1]-1]; - IntVar b = x[cc[2]-1, cc[3]-1]; + IntVar a = x[cc[0] - 1, cc[1] - 1]; + IntVar b = x[cc[2] - 1, cc[3] - 1]; IntVar r1 = a + b == res; IntVar r2 = a * b == res; @@ -49,17 +40,17 @@ public class KenKen2 IntVar r5 = a - b == res; IntVar r6 = b - a == res; - solver.Add(r1+r2+r3+r4+r5+r6 >= 1); + solver.Add(r1 + r2 + r3 + r4 + r5 + r6 >= 1); } else { - // For length > 2 then res is either the sum // the the product of the segment // sum the numbers int len = cc.Length / 2; IntVar[] xx = (from i in Enumerable.Range(0, len) - select x[cc[i*2]-1,cc[i*2+1]-1]).ToArray(); + select x[cc[i * 2] - 1, cc[i * 2 + 1] - 1]) + .ToArray(); // Sum IntVar this_sum = xx.Sum() == res; @@ -68,25 +59,17 @@ public class KenKen2 // IntVar this_prod = (xx.Prod() == res).Var(); // don't work IntVar this_prod; if (xx.Length == 3) { - this_prod = (x[cc[0]-1,cc[1]-1] * - x[cc[2]-1,cc[3]-1] * - x[cc[4]-1,cc[5]-1]) == res; + this_prod = (x[cc[0] - 1, cc[1] - 1] * x[cc[2] - 1, cc[3] - 1] * + x[cc[4] - 1, cc[5] - 1]) == res; } else { - this_prod = (x[cc[0]-1,cc[1]-1] * - x[cc[2]-1,cc[3]-1] * - x[cc[4]-1,cc[5]-1] * - x[cc[6]-1,cc[7]-1]) == res; - + this_prod = (x[cc[0] - 1, cc[1] - 1] * x[cc[2] - 1, cc[3] - 1] * + x[cc[4] - 1, cc[5] - 1] * x[cc[6] - 1, cc[7] - 1]) == res; } solver.Add(this_sum + this_prod >= 1); - - } } - - /** * * KenKen puzzle. @@ -130,9 +113,7 @@ public class KenKen2 * the problem instance. * */ - private static void Solve() - { - + private static void Solve() { Solver solver = new Solver("KenKen2"); // size of matrix @@ -145,32 +126,28 @@ public class KenKen2 // hints // sum, the hints // Note: this is 1-based - int[][] problem = - { - new int[] { 11, 1,1, 2,1}, - new int[] { 2, 1,2, 1,3}, - new int[] { 20, 1,4, 2,4}, - new int[] { 6, 1,5, 1,6, 2,6, 3,6}, - new int[] { 3, 2,2, 2,3}, - new int[] { 3, 2,5, 3,5}, - new int[] {240, 3,1, 3,2, 4,1, 4,2}, - new int[] { 6, 3,3, 3,4}, - new int[] { 6, 4,3, 5,3}, - new int[] { 7, 4,4, 5,4, 5,5}, - new int[] { 30, 4,5, 4,6}, - new int[] { 6, 5,1, 5,2}, - new int[] { 9, 5,6, 6,6}, - new int[] { 8, 6,1, 6,2, 6,3}, - new int[] { 2, 6,4, 6,5} - }; + int[][] problem = {new int[]{11, 1, 1, 2, 1}, + new int[]{2, 1, 2, 1, 3}, + new int[]{20, 1, 4, 2, 4}, + new int[]{6, 1, 5, 1, 6, 2, 6, 3, 6}, + new int[]{3, 2, 2, 2, 3}, + new int[]{3, 2, 5, 3, 5}, + new int[]{240, 3, 1, 3, 2, 4, 1, 4, 2}, + new int[]{6, 3, 3, 3, 4}, + new int[]{6, 4, 3, 5, 3}, + new int[]{7, 4, 4, 5, 4, 5, 5}, + new int[]{30, 4, 5, 4, 6}, + new int[]{6, 5, 1, 5, 2}, + new int[]{9, 5, 6, 6, 6}, + new int[]{8, 6, 1, 6, 2, 6, 3}, + new int[]{2, 6, 4, 6, 5}}; - - int num_p = problem.GetLength(0); // Number of segments + int num_p = problem.GetLength(0); // Number of segments // // Decision variables // - IntVar[,] x = solver.MakeIntVarMatrix(n, n, 1, n, "x"); + IntVar[, ] x = solver.MakeIntVarMatrix(n, n, 1, n, "x"); IntVar[] x_flat = x.Flatten(); // @@ -179,44 +156,41 @@ public class KenKen2 // // alldifferent rows and columns - foreach(int i in RANGE) { + foreach (int i in RANGE) { // rows - solver.Add( (from j in RANGE select x[i,j]).ToArray().AllDifferent()); + solver.Add((from j in RANGE select x[i, j]).ToArray().AllDifferent()); // cols - solver.Add( (from j in RANGE select x[j,i]).ToArray().AllDifferent()); - + solver.Add((from j in RANGE select x[j, i]).ToArray().AllDifferent()); } - // Calculate the segments - for(int i = 0; i < num_p; i++) { - + for (int i = 0; i < num_p; i++) { int[] segment = problem[i]; // Remove the sum from the segment - int len = segment.Length-1; + int len = segment.Length - 1; int[] s2 = new int[len]; Array.Copy(segment, 1, s2, 0, len); // sum this segment calc(solver, s2, x, segment[0]); - } // // Search // - DecisionBuilder db = solver.MakePhase(x_flat, - Solver.INT_VAR_DEFAULT, + DecisionBuilder db = solver.MakePhase(x_flat, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { - for(int i = 0; i < n; i++) { - for(int j = 0; j < n; j++) { - Console.Write(x[i,j].Value() + " "); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + Console.Write(x [i, j] + .Value() + + " "); } Console.WriteLine(); } @@ -229,13 +203,7 @@ public class KenKen2 Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - public static void Main(String[] args) - { - - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/killer_sudoku.cs b/examples/contrib/killer_sudoku.cs index 390ec05146..6feb8edb11 100644 --- a/examples/contrib/killer_sudoku.cs +++ b/examples/contrib/killer_sudoku.cs @@ -19,29 +19,21 @@ using System.Collections.Generic; using System.Linq; using Google.OrTools.ConstraintSolver; - -public class KillerSudoku -{ - +public class KillerSudoku { /** * Ensure that the sum of the segments * in cc == res * */ - public static void calc(Solver solver, - int[] cc, - IntVar[,] x, - int res) - { - + public static void calc(Solver solver, int[] cc, IntVar[, ] x, int res) { // sum the numbers int len = cc.Length / 2; - solver.Add( (from i in Enumerable.Range(0, len) - select x[cc[i*2]-1,cc[i*2+1]-1]).ToArray().Sum() == res); + solver.Add((from i in Enumerable.Range(0, len) + select x[cc[i * 2] - 1, cc[i * 2 + 1] - 1]) + .ToArray() + .Sum() == res); } - - /** * * Killer Sudoku. @@ -89,15 +81,13 @@ public class KillerSudoku * the problem instance. * */ - private static void Solve() - { - + private static void Solve() { Solver solver = new Solver("KillerSudoku"); // size of matrix int cell_size = 3; IEnumerable CELL = Enumerable.Range(0, cell_size); - int n = cell_size*cell_size; + int n = cell_size * cell_size; IEnumerable RANGE = Enumerable.Range(0, n); // For a better view of the problem, see @@ -106,47 +96,44 @@ public class KillerSudoku // hints // sum, the hints // Note: this is 1-based - int[][] problem = - { - new int[] { 3, 1,1, 1,2}, - new int[] {15, 1,3, 1,4, 1,5}, - new int[] {22, 1,6, 2,5, 2,6, 3,5}, - new int[] {4, 1,7, 2,7}, - new int[] {16, 1,8, 2,8}, - new int[] {15, 1,9, 2,9, 3,9, 4,9}, - new int[] {25, 2,1, 2,2, 3,1, 3,2}, - new int[] {17, 2,3, 2,4}, - new int[] { 9, 3,3, 3,4, 4,4}, - new int[] { 8, 3,6, 4,6, 5,6}, - new int[] {20, 3,7, 3,8, 4,7}, - new int[] { 6, 4,1, 5,1}, - new int[] {14, 4,2, 4,3}, - new int[] {17, 4,5, 5,5, 6,5}, - new int[] {17, 4,8, 5,7, 5,8}, - new int[] {13, 5,2, 5,3, 6,2}, - new int[] {20, 5,4, 6,4, 7,4}, - new int[] {12, 5,9, 6,9}, - new int[] {27, 6,1, 7,1, 8,1, 9,1}, - new int[] { 6, 6,3, 7,2, 7,3}, - new int[] {20, 6,6, 7,6, 7,7}, - new int[] { 6, 6,7, 6,8}, - new int[] {10, 7,5, 8,4, 8,5, 9,4}, - new int[] {14, 7,8, 7,9, 8,8, 8,9}, - new int[] { 8, 8,2, 9,2}, - new int[] {16, 8,3, 9,3}, - new int[] {15, 8,6, 8,7}, - new int[] {13, 9,5, 9,6, 9,7}, - new int[] {17, 9,8, 9,9} + int[][] problem = {new int[]{3, 1, 1, 1, 2}, + new int[]{15, 1, 3, 1, 4, 1, 5}, + new int[]{22, 1, 6, 2, 5, 2, 6, 3, 5}, + new int[]{4, 1, 7, 2, 7}, + new int[]{16, 1, 8, 2, 8}, + new int[]{15, 1, 9, 2, 9, 3, 9, 4, 9}, + new int[]{25, 2, 1, 2, 2, 3, 1, 3, 2}, + new int[]{17, 2, 3, 2, 4}, + new int[]{9, 3, 3, 3, 4, 4, 4}, + new int[]{8, 3, 6, 4, 6, 5, 6}, + new int[]{20, 3, 7, 3, 8, 4, 7}, + new int[]{6, 4, 1, 5, 1}, + new int[]{14, 4, 2, 4, 3}, + new int[]{17, 4, 5, 5, 5, 6, 5}, + new int[]{17, 4, 8, 5, 7, 5, 8}, + new int[]{13, 5, 2, 5, 3, 6, 2}, + new int[]{20, 5, 4, 6, 4, 7, 4}, + new int[]{12, 5, 9, 6, 9}, + new int[]{27, 6, 1, 7, 1, 8, 1, 9, 1}, + new int[]{6, 6, 3, 7, 2, 7, 3}, + new int[]{20, 6, 6, 7, 6, 7, 7}, + new int[]{6, 6, 7, 6, 8}, + new int[]{10, 7, 5, 8, 4, 8, 5, 9, 4}, + new int[]{14, 7, 8, 7, 9, 8, 8, 8, 9}, + new int[]{8, 8, 2, 9, 2}, + new int[]{16, 8, 3, 9, 3}, + new int[]{15, 8, 6, 8, 7}, + new int[]{13, 9, 5, 9, 6, 9, 7}, + new int[]{17, 9, 8, 9, 9} - }; + }; - - int num_p = 29; // Number of segments + int num_p = 29; // Number of segments // // Decision variables // - IntVar[,] x = solver.MakeIntVarMatrix(n, n, 0, 9, "x"); + IntVar[, ] x = solver.MakeIntVarMatrix(n, n, 0, 9, "x"); IntVar[] x_flat = x.Flatten(); // @@ -157,36 +144,32 @@ public class KillerSudoku // The first three constraints is the same as for sudokus.cs // // alldifferent rows and columns - foreach(int i in RANGE) { + foreach (int i in RANGE) { // rows - solver.Add( (from j in RANGE - select x[i,j]).ToArray().AllDifferent()); + solver.Add((from j in RANGE select x[i, j]).ToArray().AllDifferent()); // cols - solver.Add( (from j in RANGE - select x[j,i]).ToArray().AllDifferent()); - + solver.Add((from j in RANGE select x[j, i]).ToArray().AllDifferent()); } // cells - foreach(int i in CELL) { - foreach(int j in CELL) { - solver.Add( (from di in CELL - from dj in CELL - select x[i*cell_size+di, j*cell_size+dj] - ).ToArray().AllDifferent()); + foreach (int i in CELL) { + foreach (int j in CELL) { + solver.Add((from di in CELL from dj in CELL select + x[i * cell_size + di, j * cell_size + dj]) + .ToArray() + .AllDifferent()); } } - // Sum the segments and ensure alldifferent - for(int i = 0; i < num_p; i++) { + for (int i = 0; i < num_p; i++) { int[] segment = problem[i]; // Remove the sum from the segment - int[] s2 = new int[segment.Length-1]; - for(int j = 1; j < segment.Length; j++) { - s2[j-1] = segment[j]; + int[] s2 = new int[segment.Length - 1]; + for (int j = 1; j < segment.Length; j++) { + s2[j - 1] = segment[j]; } // sum this segment @@ -194,24 +177,25 @@ public class KillerSudoku // all numbers in this segment must be distinct int len = segment.Length / 2; - solver.Add( (from j in Enumerable.Range(0, len) - select x[s2[j*2]-1, s2[j*2+1]-1]) - .ToArray().AllDifferent()); + solver.Add((from j in Enumerable.Range(0, len) + select x[s2[j * 2] - 1, s2[j * 2 + 1] - 1]) + .ToArray() + .AllDifferent()); } // // Search // - DecisionBuilder db = solver.MakePhase(x_flat, - Solver.INT_VAR_DEFAULT, + DecisionBuilder db = solver.MakePhase(x_flat, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { - for(int i = 0; i < n; i++) { - for(int j = 0; j < n; j++) { - int v = (int)x[i,j].Value(); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + int v = (int) x [i, j] + .Value(); if (v > 0) { Console.Write(v + " "); } else { @@ -228,13 +212,7 @@ public class KillerSudoku Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - public static void Main(String[] args) - { - - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/labeled_dice.cs b/examples/contrib/labeled_dice.cs index 5b273cfc2d..a900a82b8d 100644 --- a/examples/contrib/labeled_dice.cs +++ b/examples/contrib/labeled_dice.cs @@ -19,10 +19,7 @@ using System.Collections.Generic; using System.Linq; using Google.OrTools.ConstraintSolver; - -public class LabeledDice -{ - +public class LabeledDice { /** * * Labeled dice problem. @@ -49,9 +46,7 @@ public class LabeledDice * Also see http://www.hakank.org/or-tools/labeled_dice.py * */ - private static void Solve() - { - + private static void Solve() { Solver solver = new Solver("LabeledDice"); // @@ -85,45 +80,31 @@ public class LabeledDice int W = 22; int Y = 23; - - String[] letters_str = {"A","B","C","D","E","F","G","H","I","J","K","L","M", - "N","O","P","Q","R","S","T","U","V","W","Y"}; + String[] letters_str = {"A", "B", "C", "D", "E", "F", "G", "H", + "I", "J", "K", "L", "M", "N", "O", "P", + "Q", "R", "S", "T", "U", "V", "W", "Y"}; int num_words = 13; - int[,] words = - { - {B,U,O,Y}, - {C,A,V,E}, - {C,E,L,T}, - {F,L,U,B}, - {F,O,R,K}, - {H,E,M,P}, - {J,U,D,Y}, - {J,U,N,K}, - {L,I,M,N}, - {Q,U,I,P}, - {S,W,A,G}, - {V,I,S,A}, - {W,I,S,H} - }; - + int[, ] words = {{B, U, O, Y}, {C, A, V, E}, {C, E, L, T}, {F, L, U, B}, + {F, O, R, K}, {H, E, M, P}, {J, U, D, Y}, {J, U, N, K}, + {L, I, M, N}, {Q, U, I, P}, {S, W, A, G}, {V, I, S, A}, + {W, I, S, H}}; // // Decision variables // - IntVar[] dice = solver.MakeIntVarArray(m, 0, n-1, "dice"); - IntVar[] gcc = solver.MakeIntVarArray(n, 6, 6, "gcc"); + IntVar[] dice = solver.MakeIntVarArray(m, 0, n - 1, "dice"); + IntVar[] gcc = solver.MakeIntVarArray(n, 6, 6, "gcc"); // // Constraints // - // the letters in a word must be on a different die - for(int i = 0; i < num_words; i++) { - solver.Add( (from j in Enumerable.Range(0, n) - select dice[words[i,j]] - ).ToArray().AllDifferent()); + for (int i = 0; i < num_words; i++) { + solver.Add((from j in Enumerable.Range(0, n) select dice[words[i, j]]) + .ToArray() + .AllDifferent()); } // there must be exactly 6 letters of each die @@ -140,17 +121,17 @@ public class LabeledDice // // Search // - DecisionBuilder db = solver.MakePhase(dice, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(dice, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); while (solver.NextSolution()) { - for(int d = 0; d < n; d++) { + for (int d = 0; d < n; d++) { Console.Write("die {0}: ", d); - for(int i = 0; i < m; i++) { - if (dice[i].Value() == d) { + for (int i = 0; i < m; i++) { + if (dice [i] + .Value() == d) { Console.Write(letters_str[i]); } } @@ -158,9 +139,10 @@ public class LabeledDice } Console.WriteLine("The words with the cube label:"); - for(int i = 0; i < num_words; i++) { - for(int j = 0; j < n; j++) { - Console.Write("{0} ({1})", letters_str[words[i,j]], dice[words[i,j]].Value()); + for (int i = 0; i < num_words; i++) { + for (int j = 0; j < n; j++) { + Console.Write("{0} ({1})", letters_str[words[i, j]], + dice[words[i, j]].Value()); } Console.WriteLine(); } @@ -173,12 +155,7 @@ public class LabeledDice Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/langford.cs b/examples/contrib/langford.cs index d29d56e3be..cf8c10bfa0 100644 --- a/examples/contrib/langford.cs +++ b/examples/contrib/langford.cs @@ -19,18 +19,14 @@ using System.IO; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; -public class Langford -{ - +public class Langford { /** * * Langford number problem. * See http://www.hakank.org/or-tools/langford.py * */ - private static void Solve(int k = 8, int num_sol = 0) - { - + private static void Solve(int k = 8, int num_sol = 0) { Solver solver = new Solver("Langford"); Console.WriteLine("k: {0}", k); @@ -38,12 +34,12 @@ public class Langford // // data // - int p = 2*k; + int p = 2 * k; // // Decision variables // - IntVar[] position = solver.MakeIntVarArray(p, 0, p-1, "position"); + IntVar[] position = solver.MakeIntVarArray(p, 0, p - 1, "position"); IntVar[] solution = solver.MakeIntVarArray(p, 1, k, "solution"); // @@ -51,30 +47,32 @@ public class Langford // solver.Add(position.AllDifferent()); - for(int i = 1; i <= k; i++) { - solver.Add(position[i+k-1] - (position[i-1] + solver.MakeIntVar(i+1,i+1)) == 0); - solver.Add(solution.Element(position[i-1]) == i); - solver.Add(solution.Element(position[k+i-1]) == i); + for (int i = 1; i <= k; i++) { + solver.Add(position[i + k - 1] - + (position[i - 1] + solver.MakeIntVar(i + 1, i + 1)) == + 0); + solver.Add(solution.Element(position[i - 1]) == i); + solver.Add(solution.Element(position[k + i - 1]) == i); } // Symmetry breaking - solver.Add(solution[0] < solution[2*k-1]); + solver.Add(solution[0] < solution[2 * k - 1]); // // Search // - DecisionBuilder db = solver.MakePhase(position, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(position, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); - solver.NewSearch(db); int num_solutions = 0; while (solver.NextSolution()) { Console.Write("solution : "); - for(int i = 0; i < p; i++) { - Console.Write(solution[i].Value() + " "); + for (int i = 0; i < p; i++) { + Console.Write(solution [i] + .Value() + + " "); } Console.WriteLine(); num_solutions++; @@ -89,15 +87,11 @@ public class Langford Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - - public static void Main(String[] args) - { + public static void Main(String[] args) { int k = 8; - int num_sol = 0; // 0: print all solutions + int num_sol = 0; // 0: print all solutions if (args.Length > 0) { k = Convert.ToInt32(args[0]); @@ -108,6 +102,5 @@ public class Langford } Solve(k, num_sol); - } } diff --git a/examples/contrib/least_diff.cs b/examples/contrib/least_diff.cs index f525265e8c..571a172b75 100644 --- a/examples/contrib/least_diff.cs +++ b/examples/contrib/least_diff.cs @@ -16,16 +16,14 @@ using System; using Google.OrTools.ConstraintSolver; -public class LeastDiff -{ +public class LeastDiff { /** * * Solve the Least diff problem * For more info, see http://www.hakank.org/google_or_tools/least_diff.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("LeastDiff"); // @@ -42,13 +40,12 @@ public class LeastDiff IntVar I = solver.MakeIntVar(0, 9, "I"); IntVar J = solver.MakeIntVar(0, 9, "J"); - IntVar[] all = new IntVar[] {A,B,C,D,E,F,G,H,I,J}; - int[] coeffs = {10000,1000,100,10,1}; - IntVar x = new IntVar[]{A,B,C,D,E}.ScalProd(coeffs).Var(); - IntVar y = new IntVar[]{F,G,H,I,J}.ScalProd(coeffs).Var(); + IntVar[] all = new IntVar[]{A, B, C, D, E, F, G, H, I, J}; + int[] coeffs = {10000, 1000, 100, 10, 1}; + IntVar x = new IntVar[]{A, B, C, D, E}.ScalProd(coeffs).Var(); + IntVar y = new IntVar[]{F, G, H, I, J}.ScalProd(coeffs).Var(); IntVar diff = (x - y).VarWithName("diff"); - // // Constraints // @@ -57,7 +54,6 @@ public class LeastDiff solver.Add(F > 0); solver.Add(diff > 0); - // // Objective // @@ -66,13 +62,13 @@ public class LeastDiff // // Search // - DecisionBuilder db = solver.MakePhase(all, - Solver.CHOOSE_PATH, - Solver.ASSIGN_MIN_VALUE); + DecisionBuilder db = + solver.MakePhase(all, Solver.CHOOSE_PATH, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db, obj); while (solver.NextSolution()) { - Console.WriteLine("{0} - {1} = {2} ({3}",x.Value(), y.Value(), diff.Value(), diff.ToString()); + Console.WriteLine("{0} - {1} = {2} ({3}", x.Value(), y.Value(), + diff.Value(), diff.ToString()); } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); @@ -81,11 +77,7 @@ public class LeastDiff Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/lectures.cs b/examples/contrib/lectures.cs index 1427233fd6..95c9e57fc6 100644 --- a/examples/contrib/lectures.cs +++ b/examples/contrib/lectures.cs @@ -18,9 +18,7 @@ using System.Collections; using System.Linq; using Google.OrTools.ConstraintSolver; -public class Lectures -{ - +public class Lectures { /** * * Lectures problem in Google CP Solver. @@ -45,27 +43,17 @@ public class Lectures * Note: This can be seen as a coloring problem. * * Also see http://www.hakank.org/or-tools/lectures.py - * + * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("Lectures"); // // The schedule requirements: // lecture a cannot be held at the same time as b // Note: 1-based (compensated in the constraints). - int[,] g = - { - {1, 2}, - {1, 4}, - {3, 5}, - {2, 6}, - {4, 5}, - {5, 6}, - {1, 6} - }; - + int[, ] g = {{1, 2}, {1, 4}, {3, 5}, {2, 6}, {4, 5}, {5, 6}, {1, 6}}; + // number of nodes int n = 6; @@ -78,22 +66,21 @@ public class Lectures // // declare variables // - IntVar[] v = solver.MakeIntVarArray(n, 0, n-1,"v"); + IntVar[] v = solver.MakeIntVarArray(n, 0, n - 1, "v"); // Maximum color (hour) to minimize. // Note: since C# is 0-based, the // number of colors is max_c+1. IntVar max_c = v.Max().VarWithName("max_c"); - // // Constraints // // Ensure that there are no clashes // also, adjust to 0-base. - for(int i = 0; i < edges; i++) { - solver.Add(v[g[i,0]-1] != v[g[i,1]-1]); + for (int i = 0; i < edges; i++) { + solver.Add(v[g[i, 0] - 1] != v[g[i, 1] - 1]); } // Symmetry breaking: @@ -102,7 +89,6 @@ public class Lectures solver.Add(v[0] == 0); solver.Add(v[1] <= 1); - // // Objective // @@ -111,19 +97,21 @@ public class Lectures // // Search // - DecisionBuilder db = solver.MakePhase(v, - Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, + DecisionBuilder db = solver.MakePhase(v, Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db, obj); while (solver.NextSolution()) { - Console.WriteLine("\nmax hours: {0}", max_c.Value()+1); - Console.WriteLine("v: " + - String.Join(" ", (from i in Enumerable.Range(0, n) - select v[i].Value()).ToArray())); - for(int i = 0; i < n; i++) { - Console.WriteLine("Lecture {0} at {1}h", i, v[i].Value()); + Console.WriteLine("\nmax hours: {0}", max_c.Value() + 1); + Console.WriteLine("v: " + String.Join(" ", (from i in Enumerable + .Range(0, n) select v [i] + .Value()) + .ToArray())); + for (int i = 0; i < n; i++) { + Console.WriteLine("Lecture {0} at {1}h", i, + v [i] + .Value()); } Console.WriteLine("\n"); } @@ -134,49 +122,42 @@ public class Lectures Console.WriteLine("Branches: " + solver.Branches()); solver.EndSearch(); - } // Print the current solution - public static void PrintOneSolution(IntVar[] positions, - int rows, - int cols, - int num_solution) - { - + public static void PrintOneSolution(IntVar[] positions, int rows, int cols, + int num_solution) { Console.WriteLine("Solution {0}", num_solution); // Create empty board - int[,] board = new int[rows, cols]; - for(int i = 0; i < rows; i++) { - for(int j = 0; j < cols; j++) { - board[i,j] = 0; + int[, ] board = new int[rows, cols]; + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + board[i, j] = 0; } - } - + } + // Fill board with solution value - for(int k = 0; k < rows*cols; k++) { - int position = (int)positions[k].Value(); + for (int k = 0; k < rows * cols; k++) { + int position = (int) positions [k] + .Value(); board[position / cols, position % cols] = k + 1; } PrintMatrix(board); - } - // Pretty print of the matrix - public static void PrintMatrix(int[,] game) - { + public static void PrintMatrix(int[, ] game) { int rows = game.GetLength(0); int cols = game.GetLength(1); - for(int i = 0; i < rows; i++) { - for(int j = 0; j < cols; j++) { - if (game[i,j] == 0) { + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + if (game[i, j] == 0) { Console.Write(" ."); } else { - Console.Write(" {0,2}", game[i,j] ); + Console.Write(" {0,2}", game[i, j]); } } Console.WriteLine(); @@ -184,10 +165,5 @@ public class Lectures Console.WriteLine(); } - - - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/magic_sequence.cs b/examples/contrib/magic_sequence.cs index 609fcca2d3..08d204d3a0 100644 --- a/examples/contrib/magic_sequence.cs +++ b/examples/contrib/magic_sequence.cs @@ -20,9 +20,7 @@ using System.IO; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; -public class MagicSequence -{ - +public class MagicSequence { /** * * Magic sequence problem. @@ -37,9 +35,7 @@ public class MagicSequence * """ * */ - private static void Solve(int size) - { - + private static void Solve(int size) { Solver solver = new Solver("MagicSequence"); Console.WriteLine("\nSize: {0}", size); @@ -55,7 +51,7 @@ public class MagicSequence // // Decision variables // - IntVar[] all_vars = solver.MakeIntVarArray(size, 0, size - 1, "vars"); + IntVar[] all_vars = solver.MakeIntVarArray(size, 0, size - 1, "vars"); // // Constraints @@ -63,19 +59,19 @@ public class MagicSequence solver.Add(all_vars.Distribute(all_values, all_vars)); solver.Add(all_vars.Sum() == size); - // // Search // - DecisionBuilder db = solver.MakePhase(all_vars, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(all_vars, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); while (solver.NextSolution()) { - for(int i = 0; i < size; i++) { - Console.Write(all_vars[i].Value() + " "); + for (int i = 0; i < size; i++) { + Console.Write(all_vars [i] + .Value() + + " "); } Console.WriteLine(); } @@ -86,27 +82,18 @@ public class MagicSequence Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - - public static void Main(String[] args) - { - + public static void Main(String[] args) { if (args.Length > 0) { - int size = Convert.ToInt32(args[0]); Solve(size); } else { // Let's test some diferent sizes - foreach(int i in new int[] {2, 10, 100, 200, 500}) { + foreach (int i in new int[]{2, 10, 100, 200, 500}) { Solve(i); } - } - - } } diff --git a/examples/contrib/magic_square.cs b/examples/contrib/magic_square.cs index 99e679e3f4..9b67c4bd71 100644 --- a/examples/contrib/magic_square.cs +++ b/examples/contrib/magic_square.cs @@ -16,17 +16,14 @@ using System; using Google.OrTools.ConstraintSolver; -public class MagicSquare -{ - +public class MagicSquare { /** * * Solves the Magic Square problem. * See http://www.hakank.org/or-tools/magic_square.py * */ - private static void Solve(int n = 4, int num = 0, int print = 1) - { + private static void Solve(int n = 4, int num = 0, int print = 1) { Solver solver = new Solver("MagicSquare"); Console.WriteLine("n: {0}", n); @@ -34,11 +31,10 @@ public class MagicSquare // // Decision variables // - IntVar[,] x = solver.MakeIntVarMatrix(n, n, 1, n*n, "x"); + IntVar[, ] x = solver.MakeIntVarMatrix(n, n, 1, n * n, "x"); // for the branching IntVar[] x_flat = x.Flatten(); - // // Constraints // @@ -47,16 +43,16 @@ public class MagicSquare IntVar[] diag1 = new IntVar[n]; IntVar[] diag2 = new IntVar[n]; - for(int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { IntVar[] row = new IntVar[n]; - for(int j = 0; j < n; j++) { - row[j] = x[i,j]; + for (int j = 0; j < n; j++) { + row[j] = x[i, j]; } // sum row to s solver.Add(row.Sum() == s); - diag1[i] = x[i,i]; - diag2[i] = x[i,n - i - 1]; + diag1[i] = x[i, i]; + diag2[i] = x[i, n - i - 1]; } // sum diagonals to s @@ -64,10 +60,10 @@ public class MagicSquare solver.Add(diag2.Sum() == s); // sum columns to s - for(int j = 0; j < n; j++) { + for (int j = 0; j < n; j++) { IntVar[] col = new IntVar[n]; - for(int i = 0; i < n; i++) { - col[i] = x[i,j]; + for (int i = 0; i < n; i++) { + col[i] = x[i, j]; } solver.Add(col.Sum() == s); } @@ -78,24 +74,23 @@ public class MagicSquare // symmetry breaking: upper left is 1 // solver.Add(x[0,0] == 1); - // // Search // - DecisionBuilder db = solver.MakePhase(x_flat, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(x_flat, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_CENTER_VALUE); - solver.NewSearch(db); int c = 0; while (solver.NextSolution()) { if (print != 0) { - for(int i = 0; i < n; i++) { - for(int j = 0; j < n; j++) { - Console.Write(x[i,j].Value() + " "); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + Console.Write(x [i, j] + .Value() + + " "); } Console.WriteLine(); } @@ -114,11 +109,9 @@ public class MagicSquare Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { + public static void Main(String[] args) { int n = 4; int num = 0; int print = 1; diff --git a/examples/contrib/magic_square_and_cards.cs b/examples/contrib/magic_square_and_cards.cs index a76039f2d3..f291b7e96c 100644 --- a/examples/contrib/magic_square_and_cards.cs +++ b/examples/contrib/magic_square_and_cards.cs @@ -19,10 +19,7 @@ using System.Collections.Generic; using System.Linq; using Google.OrTools.ConstraintSolver; - -public class MagicSquareAndCards -{ - +public class MagicSquareAndCards { /** * * Magic squares and cards problem. @@ -37,21 +34,18 @@ public class MagicSquareAndCards * Also see http://www.hakank.org/or-tools/magic_square_and_cards.py * */ - private static void Solve(int n=3) - { - + private static void Solve(int n = 3) { Solver solver = new Solver("MagicSquareAndCards"); IEnumerable RANGE = Enumerable.Range(0, n); - // // Decision variables // - IntVar[,] x = solver.MakeIntVarMatrix(n, n, 1, 13, "x"); + IntVar[, ] x = solver.MakeIntVarMatrix(n, n, 1, 13, "x"); IntVar[] x_flat = x.Flatten(); - IntVar s = solver.MakeIntVar(1, 13*4, "s"); + IntVar s = solver.MakeIntVar(1, 13 * 4, "s"); IntVar[] counts = solver.MakeIntVarArray(14, 0, 4, "counts"); // @@ -61,22 +55,20 @@ public class MagicSquareAndCards solver.Add(x_flat.Distribute(counts)); // the standard magic square constraints (sans all_different) - foreach(int i in RANGE) { + foreach (int i in RANGE) { // rows - solver.Add( (from j in RANGE select x[i,j]).ToArray().Sum() == s); + solver.Add((from j in RANGE select x[i, j]).ToArray().Sum() == s); // columns - solver.Add( (from j in RANGE select x[j,i]).ToArray().Sum() == s); + solver.Add((from j in RANGE select x[j, i]).ToArray().Sum() == s); } // diagonals - solver.Add( (from i in RANGE select x[i,i]).ToArray().Sum() == s); - solver.Add( (from i in RANGE select x[i,n-i-1]).ToArray().Sum() == s); - + solver.Add((from i in RANGE select x[i, i]).ToArray().Sum() == s); + solver.Add((from i in RANGE select x[i, n - i - 1]).ToArray().Sum() == s); // redundant constraint - solver.Add(counts.Sum() == n*n); - + solver.Add(counts.Sum() == n * n); // // Objective @@ -86,8 +78,7 @@ public class MagicSquareAndCards // // Search // - DecisionBuilder db = solver.MakePhase(x_flat, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(x_flat, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MAX_VALUE); solver.NewSearch(db, obj); @@ -95,13 +86,17 @@ public class MagicSquareAndCards while (solver.NextSolution()) { Console.WriteLine("s: {0}", s.Value()); Console.Write("counts:"); - for(int i = 0; i < 14; i++) { - Console.Write(counts[i].Value() + " "); + for (int i = 0; i < 14; i++) { + Console.Write(counts [i] + .Value() + + " "); } Console.WriteLine(); - for(int i = 0; i < n; i++) { - for(int j = 0; j < n; j++) { - Console.Write(x[i,j].Value() + " "); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + Console.Write(x [i, j] + .Value() + + " "); } Console.WriteLine(); } @@ -114,12 +109,9 @@ public class MagicSquareAndCards Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - public static void Main(String[] args) - { + public static void Main(String[] args) { int n = 3; if (args.Length > 0) { diff --git a/examples/contrib/map.cs b/examples/contrib/map.cs index bafba79858..a1a162c386 100644 --- a/examples/contrib/map.cs +++ b/examples/contrib/map.cs @@ -16,8 +16,7 @@ using System; using Google.OrTools.ConstraintSolver; -public class Map -{ +public class Map { /** * * Solves a simple map coloring problem. @@ -25,19 +24,18 @@ public class Map * See http://www.hakank.org/google_or_tools/map.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("Map"); // // data // - int Belgium = 0; - int Denmark = 1; - int France = 2; - int Germany = 3; + int Belgium = 0; + int Denmark = 1; + int France = 2; + int Germany = 3; int Netherlands = 4; - int Luxembourg = 5; + int Luxembourg = 5; int n = 6; int max_num_colors = 4; @@ -66,15 +64,15 @@ public class Map // // Search // - DecisionBuilder db = solver.MakePhase(color, - Solver.CHOOSE_MIN_SIZE_LOWEST_MAX, - Solver.ASSIGN_CENTER_VALUE); + DecisionBuilder db = solver.MakePhase( + color, Solver.CHOOSE_MIN_SIZE_LOWEST_MAX, Solver.ASSIGN_CENTER_VALUE); solver.NewSearch(db); while (solver.NextSolution()) { Console.Write("colors: "); - for(int i = 0; i < n; i++) { - Console.Write("{0} ", color[i].Value()); + for (int i = 0; i < n; i++) { + Console.Write("{0} ", color [i] + .Value()); } Console.WriteLine(); @@ -86,11 +84,7 @@ public class Map Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/map2.cs b/examples/contrib/map2.cs index b58eaa1411..61776c087b 100644 --- a/examples/contrib/map2.cs +++ b/examples/contrib/map2.cs @@ -16,8 +16,7 @@ using System; using Google.OrTools.ConstraintSolver; -public class Map2 -{ +public class Map2 { /** * * Solves a simple map coloring problem. @@ -29,34 +28,26 @@ public class Map2 * * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("Map2"); // // data // - int Belgium = 0; - int Denmark = 1; - int France = 2; - int Germany = 3; + int Belgium = 0; + int Denmark = 1; + int France = 2; + int Germany = 3; int Netherlands = 4; - int Luxembourg = 5; + int Luxembourg = 5; int n = 6; int max_num_colors = 4; - int[,] neighbours = {{France, Belgium}, - {France, Luxembourg}, - {France, Germany}, - {Luxembourg, Germany}, - {Luxembourg, Belgium}, - {Belgium, Netherlands}, - {Belgium, Germany}, - {Germany, Netherlands}, - {Germany, Denmark}}; - - + int[, ] neighbours = { + {France, Belgium}, {France, Luxembourg}, {France, Germany}, + {Luxembourg, Germany}, {Luxembourg, Belgium}, {Belgium, Netherlands}, + {Belgium, Germany}, {Germany, Netherlands}, {Germany, Denmark}}; // // Decision variables @@ -66,26 +57,25 @@ public class Map2 // // Constraints // - for(int i = 0; i < neighbours.GetLength(0); i++) { - solver.Add(color[neighbours[i,0]] != color[neighbours[i,1]]); + for (int i = 0; i < neighbours.GetLength(0); i++) { + solver.Add(color[neighbours[i, 0]] != color[neighbours[i, 1]]); } // Symmetry breaking solver.Add(color[Belgium] == 1); - // // Search // - DecisionBuilder db = solver.MakePhase(color, - Solver.CHOOSE_MIN_SIZE_LOWEST_MAX, - Solver.ASSIGN_CENTER_VALUE); + DecisionBuilder db = solver.MakePhase( + color, Solver.CHOOSE_MIN_SIZE_LOWEST_MAX, Solver.ASSIGN_CENTER_VALUE); solver.NewSearch(db); while (solver.NextSolution()) { Console.Write("colors: "); - for(int i = 0; i < n; i++) { - Console.Write("{0} ", color[i].Value()); + for (int i = 0; i < n; i++) { + Console.Write("{0} ", color [i] + .Value()); } Console.WriteLine(); @@ -97,11 +87,7 @@ public class Map2 Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/marathon2.cs b/examples/contrib/marathon2.cs index 4c63f39da1..54a45c0a05 100644 --- a/examples/contrib/marathon2.cs +++ b/examples/contrib/marathon2.cs @@ -16,8 +16,7 @@ using System; using Google.OrTools.ConstraintSolver; -public class Marathon2 -{ +public class Marathon2 { /** * * Marathon puzzle. @@ -45,28 +44,26 @@ public class Marathon2 * Also see http://www.hakank.org/or-tools/marathon2.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("Marathon2"); // // Data // int n = 6; - String[] runners_str = {"Dominique", "Ignace", "Naren", - "Olivier", "Philippe", "Pascal"}; - + String[] runners_str = {"Dominique", "Ignace", "Naren", + "Olivier", "Philippe", "Pascal"}; // // Decision variables // IntVar[] runners = solver.MakeIntVarArray(n, 1, n, "runners"); IntVar Dominique = runners[0]; - IntVar Ignace = runners[1]; - IntVar Naren = runners[2]; - IntVar Olivier = runners[3]; - IntVar Philippe = runners[4]; - IntVar Pascal = runners[5]; + IntVar Ignace = runners[1]; + IntVar Naren = runners[2]; + IntVar Olivier = runners[3]; + IntVar Philippe = runners[4]; + IntVar Pascal = runners[5]; // // Constraints @@ -77,50 +74,49 @@ public class Marathon2 solver.Add(Olivier != n); // b: Dominique, Pascal and Ignace before Naren and Olivier - solver.Add(Dominique < Naren); - solver.Add(Dominique < Olivier); - solver.Add(Pascal < Naren); - solver.Add(Pascal < Olivier); - solver.Add(Ignace < Naren); - solver.Add(Ignace < Olivier); + solver.Add(Dominique < Naren); + solver.Add(Dominique < Olivier); + solver.Add(Pascal < Naren); + solver.Add(Pascal < Olivier); + solver.Add(Ignace < Naren); + solver.Add(Ignace < Olivier); // c: Dominique better than third - solver.Add(Dominique < 3); + solver.Add(Dominique < 3); // d: Philippe is among the first four - solver.Add(Philippe <= 4); + solver.Add(Philippe <= 4); // e: Ignace neither second nor third - solver.Add(Ignace != 2); - solver.Add(Ignace != 3); + solver.Add(Ignace != 2); + solver.Add(Ignace != 3); // f: Pascal three places earlier than Naren solver.Add(Pascal + 3 == Naren); // g: Neither Ignace nor Dominique on fourth position - solver.Add(Ignace != 4); - solver.Add(Dominique != 4); - + solver.Add(Ignace != 4); + solver.Add(Dominique != 4); // // Search // - DecisionBuilder db = solver.MakePhase(runners, - Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, - Solver.ASSIGN_CENTER_VALUE); + DecisionBuilder db = solver.MakePhase( + runners, Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, Solver.ASSIGN_CENTER_VALUE); solver.NewSearch(db); while (solver.NextSolution()) { - int[] runners_val = new int[n]; + int[] runners_val = new int[n]; Console.Write("runners: "); - for(int i = 0; i < n; i++) { - runners_val[i] = (int)runners[i].Value(); + for (int i = 0; i < n; i++) { + runners_val[i] = (int) runners [i] + .Value(); Console.Write(runners_val[i] + " "); } Console.WriteLine("\nPlaces:"); - for(int i = 1; i < n+1; i++) { - for(int j = 0; j < n; j++) { + for (int i = 1; i < n + 1; i++) { + for (int j = 0; j < n; j++) { if (runners_val[j] == i) { Console.WriteLine("{0}: {1}", i, runners_str[j]); } @@ -134,11 +130,7 @@ public class Marathon2 Console.WriteLine("Branches: " + solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/max_flow_taha.cs b/examples/contrib/max_flow_taha.cs index 8bfc2a473a..4f45754e63 100644 --- a/examples/contrib/max_flow_taha.cs +++ b/examples/contrib/max_flow_taha.cs @@ -19,8 +19,7 @@ using System.Collections.Generic; using System.Linq; using Google.OrTools.ConstraintSolver; -public class MaxFlowTaha -{ +public class MaxFlowTaha { /** * * Max flow problem. @@ -33,38 +32,32 @@ public class MaxFlowTaha * Also see http://www.hakank.org/or-tools/max_flow_taha.py * */ - private static void Solve() - { - + private static void Solve() { Solver solver = new Solver("MaxFlowTaha"); // // Data // - int n = 5; + int n = 5; int start = 0; - int end = n-1; + int end = n - 1; IEnumerable NODES = Enumerable.Range(0, n); // cost matrix - int[,] c = { - {0, 20, 30, 10, 0}, - {0, 0, 40, 0, 30}, - {0, 0, 0, 10, 20}, - {0, 0, 5, 0, 20}, - {0, 0, 0, 0, 0} - }; - - + int[, ] c = {{0, 20, 30, 10, 0}, + {0, 0, 40, 0, 30}, + {0, 0, 0, 10, 20}, + {0, 0, 5, 0, 20}, + {0, 0, 0, 0, 0}}; // // Decision variables // - IntVar[,] x = new IntVar[n,n]; - foreach(int i in NODES) { - foreach(int j in NODES) { - x[i,j] = solver.MakeIntVar(0, c[i,j], "x"); + IntVar[, ] x = new IntVar[n, n]; + foreach (int i in NODES) { + foreach (int j in NODES) { + x[i, j] = solver.MakeIntVar(0, c[i, j], "x"); } } @@ -77,49 +70,39 @@ public class MaxFlowTaha // // Constraints // - solver.Add( (from j in NODES - where c[start,j] > 0 - select x[start,j] - ).ToArray().Sum() == total); + solver.Add((from j in NODES where c[start, j] > 0 select x[start, j]) + .ToArray() + .Sum() == total); - foreach(int i in NODES) { - - var in_flow_sum = (from j in NODES - where c[j,i] > 0 - select x[j,i] - ); + foreach (int i in NODES) { + var in_flow_sum = (from j in NODES where c[j, i] > 0 select x[j, i]); if (in_flow_sum.Count() > 0) { - solver.Add(in_flow_sum.ToArray().Sum() == in_flow[i]); + solver.Add(in_flow_sum.ToArray().Sum() == in_flow[i]); } - var out_flow_sum = (from j in NODES - where c[i,j] > 0 - select x[i,j] - ); + var out_flow_sum = (from j in NODES where c[i, j] > 0 select x[i, j]); if (out_flow_sum.Count() > 0) { - solver.Add(out_flow_sum.ToArray().Sum() == out_flow[i]); + solver.Add(out_flow_sum.ToArray().Sum() == out_flow[i]); } - } // in_flow == out_flow - foreach(int i in NODES) { + foreach (int i in NODES) { if (i != start && i != end) { solver.Add(out_flow[i] == in_flow[i]); } } - var s1 = (from i in NODES where c[i,start] > 0 select x[i,start]); + var s1 = (from i in NODES where c[i, start] > 0 select x[i, start]); if (s1.Count() > 0) { solver.Add(s1.ToArray().Sum() == 0); } - var s2 = (from j in NODES where c[end, j] > 0 select x[end,j]); + var s2 = (from j in NODES where c[end, j] > 0 select x[end, j]); if (s2.Count() > 0) { solver.Add(s2.ToArray().Sum() == 0); } - // // Objective // @@ -128,30 +111,34 @@ public class MaxFlowTaha // // Search // - DecisionBuilder db = solver.MakePhase(x_flat.Concat(in_flow).Concat(out_flow).ToArray(), - Solver.INT_VAR_DEFAULT, - Solver.ASSIGN_MAX_VALUE); + DecisionBuilder db = + solver.MakePhase(x_flat.Concat(in_flow).Concat(out_flow).ToArray(), + Solver.INT_VAR_DEFAULT, Solver.ASSIGN_MAX_VALUE); solver.NewSearch(db, obj); while (solver.NextSolution()) { - Console.WriteLine("total: {0}",total.Value()); + Console.WriteLine("total: {0}", total.Value()); Console.Write("in_flow : "); - foreach(int i in NODES) { - Console.Write(in_flow[i].Value() + " "); + foreach (int i in NODES) { + Console.Write(in_flow [i] + .Value() + + " "); } Console.Write("\nout_flow: "); - foreach(int i in NODES) { - Console.Write(out_flow[i].Value() + " "); + foreach (int i in NODES) { + Console.Write(out_flow [i] + .Value() + + " "); } Console.WriteLine(); - foreach(int i in NODES) { - foreach(int j in NODES) { - Console.Write("{0,2} ", x[i,j].Value()); + foreach (int i in NODES) { + foreach (int j in NODES) { + Console.Write("{0,2} ", x [i, j] + .Value()); } Console.WriteLine(); } Console.WriteLine(); - } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); @@ -160,11 +147,7 @@ public class MaxFlowTaha Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/max_flow_winston1.cs b/examples/contrib/max_flow_winston1.cs index 0fa4573b11..efc5edd3df 100644 --- a/examples/contrib/max_flow_winston1.cs +++ b/examples/contrib/max_flow_winston1.cs @@ -19,8 +19,7 @@ using System.Collections.Generic; using System.Linq; using Google.OrTools.ConstraintSolver; -public class MaxFlowWinston1 -{ +public class MaxFlowWinston1 { /** * * Max flow problem. @@ -32,99 +31,88 @@ public class MaxFlowWinston1 * Also see http://www.hakank.org/or-tools/max_flow_winston1.py * */ - private static void Solve() - { - + private static void Solve() { Solver solver = new Solver("MaxFlowWinston1"); // // Data // - int n = 5; + int n = 5; IEnumerable NODES = Enumerable.Range(0, n); // The arcs // Note: // This is 1-based to be compatible with other implementations. // - int[,] arcs1 = { - {1, 2}, - {1, 3}, - {2, 3}, - {2, 4}, - {3, 5}, - {4, 5}, - {5, 1} - }; + int[, ] arcs1 = {{1, 2}, {1, 3}, {2, 3}, {2, 4}, {3, 5}, {4, 5}, {5, 1}}; // Capacities - int [] cap = {2,3,3,4,2,1,100}; + int[] cap = {2, 3, 3, 4, 2, 1, 100}; // Convert arcs to 0-based int num_arcs = arcs1.GetLength(0); IEnumerable ARCS = Enumerable.Range(0, num_arcs); - int[,] arcs = new int[num_arcs, 2]; - foreach(int i in ARCS) { - for(int j = 0; j < 2; j++) { - arcs[i,j] = arcs1[i,j] - 1; + int[, ] arcs = new int[num_arcs, 2]; + foreach (int i in ARCS) { + for (int j = 0; j < 2; j++) { + arcs[i, j] = arcs1[i, j] - 1; } } // Convert arcs to matrix (for sanity checking below) - int[,] mat = new int[num_arcs, num_arcs]; - foreach(int i in NODES) { - foreach(int j in NODES) { + int[, ] mat = new int[num_arcs, num_arcs]; + foreach (int i in NODES) { + foreach (int j in NODES) { int c = 0; - foreach(int k in ARCS) { - if (arcs[k,0] == i && arcs[k,1] == j) { + foreach (int k in ARCS) { + if (arcs[k, 0] == i && arcs[k, 1] == j) { c = 1; } } - mat[i,j] = c; + mat[i, j] = c; } } // // Decision variables // - IntVar[,] flow = solver.MakeIntVarMatrix(n, n, 0, 200, "flow"); - IntVar z = flow[n-1, 0].VarWithName("z"); + IntVar[, ] flow = solver.MakeIntVarMatrix(n, n, 0, 200, "flow"); + IntVar z = flow [n - 1, 0] + .VarWithName("z"); // // Constraints // // capacity of arcs - foreach(int i in ARCS) { - solver.Add(flow[arcs[i,0], arcs[i,1]] <= cap[i]); + foreach (int i in ARCS) { + solver.Add(flow[arcs[i, 0], arcs[i, 1]] <= cap[i]); } // inflows == outflows - foreach(int i in NODES) { - var s1 = (from k in ARCS - where arcs[k,1] == i - select flow[arcs[k,0], arcs[k,1]] - ).ToArray().Sum(); + foreach (int i in NODES) { + var s1 = (from k in ARCS where arcs[k, 1] == + i select flow[arcs[k, 0], arcs[k, 1]]) + .ToArray() + .Sum(); - var s2 = (from k in ARCS - where arcs[k,0] == i - select flow[arcs[k,0], arcs[k,1]] - ).ToArray().Sum(); + var s2 = (from k in ARCS where arcs[k, 0] == + i select flow[arcs[k, 0], arcs[k, 1]]) + .ToArray() + .Sum(); solver.Add(s1 == s2); - } // Sanity check: just arcs with connections can have a flow. - foreach(int i in NODES) { - foreach(int j in NODES) { - if (mat[i,j] == 0) { - solver.Add(flow[i,j] == 0); + foreach (int i in NODES) { + foreach (int j in NODES) { + if (mat[i, j] == 0) { + solver.Add(flow[i, j] == 0); } } } - // // Objective // @@ -133,16 +121,17 @@ public class MaxFlowWinston1 // // Search // - DecisionBuilder db = solver.MakePhase(flow.Flatten(), - Solver.INT_VAR_DEFAULT, - Solver.ASSIGN_MAX_VALUE); + DecisionBuilder db = solver.MakePhase( + flow.Flatten(), Solver.INT_VAR_DEFAULT, Solver.ASSIGN_MAX_VALUE); solver.NewSearch(db, obj); while (solver.NextSolution()) { - Console.WriteLine("z: {0}",z.Value()); - foreach(int i in NODES) { - foreach(int j in NODES) { - Console.Write(flow[i,j].Value() + " "); + Console.WriteLine("z: {0}", z.Value()); + foreach (int i in NODES) { + foreach (int j in NODES) { + Console.Write(flow [i, j] + .Value() + + " "); } Console.WriteLine(); } @@ -155,11 +144,7 @@ public class MaxFlowWinston1 Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/minesweeper.cs b/examples/contrib/minesweeper.cs index 2f51764932..d931c0c0da 100644 --- a/examples/contrib/minesweeper.cs +++ b/examples/contrib/minesweeper.cs @@ -20,10 +20,7 @@ using System.Linq; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; - -public class Minesweeper -{ - +public class Minesweeper { static int X = -1; // @@ -32,20 +29,16 @@ public class Minesweeper // static int default_r = 8; static int default_c = 8; - static int[,] default_game = {{2, 3, X, 2, 2, X, 2, 1}, - {X, X, 4, X, X, 4, X, 2}, - {X, X, X, X, X, X, 4, X}, - {X, 5, X, 6, X, X, X, 2}, - {2, X, X, X, 5, 5, X, 2}, - {1, 3, 4, X, X, X, 4, X}, - {0, 1, X, 4, X, X, X, 3}, - {0, 1, 2, X, 2, 3, X, 2}}; + static int[, ] default_game = { + {2, 3, X, 2, 2, X, 2, 1}, {X, X, 4, X, X, 4, X, 2}, + {X, X, X, X, X, X, 4, X}, {X, 5, X, 6, X, X, X, 2}, + {2, X, X, X, 5, 5, X, 2}, {1, 3, 4, X, X, X, 4, X}, + {0, 1, X, 4, X, X, X, 3}, {0, 1, 2, X, 2, 3, X, 2}}; // for the actual problem static int r; static int c; - static int[,] game; - + static int[, ] game; /** * @@ -54,8 +47,7 @@ public class Minesweeper * See http://www.hakank.org/google_or_tools/minesweeper.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("Minesweeper"); // @@ -64,10 +56,10 @@ public class Minesweeper int[] S = {-1, 0, 1}; Console.WriteLine("Problem:"); - for(int i = 0; i < r; i++) { - for(int j = 0; j < c; j++) { - if (game[i,j] > X) { - Console.Write(game[i,j] + " "); + for (int i = 0; i < r; i++) { + for (int j = 0; j < c; j++) { + if (game[i, j] > X) { + Console.Write(game[i, j] + " "); } else { Console.Write("X "); } @@ -76,48 +68,40 @@ public class Minesweeper } Console.WriteLine(); - // // Decision variables // - IntVar[,] mines = solver.MakeIntVarMatrix(r, c, 0, 1, "mines"); + IntVar[, ] mines = solver.MakeIntVarMatrix(r, c, 0, 1, "mines"); // for branching IntVar[] mines_flat = mines.Flatten(); // // Constraints - // - for(int i = 0; i < r; i++) { - for(int j = 0; j < c; j++) { - if (game[i,j] >= 0) { - solver.Add( mines[i,j] == 0); + // + for (int i = 0; i < r; i++) { + for (int j = 0; j < c; j++) { + if (game[i, j] >= 0) { + solver.Add(mines[i, j] == 0); // this cell is the sum of all its neighbours - var tmp = from a in S from b in S where - i + a >= 0 && - j + b >= 0 && - i + a < r && - j + b < c - select(mines[i+a,j+b]); - - solver.Add(tmp.ToArray().Sum() == game[i,j]); + var tmp = from a in S from b in S where i + a >= 0 && j + b >= 0 && + i + a < r && j + b < c select(mines[i + a, j + b]); + solver.Add(tmp.ToArray().Sum() == game[i, j]); } - if (game[i,j] > X) { - // This cell cannot be a mine since it + if (game[i, j] > X) { + // This cell cannot be a mine since it // has some value assigned to it - solver.Add(mines[i,j] == 0); + solver.Add(mines[i, j] == 0); } } } - // // Search // - DecisionBuilder db = solver.MakePhase(mines_flat, - Solver.CHOOSE_PATH, + DecisionBuilder db = solver.MakePhase(mines_flat, Solver.CHOOSE_PATH, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); @@ -126,13 +110,14 @@ public class Minesweeper while (solver.NextSolution()) { sol++; Console.WriteLine("Solution #{0} ", sol + " "); - for(int i = 0; i < r; i++) { - for(int j = 0; j < c; j++){ - Console.Write("{0} ", mines[i,j].Value()); + for (int i = 0; i < r; i++) { + for (int j = 0; j < c; j++) { + Console.Write("{0} ", mines [i, j] + .Value()); } Console.WriteLine(); } - + Console.WriteLine(); } @@ -142,7 +127,6 @@ public class Minesweeper Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } /** @@ -156,9 +140,9 @@ public class Minesweeper * < * row number of neighbours lines... * > - * + * * 0..8 means number of neighbours, "." mean unknown (may be a mine) - * + * * Example (from minesweeper0.txt) * # Problem from Gecode/examples/minesweeper.cc problem 0 * 6 @@ -172,51 +156,47 @@ public class Minesweeper * */ private static void readFile(String file) { - Console.WriteLine("readFile(" + file + ")"); int lineCount = 0; - + TextReader inr = new StreamReader(file); String str; while ((str = inr.ReadLine()) != null && str.Length > 0) { - str = str.Trim(); - + // ignore comments - if(str.StartsWith("#") || str.StartsWith("%")) { + if (str.StartsWith("#") || str.StartsWith("%")) { continue; } - + Console.WriteLine(str); if (lineCount == 0) { - r = Convert.ToInt32(str); // number of rows + r = Convert.ToInt32(str); // number of rows } else if (lineCount == 1) { - c = Convert.ToInt32(str); // number of columns - game = new int[r,c]; + c = Convert.ToInt32(str); // number of columns + game = new int[r, c]; } else { // the problem matrix String[] row = Regex.Split(str, ""); - for(int j = 1; j <= c; j++) { + for (int j = 1; j <= c; j++) { String s = row[j]; if (s.Equals(".")) { - game[lineCount-2,j-1] = -1; + game[lineCount - 2, j - 1] = -1; } else { - game[lineCount-2,j-1] = Convert.ToInt32(s); + game[lineCount - 2, j - 1] = Convert.ToInt32(s); } } } - + lineCount++; - - } // end while - + + } // end while + inr.Close(); - - } // end readFile + } // end readFile - public static void Main(String[] args) - { + public static void Main(String[] args) { String file = ""; if (args.Length > 0) { file = args[0]; diff --git a/examples/contrib/mr_smith.cs b/examples/contrib/mr_smith.cs index 16f32f1bb0..c44e4b57d0 100644 --- a/examples/contrib/mr_smith.cs +++ b/examples/contrib/mr_smith.cs @@ -16,8 +16,7 @@ using System; using Google.OrTools.ConstraintSolver; -public class MrSmith -{ +public class MrSmith { /** * * Mr Smith problem. @@ -34,7 +33,7 @@ public class MrSmith * o If Matt comes, then John and his father will * also come. * """ - * + * * The answer should be: * Mr_Smith_comes = 0 * Mrs_Smith_comes = 0 @@ -46,8 +45,7 @@ public class MrSmith * Also see http://www.hakank.org/or-tools/mr_smith.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("MrSmith"); // @@ -59,12 +57,11 @@ public class MrSmith // Decision variables // IntVar[] x = solver.MakeIntVarArray(n, 0, 1, "x"); - IntVar Mr_Smith = x[0]; + IntVar Mr_Smith = x[0]; IntVar Mrs_Smith = x[1]; - IntVar Matt = x[2]; - IntVar John = x[3]; - IntVar Tim = x[4]; - + IntVar Matt = x[2]; + IntVar John = x[3]; + IntVar Tim = x[4]; // // Constraints @@ -81,7 +78,7 @@ public class MrSmith // At least one of their two sons Matt and John will come. // (Matt \/ John) - solver.Add(Matt+John >= 1); + solver.Add(Matt + John >= 1); // Either Mrs Smith or Tim will come but not both. // bool2int(Mrs_Smith) + bool2int(Tim) = 1 @@ -94,22 +91,21 @@ public class MrSmith // If Matt comes /\ then John and his father will also come. // (Matt -> (John /\ Mr_Smith)) - solver.Add(Matt - (John*Mr_Smith) <= 0); - - + solver.Add(Matt - (John * Mr_Smith) <= 0); // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, + DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, Solver.ASSIGN_CENTER_VALUE); solver.NewSearch(db); while (solver.NextSolution()) { - for(int i = 0; i < n; i++) { - Console.Write(x[i].Value() + " "); + for (int i = 0; i < n; i++) { + Console.Write(x [i] + .Value() + + " "); } Console.WriteLine("\n"); Console.WriteLine("Mr Smith : {0}", Mr_Smith.Value()); @@ -117,7 +113,6 @@ public class MrSmith Console.WriteLine("Matt : {0}", Matt.Value()); Console.WriteLine("John : {0}", John.Value()); Console.WriteLine("Tim : {0}", Tim.Value()); - } Console.WriteLine("\nSolutions: " + solver.Solutions()); @@ -126,11 +121,7 @@ public class MrSmith Console.WriteLine("Branches: " + solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/nontransitive_dice.cs b/examples/contrib/nontransitive_dice.cs index a4284496f0..be222d2802 100644 --- a/examples/contrib/nontransitive_dice.cs +++ b/examples/contrib/nontransitive_dice.cs @@ -19,10 +19,7 @@ using System.Linq; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; - -public class NonTransitiveDice -{ - +public class NonTransitiveDice { /** * * Nontransitive dice. @@ -43,9 +40,7 @@ public class NonTransitiveDice * * */ - private static void Solve(int m=3, int n=6, int minimize_val=0) - { - + private static void Solve(int m = 3, int n = 6, int minimize_val = 0) { Solver solver = new Solver("Nontransitive_dice"); Console.WriteLine("Number of dice: {0}", m); @@ -57,26 +52,25 @@ public class NonTransitiveDice // // The dice - IntVar[,] dice = solver.MakeIntVarMatrix(m, n, 1, n*2, "dice"); + IntVar[, ] dice = solver.MakeIntVarMatrix(m, n, 1, n * 2, "dice"); IntVar[] dice_flat = dice.Flatten(); // For comparison (probability) - IntVar[,] comp = solver.MakeIntVarMatrix(m, 2, 0, n*n, "dice"); + IntVar[, ] comp = solver.MakeIntVarMatrix(m, 2, 0, n * n, "dice"); IntVar[] comp_flat = comp.Flatten(); // For branching IntVar[] all = dice_flat.Concat(comp_flat).ToArray(); // The following variables are for summaries or objectives - IntVar[] gap = solver.MakeIntVarArray(m, 0, n*n, "gap"); + IntVar[] gap = solver.MakeIntVarArray(m, 0, n * n, "gap"); IntVar gap_sum = gap.Sum().Var(); IntVar max_val = dice_flat.Max().Var(); IntVar max_win = comp_flat.Max().Var(); // number of occurrences of each value of the dice - IntVar[] counts = solver.MakeIntVarArray(n*2+1, 0, n*m, "counts"); - + IntVar[] counts = solver.MakeIntVarArray(n * 2 + 1, 0, n * m, "counts"); // // Constraints @@ -86,48 +80,50 @@ public class NonTransitiveDice solver.Add(dice_flat.Distribute(counts)); // Order of the number of each die, lowest first - for(int i = 0; i < m; i++) { - for(int j = 0; j < n-1; j++) { - solver.Add(dice[i,j] <= dice[i,j+1]); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n - 1; j++) { + solver.Add(dice[i, j] <= dice[i, j + 1]); } } // Nontransitivity - for(int i = 0; i < m; i++) { - solver.Add(comp[i,0] > comp[i,1]); + for (int i = 0; i < m; i++) { + solver.Add(comp[i, 0] > comp[i, 1]); } // Probability gap - for(int i = 0; i < m; i++) { - solver.Add(gap[i] == comp[i,0] - comp[i,1]); + for (int i = 0; i < m; i++) { + solver.Add(gap[i] == comp[i, 0] - comp[i, 1]); solver.Add(gap[i] > 0); } // And now we roll... // comp[] is the number of wins for [A vs B, B vs A] - for(int d = 0; d < m; d++) { - IntVar sum1 = ( from r1 in Enumerable.Range(0, n) - from r2 in Enumerable.Range(0, n) - select (dice[d % m, r1] > dice[(d+1) % m, r2]) - ).ToArray().Sum().Var(); + for (int d = 0; d < m; d++) { + IntVar sum1 = + (from r1 in Enumerable.Range(0, n) from r2 in Enumerable.Range(0, n) + select(dice[d % m, r1] > dice[(d + 1) % m, r2])) + .ToArray() + .Sum() + .Var(); - solver.Add(comp[d%m,0] == sum1); + solver.Add(comp[d % m, 0] == sum1); - IntVar sum2 = ( from r1 in Enumerable.Range(0, n) - from r2 in Enumerable.Range(0, n) - select (dice[(d+1) % m, r1] > dice[d % m, r2]) - ).ToArray().Sum().Var(); + IntVar sum2 = + (from r1 in Enumerable.Range(0, n) from r2 in Enumerable.Range(0, n) + select(dice[(d + 1) % m, r1] > dice[d % m, r2])) + .ToArray() + .Sum() + .Var(); - solver.Add(comp[d%m,1] == sum2); + solver.Add(comp[d % m, 1] == sum2); } - // // Search // - DecisionBuilder db = solver.MakePhase(all, - Solver.INT_VAR_DEFAULT, - Solver.ASSIGN_MIN_VALUE); + DecisionBuilder db = + solver.MakePhase(all, Solver.INT_VAR_DEFAULT, Solver.ASSIGN_MIN_VALUE); if (minimize_val > 0) { Console.WriteLine("Minimizing max_val"); @@ -146,29 +142,35 @@ public class NonTransitiveDice while (solver.NextSolution()) { Console.WriteLine("gap_sum: {0}", gap_sum.Value()); - Console.WriteLine("gap: {0}", (from i in Enumerable.Range(0, m) - select gap[i].Value().ToString() - ).ToArray() - ); + Console.WriteLine("gap: {0}", (from i in Enumerable + .Range(0, m) select gap [i] + .Value() + .ToString()) + .ToArray()); Console.WriteLine("max_val: {0}", max_val.Value()); Console.WriteLine("max_win: {0}", max_win.Value()); Console.WriteLine("dice:"); - for(int i = 0; i < m; i++) { - for(int j = 0; j < n; j++) { - Console.Write(dice[i,j].Value() + " "); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + Console.Write(dice [i, j] + .Value() + + " "); } Console.WriteLine(); } Console.WriteLine("comp:"); - for(int i = 0; i < m; i++) { - for(int j = 0; j < 2; j++) { - Console.Write(comp[i,j].Value() + " "); + for (int i = 0; i < m; i++) { + for (int j = 0; j < 2; j++) { + Console.Write(comp [i, j] + .Value() + + " "); } Console.WriteLine(); } Console.WriteLine("counts:"); - for(int i = 1; i < n*2+1; i++) { - int c = (int)counts[i].Value(); + for (int i = 1; i < n * 2 + 1; i++) { + int c = (int) counts [i] + .Value(); if (c > 0) { Console.Write("{0}({1}) ", i, c); } @@ -182,16 +184,12 @@ public class NonTransitiveDice Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - - public static void Main(String[] args) - { - int m = 3; // number of dice - int n = 6; // number of sides of each die - int minimize_val = 0; // minimizing max_max (0: no, 1: yes) + public static void Main(String[] args) { + int m = 3; // number of dice + int n = 6; // number of sides of each die + int minimize_val = 0; // minimizing max_max (0: no, 1: yes) if (args.Length > 0) { m = Convert.ToInt32(args[0]); diff --git a/examples/contrib/nqueens.cs b/examples/contrib/nqueens.cs index ff14865aa0..f7f9ac9de9 100644 --- a/examples/contrib/nqueens.cs +++ b/examples/contrib/nqueens.cs @@ -17,37 +17,34 @@ using System; using System.Linq; using Google.OrTools.ConstraintSolver; -public class NQueens -{ +public class NQueens { /** * * Solves the N-Queens problem. * * Syntax: nqueens.exe n num print - * where + * where * n : size of board * num : number of solutions to calculate * print: print the results (if > 0) * */ - private static void Solve(int n=8, int num=0, int print=1) - { + private static void Solve(int n = 8, int num = 0, int print = 1) { Solver solver = new Solver("N-Queens"); // // Decision variables // - IntVar[] q = solver.MakeIntVarArray(n, 0, n-1, "q"); - + IntVar[] q = solver.MakeIntVarArray(n, 0, n - 1, "q"); // // Constraints - // + // solver.Add(q.AllDifferent()); IntVar[] q1 = new IntVar[n]; IntVar[] q2 = new IntVar[n]; - for(int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { q1[i] = (q[i] + i).Var(); q2[i] = (q[i] - i).Var(); } @@ -66,18 +63,18 @@ public class NQueens // // Search // - DecisionBuilder db = solver.MakePhase(q, - Solver.CHOOSE_MIN_SIZE_LOWEST_MAX, + DecisionBuilder db = solver.MakePhase(q, Solver.CHOOSE_MIN_SIZE_LOWEST_MAX, Solver.ASSIGN_CENTER_VALUE); solver.NewSearch(db); int c = 0; while (solver.NextSolution()) { if (print > 0) { - for(int i = 0; i < n; i++) { - Console.Write("{0} ", q[i].Value()); + for (int i = 0; i < n; i++) { + Console.Write("{0} ", q [i] + .Value()); } - + Console.WriteLine(); } c++; @@ -92,11 +89,9 @@ public class NQueens Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { + public static void Main(String[] args) { int n = 8; int num = 0; int print = 1; diff --git a/examples/contrib/nurse_rostering_regular.cs b/examples/contrib/nurse_rostering_regular.cs index 35654a186a..4683877794 100644 --- a/examples/contrib/nurse_rostering_regular.cs +++ b/examples/contrib/nurse_rostering_regular.cs @@ -20,10 +20,7 @@ using System.Linq; using System.Diagnostics; using Google.OrTools.ConstraintSolver; -public class NurseRostering -{ - - +public class NurseRostering { /* * Global constraint regular * @@ -46,16 +43,8 @@ public class NurseRostering * F : accepting states * */ - static void MyRegular(Solver solver, - IntVar[] x, - int Q, - int S, - int[,] d, - int q0, - int[] F) { - - - + static void MyRegular(Solver solver, IntVar[] x, int Q, int S, int[, ] d, + int q0, int[] F) { Debug.Assert(Q > 0, "regular: 'Q' must be greater than zero"); Debug.Assert(S > 0, "regular: 'S' must be greater than zero"); @@ -63,22 +52,25 @@ public class NurseRostering // each possible input; each extra transition is from state zero // to state zero. This allows us to continue even if we hit a // non-accepted input. - int[][] d2 = new int[Q+1][]; - for(int i = 0; i <= Q; i++) { + int[][] d2 = new int [Q + 1] + []; + for (int i = 0; i <= Q; i++) { int[] row = new int[S]; - for(int j = 0; j < S; j++) { + for (int j = 0; j < S; j++) { if (i == 0) { row[j] = 0; } else { - row[j] = d[i-1,j]; + row[j] = d[i - 1, j]; } } d2[i] = row; } - int[] d2_flatten = (from i in Enumerable.Range(0, Q+1) - from j in Enumerable.Range(0, S) - select d2[i][j]).ToArray(); + int[] d2_flatten = + (from i in Enumerable.Range(0, Q + 1) from j in Enumerable.Range(0, S) + select d2 [i] + [j]) + .ToArray(); // If x has index set m..n, then a[m-1] holds the initial state // (q0), and a[i+1] holds the state we're in after processing @@ -87,23 +79,21 @@ public class NurseRostering int m = 0; int n = x.Length; - IntVar[] a = solver.MakeIntVarArray(n+1-m, 0,Q+1, "a"); + IntVar[] a = solver.MakeIntVarArray(n + 1 - m, 0, Q + 1, "a"); // Check that the final state is in F - solver.Add(a[a.Length-1].Member(F)); + solver.Add(a [a.Length - 1] + .Member(F)); // First state is q0 solver.Add(a[m] == q0); - for(int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { solver.Add(x[i] >= 1); solver.Add(x[i] <= S); // Determine a[i+1]: a[i+1] == d2[a[i], x[i]] - solver.Add(a[i+1] == d2_flatten.Element(((a[i])*S)+(x[i]-1))); - + solver.Add(a[i + 1] == d2_flatten.Element(((a[i]) * S) + (x[i] - 1))); } - } - /** * * Nurse rostering @@ -118,8 +108,7 @@ public class NurseRostering * Also see http://www.hakank.org/or-tools/nurse_rostering.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("NurseRostering"); // @@ -143,27 +132,27 @@ public class NurseRostering // the DFA (for regular) int n_states = 6; int input_max = 3; - int initial_state = 1; // 0 is for the failing state - int[] accepting_states = {1,2,3,4,5,6}; + int initial_state = 1; // 0 is for the failing state + int[] accepting_states = {1, 2, 3, 4, 5, 6}; - int[,] transition_fn = { - // d,n,o - {2,3,1}, // state 1 - {4,4,1}, // state 2 - {4,5,1}, // state 3 - {6,6,1}, // state 4 - {6,0,1}, // state 5 - {0,0,1} // state 6 + int[, ] transition_fn = { + // d,n,o + {2, 3, 1}, // state 1 + {4, 4, 1}, // state 2 + {4, 5, 1}, // state 3 + {6, 6, 1}, // state 4 + {6, 0, 1}, // state 5 + {0, 0, 1} // state 6 }; - string[] days = {"d","n","o"}; // for presentation + string[] days = {"d", "n", "o"}; // for presentation // // Decision variables // // For regular - IntVar[,] x = + IntVar[, ] x = solver.MakeIntVarMatrix(num_nurses, num_days, valid_shifts, "x"); IntVar[] x_flat = x.Flatten(); @@ -173,38 +162,33 @@ public class NurseRostering // summary of the shifts per day int num_shifts = shifts.Length; - IntVar[,] day_stat = new IntVar[num_days, num_shifts]; - for(int i = 0; i < num_days; i++) { - for(int j = 0; j < num_shifts; j++) { - day_stat[i,j] = solver.MakeIntVar(0, num_nurses, "day_stat"); + IntVar[, ] day_stat = new IntVar[num_days, num_shifts]; + for (int i = 0; i < num_days; i++) { + for (int j = 0; j < num_shifts; j++) { + day_stat[i, j] = solver.MakeIntVar(0, num_nurses, "day_stat"); } } - // // Constraints // - for(int i = 0; i < num_nurses; i++) { + for (int i = 0; i < num_nurses; i++) { IntVar[] reg_input = new IntVar[num_days]; - for(int j = 0; j < num_days; j++) { - reg_input[j] = x[i,j]; + for (int j = 0; j < num_days; j++) { + reg_input[j] = x[i, j]; } MyRegular(solver, reg_input, n_states, input_max, transition_fn, initial_state, accepting_states); - - - } // // Statistics and constraints for each nurse // - for(int i = 0; i < num_nurses; i++) { - + for (int i = 0; i < num_nurses; i++) { // Number of worked days (either day or night shift) IntVar[] b = new IntVar[num_days]; - for(int j = 0; j < num_days; j++) { - b[j] = ((x[i,j] == day_shift) + (x[i,j] == night_shift)).Var(); + for (int j = 0; j < num_days; j++) { + b[j] = ((x[i, j] == day_shift) + (x[i, j] == night_shift)).Var(); } solver.Add(b.Sum() == nurse_stat[i]); @@ -212,20 +196,18 @@ public class NurseRostering // days/nights during this period solver.Add(nurse_stat[i] >= 7); solver.Add(nurse_stat[i] <= 10); - } - // // Statistics and constraints for each day // - for(int j = 0; j < num_days; j++) { - for(int t = 0; t < num_shifts; t++) { + for (int j = 0; j < num_days; j++) { + for (int t = 0; t < num_shifts; t++) { IntVar[] b = new IntVar[num_nurses]; - for(int i = 0; i < num_nurses; i++) { - b[i] = x[i,j] == t; + for (int i = 0; i < num_nurses; i++) { + b[i] = x[i, j] == t; } - solver.Add(b.Sum() == day_stat[j,t]); + solver.Add(b.Sum() == day_stat[j, t]); } // @@ -238,27 +220,25 @@ public class NurseRostering // if (j % 7 == 5 || j % 7 == 6) { // special constraints for the weekends - solver.Add(day_stat[j,day_shift] == 2); - solver.Add(day_stat[j,night_shift] == 1); - solver.Add(day_stat[j,off_shift] == 4 ); + solver.Add(day_stat[j, day_shift] == 2); + solver.Add(day_stat[j, night_shift] == 1); + solver.Add(day_stat[j, off_shift] == 4); } else { // for workdays: // - exactly 3 on day shift - solver.Add(day_stat[j,day_shift] == 3); + solver.Add(day_stat[j, day_shift] == 3); // - exactly 2 on night - solver.Add(day_stat[j,night_shift] == 2); + solver.Add(day_stat[j, night_shift] == 2); // - exactly 2 off duty - solver.Add(day_stat[j,off_shift] == 2 ); + solver.Add(day_stat[j, off_shift] == 2); } } - // // Search // - DecisionBuilder db = solver.MakePhase(x_flat, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(x_flat, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); @@ -266,11 +246,13 @@ public class NurseRostering int num_solutions = 0; while (solver.NextSolution()) { num_solutions++; - for(int i = 0; i < num_nurses; i++) { + for (int i = 0; i < num_nurses; i++) { Console.Write("Nurse #{0,-2}: ", i); var occ = new Dictionary(); - for(int j = 0; j < num_days; j++) { - int v = (int)x[i,j].Value()-1; + for (int j = 0; j < num_days; j++) { + int v = (int) x [i, j] + .Value() - + 1; if (!occ.ContainsKey(v)) { occ[v] = 0; } @@ -278,24 +260,26 @@ public class NurseRostering Console.Write(days[v] + " "); } - Console.Write(" #workdays: {0,2}", nurse_stat[i].Value()); - foreach(int s in valid_shifts) { + Console.Write(" #workdays: {0,2}", nurse_stat [i] + .Value()); + foreach (int s in valid_shifts) { int v = 0; - if (occ.ContainsKey(s-1)) { - v = occ[s-1]; + if (occ.ContainsKey(s - 1)) { + v = occ[s - 1]; } - Console.Write(" {0}:{1}", days[s-1], v); + Console.Write(" {0}:{1}", days[s - 1], v); } Console.WriteLine(); - } Console.WriteLine(); Console.WriteLine("Statistics per day:\nDay d n o"); - for(int j = 0; j < num_days; j++) { + for (int j = 0; j < num_days; j++) { Console.Write("Day #{0,2}: ", j); - foreach(int t in valid_shifts) { - Console.Write(day_stat[j,t].Value() + " "); + foreach (int t in valid_shifts) { + Console.Write(day_stat [j, t] + .Value() + + " "); } Console.WriteLine(); } @@ -313,11 +297,7 @@ public class NurseRostering Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/nurse_rostering_transition.cs b/examples/contrib/nurse_rostering_transition.cs index dc39b431a6..0457d95dcc 100644 --- a/examples/contrib/nurse_rostering_transition.cs +++ b/examples/contrib/nurse_rostering_transition.cs @@ -20,9 +20,7 @@ using System.Linq; using System.Diagnostics; using Google.OrTools.ConstraintSolver; -public class NurseRostering -{ - +public class NurseRostering { /** * * Nurse rostering @@ -40,8 +38,7 @@ public class NurseRostering * which use (a decomposition of) regular constraint * */ - private static void Solve(int nurse_multiplier, int week_multiplier) - { + private static void Solve(int nurse_multiplier, int week_multiplier) { Console.WriteLine("Starting Nurse Rostering"); Console.WriteLine(" - {0} teams of 7 nurses", nurse_multiplier); Console.WriteLine(" - {0} blocks of 14 days", week_multiplier); @@ -68,7 +65,7 @@ public class NurseRostering // the DFA (for regular) int initial_state = 1; - int[] accepting_states = {1,2,3,4,5,6}; + int[] accepting_states = {1, 2, 3, 4, 5, 6}; /* // This is the transition function @@ -87,24 +84,14 @@ public class NurseRostering // For TransitionConstraint IntTupleSet transition_tuples = new IntTupleSet(3); // state, input, next state - transition_tuples.InsertAll(new long[][] { - new long[] {1,1,2}, - new long[] {1,2,3}, - new long[] {1,3,1}, - new long[] {2,1,4}, - new long[] {2,2,4}, - new long[] {2,3,1}, - new long[] {3,1,4}, - new long[] {3,2,5}, - new long[] {3,3,1}, - new long[] {4,1,6}, - new long[] {4,2,6}, - new long[] {4,3,1}, - new long[] {5,1,6}, - new long[] {5,3,1}, - new long[] {6,3,1} }); + transition_tuples.InsertAll(new long[][]{ + new long[]{1, 1, 2}, new long[]{1, 2, 3}, new long[]{1, 3, 1}, + new long[]{2, 1, 4}, new long[]{2, 2, 4}, new long[]{2, 3, 1}, + new long[]{3, 1, 4}, new long[]{3, 2, 5}, new long[]{3, 3, 1}, + new long[]{4, 1, 6}, new long[]{4, 2, 6}, new long[]{4, 3, 1}, + new long[]{5, 1, 6}, new long[]{5, 3, 1}, new long[]{6, 3, 1}}); - string[] days = {"d","n","o"}; // for presentation + string[] days = {"d", "n", "o"}; // for presentation // // Decision variables @@ -113,7 +100,7 @@ public class NurseRostering // // For TransitionConstraint // - IntVar[,] x = + IntVar[, ] x = solver.MakeIntVarMatrix(num_nurses, num_days, valid_shifts, "x"); IntVar[] x_flat = x.Flatten(); @@ -126,37 +113,35 @@ public class NurseRostering // summary of the shifts per day // int num_shifts = shifts.Length; - IntVar[,] day_stat = new IntVar[num_days, num_shifts]; - for(int i = 0; i < num_days; i++) { - for(int j = 0; j < num_shifts; j++) { - day_stat[i,j] = solver.MakeIntVar(0, num_nurses, "day_stat"); + IntVar[, ] day_stat = new IntVar[num_days, num_shifts]; + for (int i = 0; i < num_days; i++) { + for (int j = 0; j < num_shifts; j++) { + day_stat[i, j] = solver.MakeIntVar(0, num_nurses, "day_stat"); } } // // Constraints // - for(int i = 0; i < num_nurses; i++) { + for (int i = 0; i < num_nurses; i++) { IntVar[] reg_input = new IntVar[num_days]; - for(int j = 0; j < num_days; j++) { - reg_input[j] = x[i,j]; + for (int j = 0; j < num_days; j++) { + reg_input[j] = x[i, j]; } - solver.Add(reg_input.Transition(transition_tuples, - initial_state, + solver.Add(reg_input.Transition(transition_tuples, initial_state, accepting_states)); } // // Statistics and constraints for each nurse // - for(int nurse = 0; nurse < num_nurses; nurse++) { - + for (int nurse = 0; nurse < num_nurses; nurse++) { // Number of worked days (either day or night shift) IntVar[] nurse_days = new IntVar[num_days]; - for(int day = 0; day < num_days; day++) { - nurse_days[day] = - x[nurse, day].IsMember(new int[] { day_shift, night_shift }); + for (int day = 0; day < num_days; day++) { + nurse_days[day] = x [nurse, day] + .IsMember(new int[]{day_shift, night_shift}); } nurse_stat[nurse] = nurse_days.Sum().Var(); @@ -164,20 +149,18 @@ public class NurseRostering // days/nights during this period solver.Add(nurse_stat[nurse] >= 7 * week_multiplier / nurse_multiplier); solver.Add(nurse_stat[nurse] <= 10 * week_multiplier / nurse_multiplier); - } // // Statistics and constraints for each day // - for(int day = 0; day < num_days; day++) { + for (int day = 0; day < num_days; day++) { IntVar[] nurses = new IntVar[num_nurses]; - for(int nurse = 0; nurse < num_nurses; nurse++) { + for (int nurse = 0; nurse < num_nurses; nurse++) { nurses[nurse] = x[nurse, day]; } IntVar[] stats = new IntVar[num_shifts]; - for (int shift = 0; shift < num_shifts; ++shift) - { + for (int shift = 0; shift < num_shifts; ++shift) { stats[shift] = day_stat[day, shift]; } solver.Add(nurses.Distribute(stats)); @@ -210,8 +193,7 @@ public class NurseRostering // // Search // - DecisionBuilder db = solver.MakePhase(x_flat, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(x_flat, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); SearchMonitor log = solver.MakeSearchLog(1000000); @@ -221,11 +203,13 @@ public class NurseRostering int num_solutions = 0; while (solver.NextSolution()) { num_solutions++; - for(int i = 0; i < num_nurses; i++) { + for (int i = 0; i < num_nurses; i++) { Console.Write("Nurse #{0,-2}: ", i); var occ = new Dictionary(); - for(int j = 0; j < num_days; j++) { - int v = (int)x[i,j].Value()-1; + for (int j = 0; j < num_days; j++) { + int v = (int) x [i, j] + .Value() - + 1; if (!occ.ContainsKey(v)) { occ[v] = 0; } @@ -233,24 +217,26 @@ public class NurseRostering Console.Write(days[v] + " "); } - Console.Write(" #workdays: {0,2}", nurse_stat[i].Value()); - foreach(int s in valid_shifts) { + Console.Write(" #workdays: {0,2}", nurse_stat [i] + .Value()); + foreach (int s in valid_shifts) { int v = 0; - if (occ.ContainsKey(s-1)) { - v = occ[s-1]; + if (occ.ContainsKey(s - 1)) { + v = occ[s - 1]; } - Console.Write(" {0}:{1}", days[s-1], v); + Console.Write(" {0}:{1}", days[s - 1], v); } Console.WriteLine(); - } Console.WriteLine(); Console.WriteLine("Statistics per day:\nDay d n o"); - for(int j = 0; j < num_days; j++) { + for (int j = 0; j < num_days; j++) { Console.Write("Day #{0,2}: ", j); - foreach(int t in valid_shifts) { - Console.Write(day_stat[j,t].Value() + " "); + foreach (int t in valid_shifts) { + Console.Write(day_stat [j, t] + .Value() + + " "); } Console.WriteLine(); } @@ -268,11 +254,9 @@ public class NurseRostering Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { + public static void Main(String[] args) { int nurse_multiplier = 1; int week_multiplier = 1; if (args.Length > 0) { diff --git a/examples/contrib/olympic.cs b/examples/contrib/olympic.cs index 9e1df76e4b..61f54fec98 100644 --- a/examples/contrib/olympic.cs +++ b/examples/contrib/olympic.cs @@ -16,23 +16,15 @@ using System; using Google.OrTools.ConstraintSolver; -public class Olympic -{ - - public static void minus(Solver solver, - IntVar x, - IntVar y, - IntVar z) - { +public class Olympic { + public static void minus(Solver solver, IntVar x, IntVar y, IntVar z) { solver.Add(z == (x - y).Abs()); } - - /** * * Olympic puzzle. - * + * * Benchmark for Prolog (BProlog) * """ * File : olympic.pl @@ -66,8 +58,7 @@ public class Olympic * Also see http://www.hakank.org/or-tools/olympic.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("Olympic"); // @@ -79,18 +70,17 @@ public class Olympic // Decision variables // IntVar[] x = solver.MakeIntVarArray(n, 1, n, "x"); - IntVar X1 = x[0]; - IntVar X2 = x[1]; - IntVar X3 = x[2]; - IntVar X4 = x[3]; - IntVar X5 = x[4]; - IntVar X6 = x[5]; - IntVar X7 = x[6]; - IntVar X8 = x[7]; - IntVar X9 = x[8]; + IntVar X1 = x[0]; + IntVar X2 = x[1]; + IntVar X3 = x[2]; + IntVar X4 = x[3]; + IntVar X5 = x[4]; + IntVar X6 = x[5]; + IntVar X7 = x[6]; + IntVar X8 = x[7]; + IntVar X9 = x[8]; IntVar X10 = x[9]; - // // Constraints // @@ -104,19 +94,18 @@ public class Olympic minus(solver, X8, X9, X5); minus(solver, X9, X10, X6); - // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.INT_VAR_SIMPLE, - Solver.INT_VALUE_DEFAULT); + DecisionBuilder db = + solver.MakePhase(x, Solver.INT_VAR_SIMPLE, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { - for(int i = 0; i < n; i++) { - Console.Write("{0,2} ", x[i].Value()); + for (int i = 0; i < n; i++) { + Console.Write("{0,2} ", x [i] + .Value()); } Console.WriteLine(); } @@ -127,11 +116,7 @@ public class Olympic Console.WriteLine("Branches: " + solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/organize_day.cs b/examples/contrib/organize_day.cs index f41c4647d5..2a9a353311 100644 --- a/examples/contrib/organize_day.cs +++ b/examples/contrib/organize_day.cs @@ -20,23 +20,15 @@ using System.Linq; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; - -public class OrganizeDay -{ - - +public class OrganizeDay { // // No overlapping of tasks s1 and s2 // - public static void NoOverlap(Solver solver, - IntVar s1, int d1, - IntVar s2, int d2) - { + public static void NoOverlap(Solver solver, IntVar s1, int d1, IntVar s2, + int d2) { solver.Add((s1 + d1 <= s2) + (s2 + d2 <= s1) == 1); } - - /** * * @@ -52,31 +44,24 @@ public class OrganizeDay * Also see http://www.hakank.org/google_or_tools/organize_day.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("OrganizeDay"); - int n = 4; - int work = 0; int mail = 1; int shop = 2; int bank = 3; int[] tasks = {work, mail, shop, bank}; - int[] durations = {4,1,2,1}; + int[] durations = {4, 1, 2, 1}; // task [i,0] must be finished before task [i,1] - int[,] before_tasks = { - {bank, shop}, - {mail, work} - }; + int[, ] before_tasks = {{bank, shop}, {mail, work}}; // the valid times of the day int begin = 9; - int end = 17; - + int end = 17; // // Decision variables @@ -87,46 +72,41 @@ public class OrganizeDay // // Constraints // - foreach(int t in tasks) { + foreach (int t in tasks) { solver.Add(ends[t] == begins[t] + durations[t]); } - foreach(int i in tasks) { - foreach(int j in tasks) { + foreach (int i in tasks) { + foreach (int j in tasks) { if (i < j) { - NoOverlap(solver, - begins[i], durations[i], - begins[j], durations[j]); + NoOverlap(solver, begins[i], durations[i], begins[j], durations[j]); } } } // specific constraints - for(int t = 0; t < before_tasks.GetLength(0); t++) { - solver.Add(ends[before_tasks[t,0]] <= begins[before_tasks[t,1]]); + for (int t = 0; t < before_tasks.GetLength(0); t++) { + solver.Add(ends[before_tasks[t, 0]] <= begins[before_tasks[t, 1]]); } solver.Add(begins[work] >= 11); - - - // // Search // - DecisionBuilder db = solver.MakePhase(begins, - Solver.INT_VAR_DEFAULT, + DecisionBuilder db = solver.MakePhase(begins, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { - foreach(int t in tasks) { - Console.WriteLine("Task {0}: {1,2} .. ({2}) .. {3,2}", - t, - begins[t].Value(), + foreach (int t in tasks) { + Console.WriteLine("Task {0}: {1,2} .. ({2}) .. {3,2}", t, + begins [t] + .Value(), durations[t], - ends[t].Value()); + ends [t] + .Value()); } Console.WriteLine(); } @@ -137,12 +117,7 @@ public class OrganizeDay Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/organize_day_intervals.cs b/examples/contrib/organize_day_intervals.cs index 09f7e75ab0..a498bfcf24 100644 --- a/examples/contrib/organize_day_intervals.cs +++ b/examples/contrib/organize_day_intervals.cs @@ -18,8 +18,7 @@ using System.Linq; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; -public class OrganizeDay -{ +public class OrganizeDay { /** * * @@ -35,47 +34,34 @@ public class OrganizeDay * Also see http://www.hakank.org/google_or_tools/organize_day.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("OrganizeDayIntervals"); - int n = 4; - int work = 0; int mail = 1; int shop = 2; int bank = 3; // the valid times of the day int begin = 9; - int end = 17; + int end = 17; // tasks int[] tasks = {work, mail, shop, bank}; // durations - int[] durations = {4,1,2,1}; + int[] durations = {4, 1, 2, 1}; // Arrays for interval variables. - int[] starts_max = { begin,begin,begin,begin }; - int[] ends_max = { end -4, end - 1, end - 2, end - 1 }; + int[] starts_max = {begin, begin, begin, begin}; + int[] ends_max = {end - 4, end - 1, end - 2, end - 1}; // task [i,0] must be finished before task [i,1] - int[,] before_tasks = { - {bank, shop}, - {mail, work} - }; - - + int[, ] before_tasks = {{bank, shop}, {mail, work}}; // // Decision variables // - IntervalVar[] intervals = - solver.MakeFixedDurationIntervalVarArray(n, - starts_max, - ends_max, - durations, - false, - "task"); + IntervalVar[] intervals = solver.MakeFixedDurationIntervalVarArray( + n, starts_max, ends_max, durations, false, "task"); // // Constraints // @@ -83,26 +69,29 @@ public class OrganizeDay solver.Add(disjunctive); // specific constraints - for(int t = 0; t < before_tasks.GetLength(0); t++) { + for (int t = 0; t < before_tasks.GetLength(0); t++) { int before = before_tasks[t, 0]; int after = before_tasks[t, 1]; - solver.Add(intervals[after].StartsAfterEnd(intervals[before])); + solver.Add(intervals [after] + .StartsAfterEnd(intervals[before])); } - solver.Add(intervals[work].StartsAfter(11)); + solver.Add(intervals [work] + .StartsAfter(11)); // // Search // SequenceVar var = disjunctive.SequenceVar(); - SequenceVar[] seq_array = new SequenceVar[] { var }; + SequenceVar[] seq_array = new SequenceVar[]{var}; DecisionBuilder db = solver.MakePhase(seq_array, Solver.SEQUENCE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { - foreach(int t in tasks) { - Console.WriteLine(intervals[t].ToString()); + foreach (int t in tasks) { + Console.WriteLine(intervals [t] + .ToString()); } Console.WriteLine(); } @@ -113,12 +102,7 @@ public class OrganizeDay Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/p_median.cs b/examples/contrib/p_median.cs index 53a2f72c0b..06de8c3737 100644 --- a/examples/contrib/p_median.cs +++ b/examples/contrib/p_median.cs @@ -19,8 +19,7 @@ using System.Collections.Generic; using System.Linq; using Google.OrTools.ConstraintSolver; -public class PMedian -{ +public class PMedian { /** * * P-median problem. @@ -38,9 +37,7 @@ public class PMedian * Also see http://www.hakank.org/or-tools/p_median.py * */ - private static void Solve() - { - + private static void Solve() { Solver solver = new Solver("PMedian"); // @@ -53,44 +50,38 @@ public class PMedian int num_warehouses = 3; IEnumerable WAREHOUSES = Enumerable.Range(0, num_warehouses); - int[] demand = {100,80,80,70}; - int [,] distance = { - { 2, 10, 50}, - { 2, 10, 52}, - {50, 60, 3}, - {40, 60, 1} - }; + int[] demand = {100, 80, 80, 70}; + int[, ] distance = {{2, 10, 50}, {2, 10, 52}, {50, 60, 3}, {40, 60, 1}}; // // Decision variables // - IntVar[] open = solver.MakeIntVarArray(num_warehouses, 0, num_warehouses, "open"); - IntVar[,] ship = solver.MakeIntVarMatrix(num_customers, num_warehouses, - 0, 1, "ship"); + IntVar[] open = + solver.MakeIntVarArray(num_warehouses, 0, num_warehouses, "open"); + IntVar[, ] ship = + solver.MakeIntVarMatrix(num_customers, num_warehouses, 0, 1, "ship"); IntVar z = solver.MakeIntVar(0, 1000, "z"); - // // Constraints // - solver.Add((from c in CUSTOMERS - from w in WAREHOUSES - select (demand[c]*distance[c,w]*ship[c,w]) - ).ToArray().Sum() == z); + solver.Add((from c in CUSTOMERS from w in WAREHOUSES select( + demand[c] * distance[c, w] * ship[c, w])) + .ToArray() + .Sum() == z); solver.Add(open.Sum() == p); - foreach(int c in CUSTOMERS) { - foreach(int w in WAREHOUSES) { - solver.Add(ship[c,w] <= open[w]); + foreach (int c in CUSTOMERS) { + foreach (int w in WAREHOUSES) { + solver.Add(ship[c, w] <= open[w]); } - solver.Add((from w in WAREHOUSES select ship[c,w]).ToArray().Sum() == 1); + solver.Add((from w in WAREHOUSES select ship[c, w]).ToArray().Sum() == 1); } - // // Objective // @@ -99,22 +90,26 @@ public class PMedian // // Search // - DecisionBuilder db = solver.MakePhase(open.Concat(ship.Flatten()).ToArray(), - Solver.CHOOSE_FIRST_UNBOUND, - Solver.ASSIGN_MIN_VALUE); + DecisionBuilder db = + solver.MakePhase(open.Concat(ship.Flatten()).ToArray(), + Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db, obj); while (solver.NextSolution()) { - Console.WriteLine("z: {0}",z.Value()); + Console.WriteLine("z: {0}", z.Value()); Console.Write("open:"); - foreach(int w in WAREHOUSES) { - Console.Write(open[w].Value() + " "); + foreach (int w in WAREHOUSES) { + Console.Write(open [w] + .Value() + + " "); } Console.WriteLine(); - foreach(int c in CUSTOMERS) { - foreach(int w in WAREHOUSES) { - Console.Write(ship[c,w].Value()+ " "); + foreach (int c in CUSTOMERS) { + foreach (int w in WAREHOUSES) { + Console.Write(ship [c, w] + .Value() + + " "); } Console.WriteLine(); } @@ -127,11 +122,7 @@ public class PMedian Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/pandigital_numbers.cs b/examples/contrib/pandigital_numbers.cs index 117b6b786e..b26b5c5ced 100644 --- a/examples/contrib/pandigital_numbers.cs +++ b/examples/contrib/pandigital_numbers.cs @@ -19,9 +19,7 @@ using System.Collections.Generic; using System.Linq; using Google.OrTools.ConstraintSolver; -public class PandigitalNumbers -{ - +public class PandigitalNumbers { /** * * toNum(solver, a, num, base) @@ -29,18 +27,15 @@ public class PandigitalNumbers * channelling between the array a and the number num. * */ - private static Constraint ToNum(IntVar[] a, - IntVar num, - int bbase) { + private static Constraint ToNum(IntVar[] a, IntVar num, int bbase) { int len = a.Length; IntVar[] tmp = new IntVar[len]; - for(int i = 0; i < len; i++) { - tmp[i] = (a[i]*(int)Math.Pow(bbase,len-i-1)).Var(); + for (int i = 0; i < len; i++) { + tmp[i] = (a[i] * (int) Math.Pow(bbase, len - i - 1)).Var(); } return tmp.Sum() == num; } - /** * * Pandigital numbers in Google CP Solver. @@ -80,63 +75,59 @@ public class PandigitalNumbers * Also see http://www.hakank.org/or-tools/pandigital_numbers.py * */ - private static void Solve(int bbase=10, int start=1, int len1=1, int len2=4) - { - + private static void Solve(int bbase = 10, int start = 1, int len1 = 1, + int len2 = 4) { Solver solver = new Solver("PandigitalNumbers"); // // Data // - int max_d = bbase-1; - int x_len = max_d + 1 - start; - int max_num = (int)Math.Pow(bbase,4)-1; + int max_d = bbase - 1; + int x_len = max_d + 1 - start; + int max_num = (int) Math.Pow(bbase, 4) - 1; // // Decision variables // IntVar num1 = solver.MakeIntVar(1, max_num, "num1"); IntVar num2 = solver.MakeIntVar(1, max_num, "num2"); - IntVar res = solver.MakeIntVar(1, max_num, "res"); + IntVar res = solver.MakeIntVar(1, max_num, "res"); IntVar[] x = solver.MakeIntVarArray(x_len, start, max_d, "x"); // for labeling - IntVar[] all = new IntVar[x_len+3]; - for(int i = 0; i < x_len; i++) { + IntVar[] all = new IntVar[x_len + 3]; + for (int i = 0; i < x_len; i++) { all[i] = x[i]; } - all[x_len] = num1; - all[x_len+1] = num2; - all[x_len+2] = res; + all[x_len] = num1; + all[x_len + 1] = num2; + all[x_len + 2] = res; // // Constraints // solver.Add(x.AllDifferent()); - solver.Add(ToNum(( from i in Enumerable.Range(0, len1) - select x[i]).ToArray(), - num1, - bbase)); + solver.Add( + ToNum((from i in Enumerable.Range(0, len1) select x[i]).ToArray(), num1, + bbase)); - solver.Add(ToNum(( from i in Enumerable.Range(len1, len2) - select x[i]).ToArray(), - num2, - bbase)); + solver.Add( + ToNum((from i in Enumerable.Range(len1, len2) select x[i]).ToArray(), + num2, bbase)); - solver.Add(ToNum(( from i in Enumerable.Range(len1+len2, x_len-(len1+len2)) - select x[i]).ToArray(), - res, - bbase)); + solver.Add(ToNum((from i in Enumerable.Range( + len1 + len2, x_len - (len1 + len2)) select x[i]) + .ToArray(), + res, bbase)); - - solver.Add(num1*num2 == res); + solver.Add(num1 * num2 == res); // no number must start with 0 solver.Add(x[0] > 0); solver.Add(x[len1] > 0); - solver.Add(x[len1+len2] > 0); + solver.Add(x[len1 + len2] > 0); // symmetry breaking solver.Add(num1 < num2); @@ -144,14 +135,14 @@ public class PandigitalNumbers // // Search // - DecisionBuilder db = solver.MakePhase(all, - Solver.INT_VAR_SIMPLE, - Solver.INT_VALUE_DEFAULT); + DecisionBuilder db = + solver.MakePhase(all, Solver.INT_VAR_SIMPLE, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { - Console.WriteLine("{0} * {1} = {2}", num1.Value(), num2.Value(), res.Value()); + Console.WriteLine("{0} * {1} = {2}", num1.Value(), num2.Value(), + res.Value()); } /* @@ -162,32 +153,27 @@ public class PandigitalNumbers */ solver.EndSearch(); - } - public static void Main(String[] args) - { + public static void Main(String[] args) { int bbase = 10; int start = 1; - if(args.Length > 0) { + if (args.Length > 0) { bbase = Convert.ToInt32(args[0]); } - if(args.Length > 1) { + if (args.Length > 1) { start = Convert.ToInt32(args[1]); } - int x_len = bbase - 1 + 1-start; - for(int len1 = 0; len1 <= x_len; len1++) { - for(int len2 = 0; len2 <= x_len; len2++) { - if (x_len > len1 + len2 - && len1 > 0 && len2 > 0 - ) { + int x_len = bbase - 1 + 1 - start; + for (int len1 = 0; len1 <= x_len; len1++) { + for (int len2 = 0; len2 <= x_len; len2++) { + if (x_len > len1 + len2 && len1 > 0 && len2 > 0) { Solve(bbase, start, len1, len2); } } } - } } diff --git a/examples/contrib/partition.cs b/examples/contrib/partition.cs index 3826c4ebe7..15b4849463 100644 --- a/examples/contrib/partition.cs +++ b/examples/contrib/partition.cs @@ -19,9 +19,7 @@ using System.IO; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; -public class Partition -{ - +public class Partition { /** * * This is a port of Charles Prud'homme's Java model @@ -34,23 +32,19 @@ public class Partition * """ * */ - private static void Solve(int m) - { - + private static void Solve(int m) { Solver solver = new Solver("Partition"); - // // Decision variables // IntVar[] x = solver.MakeIntVarArray(m, 1, 2 * m, "x"); IntVar[] y = solver.MakeIntVarArray(m, 1, 2 * m, "y"); - // // Constraints // - // break symmetries + // break symmetries for (int i = 0; i < m - 1; i++) { solver.Add(x[i] < x[i + 1]); solver.Add(y[i] < y[i + 1]); @@ -77,9 +71,13 @@ public class Partition sx = new IntVar[m]; sy = new IntVar[m]; for (int i = m - 1; i >= 0; i--) { - sx[i] = x[i].Square().Var(); + sx[i] = x [i] + .Square() + .Var(); sxy[i] = sx[i]; - sy[i] = y[i].Square().Var(); + sy[i] = y [i] + .Square() + .Var(); sxy[m + i] = sy[i]; } solver.Add(sxy.ScalProd(coeffs) == 0); @@ -98,12 +96,18 @@ public class Partition solver.NewSearch(db, log); while (solver.NextSolution()) { - for(int i = 0; i < m; i++) { - Console.Write("[" + xy[i].Value() + "] "); + for (int i = 0; i < m; i++) { + Console.Write("[" + + xy [i] + .Value() + + "] "); } Console.WriteLine(); - for(int i = 0; i < m; i++) { - Console.Write("[" + xy[m+i].Value() + "] "); + for (int i = 0; i < m; i++) { + Console.Write("[" + + xy [m + i] + .Value() + + "] "); } Console.WriteLine("\n"); } @@ -114,12 +118,9 @@ public class Partition Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - + public static void Main(String[] args) { int m = 32; if (args.Length > 0) { m = Convert.ToInt32(args[0]); diff --git a/examples/contrib/perfect_square_sequence.cs b/examples/contrib/perfect_square_sequence.cs index d51bc9a592..91544fec9e 100644 --- a/examples/contrib/perfect_square_sequence.cs +++ b/examples/contrib/perfect_square_sequence.cs @@ -19,10 +19,7 @@ using System.Collections.Generic; using System.Linq; using Google.OrTools.ConstraintSolver; - -public class PerfectSquareSequence -{ - +public class PerfectSquareSequence { /** * * Perfect square sequence. @@ -31,17 +28,18 @@ public class PerfectSquareSequence * "Sequence" * http://benvitale-funwithnum3ers.blogspot.com/2010/11/sequence.html * """ - * If we take the numbers from 1 to 15 - * (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) - * and rearrange them in such an order that any two consecutive + * If we take the numbers from 1 to 15 + * (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) + * and rearrange them in such an order that any two consecutive * numbers in the sequence add up to a perfect square, we get, - * - * 8 1 15 10 6 3 13 12 4 5 11 14 2 7 9 - * 9 16 25 16 9 16 25 16 9 16 25 16 9 16 * - * + * 8 1 15 10 6 3 13 12 4 5 11 14 2 + * 7 9 9 16 25 16 9 16 25 16 9 16 25 16 + * 9 16 + * + * * I ask the readers the following: - * + * * Can you take the numbers from 1 to 25 to produce such an arrangement? * How about the numbers from 1 to 100? * """ @@ -49,20 +47,19 @@ public class PerfectSquareSequence * Via http://wildaboutmath.com/2010/11/26/wild-about-math-bloggers-111910 * * - * Also see http://www.hakank.org/or-tools/perfect_square_sequence.py + * Also see http://www.hakank.org/or-tools/perfect_square_sequence.py * */ - private static int Solve(int n = 15, int print_solutions=1, int show_num_sols=0) - { - + private static int Solve(int n = 15, int print_solutions = 1, + int show_num_sols = 0) { Solver solver = new Solver("PerfectSquareSequence"); IEnumerable RANGE = Enumerable.Range(0, n); // create the table of possible squares - int[] squares = new int[n-1]; - for(int i = 1; i < n; i++) { - squares[i-1] = i*i; + int[] squares = new int[n - 1]; + for (int i = 1; i < n; i++) { + squares[i - 1] = i * i; } // @@ -70,26 +67,23 @@ public class PerfectSquareSequence // IntVar[] x = solver.MakeIntVarArray(n, 1, n, "x"); - // // Constraints // solver.Add(x.AllDifferent()); - for(int i = 1; i < n; i++) { - solver.Add((x[i-1]+x[i]).Member(squares)); + for (int i = 1; i < n; i++) { + solver.Add((x[i - 1] + x[i]).Member(squares)); } // symmetry breaking - solver.Add(x[0] < x[n-1]); - + solver.Add(x[0] < x[n - 1]); // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); @@ -99,8 +93,10 @@ public class PerfectSquareSequence num_solutions++; if (print_solutions > 0) { Console.Write("x: "); - foreach(int i in RANGE) { - Console.Write(x[i].Value() + " "); + foreach (int i in RANGE) { + Console.Write(x [i] + .Value() + + " "); } Console.WriteLine(); } @@ -114,28 +110,26 @@ public class PerfectSquareSequence Console.WriteLine("\nSolutions: {0}", solver.Solutions()); Console.WriteLine("WallTime: {0}ms", solver.WallTime()); Console.WriteLine("Failures: {0}", solver.Failures()); - Console.WriteLine("Branches: {0} ", solver.Branches()); + Console.WriteLine("Branches: {0} ", solver.Branches()); } solver.EndSearch(); return num_solutions; - } - public static void Main(String[] args) - { + public static void Main(String[] args) { int n = 15; if (args.Length > 0) { n = Convert.ToInt32(args[0]); } if (n == 0) { - for(int i = 2; i < 100; i++) { + for (int i = 2; i < 100; i++) { int num_solutions = Solve(i, 0, 0); Console.WriteLine("{0}: {1} solution(s)", i, num_solutions); } - + } else { int num_solutions = Solve(n); Console.WriteLine("{0}: {1} solution(s)", n, num_solutions); diff --git a/examples/contrib/photo_problem.cs b/examples/contrib/photo_problem.cs index 4137f6c32b..91b049842a 100644 --- a/examples/contrib/photo_problem.cs +++ b/examples/contrib/photo_problem.cs @@ -19,11 +19,7 @@ using System.Collections.Generic; using System.Linq; using Google.OrTools.ConstraintSolver; -public class PhotoProblem -{ - - - +public class PhotoProblem { /** * * Photo problem. @@ -45,35 +41,34 @@ public class PhotoProblem * """ * * Oz solution: - * 6 # alignment(betty:5 chris:6 donald:1 fred:3 gary:7 mary:4 paul:2) - * [5, 6, 1, 3, 7, 4, 2] + * 6 # alignment(betty:5 chris:6 donald:1 fred:3 gary:7 mary:4 + * paul:2) [5, 6, 1, 3, 7, 4, 2] * * * Also see http://www.hakank.org/or-tools/photo_problem.py * */ - private static void Solve(int show_all_max=0) - { - + private static void Solve(int show_all_max = 0) { Solver solver = new Solver("PhotoProblem"); // // Data // - String[] persons = {"Betty", "Chris", "Donald", "Fred", "Gary", "Mary", "Paul"}; + String[] persons = {"Betty", "Chris", "Donald", "Fred", + "Gary", "Mary", "Paul"}; int n = persons.Length; IEnumerable RANGE = Enumerable.Range(0, n); - int[,] preferences = { - // 0 1 2 3 4 5 6 - // B C D F G M P - { 0,0,0,0,1,1,0 }, // Betty 0 - { 1,0,0,0,1,0,0 }, // Chris 1 - { 0,0,0,0,0,0,0 }, // Donald 2 - { 0,0,1,0,0,1,0 }, // Fred 3 - { 0,0,0,0,0,0,0 }, // Gary 4 - { 0,0,0,0,0,0,0 }, // Mary 5 - { 0,0,1,1,0,0,0 } // Paul 6 + int[, ] preferences = { + // 0 1 2 3 4 5 6 + // B C D F G M P + {0, 0, 0, 0, 1, 1, 0}, // Betty 0 + {1, 0, 0, 0, 1, 0, 0}, // Chris 1 + {0, 0, 0, 0, 0, 0, 0}, // Donald 2 + {0, 0, 1, 0, 0, 1, 0}, // Fred 3 + {0, 0, 0, 0, 0, 0, 0}, // Gary 4 + {0, 0, 0, 0, 0, 0, 0}, // Mary 5 + {0, 0, 1, 1, 0, 0, 0} // Paul 6 }; Console.WriteLine("Preferences:"); @@ -82,13 +77,12 @@ public class PhotoProblem Console.WriteLine("3. Fred wants to stand next to Mary and Donald."); Console.WriteLine("4. Paul wants to stand next to Fred and Donald.\n"); - // // Decision variables // - IntVar[] positions = solver.MakeIntVarArray(n, 0, n-1, "positions"); + IntVar[] positions = solver.MakeIntVarArray(n, 0, n - 1, "positions"); // successful preferences (to Maximize) - IntVar z = solver.MakeIntVar(0, n*n, "z"); + IntVar z = solver.MakeIntVar(0, n * n, "z"); // // Constraints @@ -96,18 +90,16 @@ public class PhotoProblem solver.Add(positions.AllDifferent()); // calculate all the successful preferences - solver.Add( ( from i in RANGE - from j in RANGE - where preferences[i,j] == 1 - select (positions[i] - positions[j]).Abs() == 1 - ).ToArray().Sum() == z); + solver.Add((from i in RANGE from j in RANGE where preferences[i, j] == + 1 select(positions[i] - positions[j]).Abs() == 1) + .ToArray() + .Sum() == z); // // Symmetry breaking (from the Oz page): // Fred is somewhere left of Betty solver.Add(positions[3] < positions[0]); - // // Objective // @@ -118,13 +110,11 @@ public class PhotoProblem solver.Add(z == 6); } - // // Search // - DecisionBuilder db = solver.MakePhase(positions, - Solver.CHOOSE_FIRST_UNBOUND, - Solver.ASSIGN_MAX_VALUE); + DecisionBuilder db = solver.MakePhase( + positions, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MAX_VALUE); solver.NewSearch(db, obj); @@ -132,13 +122,14 @@ public class PhotoProblem Console.WriteLine("z: {0}", z.Value()); int[] p = new int[n]; Console.Write("p: "); - for(int i = 0; i < n; i++) { - p[i] = (int)positions[i].Value(); + for (int i = 0; i < n; i++) { + p[i] = (int) positions [i] + .Value(); Console.Write(p[i] + " "); } Console.WriteLine(); - for(int i = 0; i < n; i++) { - for(int j = 0; j < n; j++) { + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { if (p[j] == i) { Console.Write(persons[j] + " "); } @@ -146,10 +137,9 @@ public class PhotoProblem } Console.WriteLine(); Console.WriteLine("Successful preferences:"); - for(int i = 0; i < n; i++) { - for(int j = 0; j < n; j++) { - if (preferences[i,j] == 1 && - Math.Abs(p[i]-p[j])==1) { + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + if (preferences[i, j] == 1 && Math.Abs(p[i] - p[j]) == 1) { Console.WriteLine("\t{0} {1}", persons[i], persons[j]); } } @@ -163,11 +153,9 @@ public class PhotoProblem Console.WriteLine("Branches: " + solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { + public static void Main(String[] args) { int show_all_max = 0; if (args.Length > 0) { show_all_max = Convert.ToInt32(args[0]); diff --git a/examples/contrib/place_number_puzzle.cs b/examples/contrib/place_number_puzzle.cs index 624ac5f99b..98263ee29e 100644 --- a/examples/contrib/place_number_puzzle.cs +++ b/examples/contrib/place_number_puzzle.cs @@ -19,13 +19,12 @@ using System.Collections; using System.Collections.Generic; using Google.OrTools.ConstraintSolver; -public class PlaceNumberPuzzle -{ +public class PlaceNumberPuzzle { /** * * Place number puzzle. - * - * From + * + * From * http://ai.uwaterloo.ca/~vanbeek/Courses/Slides/introduction.pdf * """ * Place numbers 1 through 8 on nodes @@ -42,8 +41,7 @@ public class PlaceNumberPuzzle * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("PlaceNumberPuzzle"); // @@ -53,74 +51,43 @@ public class PlaceNumberPuzzle int n = 8; // Note: this is 1-based for compatibility (and lazyness) - int[,] graph = { - {1,2}, - {1,3}, - {1,4}, - {2,1}, - {2,3}, - {2,5}, - {2,6}, - {3,2}, - {3,4}, - {3,6}, - {3,7}, - {4,1}, - {4,3}, - {4,6}, - {4,7}, - {5,2}, - {5,3}, - {5,6}, - {5,8}, - {6,2}, - {6,3}, - {6,4}, - {6,5}, - {6,7}, - {6,8}, - {7,3}, - {7,4}, - {7,6}, - {7,8}, - {8,5}, - {8,6}, - {8,7} - }; - + int[, ] graph = {{1, 2}, {1, 3}, {1, 4}, {2, 1}, {2, 3}, {2, 5}, {2, 6}, + {3, 2}, {3, 4}, {3, 6}, {3, 7}, {4, 1}, {4, 3}, {4, 6}, + {4, 7}, {5, 2}, {5, 3}, {5, 6}, {5, 8}, {6, 2}, {6, 3}, + {6, 4}, {6, 5}, {6, 7}, {6, 8}, {7, 3}, {7, 4}, {7, 6}, + {7, 8}, {8, 5}, {8, 6}, {8, 7}}; // // Decision variables // IntVar[] x = solver.MakeIntVarArray(n, 1, n, "x"); - // // Constraints // solver.Add(x.AllDifferent()); - for(int i = 0; i < m; i++) { + for (int i = 0; i < m; i++) { // (also base 0-base) - solver.Add( (x[graph[i,0]-1]-x[graph[i,1]-1]).Abs() > 1); + solver.Add((x[graph[i, 0] - 1] - x[graph[i, 1] - 1]).Abs() > 1); } // symmetry breaking - solver.Add(x[0] < x[n-1]); - + solver.Add(x[0] < x[n - 1]); // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.INT_VAR_DEFAULT, - Solver.INT_VALUE_DEFAULT); + DecisionBuilder db = + solver.MakePhase(x, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { Console.Write("x: "); - for(int i = 0; i < n; i++) { - Console.Write(x[i].Value() + " "); + for (int i = 0; i < n; i++) { + Console.Write(x [i] + .Value() + + " "); } Console.WriteLine(); } @@ -131,11 +98,7 @@ public class PlaceNumberPuzzle Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/post_office_problem2.cs b/examples/contrib/post_office_problem2.cs index 2730ed60f5..d00a52539d 100644 --- a/examples/contrib/post_office_problem2.cs +++ b/examples/contrib/post_office_problem2.cs @@ -19,10 +19,7 @@ using System.Linq; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; - -public class PostOfficeProblem2 -{ - +public class PostOfficeProblem2 { /** * * Post office problem. @@ -58,9 +55,7 @@ public class PostOfficeProblem2 * Also see http://www.hakank.org/or-tools/post_office_problem2.py * */ - private static void Solve() - { - + private static void Solve() { Solver solver = new Solver("PostOfficeProblem2"); // @@ -77,7 +72,6 @@ public class PostOfficeProblem2 // Working sunday is 200 extra. int[] cost = {500, 600, 800, 800, 800, 800, 700}; - // // Decision variables // @@ -91,10 +85,12 @@ public class PostOfficeProblem2 // // Constraints // - for(int i = 0; i < n; i++) { - IntVar s = (from j in Enumerable.Range(0, n) - where j != (i+5) % n && j != (i+6) % n - select x[j]).ToArray().Sum().Var(); + for (int i = 0; i < n; i++) { + IntVar s = (from j in Enumerable.Range(0, n) where j != (i + 5) % n && + j != (i + 6) % n select x[j]) + .ToArray() + .Sum() + .Var(); solver.Add(s >= need[i]); } @@ -108,24 +104,22 @@ public class PostOfficeProblem2 // OptimizeVar obj = total_cost.Minimize(100); - - // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, + DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, Solver.ASSIGN_MIN_VALUE); - solver.NewSearch(db, obj); while (solver.NextSolution()) { Console.WriteLine("num_workers: {0}", num_workers.Value()); Console.WriteLine("total_cost: {0}", total_cost.Value()); Console.Write("x: "); - for(int i = 0; i < n; i++) { - Console.Write(x[i].Value() + " "); + for (int i = 0; i < n; i++) { + Console.Write(x [i] + .Value() + + " "); } Console.WriteLine("\n"); } @@ -136,13 +130,7 @@ public class PostOfficeProblem2 Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/quasigroup_completion.cs b/examples/contrib/quasigroup_completion.cs index 26846e6a93..c2fffa7de2 100644 --- a/examples/contrib/quasigroup_completion.cs +++ b/examples/contrib/quasigroup_completion.cs @@ -19,10 +19,7 @@ using System.IO; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; - -public class QuasigroupCompletion -{ - +public class QuasigroupCompletion { static int X = 0; /* @@ -37,19 +34,17 @@ public class QuasigroupCompletion * 4 1 3 2 5 * 5 4 1 3 2 * 3 2 5 4 1 - */ + */ static int default_n = 5; - static int[,] default_problem = {{1, X, X, X, 4}, - {X, 5, X, X, X}, - {4, X, X, 2, X}, - {X, 4, X, X, X}, - {X, X, 5, X, 1}}; - + static int[, ] default_problem = {{1, X, X, X, 4}, + {X, 5, X, X, X}, + {4, X, X, 2, X}, + {X, 4, X, X, X}, + {X, X, 5, X, 1}}; // for the actual problem static int n; - static int[,] problem; - + static int[, ] problem; /** * @@ -57,36 +52,34 @@ public class QuasigroupCompletion * See http://www.hakank.org/or-tools/quasigroup_completion.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("QuasigroupCompletion"); // // data // Console.WriteLine("Problem:"); - for(int i = 0; i < n; i++) { - for(int j = 0; j < n; j++) { - Console.Write(problem[i,j] + " "); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + Console.Write(problem[i, j] + " "); } Console.WriteLine(); } Console.WriteLine(); - // // Decision variables // - IntVar[,] x = solver.MakeIntVarMatrix(n, n, 1, n, "x"); + IntVar[, ] x = solver.MakeIntVarMatrix(n, n, 1, n, "x"); IntVar[] x_flat = x.Flatten(); // // Constraints - // - for(int i = 0; i < n; i++) { - for(int j = 0; j < n; j++) { - if (problem[i,j] > X) { - solver.Add(x[i,j] == problem[i,j]); + // + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + if (problem[i, j] > X) { + solver.Add(x[i, j] == problem[i, j]); } } } @@ -96,29 +89,27 @@ public class QuasigroupCompletion // // rows - for(int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { IntVar[] row = new IntVar[n]; - for(int j = 0; j < n; j++) { - row[j] = x[i,j]; + for (int j = 0; j < n; j++) { + row[j] = x[i, j]; } solver.Add(row.AllDifferent()); } // columns - for(int j = 0; j < n; j++) { + for (int j = 0; j < n; j++) { IntVar[] col = new IntVar[n]; - for(int i = 0; i < n; i++) { - col[i] = x[i,j]; + for (int i = 0; i < n; i++) { + col[i] = x[i, j]; } solver.Add(col.AllDifferent()); } - // // Search // - DecisionBuilder db = solver.MakePhase(x_flat, - Solver.INT_VAR_SIMPLE, + DecisionBuilder db = solver.MakePhase(x_flat, Solver.INT_VAR_SIMPLE, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); @@ -127,13 +118,14 @@ public class QuasigroupCompletion while (solver.NextSolution()) { sol++; Console.WriteLine("Solution #{0} ", sol + " "); - for(int i = 0; i < n; i++) { - for(int j = 0; j < n; j++){ - Console.Write("{0} ", x[i,j].Value()); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + Console.Write("{0} ", x [i, j] + .Value()); } Console.WriteLine(); } - + Console.WriteLine(); } @@ -143,10 +135,8 @@ public class QuasigroupCompletion Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - /** * * Reads a Quasigroup completion file. @@ -157,9 +147,9 @@ public class QuasigroupCompletion * < * row number of space separated entries * > - * + * * "." or "0" means unknown, integer 1..n means known value - * + * * Example * 5 * 1 . . . 4 @@ -170,29 +160,27 @@ public class QuasigroupCompletion * */ private static void readFile(String file) { - Console.WriteLine("readFile(" + file + ")"); int lineCount = 0; - + TextReader inr = new StreamReader(file); String str; while ((str = inr.ReadLine()) != null && str.Length > 0) { - str = str.Trim(); // ignore comments - if(str.StartsWith("#") || str.StartsWith("%")) { + if (str.StartsWith("#") || str.StartsWith("%")) { continue; } Console.WriteLine(str); if (lineCount == 0) { - n = Convert.ToInt32(str); // number of rows - problem = new int[n,n]; + n = Convert.ToInt32(str); // number of rows + problem = new int[n, n]; } else { // the problem matrix String[] row = Regex.Split(str, " "); - for(int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { String s = row[i]; if (s.Equals(".")) { problem[lineCount - 1, i] = 0; @@ -201,20 +189,16 @@ public class QuasigroupCompletion } } } - + lineCount++; - - } // end while - + + } // end while + inr.Close(); + } // end readFile - } // end readFile - - - - public static void Main(String[] args) - { + public static void Main(String[] args) { String file = ""; if (args.Length > 0) { file = args[0]; diff --git a/examples/contrib/regex.cs b/examples/contrib/regex.cs index d7cc0dc101..63307d964a 100644 --- a/examples/contrib/regex.cs +++ b/examples/contrib/regex.cs @@ -18,9 +18,7 @@ using System.Collections.Generic; using System.Linq; using Google.OrTools.ConstraintSolver; -public class RegexGeneration -{ - +public class RegexGeneration { /* * Global constraint regular * @@ -43,36 +41,31 @@ public class RegexGeneration * F : accepting states * */ - static void MyRegular(Solver solver, - IntVar[] x, - int Q, - int S, - int[,] d, - int q0, - int[] F) { - - - + static void MyRegular(Solver solver, IntVar[] x, int Q, int S, int[, ] d, + int q0, int[] F) { // d2 is the same as d, except we add one extra transition for // each possible input; each extra transition is from state zero // to state zero. This allows us to continue even if we hit a // non-accepted input. - int[][] d2 = new int[Q+1][]; - for(int i = 0; i <= Q; i++) { + int[][] d2 = new int [Q + 1] + []; + for (int i = 0; i <= Q; i++) { int[] row = new int[S]; - for(int j = 0; j < S; j++) { + for (int j = 0; j < S; j++) { if (i == 0) { row[j] = 0; } else { - row[j] = d[i-1,j]; + row[j] = d[i - 1, j]; } } d2[i] = row; } - int[] d2_flatten = (from i in Enumerable.Range(0, Q+1) - from j in Enumerable.Range(0, S) - select d2[i][j]).ToArray(); + int[] d2_flatten = + (from i in Enumerable.Range(0, Q + 1) from j in Enumerable.Range(0, S) + select d2 [i] + [j]) + .ToArray(); // If x has index set m..n, then a[m-1] holds the initial state // (q0), and a[i+1] holds the state we're in after processing @@ -81,23 +74,21 @@ public class RegexGeneration int m = 0; int n = x.Length; - IntVar[] a = solver.MakeIntVarArray(n+1-m, 0,Q+1, "a"); + IntVar[] a = solver.MakeIntVarArray(n + 1 - m, 0, Q + 1, "a"); // Check that the final state is in F - solver.Add(a[a.Length-1].Member(F)); + solver.Add(a [a.Length - 1] + .Member(F)); // First state is q0 solver.Add(a[m] == q0); - for(int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { solver.Add(x[i] >= 1); solver.Add(x[i] <= S); // Determine a[i+1]: a[i+1] == d2[a[i], x[i]] - solver.Add(a[i+1] == d2_flatten.Element(((a[i]*S)+(x[i]-1)))); + solver.Add(a[i + 1] == d2_flatten.Element(((a[i] * S) + (x[i] - 1)))); } - } - - /** * * Simple regular expression. @@ -113,8 +104,7 @@ public class RegexGeneration * Also see http://www.hakank.org/or-tools/regex.py * */ - private static void Solve(int n, List res) - { + private static void Solve(int n, List res) { Solver solver = new Solver("RegexGeneration"); Console.WriteLine("\nn: {0}", n); @@ -122,29 +112,29 @@ public class RegexGeneration // The DFS (for regular) int n_states = 11; int input_max = 12; - int initial_state = 1; // 0 is for the failing state + int initial_state = 1; // 0 is for the failing state int[] accepting_states = {12}; // The DFA - int [,] transition_fn = { - // 1 2 3 4 5 6 7 8 9 0 1 2 // - {0,2,3,0,0,0,0,0,0,0,0,0}, // 1 k - {0,0,0,4,0,0,0,0,0,0,0,0}, // 2 je - {0,0,0,4,0,0,0,0,0,0,0,0}, // 3 ä - {0,0,0,0,5,6,7,8,0,0,0,0}, // 4 ll - {0,0,0,0,0,0,7,8,0,0,0,0}, // 5 er - {0,0,0,0,0,0,7,8,0,0,0,0}, // 6 ar - {0,0,0,0,0,0,0,0,9,10,0,0}, // 7 st - {0,0,0,0,0,0,0,0,9,10,0,0}, // 8 b - {0,0,0,0,0,0,0,0,0,10,0,0}, // 9 r - {0,0,0,0,0,0,0,0,0,0,11,12}, // 10 a - {0,0,0,0,0,0,0,0,0,0,0,12}, // 11 n - // 12 d + int[, ] transition_fn = { + // 1 2 3 4 5 6 7 8 9 0 1 2 // + {0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // 1 k + {0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0}, // 2 je + {0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0}, // 3 ä + {0, 0, 0, 0, 5, 6, 7, 8, 0, 0, 0, 0}, // 4 ll + {0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 0, 0}, // 5 er + {0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 0, 0}, // 6 ar + {0, 0, 0, 0, 0, 0, 0, 0, 9, 10, 0, 0}, // 7 st + {0, 0, 0, 0, 0, 0, 0, 0, 9, 10, 0, 0}, // 8 b + {0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0}, // 9 r + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12}, // 10 a + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12}, // 11 n + // 12 d }; // Name of the states - String[] s = {"k","je","ä","ll","er","ar","st","b","r","a","n","d"}; - + String[] s = {"k", "je", "ä", "ll", "er", "ar", + "st", "b", "r", "a", "n", "d"}; // // Decision variables @@ -154,15 +144,13 @@ public class RegexGeneration // // Constraints // - MyRegular(solver, x, n_states, input_max, transition_fn, - initial_state, accepting_states); - + MyRegular(solver, x, n_states, input_max, transition_fn, initial_state, + accepting_states); // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); @@ -172,8 +160,11 @@ public class RegexGeneration // State 1 (the start state) is not included in the // state array (x) so we add it first. res2.Add(s[0]); - for(int i = 0; i < n; i++) { - res2.Add(s[x[i].Value()-1]); + for (int i = 0; i < n; i++) { + res2.Add(s [x [i] + .Value() - + 1] + ); } res.Add(String.Join("", res2.ToArray())); } @@ -183,19 +174,16 @@ public class RegexGeneration Console.WriteLine("Failures: {0}", solver.Failures()); Console.WriteLine("Branches: {0} ", solver.Branches()); - solver.EndSearch(); - } - public static void Main(String[] args) - { + public static void Main(String[] args) { List res = new List(); - for(int n = 4; n <= 9; n++) { + for (int n = 4; n <= 9; n++) { Solve(n, res); } Console.WriteLine("\nThe following {0} words where generated", res.Count); - foreach(string r in res) { + foreach (string r in res) { Console.WriteLine(r); } } diff --git a/examples/contrib/rogo2.cs b/examples/contrib/rogo2.cs index af48fc89e9..48be6e249b 100644 --- a/examples/contrib/rogo2.cs +++ b/examples/contrib/rogo2.cs @@ -21,9 +21,7 @@ using System.Linq; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; -public class Rogo2 -{ - +public class Rogo2 { static int W = 0; static int B = -1; @@ -39,58 +37,45 @@ public class Rogo2 static int default_cols = 9; static int default_max_steps = 12; static int default_best = 8; - static int[,] default_problem = { - {2,W,W,W,W,W,W,W,W}, - {W,3,W,W,1,W,W,2,W}, - {W,W,W,W,W,W,B,W,2}, - {W,W,2,B,W,W,W,W,W}, - {W,W,W,W,2,W,W,1,W} - }; + static int[, ] default_problem = {{2, W, W, W, W, W, W, W, W}, + {W, 3, W, W, 1, W, W, 2, W}, + {W, W, W, W, W, W, B, W, 2}, + {W, W, 2, B, W, W, W, W, W}, + {W, W, W, W, 2, W, W, 1, W}}; static String default_problem_name = "Problem Mike Trick"; - // The actual problem static int rows; static int cols; static int max_steps; static int best; - static int[,] problem; + static int[, ] problem; static string problem_name; - /** * * Build the table of valid connections of the grid. * */ - public static IntTupleSet ValidConnections(int rows, int cols) - { - + public static IntTupleSet ValidConnections(int rows, int cols) { IEnumerable ROWS = Enumerable.Range(0, rows); IEnumerable COLS = Enumerable.Range(0, cols); - var result_tmp = ( - from i1 in ROWS - from j1 in COLS - from i2 in ROWS - from j2 in COLS - where - (Math.Abs(j1-j2) == 1 && i1 == i2) || - (Math.Abs(i1-i2) == 1 && j1 % cols == j2 % cols) - select new int[] {i1*cols+j1, i2*cols+j2} - ).ToArray(); + var result_tmp = + (from i1 in ROWS from j1 in COLS from i2 in ROWS from j2 in COLS where( + Math.Abs(j1 - j2) == 1 && i1 == i2) || + (Math.Abs(i1 - i2) == 1 && j1 % cols == j2 % cols) + select new int[]{i1 * cols + j1, i2 * cols + j2}) + .ToArray(); // Convert to len x 2 matrix int len = result_tmp.Length; IntTupleSet result = new IntTupleSet(2); - foreach(int[] r in result_tmp) { + foreach (int[] r in result_tmp) { result.Insert(r); } return result; - } - - /** * * Rogo puzzle solver. @@ -118,12 +103,9 @@ AllowedAssignments) with the valid connections * - instead of two coordinates arrays, it use a single path array * */ - private static void Solve() - { - + private static void Solve() { Solver solver = new Solver("Rogo2"); - Console.WriteLine("\n"); Console.WriteLine("**********************************************"); Console.WriteLine(" {0}", problem_name); @@ -134,33 +116,34 @@ AllowedAssignments) with the valid connections // int B = -1; - Console.WriteLine("Rows: {0} Cols: {1} Max Steps: {2}", rows, cols, max_steps); + Console.WriteLine("Rows: {0} Cols: {1} Max Steps: {2}", rows, cols, + max_steps); int[] problem_flatten = problem.Cast().ToArray(); int max_point = problem_flatten.Max(); int max_sum = problem_flatten.Sum(); - Console.WriteLine("max_point: {0} max_sum: {1} best: {2}", max_point, max_sum, best); + Console.WriteLine("max_point: {0} max_sum: {1} best: {2}", max_point, + max_sum, best); IEnumerable STEPS = Enumerable.Range(0, max_steps); - IEnumerable STEPS1 = Enumerable.Range(0, max_steps-1); + IEnumerable STEPS1 = Enumerable.Range(0, max_steps - 1); // the valid connections, to be used with AllowedAssignments IntTupleSet valid_connections = ValidConnections(rows, cols); - // // Decision variables // - IntVar[] path = solver.MakeIntVarArray(max_steps, 0, rows*cols-1, "path"); + IntVar[] path = + solver.MakeIntVarArray(max_steps, 0, rows * cols - 1, "path"); IntVar[] points = solver.MakeIntVarArray(max_steps, 0, best, "points"); IntVar sum_points = points.Sum().VarWithName("sum_points"); - // // Constraints // - foreach(int s in STEPS) { + foreach (int s in STEPS) { // calculate the points (to maximize) solver.Add(points[s] == problem_flatten.Element(path[s])); @@ -171,34 +154,29 @@ AllowedAssignments) with the valid connections solver.Add(path.AllDifferent()); - // valid connections - foreach(int s in STEPS1) { - solver.Add(new IntVar[] {path[s], path[s+1]}. - AllowedAssignments(valid_connections)); + foreach (int s in STEPS1) { + solver.Add(new IntVar[]{path[s], path[s + 1]}.AllowedAssignments( + valid_connections)); } // around the corner - solver.Add(new IntVar[] {path[max_steps-1], path[0]}. - AllowedAssignments(valid_connections)); - + solver.Add(new IntVar[]{path[max_steps - 1], path[0]}.AllowedAssignments( + valid_connections)); // Symmetry breaking - for(int s = 1; s < max_steps; s++) { + for (int s = 1; s < max_steps; s++) { solver.Add(path[0] < path[s]); } - // // Objective // OptimizeVar obj = sum_points.Maximize(1); - // // Search // - DecisionBuilder db = solver.MakePhase(path, - Solver.INT_VAR_DEFAULT, + DecisionBuilder db = solver.MakePhase(path, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db, obj); @@ -206,31 +184,36 @@ AllowedAssignments) with the valid connections while (solver.NextSolution()) { Console.WriteLine("sum_points: {0}", sum_points.Value()); Console.Write("path: "); - foreach(int s in STEPS) { - Console.Write("{0} ", path[s].Value()); + foreach (int s in STEPS) { + Console.Write("{0} ", path [s] + .Value()); } Console.WriteLine(); Console.WriteLine("(Adding 1 to coords...)"); - int[,] sol = new int[rows, cols]; - foreach(int s in STEPS) { - int p = (int) path[s].Value(); - int x = (int) (p / cols); - int y = (int) (p % cols); - Console.WriteLine("{0,2},{1,2} ({2} points)", x+1, y+1, points[s].Value()); + int[, ] sol = new int[rows, cols]; + foreach (int s in STEPS) { + int p = (int) path [s] + .Value(); + int x = (int)(p / cols); + int y = (int)(p % cols); + Console.WriteLine("{0,2},{1,2} ({2} points)", x + 1, y + 1, + points [s] + .Value()); sol[x, y] = 1; } Console.WriteLine("\nThe path is marked by 'X's:"); - for(int i = 0; i < rows; i++) { - for(int j = 0; j < cols; j++) { - String p = sol[i,j] == 1 ? "X" : " "; - String q = problem[i,j] == B ? "B" : - problem[i,j] == 0 ? "." : problem[i,j].ToString(); + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + String p = sol[i, j] == 1 ? "X" : " "; + String q = problem[i, j] == B ? "B" : problem[i, j] == 0 + ? "." + : problem [i, j] + .ToString(); Console.Write("{0,2}{1} ", q, p); } Console.WriteLine(); } Console.WriteLine(); - } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); @@ -239,10 +222,8 @@ AllowedAssignments) with the valid connections Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - /** * * Reads a Rogo problem instance file. @@ -276,7 +257,6 @@ AllowedAssignments) with the valid connections */ private static void ReadFile(String file) { - Console.WriteLine("readFile(" + file + ")"); TextReader inr = new StreamReader(file); @@ -288,7 +268,7 @@ AllowedAssignments) with the valid connections Console.WriteLine(str); // ignore comments - if(str.StartsWith("#") || str.StartsWith("%")) { + if (str.StartsWith("#") || str.StartsWith("%")) { continue; } @@ -306,9 +286,8 @@ AllowedAssignments) with the valid connections best = Convert.ToInt32(str); } else { - String[] tmp = Regex.Split(str, "[,\\s]+"); - for(int j = 0; j < cols; j++) { + for (int j = 0; j < cols; j++) { int val = 0; if (tmp[j] == "B") { val = B; @@ -317,29 +296,24 @@ AllowedAssignments) with the valid connections } else { val = Convert.ToInt32(tmp[j]); } - problem[lineCount-4, j] = val; + problem[lineCount - 4, j] = val; } } lineCount++; - } // end while + } // end while inr.Close(); - } // end readFile + } // end readFile - - - - public static void Main(String[] args) - { - - rows = default_rows; - cols = default_cols; - max_steps = default_max_steps; - best = default_best; - problem = default_problem; + public static void Main(String[] args) { + rows = default_rows; + cols = default_cols; + max_steps = default_max_steps; + best = default_best; + problem = default_problem; problem_name = default_problem_name; String file = ""; @@ -351,6 +325,5 @@ AllowedAssignments) with the valid connections } Solve(); - } } diff --git a/examples/contrib/scheduling_speakers.cs b/examples/contrib/scheduling_speakers.cs index cb9afb7bc6..fef901a27e 100644 --- a/examples/contrib/scheduling_speakers.cs +++ b/examples/contrib/scheduling_speakers.cs @@ -20,10 +20,7 @@ using System.Linq; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; - -public class SchedulingSpeakers -{ - +public class SchedulingSpeakers { /** * * Scheduling speakers problem @@ -34,46 +31,42 @@ public class SchedulingSpeakers * See http://www.hakank.org/google_or_tools/scheduling_speakers.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("SchedulingSpeakers"); - // number of speakers int n = 6; // slots available to speak int[][] available = { - // Reasoning: - new int[] {3,4,5,6}, // 2) the only one with 6 after speaker F -> 1 - new int[] {3,4}, // 5) 3 or 4 - new int[] {2,3,4,5}, // 3) only with 5 after F -> 1 and A -> 6 - new int[] {2,3,4}, // 4) only with 2 after C -> 5 and F -> 1 - new int[] {3,4}, // 5) 3 or 4 - new int[] {1,2,3,4,5,6} // 1) the only with 1 + // Reasoning: + new int[]{3, 4, 5, 6}, // 2) the only one with 6 after speaker F -> 1 + new int[]{3, 4}, // 5) 3 or 4 + new int[]{2, 3, 4, 5}, // 3) only with 5 after F -> 1 and A -> 6 + new int[]{2, 3, 4}, // 4) only with 2 after C -> 5 and F -> 1 + new int[]{3, 4}, // 5) 3 or 4 + new int[]{1, 2, 3, 4, 5, 6} // 1) the only with 1 }; - // // Decision variables // - IntVar[] x = solver.MakeIntVarArray(n, 1, n, "x"); + IntVar[] x = solver.MakeIntVarArray(n, 1, n, "x"); // // Constraints // solver.Add(x.AllDifferent()); - for(int i = 0; i < n; i++) { - solver.Add(x[i].Member(available[i])); + for (int i = 0; i < n; i++) { + solver.Add(x [i] + .Member(available[i])); } - // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); @@ -88,12 +81,7 @@ public class SchedulingSpeakers Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/secret_santa.cs b/examples/contrib/secret_santa.cs index 417789d186..145114c9c3 100644 --- a/examples/contrib/secret_santa.cs +++ b/examples/contrib/secret_santa.cs @@ -19,10 +19,7 @@ using System.Collections.Generic; using System.Linq; using Google.OrTools.ConstraintSolver; - -public class SecretSanta -{ - +public class SecretSanta { /** * * Secret Santa problem in Google CP Solver. @@ -48,25 +45,23 @@ public class SecretSanta * * Your script will be fed a list of names on STDIN. * ... * Your script should then choose a Secret Santa for every name in the list. - * Obviously, a person cannot be their own Secret Santa. In addition, my friends - * no longer allow people in the same family to be Santas for each other and your - * script should take this into account. + * Obviously, a person cannot be their own Secret Santa. In addition, my + * friends no longer allow people in the same family to be Santas for each + * other and your script should take this into account. * """ * * Comment: This model skips the file input and mail parts. We * assume that the friends are identified with a number from 1..n, * and the families is identified with a number 1..num_families. * - * Also see http://www.hakank.org/or-tools/secret_santa.py - * Also see http://www.hakank.org/or-tools/secret_santa2.cs + * Also see http://www.hakank.org/or-tools/secret_santa.py + * Also see http://www.hakank.org/or-tools/secret_santa2.cs * */ - private static void Solve() - { - + private static void Solve() { Solver solver = new Solver("SecretSanta"); - int[] family = {1,1,1,1, 2, 3,3,3,3,3, 4,4}; + int[] family = {1, 1, 1, 1, 2, 3, 3, 3, 3, 3, 4, 4}; int n = family.Length; Console.WriteLine("n = {0}", n); @@ -76,8 +71,7 @@ public class SecretSanta // // Decision variables // - IntVar[] x = solver.MakeIntVarArray(n, 0, n-1, "x"); - + IntVar[] x = solver.MakeIntVarArray(n, 0, n - 1, "x"); // // Constraints @@ -86,29 +80,29 @@ public class SecretSanta // Can't be one own"s Secret Santa // (i.e. ensure that there are no fix-point in the array.) - foreach(int i in RANGE) { + foreach (int i in RANGE) { solver.Add(x[i] != i); } - // No Secret Santa to a person in the same family - foreach(int i in RANGE) { + foreach (int i in RANGE) { solver.Add(solver.MakeIntConst(family[i]) != family.Element(x[i])); } // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.INT_VAR_SIMPLE, - Solver.INT_VALUE_SIMPLE); + DecisionBuilder db = + solver.MakePhase(x, Solver.INT_VAR_SIMPLE, Solver.INT_VALUE_SIMPLE); solver.NewSearch(db); while (solver.NextSolution()) { Console.Write("x: "); - foreach(int i in RANGE) { - Console.Write(x[i].Value() + " "); + foreach (int i in RANGE) { + Console.Write(x [i] + .Value() + + " "); } Console.WriteLine(); } @@ -119,11 +113,7 @@ public class SecretSanta Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/secret_santa2.cs b/examples/contrib/secret_santa2.cs index 9467c995b5..a774f1718c 100644 --- a/examples/contrib/secret_santa2.cs +++ b/examples/contrib/secret_santa2.cs @@ -19,10 +19,7 @@ using System.Collections.Generic; using System.Linq; using Google.OrTools.ConstraintSolver; - -public class SecretSanta2 -{ - +public class SecretSanta2 { /** * * Secret Santa problem II in Google CP Solver. @@ -64,12 +61,10 @@ public class SecretSanta2 * problem don't mention. * * - * Also see http://www.hakank.org/or-tools/secret_santa2.py + * Also see http://www.hakank.org/or-tools/secret_santa2.py * */ - private static void Solve(int single=0) - { - + private static void Solve(int single = 0) { Solver solver = new Solver("SecretSanta2"); Console.WriteLine("\nSingle: {0}", single); @@ -85,15 +80,15 @@ public class SecretSanta2 int n_no_single = 8; int M = n_no_single + 1; int[][] rounds_no_single = { - // N A R M El J L Ev - new int[] {0, M, 3, M, 1, 4, M, 2}, // Noah - new int[] {M, 0, 4, 2, M, 3, M, 1}, // Ava - new int[] {M, 2, 0, M, 1, M, 3, 4}, // Ryan - new int[] {M, 1, M, 0, 2, M, 3, 4}, // Mia - new int[] {M, 4, M, 3, 0, M, 1, 2}, // Ella - new int[] {1, 4, 3, M, M, 0, 2, M}, // John - new int[] {M, 3, M, 2, 4, 1, 0, M}, // Lily - new int[] {4, M, 3, 1, M, 2, M, 0} // Evan + // N A R M El J L Ev + new int[]{0, M, 3, M, 1, 4, M, 2}, // Noah + new int[]{M, 0, 4, 2, M, 3, M, 1}, // Ava + new int[]{M, 2, 0, M, 1, M, 3, 4}, // Ryan + new int[]{M, 1, M, 0, 2, M, 3, 4}, // Mia + new int[]{M, 4, M, 3, 0, M, 1, 2}, // Ella + new int[]{1, 4, 3, M, M, 0, 2, M}, // John + new int[]{M, 3, M, 2, 4, 1, 0, M}, // Lily + new int[]{4, M, 3, 1, M, 2, M, 0} // Evan }; // @@ -103,26 +98,25 @@ public class SecretSanta2 M = n_with_single + 1; int[][] rounds_single = { // N A R M El J L Ev S - new int[] {0, M, 3, M, 1, 4, M, 2, 2}, // Noah - new int[] {M, 0, 4, 2, M, 3, M, 1, 1}, // Ava - new int[] {M, 2, 0, M, 1, M, 3, 4, 4}, // Ryan - new int[] {M, 1, M, 0, 2, M, 3, 4, 3}, // Mia - new int[] {M, 4, M, 3, 0, M, 1, 2, M}, // Ella - new int[] {1, 4, 3, M, M, 0, 2, M, M}, // John - new int[] {M, 3, M, 2, 4, 1, 0, M, M}, // Lily - new int[] {4, M, 3, 1, M, 2, M, 0, M}, // Evan - new int[] {1, 2, 3, 4, M, 2, M, M, 0} // Single + new int[]{0, M, 3, M, 1, 4, M, 2, 2}, // Noah + new int[]{M, 0, 4, 2, M, 3, M, 1, 1}, // Ava + new int[]{M, 2, 0, M, 1, M, 3, 4, 4}, // Ryan + new int[]{M, 1, M, 0, 2, M, 3, 4, 3}, // Mia + new int[]{M, 4, M, 3, 0, M, 1, 2, M}, // Ella + new int[]{1, 4, 3, M, M, 0, 2, M, M}, // John + new int[]{M, 3, M, 2, 4, 1, 0, M, M}, // Lily + new int[]{4, M, 3, 1, M, 2, M, 0, M}, // Evan + new int[]{1, 2, 3, 4, M, 2, M, M, 0} // Single }; - - int Noah = 0; - int Ava = 1; - int Ryan = 2; - int Mia = 3; - int Ella = 4; - int John = 5; - int Lily = 6; - int Evan = 7; + int Noah = 0; + int Ava = 1; + int Ryan = 2; + int Mia = 3; + int Ella = 4; + int John = 5; + int Lily = 6; + int Evan = 7; int n = n_no_single; @@ -135,34 +129,30 @@ public class SecretSanta2 IEnumerable RANGE = Enumerable.Range(0, n); - - - String[] persons = {"Noah", "Ava", "Ryan", "Mia", "Ella", - "John", "Lily", "Evan", "Single"}; + String[] persons = {"Noah", "Ava", "Ryan", "Mia", "Ella", + "John", "Lily", "Evan", "Single"}; int[] spouses = { - Ava, // Noah - Noah, // Ava - Mia, // Rya - Ryan, // Mia - John, // Ella - Ella, // John - Evan, // Lily - Lily, // Evan - -1 // Single has no spouse + Ava, // Noah + Noah, // Ava + Mia, // Rya + Ryan, // Mia + John, // Ella + Ella, // John + Evan, // Lily + Lily, // Evan + -1 // Single has no spouse }; - // // Decision variables // - IntVar[] santas = solver.MakeIntVarArray(n, 0, n-1, "santas"); + IntVar[] santas = solver.MakeIntVarArray(n, 0, n - 1, "santas"); IntVar[] santa_distance = solver.MakeIntVarArray(n, 0, M, "santa_distance"); // total of "distance", to maximize IntVar z = santa_distance.Sum().VarWithName("z"); - // // Constraints // @@ -170,62 +160,63 @@ public class SecretSanta2 // Can't be one own"s Secret Santa // (i.e. ensure that there are no fix-point in the array.) - foreach(int i in RANGE) { + foreach (int i in RANGE) { solver.Add(santas[i] != i); } - // no Santa for a spouses - foreach(int i in RANGE) { + foreach (int i in RANGE) { if (spouses[i] > -1) { solver.Add(santas[i] != spouses[i]); } } // optimize "distance" to earlier rounds: - foreach(int i in RANGE) { - solver.Add(santa_distance[i] == rounds[i].Element(santas[i])); + foreach (int i in RANGE) { + solver.Add(santa_distance[i] == rounds [i] + .Element(santas[i])); } - // cannot be a Secret Santa for the same person // two years in a row. - foreach(int i in RANGE) { - foreach(int j in RANGE) { - if (rounds[i][j] == 1) { + foreach (int i in RANGE) { + foreach (int j in RANGE) { + if (rounds [i] + [j] == 1) { solver.Add(santas[i] != j); } } } - // // Objective (minimize the distances) // OptimizeVar obj = z.Maximize(1); - // // Search // - DecisionBuilder db = solver.MakePhase(santas, - Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, - Solver.ASSIGN_CENTER_VALUE); + DecisionBuilder db = solver.MakePhase( + santas, Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, Solver.ASSIGN_CENTER_VALUE); solver.NewSearch(db, obj); while (solver.NextSolution()) { Console.WriteLine("\ntotal distances: {0}", z.Value()); Console.Write("santas: "); - for(int i = 0; i < n; i++) { - Console.Write(santas[i].Value() + " "); + for (int i = 0; i < n; i++) { + Console.Write(santas [i] + .Value() + + " "); } Console.WriteLine(); - foreach(int i in RANGE) { - Console.WriteLine("{0}\tis a Santa to {1} (distance {2})", - persons[i], - persons[santas[i].Value()], - santa_distance[i].Value()); + foreach (int i in RANGE) { + Console.WriteLine("{0}\tis a Santa to {1} (distance {2})", persons[i], + persons [santas [i] + .Value()] + , + santa_distance [i] + .Value()); } } @@ -235,11 +226,9 @@ public class SecretSanta2 Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { + public static void Main(String[] args) { int single = 0; Solve(single); single = 1; diff --git a/examples/contrib/send_more_money.cs b/examples/contrib/send_more_money.cs index e047ddb703..ff2599a2c7 100644 --- a/examples/contrib/send_more_money.cs +++ b/examples/contrib/send_more_money.cs @@ -16,15 +16,13 @@ using System; using Google.OrTools.ConstraintSolver; -public class SendMoreMoney -{ +public class SendMoreMoney { /** * * Solve the SEND+MORE=MONEY problem * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("SendMoreMoney"); // @@ -40,14 +38,15 @@ public class SendMoreMoney IntVar Y = solver.MakeIntVar(0, 9, "Y"); // for AllDifferent() - IntVar[] x = new IntVar[] {S,E,N,D,M,O,R,Y}; + IntVar[] x = new IntVar[]{S, E, N, D, M, O, R, Y}; // // Constraints // solver.Add(x.AllDifferent()); - solver.Add(S*1000 + E*100 + N*10 + D + M*1000 + O*100 + R*10 + E == - M*10000 + O*1000 + N*100 + E*10 + Y); + solver.Add(S * 1000 + E * 100 + N * 10 + D + M * 1000 + O * 100 + R * 10 + + E == + M * 10000 + O * 1000 + N * 100 + E * 10 + Y); solver.Add(S > 0); solver.Add(M > 0); @@ -55,14 +54,15 @@ public class SendMoreMoney // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); while (solver.NextSolution()) { - for(int i = 0; i < 8; i++) { - Console.Write(x[i].ToString() + " "); + for (int i = 0; i < 8; i++) { + Console.Write(x [i] + .ToString() + + " "); } Console.WriteLine(); } @@ -72,11 +72,7 @@ public class SendMoreMoney Console.WriteLine("Branches: " + solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/send_more_money2.cs b/examples/contrib/send_more_money2.cs index 2141d5ce94..59685925e6 100644 --- a/examples/contrib/send_more_money2.cs +++ b/examples/contrib/send_more_money2.cs @@ -16,16 +16,14 @@ using System; using Google.OrTools.ConstraintSolver; -public class SendMoreMoney -{ +public class SendMoreMoney { /** * * Solve the SEND+MORE=MONEY problem * using scalar product. * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("SendMoreMoney"); // @@ -41,7 +39,7 @@ public class SendMoreMoney IntVar Y = solver.MakeIntVar(0, 9, "Y"); // for AllDifferent() - IntVar[] x = new IntVar[] {S,E,N,D,M,O,R,Y}; + IntVar[] x = new IntVar[]{S, E, N, D, M, O, R, Y}; // // Constraints @@ -54,11 +52,11 @@ public class SendMoreMoney */ // Here we use scalar product instead. - int[] s1 = new int[] {1000,100,10,1}; - int[] s2 = new int[] {10000,1000,100,10,1}; - solver.Add(new IntVar[] {S,E,N,D}.ScalProd(s1) + - new IntVar[] {M,O,R,E}.ScalProd(s1) == - new IntVar[] {M,O,N,E,Y}.ScalProd(s2)); + int[] s1 = new int[]{1000, 100, 10, 1}; + int[] s2 = new int[]{10000, 1000, 100, 10, 1}; + solver.Add(new IntVar[]{S, E, N, D}.ScalProd(s1) + + new IntVar[]{M, O, R, E}.ScalProd(s1) == + new IntVar[]{M, O, N, E, Y}.ScalProd(s2)); solver.Add(S > 0); solver.Add(M > 0); @@ -66,14 +64,15 @@ public class SendMoreMoney // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); while (solver.NextSolution()) { - for(int i = 0; i < 8; i++) { - Console.Write(x[i].Value() + " "); + for (int i = 0; i < 8; i++) { + Console.Write(x [i] + .Value() + + " "); } Console.WriteLine(); } @@ -84,11 +83,7 @@ public class SendMoreMoney Console.WriteLine("Branches: {0}", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/send_most_money.cs b/examples/contrib/send_most_money.cs index 1fdf31edc2..5fcec23708 100644 --- a/examples/contrib/send_most_money.cs +++ b/examples/contrib/send_most_money.cs @@ -16,8 +16,7 @@ using System; using Google.OrTools.ConstraintSolver; -public class SendMostMoney -{ +public class SendMostMoney { /** * * Solve the SEND+MOST=MONEY problem @@ -25,9 +24,7 @@ public class SendMostMoney * See http://www.hakank.org/google_or_tools/send_most_money.py * */ - private static long Solve(long MONEY) - { - + private static long Solve(long MONEY) { Solver solver = new Solver("SendMostMoney"); // @@ -43,19 +40,22 @@ public class SendMostMoney IntVar Y = solver.MakeIntVar(0, 9, "Y"); // for AllDifferent() - IntVar[] x = new IntVar[] {S,E,N,D,M,O,T,Y}; + IntVar[] x = new IntVar[]{S, E, N, D, M, O, T, Y}; - IntVar[] eq = {S,E,N,D, M,O,S,T, M,O,N,E,Y}; - int[] coeffs = { 1000, 100, 10, 1, // S E N D + - 1000, 100, 10, 1, // M O S T - -10000,-1000, -100,-10,-1 // == M O N E Y - }; + IntVar[] eq = {S, E, N, D, M, O, S, T, M, O, N, E, Y}; + int[] coeffs = { + 1000, 100, 10, 1, // S E N D + + 1000, 100, 10, 1, // M O S T + -10000, -1000, -100, -10, -1 // == M O N E Y + }; solver.Add(eq.ScalProd(coeffs) == 0); // IntVar money = solver.MakeScalProd(new IntVar[] {M, O, N, E, Y}, - // new int[] {10000, 1000, 100, 10, 1}).Var(); - IntVar money = (new IntVar[] {M, O, N, E, Y}). - ScalProd(new int[] {10000, 1000, 100, 10, 1}).Var(); + // new int[] {10000, 1000, 100, 10, + // 1}).Var(); + IntVar money = (new IntVar[]{M, O, N, E, Y}) + .ScalProd(new int[]{10000, 1000, 100, 10, 1}) + .Var(); // // Constraints @@ -71,8 +71,7 @@ public class SendMostMoney // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); if (MONEY == 0) { @@ -85,9 +84,11 @@ public class SendMostMoney long money_ret = 0; while (solver.NextSolution()) { money_ret = money.Value(); - Console.WriteLine("money: {0}", money.Value() ); - for(int i = 0; i < x.Length; i++) { - Console.Write(x[i].Value() + " "); + Console.WriteLine("money: {0}", money.Value()); + for (int i = 0; i < x.Length; i++) { + Console.Write(x [i] + .Value() + + " "); } Console.WriteLine(); } @@ -100,14 +101,13 @@ public class SendMostMoney solver.EndSearch(); return money_ret; - } - public static void Main(String[] args) - { + public static void Main(String[] args) { Console.WriteLine("First get the max value of money:"); long this_money = Solve(0); - Console.WriteLine("\nThen we find all solutions for MONEY = {0}:", this_money); + Console.WriteLine("\nThen we find all solutions for MONEY = {0}:", + this_money); long tmp = Solve(this_money); } } diff --git a/examples/contrib/seseman.cs b/examples/contrib/seseman.cs index 51e0413434..2e5e268f75 100644 --- a/examples/contrib/seseman.cs +++ b/examples/contrib/seseman.cs @@ -16,18 +16,14 @@ using System; using Google.OrTools.ConstraintSolver; - -public class Seseman -{ - +public class Seseman { /** * * Solves the Seseman convent problem. * See http://www.hakank.org/google_or_tools/seseman.py * */ - private static void Solve(int n = 3) - { + private static void Solve(int n = 3) { Solver solver = new Solver("Seseman"); // @@ -38,27 +34,26 @@ public class Seseman // // Decision variables // - IntVar[,] x = solver.MakeIntVarMatrix(n, n, 0, n*n, "x"); + IntVar[, ] x = solver.MakeIntVarMatrix(n, n, 0, n * n, "x"); IntVar[] x_flat = x.Flatten(); IntVar total_sum = x_flat.Sum().Var(); - // // Constraints - // + // // zero in all middle cells - for(int i = 1; i < n-1; i++) { - for(int j = 1; j < n-1; j++) { - solver.Add(x[i,j] == 0); + for (int i = 1; i < n - 1; i++) { + for (int j = 1; j < n - 1; j++) { + solver.Add(x[i, j] == 0); } } // all borders must be >= 1 - for(int i = 0; i < n; i++) { - for(int j = 0; j < n; j++) { + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { if (i == 0 || j == 0 || i == n - 1 || j == n - 1) { - solver.Add(x[i,j] >= 1); + solver.Add(x[i, j] >= 1); } } } @@ -68,35 +63,34 @@ public class Seseman IntVar[] border2 = new IntVar[n]; IntVar[] border3 = new IntVar[n]; IntVar[] border4 = new IntVar[n]; - for(int i = 0; i < n; i++) { - border1[i] = x[i,0]; - border2[i] = x[i,n-1]; - border3[i] = x[0,i]; - border4[i] = x[n-1,i]; + for (int i = 0; i < n; i++) { + border1[i] = x[i, 0]; + border2[i] = x[i, n - 1]; + border3[i] = x[0, i]; + border4[i] = x[n - 1, i]; } solver.Add(border1.Sum() == border_sum); solver.Add(border2.Sum() == border_sum); solver.Add(border3.Sum() == border_sum); solver.Add(border4.Sum() == border_sum); - // // Search // - DecisionBuilder db = solver.MakePhase(x_flat, - Solver.CHOOSE_PATH, - Solver.ASSIGN_MIN_VALUE); + DecisionBuilder db = + solver.MakePhase(x_flat, Solver.CHOOSE_PATH, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); while (solver.NextSolution()) { Console.WriteLine("total_sum: {0} ", total_sum.Value()); - for(int i = 0; i < n; i++) { - for(int j = 0; j < n; j++){ - Console.Write("{0} ", x[i,j].Value()); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + Console.Write("{0} ", x [i, j] + .Value()); } Console.WriteLine(); } - + Console.WriteLine(); } @@ -106,11 +100,9 @@ public class Seseman Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { + public static void Main(String[] args) { int n = 3; if (args.Length > 0) { diff --git a/examples/contrib/set_covering.cs b/examples/contrib/set_covering.cs index 3c2de49f9d..3c034878fa 100644 --- a/examples/contrib/set_covering.cs +++ b/examples/contrib/set_covering.cs @@ -20,18 +20,14 @@ using System.Linq; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; -public class SetCovering -{ - +public class SetCovering { /** * * Solves a set covering problem. * See See http://www.hakank.org/or-tools/set_covering.py * */ - private static void Solve() - { - + private static void Solve() { Solver solver = new Solver("SetCovering"); // @@ -43,12 +39,9 @@ public class SetCovering int min_distance = 15; int num_cities = 6; - int[,] distance = {{ 0,10,20,30,30,20}, - {10, 0,25,35,20,10}, - {20,25, 0,15,30,20}, - {30,35,15, 0,15,25}, - {30,20,30,15, 0,14}, - {20,10,20,25,14, 0}}; + int[, ] distance = {{0, 10, 20, 30, 30, 20}, {10, 0, 25, 35, 20, 10}, + {20, 25, 0, 15, 30, 20}, {30, 35, 15, 0, 15, 25}, + {30, 20, 30, 15, 0, 14}, {20, 10, 20, 25, 14, 0}}; // // Decision variables @@ -61,34 +54,33 @@ public class SetCovering // // ensure that all cities are covered - for(int i = 0; i < num_cities; i++) { + for (int i = 0; i < num_cities; i++) { IntVar[] b = (from j in Enumerable.Range(0, num_cities) - where distance[i,j] <= min_distance - select x[j]).ToArray(); + where distance[i, j] <= min_distance select x[j]) + .ToArray(); solver.Add(b.Sum() >= 1); - } - // + // // objective // OptimizeVar objective = z.Minimize(1); - // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.INT_VAR_DEFAULT, - Solver.INT_VALUE_DEFAULT); + DecisionBuilder db = + solver.MakePhase(x, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db, objective); while (solver.NextSolution()) { Console.WriteLine("z: {0}", z.Value()); Console.Write("x: "); - for(int i = 0; i < num_cities; i++) { - Console.Write(x[i].Value() + " "); + for (int i = 0; i < num_cities; i++) { + Console.Write(x [i] + .Value() + + " "); } Console.WriteLine(); } @@ -99,11 +91,7 @@ public class SetCovering Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/set_covering2.cs b/examples/contrib/set_covering2.cs index 8899c046ac..d2c92d7c2d 100644 --- a/examples/contrib/set_covering2.cs +++ b/examples/contrib/set_covering2.cs @@ -19,18 +19,14 @@ using System.IO; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; -public class SetCovering2 -{ - +public class SetCovering2 { /** * * Solves a set covering problem. * See See http://www.hakank.org/or-tools/set_covering2.py * */ - private static void Solve() - { - + private static void Solve() { Solver solver = new Solver("SetCovering2"); // @@ -43,22 +39,13 @@ public class SetCovering2 // Minimize the number of security telephones in street // corners on a campus. - int n = 8; // maximum number of corners - int num_streets = 11; // number of connected streets + int n = 8; // maximum number of corners + int num_streets = 11; // number of connected streets // corners of each street // Note: 1-based (handled below) - int[,] corner = {{1,2}, - {2,3}, - {4,5}, - {7,8}, - {6,7}, - {2,6}, - {1,6}, - {4,7}, - {2,4}, - {5,8}, - {3,5}}; + int[, ] corner = {{1, 2}, {2, 3}, {4, 5}, {7, 8}, {6, 7}, {2, 6}, + {1, 6}, {4, 7}, {2, 4}, {5, 8}, {3, 5}}; // // Decision variables @@ -72,8 +59,8 @@ public class SetCovering2 // // ensure that all streets are covered - for(int i = 0; i < num_streets; i++) { - solver.Add(x[corner[i,0] - 1] + x[corner[i,1] - 1] >= 1); + for (int i = 0; i < num_streets; i++) { + solver.Add(x[corner[i, 0] - 1] + x[corner[i, 1] - 1] >= 1); } // @@ -84,17 +71,18 @@ public class SetCovering2 // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.INT_VAR_DEFAULT, - Solver.INT_VALUE_DEFAULT); + DecisionBuilder db = + solver.MakePhase(x, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db, objective); while (solver.NextSolution()) { Console.WriteLine("z: {0}", z.Value()); Console.Write("x: "); - for(int i = 0; i < n; i++) { - Console.Write(x[i].Value() + " "); + for (int i = 0; i < n; i++) { + Console.Write(x [i] + .Value() + + " "); } Console.WriteLine(); } @@ -105,11 +93,7 @@ public class SetCovering2 Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/set_covering3.cs b/examples/contrib/set_covering3.cs index 012a496c8d..c4c30f166f 100644 --- a/examples/contrib/set_covering3.cs +++ b/examples/contrib/set_covering3.cs @@ -19,18 +19,14 @@ using System.IO; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; -public class SetCovering3 -{ - +public class SetCovering3 { /** * * Solves a set covering problem. * See See http://www.hakank.org/or-tools/set_covering3.py * */ - private static void Solve() - { - + private static void Solve() { Solver solver = new Solver("SetCovering3"); // @@ -45,14 +41,13 @@ public class SetCovering3 int num_senators = 10; // which group does a senator belong to? - int[,] belongs = {{1, 1, 1, 1, 1, 0, 0, 0, 0, 0}, // 1 southern + int[, ] belongs = {{1, 1, 1, 1, 1, 0, 0, 0, 0, 0}, // 1 southern {0, 0, 0, 0, 0, 1, 1, 1, 1, 1}, // 2 northern {0, 1, 1, 0, 0, 0, 0, 1, 1, 1}, // 3 liberals {1, 0, 0, 0, 1, 1, 1, 0, 0, 0}, // 4 conservative {0, 0, 1, 1, 1, 1, 1, 0, 1, 0}, // 5 democrats {1, 1, 0, 0, 0, 0, 0, 1, 0, 1}}; // 6 republicans - // // Decision variables // @@ -66,53 +61,50 @@ public class SetCovering3 // ensure that each group is covered by at least // one senator - for(int i = 0; i < num_groups; i++) { + for (int i = 0; i < num_groups; i++) { IntVar[] b = new IntVar[num_senators]; - for(int j = 0; j < num_senators; j++) { - b[j] = (x[j]*belongs[i,j]).Var(); + for (int j = 0; j < num_senators; j++) { + b[j] = (x[j] * belongs[i, j]).Var(); } solver.Add(b.Sum() >= 1); } - // // objective // OptimizeVar objective = z.Minimize(1); - // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.INT_VAR_DEFAULT, - Solver.INT_VALUE_DEFAULT); + DecisionBuilder db = + solver.MakePhase(x, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db, objective); while (solver.NextSolution()) { Console.WriteLine("z: " + z.Value()); Console.Write("x: "); - for(int j = 0; j < num_senators; j++) { - Console.Write(x[j].Value() + " "); + for (int j = 0; j < num_senators; j++) { + Console.Write(x [j] + .Value() + + " "); } Console.WriteLine(); // More details - for(int j = 0; j < num_senators; j++) { - if (x[j].Value() == 1) { - Console.Write("Senator " + (1 + j) + - " belongs to these groups: "); - for(int i = 0; i < num_groups; i++) { - if (belongs[i,j] == 1) { + for (int j = 0; j < num_senators; j++) { + if (x [j] + .Value() == 1) { + Console.Write("Senator " + (1 + j) + " belongs to these groups: "); + for (int i = 0; i < num_groups; i++) { + if (belongs[i, j] == 1) { Console.Write((1 + i) + " "); } } Console.WriteLine(); } - } - } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); @@ -121,11 +113,7 @@ public class SetCovering3 Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/set_covering4.cs b/examples/contrib/set_covering4.cs index 1fcc4435f9..067449f96b 100644 --- a/examples/contrib/set_covering4.cs +++ b/examples/contrib/set_covering4.cs @@ -19,18 +19,14 @@ using System.IO; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; -public class SetCovering4 -{ - +public class SetCovering4 { /** * * Solves a set covering problem. * See See http://www.hakank.org/or-tools/set_covering4.py * */ - private static void Solve(int set_partition) - { - + private static void Solve(int set_partition) { Solver solver = new Solver("SetCovering4"); // @@ -49,18 +45,17 @@ public class SetCovering4 int[] costs = {19, 16, 18, 13, 15, 19, 15, 17, 16, 15}; // the alternatives, and their objects - int[,] a = { - // 1 2 3 4 5 6 7 8 the objects - {1,0,0,0,0,1,0,0}, // alternative 1 - {0,1,0,0,0,1,0,1}, // alternative 2 - {1,0,0,1,0,0,1,0}, // alternative 3 - {0,1,1,0,1,0,0,0}, // alternative 4 - {0,1,0,0,1,0,0,0}, // alternative 5 - {0,1,1,0,0,0,0,0}, // alternative 6 - {0,1,1,1,0,0,0,0}, // alternative 7 - {0,0,0,1,1,0,0,1}, // alternative 8 - {0,0,1,0,0,1,0,1}, // alternative 9 - {1,0,0,0,0,1,1,0}}; // alternative 10 + int[, ] a = { // 1 2 3 4 5 6 7 8 the objects + {1, 0, 0, 0, 0, 1, 0, 0}, // alternative 1 + {0, 1, 0, 0, 0, 1, 0, 1}, // alternative 2 + {1, 0, 0, 1, 0, 0, 1, 0}, // alternative 3 + {0, 1, 1, 0, 1, 0, 0, 0}, // alternative 4 + {0, 1, 0, 0, 1, 0, 0, 0}, // alternative 5 + {0, 1, 1, 0, 0, 0, 0, 0}, // alternative 6 + {0, 1, 1, 1, 0, 0, 0, 0}, // alternative 7 + {0, 0, 0, 1, 1, 0, 0, 1}, // alternative 8 + {0, 0, 1, 0, 0, 1, 0, 1}, // alternative 9 + {1, 0, 0, 0, 0, 1, 1, 0}}; // alternative 10 // // Decision variables @@ -73,11 +68,10 @@ public class SetCovering4 // Constraints // - - for(int j = 0; j < num_objects; j++) { + for (int j = 0; j < num_objects; j++) { IntVar[] b = new IntVar[num_alternatives]; - for(int i = 0; i < num_alternatives; i++) { - b[i] = (x[i] * a[i,j]).Var(); + for (int i = 0; i < num_alternatives; i++) { + b[i] = (x[i] * a[i, j]).Var(); } if (set_partition == 1) { @@ -87,32 +81,29 @@ public class SetCovering4 } } - // // objective // OptimizeVar objective = z.Minimize(1); - // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.INT_VAR_DEFAULT, - Solver.INT_VALUE_DEFAULT); + DecisionBuilder db = + solver.MakePhase(x, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db, objective); while (solver.NextSolution()) { Console.WriteLine("z: " + z.Value()); Console.Write("Selected alternatives: "); - for(int i = 0; i < num_alternatives; i++) { - if (x[i].Value() == 1) { - Console.Write((i+1) + " "); + for (int i = 0; i < num_alternatives; i++) { + if (x [i] + .Value() == 1) { + Console.Write((i + 1) + " "); } } Console.WriteLine("\n"); - } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); @@ -121,11 +112,9 @@ public class SetCovering4 Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { + public static void Main(String[] args) { Console.WriteLine("Set partition:"); Solve(1); Console.WriteLine("\nSet covering:"); diff --git a/examples/contrib/set_covering_deployment.cs b/examples/contrib/set_covering_deployment.cs index 3135fb402a..19605cde79 100644 --- a/examples/contrib/set_covering_deployment.cs +++ b/examples/contrib/set_covering_deployment.cs @@ -20,18 +20,14 @@ using System.Linq; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; -public class SetCoveringDeployment -{ - +public class SetCoveringDeployment { /** * * Solves a set covering deployment problem. * See See http://www.hakank.org/or-tools/set_covering_deployment.py * */ - private static void Solve() - { - + private static void Solve() { Solver solver = new Solver("SetCoveringDeployment"); // @@ -39,26 +35,16 @@ public class SetCoveringDeployment // // From http://mathworld.wolfram.com/SetCoveringDeployment.html - string[] countries = {"Alexandria", - "Asia Minor", - "Britain", - "Byzantium", - "Gaul", - "Iberia", - "Rome", - "Tunis"}; + string[] countries = {"Alexandria", "Asia Minor", "Britain", "Byzantium", + "Gaul", "Iberia", "Rome", "Tunis"}; int n = countries.Length; // the incidence matrix (neighbours) - int[,] mat = {{0, 1, 0, 1, 0, 0, 1, 1}, - {1, 0, 0, 1, 0, 0, 0, 0}, - {0, 0, 0, 0, 1, 1, 0, 0}, - {1, 1, 0, 0, 0, 0, 1, 0}, - {0, 0, 1, 0, 0, 1, 1, 0}, - {0, 0, 1, 0, 1, 0, 1, 1}, - {1, 0, 0, 1, 1, 1, 0, 1}, - {1, 0, 0, 0, 0, 1, 1, 0}}; + int[, ] mat = {{0, 1, 0, 1, 0, 0, 1, 1}, {1, 0, 0, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 0, 0}, {1, 1, 0, 0, 0, 0, 1, 0}, + {0, 0, 1, 0, 0, 1, 1, 0}, {0, 0, 1, 0, 1, 0, 1, 1}, + {1, 0, 0, 1, 1, 1, 0, 1}, {1, 0, 0, 0, 0, 1, 1, 0}}; // // Decision variables @@ -73,7 +59,6 @@ public class SetCoveringDeployment // total number of armies IntVar num_armies = (x.Sum() + y.Sum()).Var(); - // // Constraints // @@ -84,7 +69,7 @@ public class SetCoveringDeployment // Or rather: Is there a backup, there // must be an an army // - for(int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { solver.Add(x[i] >= y[i]); } @@ -92,45 +77,41 @@ public class SetCoveringDeployment // Constraint 2: There should always be an backup // army near every city // - for(int i = 0; i < n; i++) { - IntVar[] count_neighbours = ( - from j in Enumerable.Range(0, n) - where mat[i,j] == 1 - select(y[j])).ToArray(); + for (int i = 0; i < n; i++) { + IntVar[] count_neighbours = + (from j in Enumerable.Range(0, n) where mat[i, j] == 1 select(y[j])) + .ToArray(); solver.Add((x[i] + count_neighbours.Sum()) >= 1); - } - // // objective // OptimizeVar objective = num_armies.Minimize(1); - // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.INT_VAR_DEFAULT, - Solver.INT_VALUE_DEFAULT); + DecisionBuilder db = + solver.MakePhase(x, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db, objective); while (solver.NextSolution()) { Console.WriteLine("num_armies: " + num_armies.Value()); - for(int i = 0; i < n; i++) { - if (x[i].Value() == 1) { + for (int i = 0; i < n; i++) { + if (x [i] + .Value() == 1) { Console.Write("Army: " + countries[i] + " "); } - if (y[i].Value() == 1) { + if (y [i] + .Value() == 1) { Console.WriteLine(" Reverse army: " + countries[i]); } } Console.WriteLine("\n"); - } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); @@ -139,11 +120,7 @@ public class SetCoveringDeployment Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/set_covering_skiena.cs b/examples/contrib/set_covering_skiena.cs index 5446e00349..dcbe2ea978 100644 --- a/examples/contrib/set_covering_skiena.cs +++ b/examples/contrib/set_covering_skiena.cs @@ -18,8 +18,7 @@ using System.Collections.Generic; using System.Linq; using Google.OrTools.ConstraintSolver; -public class SetCoveringSkiena -{ +public class SetCoveringSkiena { /** * * Set covering. @@ -39,9 +38,7 @@ public class SetCoveringSkiena * Also see http://www.hakank.org/or-tools/set_covering_skiena.py * */ - private static void Solve() - { - + private static void Solve() { Solver solver = new Solver("SetCoveringSkiena"); int num_sets = 7; @@ -50,18 +47,16 @@ public class SetCoveringSkiena IEnumerable Elements = Enumerable.Range(0, num_elements); // Which element belongs to which set - int[,] belongs = - { + int[, ] belongs = { // 1 2 3 4 5 6 7 8 9 0 1 2 elements - {1,1,0,0,0,0,0,0,0,0,0,0}, // Set 1 - {0,1,0,0,0,0,0,1,0,0,0,0}, // 2 - {0,0,0,0,1,1,0,0,0,0,0,0}, // 3 - {0,0,0,0,0,1,1,0,0,1,1,0}, // 4 - {0,0,0,0,0,0,0,0,1,1,0,0}, // 5 - {1,1,1,0,1,0,0,0,1,1,1,0}, // 6 - {0,0,1,1,0,0,1,1,0,0,1,1} // 7 - }; - + {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Set 1 + {0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}, // 2 + {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0}, // 3 + {0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0}, // 4 + {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0}, // 5 + {1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0}, // 6 + {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1} // 7 + }; // // Decision variables @@ -69,22 +64,23 @@ public class SetCoveringSkiena IntVar[] x = solver.MakeIntVarArray(num_sets, 0, 1, "x"); IntVar z = x.Sum().VarWithName("z"); // total number of elements in the choosen sets - IntVar tot_elements = solver.MakeIntVar(0, num_sets*num_elements, "tot_elements"); - + IntVar tot_elements = + solver.MakeIntVar(0, num_sets * num_elements, "tot_elements"); // // Constraints // // all sets must be used - foreach(int j in Elements) { - solver.Add( (from i in Sets select belongs[i,j] * x[i]) - .ToArray().Sum() >= 1); + foreach (int j in Elements) { + solver.Add((from i in Sets select belongs[i, j] * x[i]).ToArray().Sum() >= + 1); } // number of used elements - solver.Add((from i in Sets from j in Elements select x[i] * belongs[i,j]) - .ToArray().Sum() == tot_elements); + solver.Add((from i in Sets from j in Elements select x[i] * belongs[i, j]) + .ToArray() + .Sum() == tot_elements); // // Objective @@ -94,20 +90,20 @@ public class SetCoveringSkiena // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.INT_VAR_DEFAULT, - Solver.INT_VALUE_DEFAULT); + DecisionBuilder db = + solver.MakePhase(x, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db, obj); while (solver.NextSolution()) { Console.WriteLine("z: {0}", z.Value()); Console.WriteLine("tot_elements: {0}", tot_elements.Value()); - Console.WriteLine( - "x: {0}", - String.Join(" ", (from i in Enumerable.Range(0, num_sets) - select x[i].Value().ToString()).ToArray())); - + Console.WriteLine("x: {0}", + String.Join(" ", (from i in Enumerable + .Range(0, num_sets) select x [i] + .Value() + .ToString()) + .ToArray())); } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); @@ -116,11 +112,7 @@ public class SetCoveringSkiena Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/set_partition.cs b/examples/contrib/set_partition.cs index e7900f3f1c..9d4c6f2b00 100644 --- a/examples/contrib/set_partition.cs +++ b/examples/contrib/set_partition.cs @@ -19,36 +19,32 @@ using System.Linq; using System.Diagnostics; using Google.OrTools.ConstraintSolver; -public class SetPartition -{ - - - // - // Partition the sets (binary matrix representation). - // - public static void partition_sets(Solver solver, - IntVar[,] x, int num_sets, int n) - { - - for(int i = 0; i Sets = Enumerable.Range(0, num_sets); IEnumerable NRange = Enumerable.Range(0, n); - // // Decision variables // - IntVar[,] a = solver.MakeIntVarMatrix(num_sets, n, 0, 1, "a"); + IntVar[, ] a = solver.MakeIntVarMatrix(num_sets, n, 0, 1, "a"); IntVar[] a_flat = a.Flatten(); - // // Constraints // @@ -100,75 +92,70 @@ public class SetPartition // partition set partition_sets(solver, a, num_sets, n); - foreach(int i in Sets) { - foreach(int j in Sets) { - + foreach (int i in Sets) { + foreach (int j in Sets) { // same cardinality - solver.Add( - (from k in NRange select a[i,k]).ToArray().Sum() - == - (from k in NRange select a[j,k]).ToArray().Sum()); + solver.Add((from k in NRange select a[i, k]).ToArray().Sum() == + (from k in NRange select a[j, k]).ToArray().Sum()); // same sum - solver.Add( - (from k in NRange select (k*a[i,k])).ToArray().Sum() - == - (from k in NRange select (k*a[j,k])).ToArray().Sum()); - + solver.Add((from k in NRange select(k * a[i, k])).ToArray().Sum() == + (from k in NRange select(k * a[j, k])).ToArray().Sum()); // same sum squared - solver.Add( - (from k in NRange select (k*a[i,k]*k*a[i,k])).ToArray().Sum() - == - (from k in NRange select (k*a[j,k]*k*a[j,k])).ToArray().Sum()); + solver.Add((from k in NRange select(k * a[i, k] * k * a[i, k])) + .ToArray() + .Sum() == + (from k in NRange select(k * a[j, k] * k * a[j, k])) + .ToArray() + .Sum()); } } - // symmetry breaking for num_sets == 2 if (num_sets == 2) { - solver.Add(a[0,0] == 1); + solver.Add(a[0, 0] == 1); } // // Search // - DecisionBuilder db = solver.MakePhase(a_flat, - Solver.INT_VAR_DEFAULT, + DecisionBuilder db = solver.MakePhase(a_flat, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { - - int[,] a_val = new int[num_sets, n]; - foreach(int i in Sets) { - foreach(int j in NRange) { - a_val[i,j] = (int)a[i,j].Value(); + int[, ] a_val = new int[num_sets, n]; + foreach (int i in Sets) { + foreach (int j in NRange) { + a_val[i, j] = (int) a [i, j] + .Value(); } } - Console.WriteLine("sums: {0}", - (from j in NRange - select (j+1)*a_val[0,j]).ToArray().Sum()); + Console.WriteLine( + "sums: {0}", + (from j in NRange select(j + 1) * a_val[0, j]).ToArray().Sum()); - Console.WriteLine("sums squared: {0}", - (from j in NRange - select (int)Math.Pow((j+1)*a_val[0,j],2)).ToArray().Sum()); + Console.WriteLine( + "sums squared: {0}", + (from j in NRange select(int) Math.Pow((j + 1) * a_val[0, j], 2)) + .ToArray() + .Sum()); // Show the numbers in each set - foreach(int i in Sets) { - if ( (from j in NRange select a_val[i,j]).ToArray().Sum() > 0 ) { - Console.Write(i+1 + ": "); - foreach(int j in NRange) { - if (a_val[i,j] == 1) { - Console.Write((j+1) + " "); + foreach (int i in Sets) { + if ((from j in NRange select a_val[i, j]).ToArray().Sum() > 0) { + Console.Write(i + 1 + ": "); + foreach (int j in NRange) { + if (a_val[i, j] == 1) { + Console.Write((j + 1) + " "); } } Console.WriteLine(); } } Console.WriteLine(); - } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); @@ -177,11 +164,9 @@ public class SetPartition Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { + public static void Main(String[] args) { int n = 16; int num_sets = 2; @@ -194,11 +179,10 @@ public class SetPartition } if (n % num_sets == 0) { - Solve(n, num_sets); } else { - Console.WriteLine("n {0} num_sets {1}: Equal sets is not possible!", - n, num_sets); + Console.WriteLine("n {0} num_sets {1}: Equal sets is not possible!", n, + num_sets); } } } diff --git a/examples/contrib/sicherman_dice.cs b/examples/contrib/sicherman_dice.cs index d0cc8e573e..4a67c53b12 100644 --- a/examples/contrib/sicherman_dice.cs +++ b/examples/contrib/sicherman_dice.cs @@ -19,8 +19,7 @@ using System.Collections.Generic; using System.Linq; using Google.OrTools.ConstraintSolver; -public class SichermanDice -{ +public class SichermanDice { /** * * Sicherman Dice. @@ -64,8 +63,7 @@ public class SichermanDice * Also see http://www.hakank.org/or-tools/sicherman_dice.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("SichermanDice"); // @@ -76,12 +74,10 @@ public class SichermanDice int lowest_value = 0; // standard distribution - int[] standard_dist = {1,2,3,4,5,6,5,4,3,2,1}; - + int[] standard_dist = {1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1}; IEnumerable RANGE = Enumerable.Range(0, n); - IEnumerable RANGE1 = Enumerable.Range(0, n-1); - + IEnumerable RANGE1 = Enumerable.Range(0, n - 1); // // Decision variables @@ -93,38 +89,40 @@ public class SichermanDice // // Constraints // - for(int k = 0; k < standard_dist.Length; k++) { - solver.Add((from i in RANGE - from j in RANGE - select x1[i] + x2[j] == k + 2 - ).ToArray().Sum() == standard_dist[k]); + for (int k = 0; k < standard_dist.Length; k++) { + solver.Add((from i in RANGE from j in RANGE select x1[i] + x2[j] == k + 2) + .ToArray() + .Sum() == standard_dist[k]); } // symmetry breaking - foreach(int i in RANGE1) { - solver.Add(x1[i] <= x1[i+1]); - solver.Add(x2[i] <= x2[i+1]); + foreach (int i in RANGE1) { + solver.Add(x1[i] <= x1[i + 1]); + solver.Add(x2[i] <= x2[i + 1]); solver.Add(x1[i] <= x2[i]); } - // // Search // - DecisionBuilder db = solver.MakePhase(x1.Concat(x2).ToArray(), - Solver.INT_VAR_DEFAULT, - Solver.INT_VALUE_DEFAULT); + DecisionBuilder db = + solver.MakePhase(x1.Concat(x2).ToArray(), Solver.INT_VAR_DEFAULT, + Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { Console.Write("x1: "); - foreach(int i in RANGE) { - Console.Write(x1[i].Value() + " "); + foreach (int i in RANGE) { + Console.Write(x1 [i] + .Value() + + " "); } Console.Write("\nx2: "); - foreach(int i in RANGE) { - Console.Write(x2[i].Value() + " "); + foreach (int i in RANGE) { + Console.Write(x2 [i] + .Value() + + " "); } Console.WriteLine("\n"); } @@ -135,11 +133,7 @@ public class SichermanDice Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/ski_assignment.cs b/examples/contrib/ski_assignment.cs index e3b520e5b6..d8e50c0721 100644 --- a/examples/contrib/ski_assignment.cs +++ b/examples/contrib/ski_assignment.cs @@ -19,8 +19,7 @@ using System.Collections; using System.Collections.Generic; using Google.OrTools.ConstraintSolver; -public class SkiAssignment -{ +public class SkiAssignment { /** * * Ski assignment in Google CP Solver. @@ -50,8 +49,7 @@ public class SkiAssignment * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("SkiAssignment"); // @@ -65,8 +63,7 @@ public class SkiAssignment // // Decision variables // - IntVar[] x = solver.MakeIntVarArray(num_skiers, 0, num_skis-1, "x"); - + IntVar[] x = solver.MakeIntVarArray(num_skiers, 0, num_skis - 1, "x"); // // Constraints @@ -74,7 +71,7 @@ public class SkiAssignment solver.Add(x.AllDifferent()); IntVar[] z_tmp = new IntVar[num_skiers]; - for(int i = 0; i < num_skiers; i++) { + for (int i = 0; i < num_skiers; i++) { z_tmp[i] = (ski_heights.Element(x[i]) - skier_heights[i]).Abs().Var(); } @@ -92,16 +89,17 @@ public class SkiAssignment // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db, obj); while (solver.NextSolution()) { Console.Write("z: {0} x: ", z.Value()); - for(int i = 0; i < num_skiers; i++) { - Console.Write(x[i].Value() + " "); + for (int i = 0; i < num_skiers; i++) { + Console.Write(x [i] + .Value() + + " "); } Console.WriteLine(); } @@ -112,11 +110,7 @@ public class SkiAssignment Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/stable_marriage.cs b/examples/contrib/stable_marriage.cs index 9a20b10a52..e1513a59a9 100644 --- a/examples/contrib/stable_marriage.cs +++ b/examples/contrib/stable_marriage.cs @@ -19,18 +19,14 @@ using System.IO; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; -public class StableMarriage -{ - +public class StableMarriage { /** * * Solves some stable marriage problems. * See http://www.hakank.org/or-tools/stable_marriage.py * */ - private static void Solve(int[][][] ranks, String problem_name) - { - + private static void Solve(int[][][] ranks, String problem_name) { Solver solver = new Solver("StableMarriage"); // @@ -42,7 +38,7 @@ public class StableMarriage Console.WriteLine("Problem: " + problem_name); int[][] rankWomen = ranks[0]; - int[][] rankMen = ranks[1]; + int[][] rankMen = ranks[1]; // // Decision variables @@ -58,57 +54,66 @@ public class StableMarriage // // forall(m in Men) // cp.post(husband[wife[m]] == m); - for(int m = 0; m < n; m++) { + for (int m = 0; m < n; m++) { solver.Add(husband.Element(wife[m]) == m); } // forall(w in Women) // cp.post(wife[husband[w]] == w); - for(int w = 0; w < n; w++) { + for (int w = 0; w < n; w++) { solver.Add(wife.Element(husband[w]) == w); } - // forall(m in Men, o in Women) // cp.post(rankMen[m,o] < rankMen[m, wife[m]] => // rankWomen[o,husband[o]] < rankWomen[o,m]); - for(int m = 0; m < n; m++) { - for(int o = 0; o < n; o++) { - IntVar b1 = rankMen[m].Element(wife[m]) > rankMen[m][o]; - IntVar b2 = rankWomen[o].Element(husband[o]) < rankWomen[o][m]; + for (int m = 0; m < n; m++) { + for (int o = 0; o < n; o++) { + IntVar b1 = rankMen [m] + .Element(wife[m]) > rankMen [m] + [o]; + IntVar b2 = rankWomen [o] + .Element(husband[o]) < rankWomen [o] + [m]; solver.Add(b1 <= b2); } - } // forall(w in Women, o in Men) // cp.post(rankWomen[w,o] < rankWomen[w,husband[w]] => // rankMen[o,wife[o]] < rankMen[o,w]); - for(int w = 0; w < n; w++) { - for(int o = 0; o < n; o++) { - IntVar b1 = rankWomen[w].Element(husband[w]) > rankWomen[w][o]; - IntVar b2 = rankMen[o].Element(wife[o]) < rankMen[o][w]; + for (int w = 0; w < n; w++) { + for (int o = 0; o < n; o++) { + IntVar b1 = rankWomen [w] + .Element(husband[w]) > rankWomen [w] + [o]; + IntVar b2 = rankMen [o] + .Element(wife[o]) < rankMen [o] + [w]; solver.Add(b1 <= b2); - } } + } // // Search // - DecisionBuilder db = solver.MakePhase(wife, - Solver.INT_VAR_DEFAULT, + DecisionBuilder db = solver.MakePhase(wife, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { Console.Write("wife : "); - for(int i = 0; i < n; i++) { - Console.Write(wife[i].Value() + " "); + for (int i = 0; i < n; i++) { + Console.Write(wife [i] + .Value() + + " "); } Console.Write("\nhusband: "); - for(int i = 0; i < n; i++) { - Console.Write(husband[i].Value() + " "); + for (int i = 0; i < n; i++) { + Console.Write(husband [i] + .Value() + + " "); } Console.WriteLine("\n"); } @@ -119,84 +124,61 @@ public class StableMarriage Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - - public static void Main(String[] args) - { + public static void Main(String[] args) { // // From Pascal Van Hentenryck's OPL book // int[][][] van_hentenryck = { - // rankWomen - new int[][] { - new int[] {1, 2, 4, 3, 5}, - new int[] {3, 5, 1, 2, 4}, - new int[] {5, 4, 2, 1, 3}, - new int[] {1, 3, 5, 4, 2}, - new int[] {4, 2, 3, 5, 1}}, + // rankWomen + new int[][]{new int[]{1, 2, 4, 3, 5}, new int[]{3, 5, 1, 2, 4}, + new int[]{5, 4, 2, 1, 3}, new int[]{1, 3, 5, 4, 2}, + new int[]{4, 2, 3, 5, 1}}, - // rankMen - new int[][] { - new int[] {5, 1, 2, 4, 3}, - new int[] {4, 1, 3, 2, 5}, - new int[] {5, 3, 2, 4, 1}, - new int[] {1, 5, 4, 3, 2}, - new int[] {4, 3, 2, 1, 5}} - }; + // rankMen + new int[][]{new int[]{5, 1, 2, 4, 3}, new int[]{4, 1, 3, 2, 5}, + new int[]{5, 3, 2, 4, 1}, new int[]{1, 5, 4, 3, 2}, + new int[]{4, 3, 2, 1, 5}}}; // // Data from MathWorld // http://mathworld.wolfram.com/StableMarriageProblem.html // - int[][][] mathworld = { - // rankWomen - new int[][] { - new int[] {3, 1, 5, 2, 8, 7, 6, 9, 4}, - new int[] {9, 4, 8, 1, 7, 6, 3, 2, 5}, - new int[] {3, 1, 8, 9, 5, 4, 2, 6, 7}, - new int[] {8, 7, 5, 3, 2, 6, 4, 9, 1}, - new int[] {6, 9, 2, 5, 1, 4, 7, 3, 8}, - new int[] {2, 4, 5, 1, 6, 8, 3, 9, 7}, - new int[] {9, 3, 8, 2, 7, 5, 4, 6, 1}, - new int[] {6, 3, 2, 1, 8, 4, 5, 9, 7}, - new int[] {8, 2, 6, 4, 9, 1, 3, 7, 5}}, + int[][][] mathworld = {// rankWomen + new int[][]{new int[]{3, 1, 5, 2, 8, 7, 6, 9, 4}, + new int[]{9, 4, 8, 1, 7, 6, 3, 2, 5}, + new int[]{3, 1, 8, 9, 5, 4, 2, 6, 7}, + new int[]{8, 7, 5, 3, 2, 6, 4, 9, 1}, + new int[]{6, 9, 2, 5, 1, 4, 7, 3, 8}, + new int[]{2, 4, 5, 1, 6, 8, 3, 9, 7}, + new int[]{9, 3, 8, 2, 7, 5, 4, 6, 1}, + new int[]{6, 3, 2, 1, 8, 4, 5, 9, 7}, + new int[]{8, 2, 6, 4, 9, 1, 3, 7, 5}}, - // rankMen - new int[][] { - new int[] {7, 3, 8, 9, 6, 4, 2, 1, 5}, - new int[] {5, 4, 8, 3, 1, 2, 6, 7, 9}, - new int[] {4, 8, 3, 9, 7, 5, 6, 1, 2}, - new int[] {9, 7, 4, 2, 5, 8, 3, 1, 6}, - new int[] {2, 6, 4, 9, 8, 7, 5, 1, 3}, - new int[] {2, 7, 8, 6, 5, 3, 4, 1, 9}, - new int[] {1, 6, 2, 3, 8, 5, 4, 9, 7}, - new int[] {5, 6, 9, 1, 2, 8, 4, 3, 7}, - new int[] {6, 1, 4, 7, 5, 8, 3, 9, 2}} - }; + // rankMen + new int[][]{new int[]{7, 3, 8, 9, 6, 4, 2, 1, 5}, + new int[]{5, 4, 8, 3, 1, 2, 6, 7, 9}, + new int[]{4, 8, 3, 9, 7, 5, 6, 1, 2}, + new int[]{9, 7, 4, 2, 5, 8, 3, 1, 6}, + new int[]{2, 6, 4, 9, 8, 7, 5, 1, 3}, + new int[]{2, 7, 8, 6, 5, 3, 4, 1, 9}, + new int[]{1, 6, 2, 3, 8, 5, 4, 9, 7}, + new int[]{5, 6, 9, 1, 2, 8, 4, 3, 7}, + new int[]{6, 1, 4, 7, 5, 8, 3, 9, 2}}}; // // Data from // http://www.csee.wvu.edu/~ksmani/courses/fa01/random/lecnotes/lecture5.pdf // int[][][] problem3 = { - // rankWomen - new int[][] { - new int[] {1,2,3,4}, - new int[] {4,3,2,1}, - new int[] {1,2,3,4}, - new int[] {3,4,1,2}}, - - // rankMen - new int[][] { - new int[] {1,2,3,4}, - new int[] {2,1,3,4}, - new int[] {1,4,3,2}, - new int[] {4,3,1,2}} - }; + // rankWomen + new int[][]{new int[]{1, 2, 3, 4}, new int[]{4, 3, 2, 1}, + new int[]{1, 2, 3, 4}, new int[]{3, 4, 1, 2}}, + // rankMen + new int[][]{new int[]{1, 2, 3, 4}, new int[]{2, 1, 3, 4}, + new int[]{1, 4, 3, 2}, new int[]{4, 3, 1, 2}}}; // // Data from @@ -204,29 +186,19 @@ public class StableMarriage // page 4 // int[][][] problem4 = { - // rankWomen - new int[][] { - new int[] {1,5,4,6,2,3}, - new int[] {4,1,5,2,6,3}, - new int[] {6,4,2,1,5,3}, - new int[] {1,5,2,4,3,6}, - new int[] {4,2,1,5,6,3}, - new int[] {2,6,3,5,1,4}}, - - // rankMen - new int[][] { - new int[] {1,4,2,5,6,3}, - new int[] {3,4,6,1,5,2}, - new int[] {1,6,4,2,3,5}, - new int[] {6,5,3,4,2,1}, - new int[] {3,1,2,4,5,6}, - new int[] {2,3,1,6,5,4}}}; + // rankWomen + new int[][]{new int[]{1, 5, 4, 6, 2, 3}, new int[]{4, 1, 5, 2, 6, 3}, + new int[]{6, 4, 2, 1, 5, 3}, new int[]{1, 5, 2, 4, 3, 6}, + new int[]{4, 2, 1, 5, 6, 3}, new int[]{2, 6, 3, 5, 1, 4}}, + // rankMen + new int[][]{new int[]{1, 4, 2, 5, 6, 3}, new int[]{3, 4, 6, 1, 5, 2}, + new int[]{1, 6, 4, 2, 3, 5}, new int[]{6, 5, 3, 4, 2, 1}, + new int[]{3, 1, 2, 4, 5, 6}, new int[]{2, 3, 1, 6, 5, 4}}}; Solve(van_hentenryck, "Van Hentenryck"); Solve(mathworld, "MathWorld"); Solve(problem3, "Problem 3"); Solve(problem4, "Problem 4"); - } } diff --git a/examples/contrib/strimko2.cs b/examples/contrib/strimko2.cs index 4b2c767019..cdb9e79e9e 100644 --- a/examples/contrib/strimko2.cs +++ b/examples/contrib/strimko2.cs @@ -20,42 +20,27 @@ using System.Linq; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; -public class Strimko2 -{ - +public class Strimko2 { /** * * Solves a Strimko problem. * See http://www.hakank.org/google_or_tools/strimko2.py * */ - private static void Solve() - { - + private static void Solve() { Solver solver = new Solver("Strimko2"); // // data // - int[,] streams = {{1,1,2,2,2,2,2}, - {1,1,2,3,3,3,2}, - {1,4,1,3,3,5,5}, - {4,4,3,1,3,5,5}, - {4,6,6,6,7,7,5}, - {6,4,6,4,5,5,7}, - {6,6,4,7,7,7,7}}; + int[, ] streams = {{1, 1, 2, 2, 2, 2, 2}, {1, 1, 2, 3, 3, 3, 2}, + {1, 4, 1, 3, 3, 5, 5}, {4, 4, 3, 1, 3, 5, 5}, + {4, 6, 6, 6, 7, 7, 5}, {6, 4, 6, 4, 5, 5, 7}, + {6, 6, 4, 7, 7, 7, 7}}; // Note: This is 1-based - int[,] placed = {{2,1,1}, - {2,3,7}, - {2,5,6}, - {2,7,4}, - {3,2,7}, - {3,6,1}, - {4,1,4}, - {4,7,5}, - {5,2,2}, - {5,6,6}}; + int[, ] placed = {{2, 1, 1}, {2, 3, 7}, {2, 5, 6}, {2, 7, 4}, {3, 2, 7}, + {3, 6, 1}, {4, 1, 4}, {4, 7, 5}, {5, 2, 2}, {5, 6, 6}}; int n = streams.GetLength(0); int num_placed = placed.GetLength(0); @@ -63,19 +48,19 @@ public class Strimko2 // // Decision variables // - IntVar[,] x = solver.MakeIntVarMatrix(n, n, 1, n, "x"); + IntVar[, ] x = solver.MakeIntVarMatrix(n, n, 1, n, "x"); IntVar[] x_flat = x.Flatten(); // // Constraints // // all rows and columns must be unique, i.e. a Latin Square - for(int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { IntVar[] row = new IntVar[n]; IntVar[] col = new IntVar[n]; - for(int j = 0; j < n; j++) { - row[j] = x[i,j]; - col[j] = x[j,i]; + for (int j = 0; j < n; j++) { + row[j] = x[i, j]; + col[j] = x[j, i]; } solver.Add(row.AllDifferent()); @@ -83,34 +68,34 @@ public class Strimko2 } // streams - for(int s = 1; s <= n; s++) { - IntVar[] tmp = (from i in Enumerable.Range(0, n) - from j in Enumerable.Range(0, n) - where streams[i,j] == s - select x[i,j]).ToArray(); + for (int s = 1; s <= n; s++) { + IntVar[] tmp = + (from i in Enumerable.Range(0, n) from j in Enumerable.Range(0, n) + where streams[i, j] == s select x[i, j]) + .ToArray(); solver.Add(tmp.AllDifferent()); - } // placed - for(int i = 0; i < num_placed; i++) { + for (int i = 0; i < num_placed; i++) { // note: also adjust to 0-based - solver.Add(x[placed[i,0] - 1,placed[i,1] - 1] == placed[i,2]); + solver.Add(x[placed[i, 0] - 1, placed[i, 1] - 1] == placed[i, 2]); } // // Search // - DecisionBuilder db = solver.MakePhase(x_flat, - Solver.INT_VAR_DEFAULT, + DecisionBuilder db = solver.MakePhase(x_flat, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); while (solver.NextSolution()) { - for(int i = 0; i < n; i++) { - for(int j = 0; j < n; j++) { - Console.Write(x[i,j].Value() + " "); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + Console.Write(x [i, j] + .Value() + + " "); } Console.WriteLine(); } @@ -123,11 +108,7 @@ public class Strimko2 Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/subset_sum.cs b/examples/contrib/subset_sum.cs index 8d223df732..d08b4c8581 100644 --- a/examples/contrib/subset_sum.cs +++ b/examples/contrib/subset_sum.cs @@ -19,12 +19,8 @@ using System.Collections.Generic; using System.Linq; using Google.OrTools.ConstraintSolver; -public class SubsetSum -{ - - public static IntVar[] subset_sum(Solver solver, - int[] values, - int total) { +public class SubsetSum { + public static IntVar[] subset_sum(Solver solver, int[] values, int total) { int n = values.Length; IntVar[] x = solver.MakeIntVarArray(n, 0, n, "x"); solver.Add(x.ScalProd(values) == total); @@ -32,7 +28,6 @@ public class SubsetSum return x; } - /** * * Subset sum problem. @@ -41,7 +36,7 @@ public class SubsetSum * http://ioe.engin.umich.edu/people/fac/books/murty/opti_model/junior-7.pdf * """ * Example 7.8.1 - * + * * A bank van had several bags of coins, each containing either * 16, 17, 23, 24, 39, or 40 coins. While the van was parked on the * street, thieves stole some bags. A total of 100 coins were lost. @@ -51,14 +46,12 @@ public class SubsetSum * Also see http://www.hakank.org/or-tools/subset_sum.py * */ - private static void Solve(int[] coins, int total) - { - + private static void Solve(int[] coins, int total) { Solver solver = new Solver("SubsetSum"); int n = coins.Length; Console.Write("Coins: "); - for(int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { Console.Write(coins[i] + " "); } Console.WriteLine("\nTotal: {0}", total); @@ -69,27 +62,26 @@ public class SubsetSum // number of coins IntVar s = solver.MakeIntVar(0, coins.Sum(), "s"); - // // Constraints - // + // IntVar[] x = subset_sum(solver, coins, total); solver.Add(x.Sum() == s); - // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); while (solver.NextSolution()) { Console.Write("x: "); - for(int i = 0; i < n; i++) { - Console.Write(x[i].Value() + " "); + for (int i = 0; i < n; i++) { + Console.Write(x [i] + .Value() + + " "); } Console.WriteLine(" s: {0}", s.Value()); } @@ -100,12 +92,9 @@ public class SubsetSum Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - + public static void Main(String[] args) { int[] coins = {16, 17, 23, 24, 39, 40}; int total = 100; diff --git a/examples/contrib/sudoku.cs b/examples/contrib/sudoku.cs index d57b3bcd19..1c6e8fcdf1 100644 --- a/examples/contrib/sudoku.cs +++ b/examples/contrib/sudoku.cs @@ -20,17 +20,13 @@ using System.Linq; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; - -public class Sudoku -{ - +public class Sudoku { /** * * Solves a Sudoku problem. * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("Sudoku"); // @@ -42,21 +38,17 @@ public class Sudoku IEnumerable RANGE = Enumerable.Range(0, n); // 0 marks an unknown value - int[,] initial_grid = {{0, 6, 0, 0, 5, 0, 0, 2, 0}, - {0, 0, 0, 3, 0, 0, 0, 9, 0}, - {7, 0, 0, 6, 0, 0, 0, 1, 0}, - {0, 0, 6, 0, 3, 0, 4, 0, 0}, - {0, 0, 4, 0, 7, 0, 1, 0, 0}, - {0, 0, 5, 0, 9, 0, 8, 0, 0}, - {0, 4, 0, 0, 0, 1, 0, 0, 6}, - {0, 3, 0, 0, 0, 8, 0, 0, 0}, - {0, 2, 0, 0, 4, 0, 0, 5, 0}}; - + int[, ] initial_grid = { + {0, 6, 0, 0, 5, 0, 0, 2, 0}, {0, 0, 0, 3, 0, 0, 0, 9, 0}, + {7, 0, 0, 6, 0, 0, 0, 1, 0}, {0, 0, 6, 0, 3, 0, 4, 0, 0}, + {0, 0, 4, 0, 7, 0, 1, 0, 0}, {0, 0, 5, 0, 9, 0, 8, 0, 0}, + {0, 4, 0, 0, 0, 1, 0, 0, 6}, {0, 3, 0, 0, 0, 8, 0, 0, 0}, + {0, 2, 0, 0, 4, 0, 0, 5, 0}}; // // Decision variables // - IntVar[,] grid = solver.MakeIntVarMatrix(n, n, 1, 9, "grid"); + IntVar[, ] grid = solver.MakeIntVarMatrix(n, n, 1, 9, "grid"); IntVar[] grid_flat = grid.Flatten(); // @@ -64,51 +56,45 @@ public class Sudoku // // init - foreach(int i in RANGE) { - foreach(int j in RANGE) { - if (initial_grid[i,j] > 0) { - solver.Add(grid[i,j] == initial_grid[i,j]); + foreach (int i in RANGE) { + foreach (int j in RANGE) { + if (initial_grid[i, j] > 0) { + solver.Add(grid[i, j] == initial_grid[i, j]); } } } - - foreach(int i in RANGE) { - + foreach (int i in RANGE) { // rows - solver.Add( (from j in RANGE - select grid[i,j]).ToArray().AllDifferent()); + solver.Add((from j in RANGE select grid[i, j]).ToArray().AllDifferent()); // cols - solver.Add( (from j in RANGE - select grid[j,i]).ToArray().AllDifferent()); - + solver.Add((from j in RANGE select grid[j, i]).ToArray().AllDifferent()); } // cells - foreach(int i in CELL) { - foreach(int j in CELL) { - solver.Add( (from di in CELL - from dj in CELL - select grid[i*cell_size+di, j*cell_size+dj] - ).ToArray().AllDifferent()); + foreach (int i in CELL) { + foreach (int j in CELL) { + solver.Add((from di in CELL from dj in CELL select + grid[i * cell_size + di, j * cell_size + dj]) + .ToArray() + .AllDifferent()); } } - // // Search // - DecisionBuilder db = solver.MakePhase(grid_flat, - Solver.INT_VAR_SIMPLE, + DecisionBuilder db = solver.MakePhase(grid_flat, Solver.INT_VAR_SIMPLE, Solver.INT_VALUE_SIMPLE); solver.NewSearch(db); while (solver.NextSolution()) { - for(int i = 0; i < n; i++) { - for(int j = 0; j < n; j++){ - Console.Write("{0} ", grid[i,j].Value()); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + Console.Write("{0} ", grid [i, j] + .Value()); } Console.WriteLine(); } @@ -122,12 +108,7 @@ public class Sudoku Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/survo_puzzle.cs b/examples/contrib/survo_puzzle.cs index 645ec77951..3012e9b283 100644 --- a/examples/contrib/survo_puzzle.cs +++ b/examples/contrib/survo_puzzle.cs @@ -19,30 +19,22 @@ using System.IO; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; - -public class SurvoPuzzle -{ - +public class SurvoPuzzle { // // default problem - // + // static int default_r = 3; static int default_c = 4; static int[] default_rowsums = {30, 18, 30}; static int[] default_colsums = {27, 16, 10, 25}; - static int[,] default_game = {{0, 6, 0, 0}, - {8, 0, 0, 0}, - {0, 0, 3, 0}}; - + static int[, ] default_game = {{0, 6, 0, 0}, {8, 0, 0, 0}, {0, 0, 3, 0}}; // for the actual problem static int r; static int c; static int[] rowsums; static int[] colsums; - static int[,] game; - - + static int[, ] game; /** * @@ -50,70 +42,63 @@ public class SurvoPuzzle * See http://www.hakank.org/or-tools/survo_puzzle.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("SurvoPuzzle"); // // data // Console.WriteLine("Problem:"); - for(int i = 0; i < r; i++) { - for(int j = 0; j < c; j++) { - Console.Write(game[i,j] + " "); + for (int i = 0; i < r; i++) { + for (int j = 0; j < c; j++) { + Console.Write(game[i, j] + " "); } Console.WriteLine(); } Console.WriteLine(); - // // Decision variables // - IntVar[,] x = solver.MakeIntVarMatrix(r, c, 1, r*c, "x"); + IntVar[, ] x = solver.MakeIntVarMatrix(r, c, 1, r * c, "x"); IntVar[] x_flat = x.Flatten(); - // // Constraints - // - for(int i = 0; i < r; i++) { - for(int j = 0; j < c; j++) { - if (game[i,j] > 0) { - solver.Add(x[i,j] == game[i,j]); + // + for (int i = 0; i < r; i++) { + for (int j = 0; j < c; j++) { + if (game[i, j] > 0) { + solver.Add(x[i, j] == game[i, j]); } } } solver.Add(x_flat.AllDifferent()); - // // calculate rowsums and colsums // - for(int i = 0; i < r; i++) { + for (int i = 0; i < r; i++) { IntVar[] row = new IntVar[c]; - for(int j = 0; j < c; j++) { - row[j] = x[i,j]; + for (int j = 0; j < c; j++) { + row[j] = x[i, j]; } solver.Add(row.Sum() == rowsums[i]); } - for(int j = 0; j < c; j++) { + for (int j = 0; j < c; j++) { IntVar[] col = new IntVar[r]; - for(int i = 0; i < r; i++) { - col[i] = x[i,j]; + for (int i = 0; i < r; i++) { + col[i] = x[i, j]; } solver.Add(col.Sum() == colsums[j]); - } - // // Search // - DecisionBuilder db = solver.MakePhase(x_flat, - Solver.INT_VAR_SIMPLE, + DecisionBuilder db = solver.MakePhase(x_flat, Solver.INT_VAR_SIMPLE, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); @@ -122,9 +107,10 @@ public class SurvoPuzzle while (solver.NextSolution()) { sol++; Console.WriteLine("Solution #{0} ", sol + " "); - for(int i = 0; i < r; i++) { - for(int j = 0; j < c; j++){ - Console.Write("{0} ", x[i,j].Value()); + for (int i = 0; i < r; i++) { + for (int j = 0; j < c; j++) { + Console.Write("{0} ", x [i, j] + .Value()); } Console.WriteLine(); } @@ -137,11 +123,9 @@ public class SurvoPuzzle Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - /** + /** * * readFile() * @@ -164,63 +148,57 @@ public class SurvoPuzzle * */ private static void readFile(String file) { - Console.WriteLine("readFile(" + file + ")"); TextReader inr = new StreamReader(file); - + r = Convert.ToInt32(inr.ReadLine()); c = Convert.ToInt32(inr.ReadLine()); rowsums = new int[r]; colsums = new int[c]; Console.WriteLine("r: " + r + " c: " + c); - - String[] rowsums_str = Regex.Split(inr.ReadLine(),",\\s*"); - String[] colsums_str = Regex.Split(inr.ReadLine(),",\\s*"); + + String[] rowsums_str = Regex.Split(inr.ReadLine(), ",\\s*"); + String[] colsums_str = Regex.Split(inr.ReadLine(), ",\\s*"); Console.WriteLine("rowsums:"); - for(int i = 0; i < r; i++) { + for (int i = 0; i < r; i++) { Console.Write(rowsums_str[i] + " "); rowsums[i] = Convert.ToInt32(rowsums_str[i]); } Console.WriteLine("\ncolsums:"); - for(int j = 0; j < c; j++) { + for (int j = 0; j < c; j++) { Console.Write(colsums_str[j] + " "); colsums[j] = Convert.ToInt32(colsums_str[j]); } Console.WriteLine(); - + // init the game matrix and read data from file - game = new int[r,c]; + game = new int[r, c]; String str; int line_count = 0; while ((str = inr.ReadLine()) != null && str.Length > 0) { str = str.Trim(); - + // ignore comments // starting with either # or % - if(str.StartsWith("#") || str.StartsWith("%")) { + if (str.StartsWith("#") || str.StartsWith("%")) { continue; } - + String[] this_row = Regex.Split(str, ",\\s*"); - for(int j = 0; j < this_row.Length; j++) { - game[line_count,j] = Convert.ToInt32(this_row[j]); + for (int j = 0; j < this_row.Length; j++) { + game[line_count, j] = Convert.ToInt32(this_row[j]); } - + line_count++; - - } // end while - - inr.Close(); - - - } // end readFile - + } // end while + inr.Close(); - public static void Main(String[] args) - { + } // end readFile + + public static void Main(String[] args) { String file = ""; if (args.Length > 0) { file = args[0]; diff --git a/examples/contrib/to_num.cs b/examples/contrib/to_num.cs index 76ff19c649..efd0389d9e 100644 --- a/examples/contrib/to_num.cs +++ b/examples/contrib/to_num.cs @@ -16,10 +16,7 @@ using System; using Google.OrTools.ConstraintSolver; -public class ToNumTest -{ - - +public class ToNumTest { /** * * toNum(solver, a, num, base) @@ -31,22 +28,19 @@ public class ToNumTest int len = a.Length; IntVar[] tmp = new IntVar[len]; - for(int i = 0; i < len; i++) { - tmp[i] = (a[i]*(int)Math.Pow(bbase,(len-i-1))).Var(); + for (int i = 0; i < len; i++) { + tmp[i] = (a[i] * (int) Math.Pow(bbase, (len - i - 1))).Var(); } - return tmp.Sum() == num; + return tmp.Sum() == num; } - - /** * * Implements toNum: channeling between a number and an array. * See http://www.hakank.org/or-tools/toNum.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("ToNum"); int n = 5; @@ -56,7 +50,7 @@ public class ToNumTest // Decision variables // IntVar[] x = solver.MakeIntVarArray(n, 0, bbase - 1, "x"); - IntVar num = solver.MakeIntVar(0, (int)Math.Pow(bbase, n) - 1, "num"); + IntVar num = solver.MakeIntVar(0, (int) Math.Pow(bbase, n) - 1, "num"); // // Constraints @@ -72,16 +66,17 @@ public class ToNumTest // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); while (solver.NextSolution()) { Console.Write("\n" + num.Value() + ": "); - for(int i = 0; i < n; i++) { - Console.Write(x[i].Value() + " "); + for (int i = 0; i < n; i++) { + Console.Write(x [i] + .Value() + + " "); } } @@ -91,11 +86,7 @@ public class ToNumTest Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/traffic_lights.cs b/examples/contrib/traffic_lights.cs index e8d2adcbb8..894ace0759 100644 --- a/examples/contrib/traffic_lights.cs +++ b/examples/contrib/traffic_lights.cs @@ -19,9 +19,7 @@ using System.IO; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; -public class TrafficLights -{ - +public class TrafficLights { /** * * Traffic lights problem. @@ -30,28 +28,31 @@ public class TrafficLights * http://www.cs.st-andrews.ac.uk/~ianm/CSPLib/prob/prob016/index.html * """ * Specification: - * Consider a four way traffic junction with eight traffic lights. Four of the traffic - * lights are for the vehicles and can be represented by the variables V1 to V4 with domains - * {r,ry,g,y} (for red, red-yellow, green and yellow). The other four traffic lights are - * for the pedestrians and can be represented by the variables P1 to P4 with domains {r,g}. + * Consider a four way traffic junction with eight traffic lights. Four of the + * traffic lights are for the vehicles and can be represented by the variables + * V1 to V4 with domains {r,ry,g,y} (for red, red-yellow, green and yellow). + * The other four traffic lights are for the pedestrians and can be + * represented by the variables P1 to P4 with domains {r,g}. * - * The constraints on these variables can be modelled by quaternary constraints on - * (Vi, Pi, Vj, Pj ) for 1<=i<=4, j=(1+i)mod 4 which allow just the tuples + * The constraints on these variables can be modelled by quaternary + * constraints on (Vi, Pi, Vj, Pj ) for 1<=i<=4, j=(1+i)mod 4 which allow just + * the tuples * {(r,r,g,g), (ry,r,y,r), (g,g,r,r), (y,r,ry,r)}. * - * It would be interesting to consider other types of junction (e.g. five roads - * intersecting) as well as modelling the evolution over time of the traffic light sequence. + * It would be interesting to consider other types of junction (e.g. five + * roads intersecting) as well as modelling the evolution over time of the + * traffic light sequence. * ... * * Results * Only 2^2 out of the 2^12 possible assignments are solutions. * * (V1,P1,V2,P2,V3,P3,V4,P4) = - * {(r,r,g,g,r,r,g,g), (ry,r,y,r,ry,r,y,r), (g,g,r,r,g,g,r,r), (y,r,ry,r,y,r,ry,r)} - * [(1,1,3,3,1,1,3,3), ( 2,1,4,1, 2,1,4,1), (3,3,1,1,3,3,1,1), (4,1, 2,1,4,1, 2,1)} - * The problem has relative few constraints, but each is very - * tight. Local propagation appears to be rather ineffective on this - * problem. + * {(r,r,g,g,r,r,g,g), (ry,r,y,r,ry,r,y,r), (g,g,r,r,g,g,r,r), + * (y,r,ry,r,y,r,ry,r)} + * [(1,1,3,3,1,1,3,3), ( 2,1,4,1, 2,1,4,1), (3,3,1,1,3,3,1,1), (4,1, 2,1,4,1, + * 2,1)} The problem has relative few constraints, but each is very tight. + * Local propagation appears to be rather ineffective on this problem. * * """ * Note: In this model we use only the constraint @@ -61,9 +62,7 @@ public class TrafficLights * See http://www.hakank.org/or-tools/traffic_lights.py * */ - private static void Solve() - { - + private static void Solve() { Solver solver = new Solver("TrafficLights"); // @@ -80,48 +79,48 @@ public class TrafficLights // The allowed combinations IntTupleSet allowed = new IntTupleSet(4); - allowed.InsertAll(new long[][] { - new long[] {r,r,g,g}, - new long[] {ry,r,y,r}, - new long[] {g,g,r,r}, - new long[] {y,r,ry,r}}); + allowed.InsertAll( + new long[][]{new long[]{r, r, g, g}, new long[]{ry, r, y, r}, + new long[]{g, g, r, r}, new long[]{y, r, ry, r}}); // // Decision variables // - IntVar[] V = solver.MakeIntVarArray(n, 0, n-1, "V"); - IntVar[] P = solver.MakeIntVarArray(n, 0, n-1, "P"); + IntVar[] V = solver.MakeIntVarArray(n, 0, n - 1, "V"); + IntVar[] P = solver.MakeIntVarArray(n, 0, n - 1, "P"); // for search IntVar[] VP = new IntVar[2 * n]; - for(int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { VP[i] = V[i]; - VP[i+n] = P[i]; + VP[i + n] = P[i]; } // // Constraints // - for(int i = 0; i < n; i++) { - int j = (1+i) % n; - IntVar[] tmp = new IntVar[] {V[i],P[i],V[j],P[j]}; + for (int i = 0; i < n; i++) { + int j = (1 + i) % n; + IntVar[] tmp = new IntVar[]{V[i], P[i], V[j], P[j]}; solver.Add(tmp.AllowedAssignments(allowed)); } // // Search // - DecisionBuilder db = solver.MakePhase(VP, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(VP, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); - solver.NewSearch(db); while (solver.NextSolution()) { - for(int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { Console.Write("{0,2} {1,2} ", - lights[V[i].Value()], - lights[P[i].Value()]); + lights [V [i] + .Value()] + , + lights [P [i] + .Value()] + ); } Console.WriteLine(); } @@ -132,12 +131,7 @@ public class TrafficLights Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/volsay.cs b/examples/contrib/volsay.cs index f01d88a9b2..0da8594b37 100644 --- a/examples/contrib/volsay.cs +++ b/examples/contrib/volsay.cs @@ -28,7 +28,7 @@ public class Volsay { */ private static void Solve() { Solver solver = new Solver( - "Volsay", Solver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING); + "Volsay", Solver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING); // // Variables @@ -50,28 +50,22 @@ public class Volsay { Console.WriteLine("Objective: {0}", solver.Objective().Value()); - Console.WriteLine("Gas : {0} ReducedCost: {1}", - Gas.SolutionValue(), + Console.WriteLine("Gas : {0} ReducedCost: {1}", Gas.SolutionValue(), Gas.ReducedCost()); Console.WriteLine("Chloride : {0} ReducedCost: {1}", - Chloride.SolutionValue(), - Chloride.ReducedCost()); + Chloride.SolutionValue(), Chloride.ReducedCost()); double[] activities = solver.ComputeConstraintActivities(); - Console.WriteLine("c1 : DualValue: {0} Activity: {1}", - c1.DualValue(), + Console.WriteLine("c1 : DualValue: {0} Activity: {1}", c1.DualValue(), activities[c1.Index()]); - Console.WriteLine("c2 : DualValue: {0} Activity: {1}", - c2.DualValue(), + Console.WriteLine("c2 : DualValue: {0} Activity: {1}", c2.DualValue(), activities[c2.Index()]); Console.WriteLine("\nWallTime: " + solver.WallTime()); Console.WriteLine("Iterations: " + solver.Iterations()); } - public static void Main(String[] args) { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/volsay2.cs b/examples/contrib/volsay2.cs index ee1c1c8345..02584d94e9 100644 --- a/examples/contrib/volsay2.cs +++ b/examples/contrib/volsay2.cs @@ -30,7 +30,7 @@ public class Volsay2 { */ private static void Solve() { Solver solver = new Solver( - "Volsay2", Solver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING); + "Volsay2", Solver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING); int num_products = 2; IEnumerable PRODUCTS = Enumerable.Range(0, num_products); @@ -42,7 +42,7 @@ public class Volsay2 { // Variables // Variable[] production = new Variable[num_products]; - foreach(int p in PRODUCTS) { + foreach (int p in PRODUCTS) { production[p] = solver.MakeNumVar(0, 100000, products[p]); } @@ -63,30 +63,33 @@ public class Volsay2 { return; } - foreach(int p in PRODUCTS) { - Console.WriteLine("{0,-10}: {1} ReducedCost: {2}", - products[p], - production[p].SolutionValue(), - production[p].ReducedCost()); + foreach (int p in PRODUCTS) { + Console.WriteLine("{0,-10}: {1} ReducedCost: {2}", products[p], + production [p] + .SolutionValue(), + production [p] + .ReducedCost()); } double[] activities = solver.ComputeConstraintActivities(); - foreach(int c in CONSTRAINTS) { + foreach (int c in CONSTRAINTS) { Console.WriteLine( "Constraint {0} DualValue {1} Activity: {2} lb: {3} ub: {4}", c.ToString(), - cons[c].DualValue(), - activities[cons[c].Index()], - cons[c].Lb(), - cons[c].Ub()); + cons [c] + .DualValue(), + activities [cons [c] + .Index()] + , + cons [c] + .Lb(), + cons [c] + .Ub()); } Console.WriteLine("\nWallTime: " + solver.WallTime()); Console.WriteLine("Iterations: " + solver.Iterations()); - } - public static void Main(String[] args) { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/volsay3.cs b/examples/contrib/volsay3.cs index a9bb502f96..6fef806d65 100644 --- a/examples/contrib/volsay3.cs +++ b/examples/contrib/volsay3.cs @@ -31,22 +31,22 @@ public class Volsay3 { */ private static void Solve() { Solver solver = new Solver( - "Volsay3", Solver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING); + "Volsay3", Solver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING); int num_products = 2; IEnumerable PRODUCTS = Enumerable.Range(0, num_products); String[] products = {"Gas", "Chloride"}; String[] components = {"nitrogen", "hydrogen", "chlorine"}; - int[,] demand = { {1,3,0}, {1,4,1}}; - int[] profit = {30,40}; - int[] stock = {50,180,40}; + int[, ] demand = {{1, 3, 0}, {1, 4, 1}}; + int[] profit = {30, 40}; + int[] stock = {50, 180, 40}; // // Variables // Variable[] production = new Variable[num_products]; - foreach(int p in PRODUCTS) { + foreach (int p in PRODUCTS) { production[p] = solver.MakeNumVar(0, 100000, products[p]); } @@ -55,19 +55,18 @@ public class Volsay3 { // int c_len = components.Length; Constraint[] cons = new Constraint[c_len]; - for(int c = 0; c < c_len; c++) { - cons[c] = solver.Add( (from p in PRODUCTS - select (demand[p,c]*production[p])). - ToArray().Sum() <= stock[c]); + for (int c = 0; c < c_len; c++) { + cons[c] = + solver.Add((from p in PRODUCTS select(demand[p, c] * production[p])) + .ToArray() + .Sum() <= stock[c]); } // // Objective // - solver.Maximize( (from p in PRODUCTS - select (profit[p]*production[p])). - ToArray().Sum() - ); + solver.Maximize( + (from p in PRODUCTS select(profit[p] * production[p])).ToArray().Sum()); if (solver.Solve() != Solver.ResultStatus.OPTIMAL) { Console.WriteLine("The problem don't have an optimal solution."); @@ -75,28 +74,32 @@ public class Volsay3 { } Console.WriteLine("Objective: {0}", solver.Objective().Value()); - foreach(int p in PRODUCTS) { - Console.WriteLine("{0,-10}: {1} ReducedCost: {2}", - products[p], - production[p].SolutionValue(), - production[p].ReducedCost()); + foreach (int p in PRODUCTS) { + Console.WriteLine("{0,-10}: {1} ReducedCost: {2}", products[p], + production [p] + .SolutionValue(), + production [p] + .ReducedCost()); } double[] activities = solver.ComputeConstraintActivities(); - for(int c = 0; c < c_len; c++) { - Console.WriteLine("Constraint {0} DualValue {1} Activity: {2} lb: {3} ub: {4}", - c, - cons[c].DualValue(), - activities[cons[c].Index()], - cons[c].Lb(), - cons[c].Ub()); + for (int c = 0; c < c_len; c++) { + Console.WriteLine( + "Constraint {0} DualValue {1} Activity: {2} lb: {3} ub: {4}", c, + cons [c] + .DualValue(), + activities [cons [c] + .Index()] + , + cons [c] + .Lb(), + cons [c] + .Ub()); } Console.WriteLine("\nWallTime: " + solver.WallTime()); Console.WriteLine("Iterations: " + solver.Iterations()); } - public static void Main(String[] args) { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/wedding_optimal_chart.cs b/examples/contrib/wedding_optimal_chart.cs index 9eecf2e473..6a94245a92 100644 --- a/examples/contrib/wedding_optimal_chart.cs +++ b/examples/contrib/wedding_optimal_chart.cs @@ -19,8 +19,7 @@ using System.Collections.Generic; using System.Linq; using Google.OrTools.ConstraintSolver; -public class WeddingOptimalChart -{ +public class WeddingOptimalChart { /** * * Finding an optimal wedding seating chart. @@ -49,9 +48,7 @@ public class WeddingOptimalChart * Also see http://www.hakank.org/minizinc/wedding_optimal_chart.mzn * */ - private static void Solve() - { - + private static void Solve() { Solver solver = new Solver("WeddingOptimalChart"); // @@ -59,9 +56,9 @@ public class WeddingOptimalChart // // Easy problem (from the paper) - int n = 2; // number of tables - int a = 10; // maximum number of guests a table can seat - int b = 1; // minimum number of people each guest knows at their table + int n = 2; // number of tables + int a = 10; // maximum number of guests a table can seat + int b = 1; // minimum number of people each guest knows at their table /* // Sligthly harder problem (also from the paper) @@ -92,73 +89,55 @@ public class WeddingOptimalChart // Connection matrix: who knows who, and how strong // is the relation - int[,] C = { - { 1,50, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}, - {50, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}, - { 1, 1, 1,50, 1, 1, 1, 1,10, 0, 0, 0, 0, 0, 0, 0, 0}, - { 1, 1,50, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}, - { 1, 1, 1, 1, 1,50, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}, - { 1, 1, 1, 1,50, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}, - { 1, 1, 1, 1, 1, 1, 1,50, 1, 0, 0, 0, 0, 0, 0, 0, 0}, - { 1, 1, 1, 1, 1, 1,50, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}, - { 1, 1,10, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,50, 1, 1, 1, 1, 1, 1}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0,50, 1, 1, 1, 1, 1, 1, 1}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1} - }; + int[, ] C = {{1, 50, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}, + {50, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 1, 50, 1, 1, 1, 1, 10, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 50, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 1, 1, 1, 50, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 1, 1, 50, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 1, 1, 1, 1, 1, 50, 1, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 1, 1, 1, 1, 50, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 10, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 50, 1, 1, 1, 1, 1, 1}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 1, 1, 1, 1, 1, 1, 1}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}}; // Names of the guests. B: Bride side, G: Groom side - String[] names = {"Deb (B)", - "John (B)", - "Martha (B)", - "Travis (B)", - "Allan (B)", - "Lois (B)", - "Jayne (B)", - "Brad (B)", - "Abby (B)", - "Mary Helen (G)", - "Lee (G)", - "Annika (G)", - "Carl (G)", - "Colin (G)", - "Shirley (G)", - "DeAnn (G)", - "Lori (G)"}; + String[] names = { + "Deb (B)", "John (B)", "Martha (B)", "Travis (B)", "Allan (B)", + "Lois (B)", "Jayne (B)", "Brad (B)", "Abby (B)", "Mary Helen (G)", + "Lee (G)", "Annika (G)", "Carl (G)", "Colin (G)", "Shirley (G)", + "DeAnn (G)", "Lori (G)"}; - - int m = C.GetLength(0); // number of quests + int m = C.GetLength(0); // number of quests IEnumerable NRANGE = Enumerable.Range(0, n); IEnumerable MRANGE = Enumerable.Range(0, m); - // // Decision variables // - IntVar[] tables = solver.MakeIntVarArray(m, 0, n-1, "tables"); - IntVar z = (from j in MRANGE - from k in MRANGE - where j < k - select C[j,k] * tables[j] == tables[k] - ).ToArray().Sum().VarWithName("z"); + IntVar[] tables = solver.MakeIntVarArray(m, 0, n - 1, "tables"); + IntVar z = (from j in MRANGE from k in MRANGE where j < + k select C[j, k] * tables[j] == + tables[k]) + .ToArray() + .Sum() + .VarWithName("z"); // // Constraints // - foreach(int i in NRANGE) { - - solver.Add((from j in MRANGE - from k in MRANGE - where j < k && C[j, k] > 0 - select (tables[j] == i) * (tables[k] == i) - ).ToArray().Sum() >= b); - + foreach (int i in NRANGE) { + solver.Add((from j in MRANGE from k in MRANGE where j < k && + C[j, k] > 0 select(tables[j] == i) * (tables[k] == i)) + .ToArray() + .Sum() >= b); solver.Add((from j in MRANGE select tables[j] == i).ToArray().Sum() <= a); } @@ -174,23 +153,25 @@ public class WeddingOptimalChart // // Search // - DecisionBuilder db = solver.MakePhase(tables, - Solver.INT_VAR_DEFAULT, + DecisionBuilder db = solver.MakePhase(tables, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db, obj); while (solver.NextSolution()) { - Console.WriteLine("z: {0}",z.Value()); + Console.WriteLine("z: {0}", z.Value()); Console.Write("Table: "); - foreach(int j in MRANGE) { - Console.Write(tables[j].Value() + " "); + foreach (int j in MRANGE) { + Console.Write(tables [j] + .Value() + + " "); } Console.WriteLine(); - foreach(int i in NRANGE) { + foreach (int i in NRANGE) { Console.Write("Table {0}: ", i); - foreach(int j in MRANGE) { - if (tables[j].Value() == i) { + foreach (int j in MRANGE) { + if (tables [j] + .Value() == i) { Console.Write(names[j] + " "); } } @@ -205,11 +186,7 @@ public class WeddingOptimalChart Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/who_killed_agatha.cs b/examples/contrib/who_killed_agatha.cs index ca2bc76045..e0ae38fecc 100644 --- a/examples/contrib/who_killed_agatha.cs +++ b/examples/contrib/who_killed_agatha.cs @@ -18,17 +18,14 @@ using Google.OrTools.ConstraintSolver; using System.Collections; using System.Linq; -public class WhoKilledAgatha -{ - +public class WhoKilledAgatha { /** * * Implements the Who killed Agatha problem. * See http://www.hakank.org/google_or_tools/who_killed_agatha.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("WhoKilledAgatha"); int n = 3; @@ -41,15 +38,15 @@ public class WhoKilledAgatha // IntVar the_killer = solver.MakeIntVar(0, 2, "the_killer"); IntVar the_victim = solver.MakeIntVar(0, 2, "the_victim"); - IntVar[,] hates = solver.MakeIntVarMatrix(n, n, 0, 1, "hates"); + IntVar[, ] hates = solver.MakeIntVarMatrix(n, n, 0, 1, "hates"); IntVar[] hates_flat = hates.Flatten(); - IntVar[,] richer = solver.MakeIntVarMatrix(n, n, 0, 1, "richer"); + IntVar[, ] richer = solver.MakeIntVarMatrix(n, n, 0, 1, "richer"); IntVar[] richer_flat = richer.Flatten(); - IntVar[] all = new IntVar[2 * n * n]; // for branching - for(int i = 0; i < n*n; i++) { + IntVar[] all = new IntVar[2 * n * n]; // for branching + for (int i = 0; i < n * n; i++) { all[i] = hates_flat[i]; - all[(n*n)+i] = richer_flat[i]; + all[(n * n) + i] = richer_flat[i]; } // @@ -69,17 +66,17 @@ public class WhoKilledAgatha // define the concept of richer: // no one is richer than him-/herself... - for(int i = 0; i < n; i++) { - solver.Add(richer[i,i] == 0); + for (int i = 0; i < n; i++) { + solver.Add(richer[i, i] == 0); } // (contd...) if i is richer than j then j is not richer than i // if (i != j) => // ((richer[i,j] = 1) <=> (richer[j,i] = 0)) - for(int i = 0; i < n; i++) { - for(int j = 0; j < n; j++) { + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { if (i != j) { - solver.Add((richer[i, j]==1) - (richer[j, i]==0) == 0); + solver.Add((richer[i, j] == 1) - (richer[j, i] == 0) == 0); } } } @@ -87,49 +84,45 @@ public class WhoKilledAgatha // Charles hates no one that Agatha hates. // forall i in 0..2: // (hates[agatha, i] = 1) => (hates[charles, i] = 0) - for(int i = 0; i < n; i++) { - solver.Add((hates[agatha,i]==1) - (hates[charles,i]==0) <= 0); - + for (int i = 0; i < n; i++) { + solver.Add((hates[agatha, i] == 1) - (hates[charles, i] == 0) <= 0); } // Agatha hates everybody except the butler. - solver.Add(hates[agatha,charles] == 1); - solver.Add(hates[agatha,agatha] == 1); - solver.Add(hates[agatha,butler] == 0); + solver.Add(hates[agatha, charles] == 1); + solver.Add(hates[agatha, agatha] == 1); + solver.Add(hates[agatha, butler] == 0); // The butler hates everyone not richer than Aunt Agatha. // forall i in 0..2: // (richer[i, agatha] = 0) => (hates[butler, i] = 1) - for(int i = 0; i < n; i++) { - solver.Add((richer[i,agatha] == 0)-(hates[butler,i] == 1)<=0); + for (int i = 0; i < n; i++) { + solver.Add((richer[i, agatha] == 0) - (hates[butler, i] == 1) <= 0); } // The butler hates everyone whom Agatha hates. // forall i : 0..2: // (hates[agatha, i] = 1) => (hates[butler, i] = 1) - for(int i = 0; i < n; i++) { - solver.Add((hates[agatha,i] == 1)-(hates[butler,i] == 1)<=0); + for (int i = 0; i < n; i++) { + solver.Add((hates[agatha, i] == 1) - (hates[butler, i] == 1) <= 0); } // Noone hates everyone. // forall i in 0..2: // (sum j in 0..2: hates[i,j]) <= 2 - for(int i = 0; i < n; i++) { - solver.Add((from j in Enumerable.Range(0, n) - select hates[i,j] - ).ToArray().Sum() <= 2 ); + for (int i = 0; i < n; i++) { + solver.Add((from j in Enumerable.Range(0, n) select hates[i, j]) + .ToArray() + .Sum() <= 2); } - // Who killed Agatha? solver.Add(the_victim == agatha); - // // Search // - DecisionBuilder db = solver.MakePhase(all, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(all, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); @@ -144,11 +137,7 @@ public class WhoKilledAgatha Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/word_square.cs b/examples/contrib/word_square.cs index 1bbdd4cf7a..9655d3dd75 100644 --- a/examples/contrib/word_square.cs +++ b/examples/contrib/word_square.cs @@ -21,10 +21,7 @@ using System.IO; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; - -public class WordSquare -{ - +public class WordSquare { /** * * Word square. @@ -40,9 +37,7 @@ public class WordSquare * See http://www.hakank.org/or-tools/word_square.py * */ - private static void Solve(String[] words, int word_len, int num_answers) - { - + private static void Solve(String[] words, int word_len, int num_answers) { Solver solver = new Solver("WordSquare"); int num_words = words.Length; @@ -50,18 +45,18 @@ public class WordSquare int n = word_len; IEnumerable WORDLEN = Enumerable.Range(0, word_len); - // + // // convert a character to integer - // + // String alpha = "abcdefghijklmnopqrstuvwxyz"; Hashtable d = new Hashtable(); Hashtable rev = new Hashtable(); int count = 1; - for(int a = 0; a < alpha.Length; a++) { + for (int a = 0; a < alpha.Length; a++) { d[alpha[a]] = count; rev[count] = a; - count++; + count++; } int num_letters = alpha.Length; @@ -69,49 +64,49 @@ public class WordSquare // // Decision variables // - IntVar[,] A = solver.MakeIntVarMatrix(num_words, word_len, - 0, num_letters, "A"); + IntVar[, ] A = + solver.MakeIntVarMatrix(num_words, word_len, 0, num_letters, "A"); IntVar[] A_flat = A.Flatten(); IntVar[] E = solver.MakeIntVarArray(n, 0, num_words, "E"); - - // // Constraints // solver.Add(E.AllDifferent()); // copy the words to a matrix - for(int i = 0; i < num_words; i++) { - char[] s = words[i].ToArray(); - foreach(int j in WORDLEN) { - int t = (int)d[s[j]]; - solver.Add(A[i,j] == t); + for (int i = 0; i < num_words; i++) { + char[] s = words [i] + .ToArray(); + foreach (int j in WORDLEN) { + int t = (int) d[s[j]]; + solver.Add(A[i, j] == t); } } - foreach(int i in WORDLEN) { - foreach(int j in WORDLEN) { - solver.Add(A_flat.Element(E[i]*word_len+j) == - A_flat.Element(E[j]*word_len+i)); + foreach (int i in WORDLEN) { + foreach (int j in WORDLEN) { + solver.Add(A_flat.Element(E[i] * word_len + j) == + A_flat.Element(E[j] * word_len + i)); } } - // // Search // - DecisionBuilder db = solver.MakePhase(E.Concat(A_flat).ToArray(), - Solver.CHOOSE_FIRST_UNBOUND, - Solver.ASSIGN_MIN_VALUE); + DecisionBuilder db = + solver.MakePhase(E.Concat(A_flat).ToArray(), + Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); int num_sols = 0; while (solver.NextSolution()) { num_sols++; - for(int i = 0; i < n; i++) { - Console.WriteLine(words[E[i].Value()] + " "); + for (int i = 0; i < n; i++) { + Console.WriteLine(words [E [i] + .Value()] + + " "); } Console.WriteLine(); @@ -126,18 +121,14 @@ public class WordSquare Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - /* * * Read the words from a word list with a specific word length. * */ - public static String[] ReadWords(String word_list, int word_len) - { - + public static String[] ReadWords(String word_list, int word_len) { Console.WriteLine("ReadWords {0} {1}", word_list, word_len); List all_words = new List(); @@ -145,37 +136,26 @@ public class WordSquare String str; int count = 0; Hashtable d = new Hashtable(); - while ((str = inr.ReadLine()) != null) { + while ((str = inr.ReadLine()) != null) { str = str.Trim().ToLower(); // skip weird words - if(Regex.Match(str, @"[^a-z]").Success - || - d.Contains(str) - || - str.Length == 0 - || - str.Length != word_len - ) { + if (Regex.Match(str, @"[^a-z]").Success || d.Contains(str) || + str.Length == 0 || str.Length != word_len) { continue; } - + d[str] = 1; all_words.Add(str); count++; - - } // end while - + } // end while + inr.Close(); return all_words.ToArray(); - } - - public static void Main(String[] args) - { - + public static void Main(String[] args) { String word_list = "/usr/share/dict/words"; int word_len = 4; int num_answers = 20; diff --git a/examples/contrib/xkcd.cs b/examples/contrib/xkcd.cs index 5ab7b29d94..4b19b7857c 100644 --- a/examples/contrib/xkcd.cs +++ b/examples/contrib/xkcd.cs @@ -16,16 +16,14 @@ using System; using Google.OrTools.ConstraintSolver; -public class Xkcd -{ +public class Xkcd { /** * * Solve the xkcd problem * See http://www.hakank.org/google_or_tools/xkcd.py * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("Xkcd"); // @@ -49,14 +47,15 @@ public class Xkcd // // Search // - DecisionBuilder db = solver.MakePhase(x, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); while (solver.NextSolution()) { - for(int i = 0; i < n; i++) { - Console.Write(x[i].Value() + " "); + for (int i = 0; i < n; i++) { + Console.Write(x [i] + .Value() + + " "); } Console.WriteLine(); } @@ -67,11 +66,7 @@ public class Xkcd Console.WriteLine("Branches: {0}", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/contrib/young_tableaux.cs b/examples/contrib/young_tableaux.cs index bfa3404cb3..a6cc00fd53 100644 --- a/examples/contrib/young_tableaux.cs +++ b/examples/contrib/young_tableaux.cs @@ -19,19 +19,14 @@ using System.IO; using System.Text.RegularExpressions; using Google.OrTools.ConstraintSolver; - -public class YoungTableaux -{ - - +public class YoungTableaux { /** * * Implements Young tableaux and partitions. * See http://www.hakank.org/or-tools/young_tableuax.py * */ - private static void Solve(int n) - { + private static void Solve(int n) { Solver solver = new Solver("YoungTableaux"); // @@ -42,7 +37,7 @@ public class YoungTableaux // // Decision variables // - IntVar[,] x = solver.MakeIntVarMatrix(n, n, 1, n + 1, "x"); + IntVar[, ] x = solver.MakeIntVarMatrix(n, n, 1, n + 1, "x"); IntVar[] x_flat = x.Flatten(); // partition structure @@ -52,30 +47,30 @@ public class YoungTableaux // Constraints // // 1..n is used exactly once - for(int i = 1; i <= n; i++) { + for (int i = 1; i <= n; i++) { solver.Add(x_flat.Count(i, 1)); } - solver.Add(x[0,0] == 1); + solver.Add(x[0, 0] == 1); // row wise - for(int i = 0; i < n; i++) { - for(int j = 1; j < n; j++) { - solver.Add(x[i,j] >= x[i,j - 1]); + for (int i = 0; i < n; i++) { + for (int j = 1; j < n; j++) { + solver.Add(x[i, j] >= x[i, j - 1]); } } // column wise - for(int j = 0; j < n; j++) { - for(int i = 1; i < n; i++) { - solver.Add(x[i,j] >= x[i - 1, j]); + for (int j = 0; j < n; j++) { + for (int i = 1; i < n; i++) { + solver.Add(x[i, j] >= x[i - 1, j]); } } // calculate the structure (i.e. the partition) - for(int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { IntVar[] b = new IntVar[n]; - for(int j = 0; j < n; j++) { + for (int j = 0; j < n; j++) { b[j] = x[i, j] <= n; } solver.Add(p[i] == b.Sum()); @@ -83,36 +78,37 @@ public class YoungTableaux solver.Add(p.Sum() == n); - for(int i = 1; i < n; i++) { + for (int i = 1; i < n; i++) { solver.Add(p[i - 1] >= p[i]); } - - // // Search // - DecisionBuilder db = solver.MakePhase(x_flat, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(x_flat, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.NewSearch(db); while (solver.NextSolution()) { Console.Write("p: "); - for(int i = 0; i < n; i++) { - Console.Write(p[i].Value() + " "); + for (int i = 0; i < n; i++) { + Console.Write(p [i] + .Value() + + " "); } Console.WriteLine("\nx:"); - for(int i = 0; i < n; i++) { - for(int j = 0; j < n; j++) { - long val = x[i,j].Value(); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + long val = x [i, j] + .Value(); if (val <= n) { Console.Write(val + " "); } } - if (p[i].Value() > 0) { + if (p [i] + .Value() > 0) { Console.WriteLine(); } } @@ -125,13 +121,9 @@ public class YoungTableaux Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - - - public static void Main(String[] args) - { + public static void Main(String[] args) { int n = 5; if (args.Length > 0) { n = Convert.ToInt32(args[0]); diff --git a/examples/contrib/zebra.cs b/examples/contrib/zebra.cs index f1d0ba6fd5..48fcdc30d7 100644 --- a/examples/contrib/zebra.cs +++ b/examples/contrib/zebra.cs @@ -17,8 +17,7 @@ using System; using System.Linq; using Google.OrTools.ConstraintSolver; -public class NQueens -{ +public class NQueens { /** * * Solves the Zebra problem. @@ -50,8 +49,7 @@ public class NQueens * """ * */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("Zebra"); int n = 5; @@ -61,64 +59,63 @@ public class NQueens // // Colors - IntVar red = solver.MakeIntVar(1, n, "red"); - IntVar green = solver.MakeIntVar(1, n, "green"); - IntVar yellow = solver.MakeIntVar(1, n, "yellow"); - IntVar blue = solver.MakeIntVar(1, n, "blue"); - IntVar ivory = solver.MakeIntVar(1, n, "ivory"); + IntVar red = solver.MakeIntVar(1, n, "red"); + IntVar green = solver.MakeIntVar(1, n, "green"); + IntVar yellow = solver.MakeIntVar(1, n, "yellow"); + IntVar blue = solver.MakeIntVar(1, n, "blue"); + IntVar ivory = solver.MakeIntVar(1, n, "ivory"); // Nationality - IntVar englishman = solver.MakeIntVar(1, n, "englishman"); - IntVar spaniard = solver.MakeIntVar(1, n, "spaniard"); - IntVar japanese = solver.MakeIntVar(1, n, "japanese"); - IntVar ukrainian = solver.MakeIntVar(1, n, "ukrainian"); - IntVar norwegian = solver.MakeIntVar(1, n, "norwegian"); + IntVar englishman = solver.MakeIntVar(1, n, "englishman"); + IntVar spaniard = solver.MakeIntVar(1, n, "spaniard"); + IntVar japanese = solver.MakeIntVar(1, n, "japanese"); + IntVar ukrainian = solver.MakeIntVar(1, n, "ukrainian"); + IntVar norwegian = solver.MakeIntVar(1, n, "norwegian"); // Animal - IntVar dog = solver.MakeIntVar(1, n, "dog"); - IntVar snails = solver.MakeIntVar(1, n, "snails"); - IntVar fox = solver.MakeIntVar(1, n, "fox"); - IntVar zebra = solver.MakeIntVar(1, n, "zebra"); - IntVar horse = solver.MakeIntVar(1, n, "horse"); + IntVar dog = solver.MakeIntVar(1, n, "dog"); + IntVar snails = solver.MakeIntVar(1, n, "snails"); + IntVar fox = solver.MakeIntVar(1, n, "fox"); + IntVar zebra = solver.MakeIntVar(1, n, "zebra"); + IntVar horse = solver.MakeIntVar(1, n, "horse"); // Drink - IntVar tea = solver.MakeIntVar(1, n, "tea"); - IntVar coffee = solver.MakeIntVar(1, n, "coffee"); - IntVar water = solver.MakeIntVar(1, n, "water"); - IntVar milk = solver.MakeIntVar(1, n, "milk"); - IntVar fruit_juice = solver.MakeIntVar(1, n, "fruit juice"); + IntVar tea = solver.MakeIntVar(1, n, "tea"); + IntVar coffee = solver.MakeIntVar(1, n, "coffee"); + IntVar water = solver.MakeIntVar(1, n, "water"); + IntVar milk = solver.MakeIntVar(1, n, "milk"); + IntVar fruit_juice = solver.MakeIntVar(1, n, "fruit juice"); // Smoke - IntVar old_gold = solver.MakeIntVar(1, n, "old gold"); - IntVar kools = solver.MakeIntVar(1, n, "kools"); + IntVar old_gold = solver.MakeIntVar(1, n, "old gold"); + IntVar kools = solver.MakeIntVar(1, n, "kools"); IntVar chesterfields = solver.MakeIntVar(1, n, "chesterfields"); - IntVar lucky_strike = solver.MakeIntVar(1, n, "lucky strike"); - IntVar parliaments = solver.MakeIntVar(1, n, "parliaments"); - + IntVar lucky_strike = solver.MakeIntVar(1, n, "lucky strike"); + IntVar parliaments = solver.MakeIntVar(1, n, "parliaments"); // for search - IntVar[] all_vars = - {parliaments, kools, chesterfields, lucky_strike, old_gold, - englishman, spaniard, japanese, ukrainian, norwegian, - dog, snails, fox, zebra, horse, - tea, coffee, water, milk, fruit_juice, - red, green, yellow, blue, ivory}; + IntVar[] all_vars = { + parliaments, kools, chesterfields, lucky_strike, old_gold, + englishman, spaniard, japanese, ukrainian, norwegian, + dog, snails, fox, zebra, horse, + tea, coffee, water, milk, fruit_juice, + red, green, yellow, blue, ivory}; // // Constraints // // Alldifferents - solver.Add(new IntVar[] - {red, green, yellow, blue, ivory}.AllDifferent()); - solver.Add(new IntVar[] - {englishman, spaniard, japanese, ukrainian, norwegian}.AllDifferent()); - solver.Add(new IntVar[] - {dog, snails, fox, zebra, horse}.AllDifferent()); - solver.Add(new IntVar[] - {tea, coffee, water, milk, fruit_juice}.AllDifferent()); - solver.Add(new IntVar[] - {parliaments, kools, chesterfields, lucky_strike, old_gold}.AllDifferent()); + solver.Add(new IntVar[]{red, green, yellow, blue, ivory}.AllDifferent()); + solver.Add( + new IntVar[]{englishman, spaniard, japanese, ukrainian, norwegian} + .AllDifferent()); + solver.Add(new IntVar[]{dog, snails, fox, zebra, horse}.AllDifferent()); + solver.Add( + new IntVar[]{tea, coffee, water, milk, fruit_juice}.AllDifferent()); + solver.Add( + new IntVar[]{parliaments, kools, chesterfields, lucky_strike, old_gold} + .AllDifferent()); // // The clues @@ -138,28 +135,27 @@ public class NQueens solver.Add(japanese == parliaments); solver.Add((norwegian - blue).Abs() == 1); - // // Search // - DecisionBuilder db = solver.MakePhase(all_vars, - Solver.INT_VAR_DEFAULT, + DecisionBuilder db = solver.MakePhase(all_vars, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT); solver.NewSearch(db); IntVar[] p = {englishman, spaniard, japanese, ukrainian, norwegian}; - int[] ix = {0,1,2,3,4}; + int[] ix = {0, 1, 2, 3, 4}; while (solver.NextSolution()) { - int water_drinker = (from i in ix - where p[i].Value() == water.Value() - select i).First(); - int zebra_owner = (from i in ix - where p[i].Value() == zebra.Value() - select i).First(); - Console.WriteLine("The {0} drinks water.", p[water_drinker].ToString()); - Console.WriteLine("The {0} owns the zebra", p[zebra_owner].ToString()); - + int water_drinker = (from i in ix where p [i] + .Value() == water.Value() select i) + .First(); + int zebra_owner = (from i in ix where p [i] + .Value() == zebra.Value() select i) + .First(); + Console.WriteLine("The {0} drinks water.", p [water_drinker] + .ToString()); + Console.WriteLine("The {0} owns the zebra", p [zebra_owner] + .ToString()); } Console.WriteLine("\nSolutions: {0}", solver.Solutions()); @@ -168,11 +164,7 @@ public class NQueens Console.WriteLine("Branches: {0} ", solver.Branches()); solver.EndSearch(); - } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/dotnet/BalanceGroupSat.cs b/examples/dotnet/BalanceGroupSat.cs index 54adcc908e..fa717501e4 100644 --- a/examples/dotnet/BalanceGroupSat.cs +++ b/examples/dotnet/BalanceGroupSat.cs @@ -18,192 +18,179 @@ using Google.OrTools.Sat; /// /// We are trying to group items in equal sized groups. -/// Each item has a color and a value. We want the sum of values of each group to -/// be as close to the average as possible. -/// Furthermore, if one color is an a group, at least k items with this color must -/// be in that group. +/// Each item has a color and a value. We want the sum of values of each group +/// to be as close to the average as possible. Furthermore, if one color is an a +/// group, at least k items with this color must be in that group. /// -public class BalanceGroupSat -{ - static void Main(string[] args) - { - int numberGroups = 10; - int numberItems = 100; - int numberColors = 3; - int minItemsOfSameColorPerGroup = 4; +public class BalanceGroupSat { + static void Main(string[] args) { + int numberGroups = 10; + int numberItems = 100; + int numberColors = 3; + int minItemsOfSameColorPerGroup = 4; - var allGroups = Enumerable.Range(0, numberGroups).ToArray(); - var allItems = Enumerable.Range(0, numberItems).ToArray(); - var allColors = Enumerable.Range(0, numberColors).ToArray(); + var allGroups = Enumerable.Range(0, numberGroups).ToArray(); + var allItems = Enumerable.Range(0, numberItems).ToArray(); + var allColors = Enumerable.Range(0, numberColors).ToArray(); - var values = allItems.Select(i => 1 + i + (i * i / 200)).ToArray(); - var colors = allItems.Select(i => i % numberColors).ToArray(); + var values = allItems.Select(i => 1 + i + (i * i / 200)).ToArray(); + var colors = allItems.Select(i => i % numberColors).ToArray(); - var sumOfValues = values.Sum(); - var averageSumPerGroup = sumOfValues / numberGroups; - var numItemsPerGroup = numberItems / numberGroups; + var sumOfValues = values.Sum(); + var averageSumPerGroup = sumOfValues / numberGroups; + var numItemsPerGroup = numberItems / numberGroups; - var itemsPerColor = new Dictionary>(); + var itemsPerColor = new Dictionary>(); - foreach (var color in allColors) - { - itemsPerColor[color] = new List(); - foreach (var item in allItems) - { - if(colors[item] == color) - itemsPerColor[color].Add(item); - } - } - - Console.WriteLine($"Model has {numberItems}, {numberGroups} groups and {numberColors} colors"); - Console.WriteLine($" Average sum per group = {averageSumPerGroup}"); - - var model = new CpModel(); - - var itemInGroup = new IntVar[numberItems, numberGroups]; - foreach (var item in allItems) - { - foreach (var @group in allGroups) - { - itemInGroup[item, @group] = model.NewBoolVar($"item {item} in group {@group}"); - } - } - - // Each group must have the same size. - foreach (var @group in allGroups) - { - var itemsInGroup = allItems.Select(x => itemInGroup[x, @group]).ToArray(); - model.AddLinearConstraint(LinearExpr.Sum(itemsInGroup), numItemsPerGroup, numItemsPerGroup); - } - - //# One item must belong to exactly one group. - foreach (var item in allItems) - { - var groupsForItem = allGroups.Select(x => itemInGroup[item, x]).ToArray(); - model.Add(LinearExpr.Sum(groupsForItem) == 1); - } - - // The deviation of the sum of each items in a group against the average. - var e = model.NewIntVar(0, 550, "epsilon"); - - // Constrain the sum of values in one group around the average sum per group. - foreach (var @group in allGroups) - { - var itemValues = allItems.Select(x => itemInGroup[x, @group]).ToArray(); - - var sum = LinearExpr.ScalProd(itemValues, values); - model.Add(sum <= averageSumPerGroup + e); - model.Add(sum >= averageSumPerGroup - e); - } - - // colorInGroup variables. - var colorInGroup = new IntVar[numberColors, numberGroups]; - foreach (var @group in allGroups) - { - foreach (var color in allColors) - { - colorInGroup[color, @group] = model.NewBoolVar($"color {color} is in group {@group}"); - } - } - - // Item is in a group implies its color is in that group. - foreach (var item in allItems) - { - foreach (var @group in allGroups) - { - model.AddImplication(itemInGroup[item, @group], colorInGroup[colors[item], @group]); - } - } - - // If a color is in a group, it must contains at least - // min_items_of_same_color_per_group items from that color. - foreach (var color in allColors) - { - foreach (var @group in allGroups) - { - var literal = colorInGroup[color, @group]; - var items = itemsPerColor[color].Select(x => itemInGroup[x, @group]).ToArray(); - model.Add(LinearExpr.Sum(items) >= minItemsOfSameColorPerGroup).OnlyEnforceIf(literal); - } - } - - // Compute the maximum number of colors in a group. - int maxColor = numItemsPerGroup / minItemsOfSameColorPerGroup; - // Redundant contraint: The problem does not solve in reasonable time without it. - if (maxColor < numberColors) - { - foreach (var @group in allGroups) - { - var all = allColors.Select(x => colorInGroup[x, @group]).ToArray(); - model.Add(LinearExpr.Sum(all) <= maxColor); - } - } - - // Minimize epsilon - model.Minimize(e); - - var solver = new CpSolver(); - solver.StringParameters = ""; - - var solutionPrinter = new SolutionPrinter(values, colors, allGroups, allItems, itemInGroup); - - var status = solver.SolveWithSolutionCallback(model, solutionPrinter); + foreach (var color in allColors) { + itemsPerColor[color] = new List(); + foreach (var item in allItems) { + if (colors[item] == color) + itemsPerColor [color] + .Add(item); + } } - public class SolutionPrinter : CpSolverSolutionCallback - { - private int[] _values; - private int[] _colors; - private int[] _allGroups; - private int[] _allItems; - private IntVar[,] _itemInGroup; + Console.WriteLine( + $"Model has {numberItems}, {numberGroups} groups and {numberColors} colors"); + Console.WriteLine($" Average sum per group = {averageSumPerGroup}"); - private int _solutionCount; + var model = new CpModel(); - public SolutionPrinter(int[] values, int[] colors, int[] allGroups, int[] allItems, IntVar[,] itemInGroup) - { - this._values = values; - this._colors = colors; - this._allGroups = allGroups; - this._allItems = allItems; - this._itemInGroup = itemInGroup; - } - - public override void OnSolutionCallback() - { - Console.WriteLine($"Solution {_solutionCount}"); - _solutionCount++; - - Console.WriteLine($" objective value = {this.ObjectiveValue()}"); - - Dictionary> groups = new Dictionary>(); - int[] sum = new int[_allGroups.Length]; - - foreach (var @group in _allGroups) - { - groups[@group] = new List(); - foreach (var item in _allItems) - { - if (BooleanValue(_itemInGroup[item, @group])) - { - groups[@group].Add(item); - sum[@group] += _values[item]; - } - } - } - - foreach (var g in _allGroups) - { - var group = groups[g]; - Console.Write($"Group {g}: sum = {sum[g]} ["); - foreach (var item in group) - { - Console.Write($"({item}, {_values[item]}, {_colors[item]})"); - } - - Console.WriteLine("]"); - } - } + var itemInGroup = new IntVar[numberItems, numberGroups]; + foreach (var item in allItems) { + foreach (var @group in allGroups) { + itemInGroup[item, @group] = + model.NewBoolVar($"item {item} in group {@group}"); + } } + + // Each group must have the same size. + foreach (var @group in allGroups) { + var itemsInGroup = allItems.Select(x => itemInGroup[x, @group]).ToArray(); + model.AddLinearConstraint(LinearExpr.Sum(itemsInGroup), numItemsPerGroup, + numItemsPerGroup); + } + + //# One item must belong to exactly one group. + foreach (var item in allItems) { + var groupsForItem = allGroups.Select(x => itemInGroup[item, x]).ToArray(); + model.Add(LinearExpr.Sum(groupsForItem) == 1); + } + + // The deviation of the sum of each items in a group against the average. + var e = model.NewIntVar(0, 550, "epsilon"); + + // Constrain the sum of values in one group around the average sum per + // group. + foreach (var @group in allGroups) { + var itemValues = allItems.Select(x => itemInGroup[x, @group]).ToArray(); + + var sum = LinearExpr.ScalProd(itemValues, values); + model.Add(sum <= averageSumPerGroup + e); + model.Add(sum >= averageSumPerGroup - e); + } + + // colorInGroup variables. + var colorInGroup = new IntVar[numberColors, numberGroups]; + foreach (var @group in allGroups) { + foreach (var color in allColors) { + colorInGroup[color, @group] = + model.NewBoolVar($"color {color} is in group {@group}"); + } + } + + // Item is in a group implies its color is in that group. + foreach (var item in allItems) { + foreach (var @group in allGroups) { + model.AddImplication(itemInGroup[item, @group], + colorInGroup[colors[item], @group]); + } + } + + // If a color is in a group, it must contains at least + // min_items_of_same_color_per_group items from that color. + foreach (var color in allColors) { + foreach (var @group in allGroups) { + var literal = colorInGroup[color, @group]; + var items = itemsPerColor [color] + .Select(x => itemInGroup[x, @group]) + .ToArray(); + model.Add(LinearExpr.Sum(items) >= minItemsOfSameColorPerGroup) + .OnlyEnforceIf(literal); + } + } + + // Compute the maximum number of colors in a group. + int maxColor = numItemsPerGroup / minItemsOfSameColorPerGroup; + // Redundant contraint: The problem does not solve in reasonable time + // without it. + if (maxColor < numberColors) { + foreach (var @group in allGroups) { + var all = allColors.Select(x => colorInGroup[x, @group]).ToArray(); + model.Add(LinearExpr.Sum(all) <= maxColor); + } + } + + // Minimize epsilon + model.Minimize(e); + + var solver = new CpSolver(); + solver.StringParameters = ""; + + var solutionPrinter = + new SolutionPrinter(values, colors, allGroups, allItems, itemInGroup); + + var status = solver.SolveWithSolutionCallback(model, solutionPrinter); + } + + public class SolutionPrinter : CpSolverSolutionCallback { + private int[] _values; + private int[] _colors; + private int[] _allGroups; + private int[] _allItems; + private IntVar[, ] _itemInGroup; + + private int _solutionCount; + + public SolutionPrinter(int[] values, int[] colors, int[] allGroups, + int[] allItems, IntVar[, ] itemInGroup) { + this._values = values; + this._colors = colors; + this._allGroups = allGroups; + this._allItems = allItems; + this._itemInGroup = itemInGroup; + } + + public override void OnSolutionCallback() { + Console.WriteLine($"Solution {_solutionCount}"); + _solutionCount++; + + Console.WriteLine($" objective value = {this.ObjectiveValue()}"); + + Dictionary> groups = new Dictionary>(); + int[] sum = new int[_allGroups.Length]; + + foreach (var @group in _allGroups) { + groups[@group] = new List(); + foreach (var item in _allItems) { + if (BooleanValue(_itemInGroup[item, @group])) { + groups [@group] + .Add(item); + sum[@group] += _values[item]; + } + } + } + + foreach (var g in _allGroups) { + var group = groups[g]; + Console.Write($"Group {g}: sum = {sum[g]} ["); + foreach (var item in group) { + Console.Write($"({item}, {_values[item]}, {_colors[item]})"); + } + + Console.WriteLine("]"); + } + } + } } - diff --git a/examples/dotnet/GateSchedulingSat.cs b/examples/dotnet/GateSchedulingSat.cs index 3f7d90190e..3b72dc739e 100644 --- a/examples/dotnet/GateSchedulingSat.cs +++ b/examples/dotnet/GateSchedulingSat.cs @@ -19,46 +19,30 @@ // At any point in time, the sum of the width of the two active jobs does not // exceed a max_length. // -//The objective is to minimize the max end time of all jobs. +// The objective is to minimize the max end time of all jobs. using System; using System.Collections.Generic; using System.Linq; using Google.OrTools.Sat; -public class GateSchedulingSat -{ - static void Main() - { +public class GateSchedulingSat { + static void Main() { CpModel model = new CpModel(); - int[,] jobs = new [,] {{3, 3}, - {2, 5}, - {1, 3}, - {3, 7}, - {7, 3}, - {2, 2}, - {2, 2}, - {5, 5}, - {10, 2}, - {4, 3}, - {2, 6}, - {1, 2}, - {6, 8}, - {4, 5}, - {3, 7}}; + int[, ] jobs = + new[, ]{{3, 3}, {2, 5}, {1, 3}, {3, 7}, {7, 3}, {2, 2}, {2, 2}, {5, 5}, + {10, 2}, {4, 3}, {2, 6}, {1, 2}, {6, 8}, {4, 5}, {3, 7}}; int max_length = 10; int num_jobs = jobs.GetLength(0); var all_jobs = Enumerable.Range(0, num_jobs); int horizon = 0; - foreach (int j in all_jobs) - { + foreach (int j in all_jobs) { horizon += jobs[j, 0]; } - List intervals = new List(); List intervals0 = new List(); List intervals1 = new List(); @@ -67,41 +51,40 @@ public class GateSchedulingSat List ends = new List(); List demands = new List(); - foreach (int i in all_jobs) - { + foreach (int i in all_jobs) { // Create main interval. IntVar start = model.NewIntVar(0, horizon, String.Format("start_{0}", i)); int duration = jobs[i, 0]; - IntVar end = model.NewIntVar(0, horizon, String.Format("end_{0}", i)); + IntVar end = model.NewIntVar(0, horizon, String.Format("end_{0}", i)); IntervalVar interval = model.NewIntervalVar( - start, duration, end, String.Format("interval_{0}", i)); + start, duration, end, String.Format("interval_{0}", i)); starts.Add(start); intervals.Add(interval); ends.Add(end); demands.Add(jobs[i, 1]); IntVar performed_on_m0 = - model.NewBoolVar(String.Format("perform_{0}_on_m0", i)); + model.NewBoolVar(String.Format("perform_{0}_on_m0", i)); performed.Add(performed_on_m0); // Create an optional copy of interval to be executed on machine 0. - IntVar start0 = model.NewIntVar( - 0, horizon, String.Format("start_{0}_on_m0", i)); - IntVar end0 = model.NewIntVar( - 0, horizon, String.Format("end_{0}_on_m0", i)); - IntervalVar interval0 = model.NewOptionalIntervalVar( - start0, duration, end0, performed_on_m0, - String.Format("interval_{0}_on_m0", i)); + IntVar start0 = + model.NewIntVar(0, horizon, String.Format("start_{0}_on_m0", i)); + IntVar end0 = + model.NewIntVar(0, horizon, String.Format("end_{0}_on_m0", i)); + IntervalVar interval0 = + model.NewOptionalIntervalVar(start0, duration, end0, performed_on_m0, + String.Format("interval_{0}_on_m0", i)); intervals0.Add(interval0); // Create an optional copy of interval to be executed on machine 1. - IntVar start1 = model.NewIntVar( - 0, horizon, String.Format("start_{0}_on_m1", i)); - IntVar end1 = model.NewIntVar( - 0, horizon, String.Format("end_{0}_on_m1", i)); + IntVar start1 = + model.NewIntVar(0, horizon, String.Format("start_{0}_on_m1", i)); + IntVar end1 = + model.NewIntVar(0, horizon, String.Format("end_{0}_on_m1", i)); IntervalVar interval1 = model.NewOptionalIntervalVar( - start1, duration, end1, performed_on_m0.Not(), - String.Format("interval_{0}_on_m1", i)); + start1, duration, end1, performed_on_m0.Not(), + String.Format("interval_{0}_on_m1", i)); intervals1.Add(interval1); // We only propagate the constraint if the tasks is performed on the @@ -129,17 +112,15 @@ public class GateSchedulingSat CpSolver solver = new CpSolver(); solver.Solve(model); - // Output solution. Console.WriteLine("Solution"); Console.WriteLine(" - makespan = " + solver.ObjectiveValue); - foreach (int i in all_jobs) - { + foreach (int i in all_jobs) { long performed_machine = 1 - solver.Value(performed[i]); long start = solver.Value(starts[i]); Console.WriteLine( - String.Format(" - Job {0} starts at {1} on machine {2}", - i, start, performed_machine)); + String.Format(" - Job {0} starts at {1} on machine {2}", i, start, + performed_machine)); } Console.WriteLine("Statistics"); Console.WriteLine(" - conflicts : " + solver.NumConflicts()); diff --git a/examples/dotnet/JobshopFt06Sat.cs b/examples/dotnet/JobshopFt06Sat.cs index 6acfc7acc2..c3accfe756 100644 --- a/examples/dotnet/JobshopFt06Sat.cs +++ b/examples/dotnet/JobshopFt06Sat.cs @@ -16,13 +16,9 @@ using System.Collections.Generic; using System.Linq; using Google.OrTools.Sat; -public class JobshopFt06Sat -{ - - public struct Task - { - public Task(IntVar s, IntVar e, IntervalVar i) - { +public class JobshopFt06Sat { + public struct Task { + public Task(IntVar s, IntVar e, IntervalVar i) { start = s; end = e; interval = i; @@ -33,20 +29,13 @@ public class JobshopFt06Sat public IntervalVar interval; } - static void Main() - { - int[,] durations = new int[,] { {1, 3, 6, 7, 3, 6}, - {8, 5, 10, 10, 10, 4}, - {5, 4, 8, 9, 1, 7}, - {5, 5, 5, 3, 8, 9}, - {9, 3, 5, 4, 3, 1}, - {3, 3, 9, 10, 4, 1} }; - int[,] machines = new int[,] { {2, 0, 1, 3, 5, 4}, - {1, 2, 4, 5, 0, 3}, - {2, 3, 5, 0, 1, 4}, - {1, 0, 2, 3, 4, 5}, - {2, 1, 4, 5, 0, 3}, - {1, 3, 5, 0, 4, 2} }; + static void Main() { + int[, ] durations = new int[, ]{{1, 3, 6, 7, 3, 6}, {8, 5, 10, 10, 10, 4}, + {5, 4, 8, 9, 1, 7}, {5, 5, 5, 3, 8, 9}, + {9, 3, 5, 4, 3, 1}, {3, 3, 9, 10, 4, 1}}; + int[, ] machines = + new int[, ]{{2, 0, 1, 3, 5, 4}, {1, 2, 4, 5, 0, 3}, {2, 3, 5, 0, 1, 4}, + {1, 0, 2, 3, 4, 5}, {2, 1, 4, 5, 0, 3}, {1, 3, 5, 0, 4, 2}}; int num_jobs = durations.GetLength(0); int num_machines = durations.GetLength(1); @@ -54,67 +43,55 @@ public class JobshopFt06Sat var all_machines = Enumerable.Range(0, num_machines); int horizon = 0; - foreach (int j in all_jobs) - { - foreach (int m in all_machines) - { + foreach (int j in all_jobs) { + foreach (int m in all_machines) { horizon += durations[j, m]; } } - // Creates the model. CpModel model = new CpModel(); // Creates jobs. - Task[,] all_tasks = new Task[num_jobs, num_machines]; - foreach (int j in all_jobs) - { - foreach (int m in all_machines) - { - IntVar start_var = model.NewIntVar( - 0, horizon, String.Format("start_{0}_{1}", j, m)); + Task[, ] all_tasks = new Task[num_jobs, num_machines]; + foreach (int j in all_jobs) { + foreach (int m in all_machines) { + IntVar start_var = + model.NewIntVar(0, horizon, String.Format("start_{0}_{1}", j, m)); int duration = durations[j, m]; - IntVar end_var = model.NewIntVar( - 0, horizon, String.Format("end_{0}_{1}", j, m)); - IntervalVar interval_var = model.NewIntervalVar( - start_var, duration, end_var, - String.Format("interval_{0}_{1}", j, m)); + IntVar end_var = + model.NewIntVar(0, horizon, String.Format("end_{0}_{1}", j, m)); + IntervalVar interval_var = + model.NewIntervalVar(start_var, duration, end_var, + String.Format("interval_{0}_{1}", j, m)); all_tasks[j, m] = new Task(start_var, end_var, interval_var); } } // Create disjuctive constraints. - List[] machine_to_jobs = new List[num_machines]; - foreach (int m in all_machines) - { + List[] machine_to_jobs = new List[ num_machines ]; + foreach (int m in all_machines) { machine_to_jobs[m] = new List(); } - foreach (int j in all_jobs) - { - foreach (int m in all_machines) - { + foreach (int j in all_jobs) { + foreach (int m in all_machines) { machine_to_jobs[machines[j, m]].Add(all_tasks[j, m].interval); } } - foreach (int m in all_machines) - { + foreach (int m in all_machines) { model.AddNoOverlap(machine_to_jobs[m]); } // Precedences inside a job. - foreach (int j in all_jobs) - { - for (int k = 0; k < num_machines - 1; ++k) - { + foreach (int j in all_jobs) { + for (int k = 0; k < num_machines - 1; ++k) { model.Add(all_tasks[j, k + 1].start >= all_tasks[j, k].end); } } // Makespan objective. IntVar[] all_ends = new IntVar[num_jobs]; - foreach (int j in all_jobs) - { + foreach (int j in all_jobs) { all_ends[j] = all_tasks[j, num_machines - 1].end; } IntVar makespan = model.NewIntVar(0, horizon, "makespan"); diff --git a/examples/dotnet/JobshopSat.cs b/examples/dotnet/JobshopSat.cs index 395096446c..e51269e0b2 100644 --- a/examples/dotnet/JobshopSat.cs +++ b/examples/dotnet/JobshopSat.cs @@ -3,41 +3,45 @@ using System.Collections.Generic; using System.Linq; using Google.OrTools.Sat; - -class Task -{ - public Task(int taskId, int jobId, int duration, int machine) - { +class Task { + public Task(int taskId, int jobId, int duration, int machine) { TaskId = taskId; JobId = jobId; Duration = duration; Machine = machine; - Name = "T" + taskId + "J" + jobId + "M" + - machine + "D" + duration; + Name = "T" + taskId + "J" + jobId + "M" + machine + "D" + duration; + } + public int TaskId { + get; + set; + } + public int JobId { + get; + set; + } + public int Machine { + get; + set; + } + public int Duration { + get; + set; } - public int TaskId { get; set; } - public int JobId { get; set; } - public int Machine { get; set; } - public int Duration { get; set; } public string Name { get; } } - - -class JobshopSat -{ - //Number of machines. +class JobshopSat { + // Number of machines. public const int machinesCount = 3; - //horizon is the upper bound of the start time of all tasks. + // horizon is the upper bound of the start time of all tasks. public const int horizon = 300; - //this will be set to the size of myJobList variable. + // this will be set to the size of myJobList variable. public static int jobsCount; /*Search time limit in milliseconds. if it's equal to 0, then no time limit will be used.*/ public const int timeLimitInSeconds = 0; public static List> myJobList = new List>(); - public static void InitTaskList() - { + public static void InitTaskList() { List taskList = new List(); taskList.Add(new Task(0, 0, 65, 0)); taskList.Add(new Task(1, 0, 5, 1)); @@ -95,75 +99,72 @@ class JobshopSat jobsCount = myJobList.Count; } - public static void Main(String[] args) - { + public static void Main(String[] args) { InitTaskList(); CpModel model = new CpModel(); // ----- Creates all intervals and integer variables ----- // Stores all tasks attached interval variables per job. - List> - jobsToTasks = new List>(jobsCount); - List> - jobsToStarts = new List>(jobsCount); - List> - jobsToEnds = new List>(jobsCount); + List> jobsToTasks = + new List>(jobsCount); + List> jobsToStarts = new List>(jobsCount); + List> jobsToEnds = new List>(jobsCount); // machinesToTasks stores the same interval variables as above, but // grouped my machines instead of grouped by jobs. - List> - machinesToTasks = new List>(machinesCount); - List> - machinesToStarts = new List>(machinesCount); - for (int i = 0; i < machinesCount; i++) - { + List> machinesToTasks = + new List>(machinesCount); + List> machinesToStarts = new List>(machinesCount); + for (int i = 0; i < machinesCount; i++) { machinesToTasks.Add(new List()); machinesToStarts.Add(new List()); } // Creates all individual interval variables. - foreach (List job in myJobList) - { + foreach (List job in myJobList) { jobsToTasks.Add(new List()); jobsToStarts.Add(new List()); jobsToEnds.Add(new List()); - foreach (Task task in job) - { + foreach (Task task in job) { IntVar start = model.NewIntVar(0, horizon, task.Name); IntVar end = model.NewIntVar(0, horizon, task.Name); IntervalVar oneTask = model.NewIntervalVar(start, task.Duration, end, task.Name); - jobsToTasks[task.JobId].Add(oneTask); - jobsToStarts[task.JobId].Add(start); - jobsToEnds[task.JobId].Add(end); - machinesToTasks[task.Machine].Add(oneTask); - machinesToStarts[task.Machine].Add(start); + jobsToTasks [task.JobId] + .Add(oneTask); + jobsToStarts [task.JobId] + .Add(start); + jobsToEnds [task.JobId] + .Add(end); + machinesToTasks [task.Machine] + .Add(oneTask); + machinesToStarts [task.Machine] + .Add(start); } } // ----- Creates model ----- // Creates precedences inside jobs. - for (int j = 0; j < jobsToTasks.Count; ++j) - { - for (int t = 0; t < jobsToTasks[j].Count - 1; ++t) - { - model.Add(jobsToEnds[j][t] <= jobsToStarts[j][t + 1]); + for (int j = 0; j < jobsToTasks.Count; ++j) { + for (int t = 0; t < jobsToTasks[j].Count - 1; ++t) { + model.Add(jobsToEnds [j] + [t] <= jobsToStarts [j] + [t + 1]); } } // Adds no_overkap constraints on unary resources. - for (int machineId = 0; machineId < machinesCount; ++machineId) - { + for (int machineId = 0; machineId < machinesCount; ++machineId) { model.AddNoOverlap(machinesToTasks[machineId]); } // Creates array of end_times of jobs. IntVar[] allEnds = new IntVar[jobsCount]; - for (int i = 0; i < jobsCount; i++) - { - allEnds[i] = jobsToEnds[i].Last(); + for (int i = 0; i < jobsCount; i++) { + allEnds[i] = jobsToEnds [i] + .Last(); } // Objective: minimize the makespan (maximum end times of all tasks) @@ -172,36 +173,29 @@ class JobshopSat model.AddMaxEquality(makespan, allEnds); model.Minimize(makespan); - // Create the solver. CpSolver solver = new CpSolver(); // Set the time limit. - if (timeLimitInSeconds > 0) - { + if (timeLimitInSeconds > 0) { solver.StringParameters = "max_time_in_seconds:" + timeLimitInSeconds; } // Solve the problem. CpSolverStatus status = solver.Solve(model); - if (status == CpSolverStatus.Optimal) - { + if (status == CpSolverStatus.Optimal) { Console.WriteLine("Makespan = " + solver.ObjectiveValue); - for (int m = 0; m < machinesCount; ++m) - { + for (int m = 0; m < machinesCount; ++m) { Console.WriteLine($"Machine {m}:"); - SortedDictionary starts = new SortedDictionary(); - foreach (IntVar var in machinesToStarts[m]) - { + SortedDictionary starts = + new SortedDictionary(); + foreach (IntVar var in machinesToStarts[m]) { starts[solver.Value(var)] = var.Name(); } - foreach (KeyValuePair p in starts) - { + foreach (KeyValuePair p in starts) { Console.WriteLine($" Task {p.Value} starts at {p.Key}"); } } - } - else - { + } else { Console.WriteLine("No solution found!"); } } diff --git a/examples/dotnet/NetworkRoutingSat.cs b/examples/dotnet/NetworkRoutingSat.cs index 48a4a1a64b..fa21416b21 100644 --- a/examples/dotnet/NetworkRoutingSat.cs +++ b/examples/dotnet/NetworkRoutingSat.cs @@ -11,14 +11,12 @@ // See the License for the specific language governing permissions and // limitations under the License. - using Google.OrTools.Sat; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; - /// /// This model solves a multicommodity mono-routing problem with /// capacity constraints and a max usage cost structure. This means @@ -31,1118 +29,1069 @@ using System.Linq; /// Please note that constraint programming is well suited here because /// we cannot have multiple active paths for a single demand. /// Otherwise, a approach based on a linear solver is a better match. -/// A random problem generator is also included. +/// A random problem generator is also included. /// -public class NetworkRoutingSat -{ - private static int clients = 0; // Number of network clients nodes. If equal to zero, then all backbones nodes are also client nodes. - private static int backbones = 0; // "Number of backbone nodes" - private static int demands = 0; // "Number of network demands." - private static int trafficMin = 0; // "Min traffic of a demand." - private static int trafficMax = 0; // "Max traffic of a demand." - private static int minClientDegree = 0; //"Min number of connections from a client to the backbone." - private static int maxClientDegree = 0; //"Max number of connections from a client to the backbone." - private static int minBackboneDegree = 0; //"Min number of connections from a backbone node to the rest of the backbone nodes." - private static int maxBackboneDegree = 0; // "Max number of connections from a backbone node to the rest of the backbone nodes." - private static int maxCapacity = 0; //"Max traffic on any arc." - private static int fixedChargeCost = 0; //"Fixed charged cost when using an arc." - private static int seed = 0; //"Random seed" - private static double comfortZone = 0.85; // "Above this limit in 1/1000th, the link is said to be congested." - private static int extraHops = 6; // "When creating all paths for a demand, we look at paths with maximum length 'shortest path + extra_hops'" - private static int maxPaths = 1200; //"Max number of possible paths for a demand." - private static bool printModel = false; //"Print details of the model." - private static string parameters = ""; // "Sat parameters." +public class NetworkRoutingSat { + private static int clients = + 0; // Number of network clients nodes. If equal to zero, then all + // backbones nodes are also client nodes. + private static int backbones = 0; // "Number of backbone nodes" + private static int demands = 0; // "Number of network demands." + private static int trafficMin = 0; // "Min traffic of a demand." + private static int trafficMax = 0; // "Max traffic of a demand." + private static int minClientDegree = + 0; //"Min number of connections from a client to the backbone." + private static int maxClientDegree = + 0; //"Max number of connections from a client to the backbone." + private static int minBackboneDegree = + 0; //"Min number of connections from a backbone node to the rest of the + // backbone nodes." + private static int maxBackboneDegree = + 0; // "Max number of connections from a backbone node to the rest of the + // backbone nodes." + private static int maxCapacity = 0; //"Max traffic on any arc." + private static int fixedChargeCost = + 0; //"Fixed charged cost when using an arc." + private static int seed = 0; //"Random seed" + private static double comfortZone = + 0.85; // "Above this limit in 1/1000th, the link is said to be + // congested." + private static int extraHops = + 6; // "When creating all paths for a demand, we look at paths with + // maximum length 'shortest path + extra_hops'" + private static int maxPaths = + 1200; //"Max number of possible paths for a demand." + private static bool printModel = false; //"Print details of the model." + private static string parameters = ""; // "Sat parameters." - private const long kDisconnectedDistance = -1L; + private const long kDisconnectedDistance = -1L; - static void Main(string[] args) - { - readArgs(args); - var builder = new NetworkRoutingDataBuilder(); - var data = builder.BuildModelFromParameters(clients, backbones, demands, trafficMin, trafficMax, - minClientDegree, maxClientDegree, minBackboneDegree, maxBackboneDegree, maxCapacity, fixedChargeCost, seed); - var solver = new NetworkRoutingSolver(); - solver.Init(data, extraHops, maxPaths); - var cost = solver.Solve(); - Console.WriteLine($"Final cost = {cost}"); + static void Main(string[] args) { + readArgs(args); + var builder = new NetworkRoutingDataBuilder(); + var data = builder.BuildModelFromParameters( + clients, backbones, demands, trafficMin, trafficMax, minClientDegree, + maxClientDegree, minBackboneDegree, maxBackboneDegree, maxCapacity, + fixedChargeCost, seed); + var solver = new NetworkRoutingSolver(); + solver.Init(data, extraHops, maxPaths); + var cost = solver.Solve(); + Console.WriteLine($"Final cost = {cost}"); + } + + private static void readArgs(string[] args) { + readInt(args, ref clients, nameof(clients)); + readInt(args, ref backbones, nameof(backbones)); + readInt(args, ref demands, nameof(demands)); + readInt(args, ref trafficMin, nameof(trafficMin)); + readInt(args, ref trafficMax, nameof(trafficMax)); + readInt(args, ref minClientDegree, nameof(minClientDegree)); + readInt(args, ref maxClientDegree, nameof(maxClientDegree)); + readInt(args, ref minBackboneDegree, nameof(minBackboneDegree)); + readInt(args, ref maxBackboneDegree, nameof(maxBackboneDegree)); + readInt(args, ref maxCapacity, nameof(maxCapacity)); + readInt(args, ref fixedChargeCost, nameof(fixedChargeCost)); + readInt(args, ref seed, nameof(seed)); + readDouble(args, ref comfortZone, nameof(comfortZone)); + readInt(args, ref extraHops, nameof(extraHops)); + readInt(args, ref maxPaths, nameof(maxPaths)); + readBoolean(args, ref printModel, nameof(printModel)); + readString(args, ref parameters, nameof(parameters)); + } + + private static void readDouble(string[] args, ref double setting, + string arg) { + var v = getArgValue(args, arg); + if (v.IsSet) { + setting = Convert.ToDouble(v.Value); + } + } + + private static void readInt(string[] args, ref int setting, string arg) { + var v = getArgValue(args, arg); + if (v.IsSet) { + setting = Convert.ToInt32(v.Value); + } + } + + private static void readBoolean(string[] args, ref bool setting, string arg) { + var v = getArgValue(args, arg); + if (v.IsSet) { + setting = Convert.ToBoolean(v.Value); + } + } + + private static void readString(string[] args, ref string setting, + string arg) { + var v = getArgValue(args, arg); + if (v.IsSet) { + setting = v.Value; + } + } + + private static(bool IsSet, string Value) + getArgValue(string[] args, string arg) { + string lookup = $"--{arg}="; + + var item = args.FirstOrDefault(x => x.StartsWith(lookup)); + + if (string.IsNullOrEmpty(item)) { + return (false, string.Empty); } - private static void readArgs(string[] args) - { - readInt(args, ref clients, nameof(clients)); - readInt(args, ref backbones, nameof(backbones)); - readInt(args, ref demands, nameof(demands)); - readInt(args, ref trafficMin, nameof(trafficMin)); - readInt(args, ref trafficMax, nameof(trafficMax)); - readInt(args, ref minClientDegree, nameof(minClientDegree)); - readInt(args, ref maxClientDegree, nameof(maxClientDegree)); - readInt(args, ref minBackboneDegree, nameof(minBackboneDegree)); - readInt(args, ref maxBackboneDegree, nameof(maxBackboneDegree)); - readInt(args, ref maxCapacity, nameof(maxCapacity)); - readInt(args, ref fixedChargeCost, nameof(fixedChargeCost)); - readInt(args, ref seed, nameof(seed)); - readDouble(args, ref comfortZone, nameof(comfortZone)); - readInt(args, ref extraHops, nameof(extraHops)); - readInt(args, ref maxPaths, nameof(maxPaths)); - readBoolean(args, ref printModel, nameof(printModel)); - readString(args, ref parameters, nameof(parameters)); + return (true, item.Replace(lookup, string.Empty)); + } + + /// + /// Contains problem data. It assumes capacities are symmetrical: + /// (capacity(i->j) == capacity(j->i)). + /// Demands are not symmetrical. + /// + public class NetworkRoutingData { + private Dictionary<(int source, int destination), int> _arcs = + new Dictionary<(int source, int destination), int>(); + private Dictionary<(int node1, int node2), int> _demands = + new Dictionary<(int node1, int node2), int>(); + + public int NumberOfNodes { + get; + set; + } + = -1; + + public int NumberOfArcs { + get { return _arcs.Count(); } } - private static void readDouble(string[] args, ref double setting, string arg) - { - var v = getArgValue(args, arg); - if (v.IsSet) - { - setting = Convert.ToDouble(v.Value); - } + public int NumberOfDemands { + get { return _demands.Count(); } } - private static void readInt(string[] args, ref int setting, string arg) - { - var v = getArgValue(args, arg); - if (v.IsSet) - { - setting = Convert.ToInt32(v.Value); - } + public int MaximumCapacity { + get; + set; + } + = -1; + public int FixedChargeCost { + get; + set; + } + = -1; + public string Name { + get; + set; + } + = string.Empty; + + public void AddDemand(int source, int destination, int traffic) { + var pair = (source, destination); + if (!_demands.ContainsKey(pair)) _demands.Add(pair, traffic); } - private static void readBoolean(string[] args, ref bool setting, string arg) - { - var v = getArgValue(args, arg); - if (v.IsSet) - { - setting = Convert.ToBoolean(v.Value); - } + public void AddArc(int node1, int node2, int capacity) { + _arcs.Add((Math.Min(node1, node2), Math.Max(node1, node2)), capacity); } - private static void readString(string[] args, ref string setting, string arg) - { - var v = getArgValue(args, arg); - if (v.IsSet) - { - setting = v.Value; - } + public int Demand(int source, int destination) { + var pair = (source, destination); + if (_demands.TryGetValue(pair, out var demand)) return demand; + + return 0; } - private static (bool IsSet, string Value) getArgValue(string[] args, string arg) - { - string lookup = $"--{arg}="; + public int Capacity(int node1, int node2) { + var pair = (Math.Min(node1, node2), Math.Max(node1, node2)); + if (_arcs.TryGetValue(pair, out var capacity)) return capacity; - var item = args.FirstOrDefault(x => x.StartsWith(lookup)); + return 0; + } + } - if (string.IsNullOrEmpty(item)) - { - return (false, string.Empty); - } + /// + /// Random generator of problem. This generator creates a random + /// problem. This problem uses a special topology. There are + /// 'numBackbones' nodes and 'numClients' nodes. if 'numClients' is + /// null, then all backbones nodes are also client nodes. All traffic + /// originates and terminates in client nodes. Each client node is + /// connected to 'minClientDegree' - 'maxClientDegree' backbone + /// nodes. Each backbone node is connected to 'minBackboneDegree' - + /// 'maxBackboneDegree' other backbone nodes. There are 'numDemands' + /// demands, with a traffic between 'trafficMin' and 'trafficMax'. + /// Each arc has a capacity of 'maxCapacity'. Using an arc incurs a + /// fixed cost of 'fixedChargeCost'. + /// + public class NetworkRoutingDataBuilder { + private List> _network; + private List _degrees; + private Random _random; - return (true, item.Replace(lookup, string.Empty)); + public NetworkRoutingData BuildModelFromParameters( + int numClients, int numBackbones, int numDemands, int trafficMin, + int trafficMax, int minClientDegree, int maxClientDegree, + int minBackboneDegree, int maxBackboneDegree, int maxCapacity, + int fixedChargeCost, int seed) { + Debug.Assert(numBackbones >= 1); + Debug.Assert(numClients >= 0); + Debug.Assert(numDemands >= 1); + Debug.Assert(numDemands <= (numClients == 0 ? numBackbones * numBackbones + : numClients * numBackbones)); + Debug.Assert(maxClientDegree >= minClientDegree); + Debug.Assert(maxBackboneDegree >= minBackboneDegree); + Debug.Assert(trafficMax >= 1); + Debug.Assert(trafficMax >= trafficMin); + Debug.Assert(trafficMin >= 1); + Debug.Assert(maxBackboneDegree >= 2); + Debug.Assert(maxClientDegree >= 2); + Debug.Assert(maxClientDegree <= numBackbones); + Debug.Assert(maxBackboneDegree <= numBackbones); + Debug.Assert(maxCapacity >= 1); + + int size = numBackbones + numClients; + initData(size, seed); + buildGraph(numClients, numBackbones, minClientDegree, maxClientDegree, + minBackboneDegree, maxBackboneDegree); + NetworkRoutingData data = new NetworkRoutingData(); + createDemands(numClients, numBackbones, numDemands, trafficMin, + trafficMax, data); + fillData(numClients, numBackbones, numDemands, trafficMin, trafficMax, + minClientDegree, maxClientDegree, minBackboneDegree, + maxBackboneDegree, maxCapacity, fixedChargeCost, seed, data); + + return data; } - /// - /// Contains problem data. It assumes capacities are symmetrical: - /// (capacity(i->j) == capacity(j->i)). - /// Demands are not symmetrical. - /// - public class NetworkRoutingData - { - private Dictionary<(int source, int destination), int> _arcs = new Dictionary<(int source, int destination), int>(); - private Dictionary<(int node1, int node2), int> _demands = new Dictionary<(int node1, int node2), int>(); - - public int NumberOfNodes { get; set; } = -1; - - public int NumberOfArcs - { - get { return _arcs.Count(); } + private void initData(int size, int seed) { + _network = new List>(size); + for (int i = 0; i < size; i++) { + _network.Add(new List(size)); + for (int j = 0; j < size; j++) { + _network [i] + .Add(false); } + } - public int NumberOfDemands - { - get { return _demands.Count(); } - } + _degrees = new List(size); + for (int i = 0; i < size; i++) { + _degrees.Add(0); + } - public int MaximumCapacity { get; set; } = -1; - public int FixedChargeCost { get; set; } = -1; - public string Name { get; set; } = string.Empty; - - public void AddDemand(int source, int destination, int traffic) - { - var pair = (source, destination); - if(!_demands.ContainsKey(pair)) - _demands.Add(pair, traffic); - } - - public void AddArc(int node1, int node2, int capacity) - { - _arcs.Add((Math.Min(node1, node2), Math.Max(node1, node2)), capacity); - } - - public int Demand(int source, int destination) - { - var pair = (source, destination); - if (_demands.TryGetValue(pair, out var demand)) - return demand; - - return 0; - } - - public int Capacity(int node1, int node2) - { - var pair = (Math.Min(node1, node2), Math.Max(node1, node2)); - if (_arcs.TryGetValue(pair, out var capacity)) - return capacity; - - return 0; - } + _random = new Random(seed); } - /// - /// Random generator of problem. This generator creates a random - /// problem. This problem uses a special topology. There are - /// 'numBackbones' nodes and 'numClients' nodes. if 'numClients' is - /// null, then all backbones nodes are also client nodes. All traffic - /// originates and terminates in client nodes. Each client node is - /// connected to 'minClientDegree' - 'maxClientDegree' backbone - /// nodes. Each backbone node is connected to 'minBackboneDegree' - - /// 'maxBackboneDegree' other backbone nodes. There are 'numDemands' - /// demands, with a traffic between 'trafficMin' and 'trafficMax'. - /// Each arc has a capacity of 'maxCapacity'. Using an arc incurs a - /// fixed cost of 'fixedChargeCost'. - /// - public class NetworkRoutingDataBuilder - { - private List> _network; - private List _degrees; - private Random _random; + private void buildGraph(int numClients, int numBackbones, + int minClientDegree, int maxClientDegree, + int minBackboneDegree, int maxBackboneDegree) { + int size = numBackbones + numClients; + for (int i = 1; i < numBackbones; i++) { + int j = randomUniform(i); + addEdge(i, j); + } - public NetworkRoutingData BuildModelFromParameters(int numClients, int numBackbones, - int numDemands, int trafficMin, - int trafficMax, int minClientDegree, - int maxClientDegree, int minBackboneDegree, - int maxBackboneDegree, int maxCapacity, - int fixedChargeCost, int seed) - { - Debug.Assert(numBackbones >= 1); - Debug.Assert(numClients >= 0); - Debug.Assert(numDemands >= 1); - Debug.Assert(numDemands <= (numClients == 0 ? numBackbones * numBackbones : numClients * numBackbones)); - Debug.Assert(maxClientDegree >= minClientDegree); - Debug.Assert(maxBackboneDegree >= minBackboneDegree); - Debug.Assert(trafficMax >= 1); - Debug.Assert(trafficMax >= trafficMin); - Debug.Assert(trafficMin >= 1); - Debug.Assert(maxBackboneDegree >= 2); - Debug.Assert(maxClientDegree >= 2); - Debug.Assert(maxClientDegree <= numBackbones); - Debug.Assert(maxBackboneDegree <= numBackbones); - Debug.Assert(maxCapacity >= 1); + List notFull = new List(); + HashSet toComplete = new HashSet(); - int size = numBackbones + numClients; - initData(size, seed); - buildGraph(numClients, numBackbones, minClientDegree, maxClientDegree, minBackboneDegree, maxBackboneDegree); - NetworkRoutingData data = new NetworkRoutingData(); - createDemands(numClients, numBackbones, numDemands, trafficMin, trafficMax, data); - fillData(numClients, numBackbones, numDemands, trafficMin, trafficMax, minClientDegree, maxClientDegree, - minBackboneDegree, maxBackboneDegree, maxCapacity, fixedChargeCost, seed, data); - - return data; + for (int i = 0; i < numBackbones; i++) { + if (_degrees[i] < minBackboneDegree) { + toComplete.Add(i); } - private void initData(int size, int seed) - { - _network = new List>(size); - for (int i = 0; i < size; i++) - { - _network.Add(new List(size)); - for (int j = 0; j < size; j++) - { - _network[i].Add(false); - } - } + if (_degrees[i] < maxBackboneDegree) { + notFull.Add(i); + } + } - _degrees = new List(size); - for (int i = 0; i < size; i++) - { - _degrees.Add(0); - } - - _random = new Random(seed); + while (toComplete.Any() && notFull.Count > 1) { + int node1 = getNextToComplete(toComplete); + int node2 = node1; + while (node2 == node1 || _degrees[node2] >= maxBackboneDegree) { + node2 = randomUniform(numBackbones); } - private void buildGraph(int numClients, int numBackbones, int minClientDegree, - int maxClientDegree, int minBackboneDegree, int maxBackboneDegree) - { - int size = numBackbones + numClients; - for (int i = 1; i < numBackbones; i++) - { - int j = randomUniform(i); - addEdge(i, j); - } + addEdge(node1, node2); - List notFull = new List(); - HashSet toComplete = new HashSet(); - - for (int i = 0; i < numBackbones; i++) - { - if (_degrees[i] < minBackboneDegree) - { - toComplete.Add(i); - } - - if (_degrees[i] < maxBackboneDegree) - { - notFull.Add(i); - } - } - - while (toComplete.Any() && notFull.Count > 1) - { - int node1 = getNextToComplete(toComplete); - int node2 = node1; - while (node2 == node1 || _degrees[node2] >= maxBackboneDegree) - { - node2 = randomUniform(numBackbones); - } - - addEdge(node1, node2); - - if (_degrees[node1] >= minBackboneDegree) - { - toComplete.Remove(node1); - } - - if (_degrees[node2] >= minBackboneDegree) - { - toComplete.Remove(node2); - } - - if (_degrees[node1] >= maxBackboneDegree) - { - notFull.Remove(node1); - } - - if (_degrees[node2] >= maxBackboneDegree) - { - notFull.Remove(node2); - } - } - - // Then create the client nodes connected to the backbone nodes. - // If numClient is 0, then backbone nodes are also client nodes. - - for (int i = numBackbones; i < size; i++) - { - int degree = randomInInterval(minClientDegree, maxClientDegree); - - while (_degrees[i] < degree) - { - int j = randomUniform(numBackbones); - if (!_network[i][j]) - { - addEdge(i, j); - } - } - } + if (_degrees[node1] >= minBackboneDegree) { + toComplete.Remove(node1); } - private int getNextToComplete(HashSet toComplete) - { - return toComplete.Last(); + if (_degrees[node2] >= minBackboneDegree) { + toComplete.Remove(node2); } - private void createDemands(int numClients, int numBackbones, int numDemands, - int trafficMin, int trafficMax, NetworkRoutingData data) - { - while (data.NumberOfDemands < numDemands) - { - int source = randomClient(numClients, numBackbones); - int dest = source; - while (dest == source) - { - dest = randomClient(numClients, numBackbones); - } - - int traffic = randomInInterval(trafficMin, trafficMax); - data.AddDemand(source, dest, traffic); - } + if (_degrees[node1] >= maxBackboneDegree) { + notFull.Remove(node1); } - private void fillData(int numClients, int numBackbones, int numDemands, - int trafficMin, int trafficMax, int minClientDegree, - int maxClientDegree, int minBackboneDegree, - int maxBackboneDegree, int maxCapacity, - int fixedChargeCost, int seed, - NetworkRoutingData data) - { - int size = numBackbones + numClients; - string name = $"mp_c{numClients}_b{numBackbones}_d{numDemands}.t{trafficMin}-{trafficMax}.cd{minClientDegree}-{maxClientDegree}.bd{minBackboneDegree}-{maxBackboneDegree}.mc{maxCapacity}.fc{fixedChargeCost}.s{seed}"; - data.Name = name; - - data.NumberOfNodes = size; - int numArcs = 0; - for (int i = 0; i < size - 1; i++) - { - for (int j = i + 1; j < size; j++) - { - if (_network[i][j]) - { - data.AddArc(i, j, maxCapacity); - numArcs++; - } - } - } - - data.MaximumCapacity = maxCapacity; - data.FixedChargeCost = fixedChargeCost; + if (_degrees[node2] >= maxBackboneDegree) { + notFull.Remove(node2); } + } - private void addEdge(int i, int j) - { - _degrees[i]++; - _degrees[j]++; - _network[i][j] = true; - _network[j][i] = true; - } + // Then create the client nodes connected to the backbone nodes. + // If numClient is 0, then backbone nodes are also client nodes. - private int randomInInterval(int intervalMin, int intervalMax) - { - var p = randomUniform(intervalMax - intervalMin + 1) + intervalMin; - return p; - } + for (int i = numBackbones; i < size; i++) { + int degree = randomInInterval(minClientDegree, maxClientDegree); - private int randomClient(int numClients, int numBackbones) - { - var p = (numClients == 0) - ? randomUniform(numBackbones) - : randomUniform(numClients) + numBackbones; - return p; - } - - private int randomUniform(int max) - { - var r = _random.Next(max); - return r; + while (_degrees[i] < degree) { + int j = randomUniform(numBackbones); + if (!_network [i] + [j]) { + addEdge(i, j); + } } + } } - [DebuggerDisplay("Source {Source} Destination {Destination} Traffic {Traffic}")] - public struct Demand - { - public Demand(int source, int destination, int traffic) - { - Source = source; - Destination = destination; - Traffic = traffic; - } - - public int Source { get; } - public int Destination { get; } - public int Traffic { get; } + private int getNextToComplete(HashSet toComplete) { + return toComplete.Last(); } - public class NetworkRoutingSolver - { - private List<(long source, long destination, int arcId)> _arcsData = new List<(long source, long destination, int arcId)>(); - private List _arcCapacity = new List(); - private List _demands = new List(); - private List _allMinPathLengths = new List(); - private List> _capacity; - private List>> _allPaths; - - public int NumberOfNodes { get; private set; } = -1; - - private int countArcs - { - get { return _arcsData.Count / 2; } + private void createDemands(int numClients, int numBackbones, int numDemands, + int trafficMin, int trafficMax, + NetworkRoutingData data) { + while (data.NumberOfDemands < numDemands) { + int source = randomClient(numClients, numBackbones); + int dest = source; + while (dest == source) { + dest = randomClient(numClients, numBackbones); } - public void ComputeAllPathsForOneDemandAndOnePathLength(int demandIndex, int maxLength, int maxPaths) - { - // We search for paths of length exactly 'maxLength'. - CpModel cpModel = new CpModel(); - var arcVars = new List(); - var nodeVars = new List(); - - for (int i = 0; i < maxLength; i++) - { - nodeVars.Add(cpModel.NewIntVar(0, NumberOfNodes - 1, string.Empty)); - } - - for (int i = 0; i < maxLength - 1; i++) - { - arcVars.Add(cpModel.NewIntVar(-1, countArcs - 1, string.Empty)); - } - - var arcs = getArcsData(); - - for (int i = 0; i < maxLength - 1; i++) - { - var tmpVars = new List(); - tmpVars.Add(nodeVars[i]); - tmpVars.Add(nodeVars[i + 1]); - tmpVars.Add(arcVars[i]); - var table = cpModel.AddAllowedAssignments(tmpVars, arcs); - } - - var demand = _demands[demandIndex]; - cpModel.Add(nodeVars[0] == demand.Source); - cpModel.Add(nodeVars[maxLength - 1] == demand.Destination); - cpModel.AddAllDifferent(arcVars); - cpModel.AddAllDifferent(nodeVars); - - var solver = new CpSolver(); - - var solutionPrinter = new FeasibleSolutionChecker(demandIndex, ref _allPaths, maxLength, arcVars, maxPaths, nodeVars); - var status = solver.SearchAllSolutions(cpModel, solutionPrinter); - } - - private long[,] getArcsData() - { - long[,] arcs = new long[_arcsData.Count, 3]; - - for (int i = 0; i < _arcsData.Count; i++) - { - var data = _arcsData[i]; - arcs[i, 0] = data.source; - arcs[i, 1] = data.destination; - arcs[i, 2] = data.arcId; - } - - return arcs; - } - - public int ComputeAllPaths(int extraHops, int maxPaths) - { - int numPaths = 0; - for (int demandIndex = 0; demandIndex < _demands.Count; demandIndex++) - { - int minPathLength = _allMinPathLengths[demandIndex]; - - for (int maxLength = minPathLength + 1; maxLength <= minPathLength + extraHops+1; maxLength++) - { - ComputeAllPathsForOneDemandAndOnePathLength(demandIndex, maxLength, maxPaths); - - if (_allPaths[demandIndex].Count >= maxPaths) - break; - } - - numPaths += _allPaths[demandIndex].Count; - } - - return numPaths; - } - - public void AddArcData(long source, long destination, int arcId) - { - _arcsData.Add((source, destination, arcId)); - } - - public void InitArcInfo(NetworkRoutingData data) - { - int numArcs = data.NumberOfArcs; - _capacity = new List>(NumberOfNodes); - - for (int nodeIndex = 0; nodeIndex < NumberOfNodes; nodeIndex++) - { - _capacity.Add(new List(NumberOfNodes)); - for (int i = 0; i < NumberOfNodes; i++) - { - _capacity[nodeIndex].Add(0); - } - } - - int arcId = 0; - for (int i = 0; i < NumberOfNodes - 1; i++) - { - for (int j = i + 1; j < NumberOfNodes; j++) - { - int capacity = data.Capacity(i, j); - if (capacity > 0) - { - AddArcData(i, j, arcId); - AddArcData(j, i, arcId); - arcId++; - _arcCapacity.Add(capacity); - _capacity[i][j] = capacity; - _capacity[j][i] = capacity; - - if (printModel) - { - Console.WriteLine($"Arc {i} <-> {j} with capacity {capacity}"); - } - } - } - } - - Debug.Assert(arcId == numArcs); - } - - public int InitDemandInfo(NetworkRoutingData data) - { - int numDemands = data.NumberOfDemands; - int totalDemand = 0; - for (int i = 0; i < NumberOfNodes; i++) - { - for (int j = 0; j < NumberOfNodes; j++) - { - int traffic = data.Demand(i, j); - if (traffic > 0) - { - _demands.Add(new Demand(i, j, traffic)); - totalDemand += traffic; - } - } - } - - Debug.Assert(numDemands == _demands.Count); - - return totalDemand; - } - - public long InitShortestPaths(NetworkRoutingData data) - { - int numDemands = data.NumberOfDemands; - long totalCumulatedTraffic = 0L; - _allMinPathLengths.Clear(); - var paths = new List(); - - for (int demandIndex = 0; demandIndex < numDemands; demandIndex++) - { - paths.Clear(); - var demand = _demands[demandIndex]; - var r = DijkstraShortestPath(NumberOfNodes, demand.Source, demand.Destination, - ((int x, int y) p) => hasArc(p.x, p.y), kDisconnectedDistance, paths); - - _allMinPathLengths.Add(paths.Count - 1); - var minPathLength = _allMinPathLengths[demandIndex]; - totalCumulatedTraffic += minPathLength * demand.Traffic; - } - - return totalCumulatedTraffic; - } - - public int InitPaths(NetworkRoutingData data, int extraHops, int maxPaths) - { - var numDemands = data.NumberOfDemands; - Console.WriteLine("Computing all possible paths "); - Console.WriteLine($" - extra hops = {extraHops}"); - Console.WriteLine($" - max paths per demand = {maxPaths}"); - - _allPaths =new List>>(numDemands); - - var numPaths = ComputeAllPaths(extraHops, maxPaths); - - for (int demandIndex = 0; demandIndex < numDemands; demandIndex++) - { - var demand = _demands[demandIndex]; - Console.WriteLine($"Demand from {demand.Source} to {demand.Destination} with traffic {demand.Traffic}, amd {_allPaths[demandIndex].Count} possible paths."); - } - - return numPaths; - } - - public void Init(NetworkRoutingData data, int extraHops, int maxPaths) - { - Console.WriteLine($"Model {data.Name}"); - NumberOfNodes = data.NumberOfNodes; - var numArcs = data.NumberOfArcs; - var numDemands = data.NumberOfDemands; - - InitArcInfo(data); - var totalDemand = InitDemandInfo(data); - var totalAccumulatedTraffic = InitShortestPaths(data); - var numPaths = InitPaths(data, extraHops, maxPaths); - - Console.WriteLine("Model created:"); - Console.WriteLine($" - {NumberOfNodes} nodes"); - Console.WriteLine($" - {numArcs} arcs"); - Console.WriteLine($" - {numDemands} demands"); - Console.WriteLine($" - a total traffic of {totalDemand}"); - Console.WriteLine($" - a minimum cumulated traffic of {totalAccumulatedTraffic}"); - Console.WriteLine($" - {numPaths} possible paths for all demands"); - } - - private long hasArc(int i, int j) - { - if (_capacity[i][j] > 0) - return 1; - else - return kDisconnectedDistance; - } - - public long Solve() - { - Console.WriteLine("Solving model"); - var numDemands = _demands.Count; - var numArcs = countArcs; - - CpModel cpModel = new CpModel(); - - var pathVars = new List>(numDemands); - - for (int demandIndex = 0; demandIndex < numDemands; demandIndex++) - { - pathVars.Add(new List()); - - for (int arc = 0; arc < numArcs; arc++) - { - pathVars[demandIndex].Add(cpModel.NewBoolVar("")); - } - - long[,] tuples = new long[_allPaths[demandIndex].Count, numArcs]; - - int pathCount = 0; - foreach (var set in _allPaths[demandIndex]) - { - foreach (var arc in set) - { - tuples[pathCount, arc] = 1; - } - - pathCount++; - } - - var pathCt = cpModel.AddAllowedAssignments(pathVars[demandIndex], tuples); - } - - var trafficVars = new List(numArcs); - var normalizedTrafficVars = new List(numArcs); - var comfortableTrafficVars = new List(numArcs); - - long maxNormalizedTraffic = 0; - - for (int arcIndex = 0; arcIndex < numArcs; arcIndex++) - { - long sumOfTraffic = 0; - - var vars = new List(); - var traffics = new List(); - - for (int i = 0; i < pathVars.Count; i++) - { - sumOfTraffic += _demands[i].Traffic; - vars.Add(pathVars[i][arcIndex]); - traffics.Add(_demands[i].Traffic); - } - - var sum = LinearExpr.ScalProd(vars, traffics); - var trafficVar = cpModel.NewIntVar(0, sumOfTraffic, $"trafficVar{arcIndex}"); - trafficVars.Add(trafficVar); - cpModel.Add(sum == trafficVar); - - var capacity = _arcCapacity[arcIndex]; - var scaledTraffic = cpModel.NewIntVar(0, sumOfTraffic * 1000, $"scaledTrafficVar{arcIndex}"); - var scaledTrafficVar = trafficVar * 1000; - cpModel.Add(scaledTrafficVar == scaledTraffic); - - var normalizedTraffic = - cpModel.NewIntVar(0, sumOfTraffic * 1000 / capacity, $"normalizedTraffic{arcIndex}"); - - maxNormalizedTraffic = Math.Max(maxNormalizedTraffic, sumOfTraffic * 1000 / capacity); - cpModel.AddDivisionEquality(normalizedTraffic, scaledTraffic, cpModel.NewConstant(capacity)); - normalizedTrafficVars.Add(normalizedTraffic); - var comfort = cpModel.NewBoolVar($"comfort{arcIndex}"); - var safeCapacity = (long)(capacity * comfortZone); - cpModel.Add(trafficVar > safeCapacity).OnlyEnforceIf(comfort); - cpModel.Add(trafficVar <=safeCapacity).OnlyEnforceIf(comfort.Not()); - comfortableTrafficVars.Add(comfort); - } - - var maxUsageCost = cpModel.NewIntVar(0, maxNormalizedTraffic, "maxUsageCost"); - cpModel.AddMaxEquality(maxUsageCost, normalizedTrafficVars); - - var obj = new List() {maxUsageCost}; - obj.AddRange(comfortableTrafficVars); - cpModel.Minimize(LinearExpr.Sum(obj)); - - CpSolver solver = new CpSolver(); - solver.StringParameters = parameters; - - CpSolverStatus status = solver.SearchAllSolutions(cpModel, - new FeasibleSolutionChecker2(maxUsageCost, comfortableTrafficVars, trafficVars)); - - return (long)solver.ObjectiveValue; - - } + int traffic = randomInInterval(trafficMin, trafficMax); + data.AddDemand(source, dest, traffic); + } } - private class DijkstraSP - { - private const long kInfinity = long.MaxValue / 2; + private void fillData(int numClients, int numBackbones, int numDemands, + int trafficMin, int trafficMax, int minClientDegree, + int maxClientDegree, int minBackboneDegree, + int maxBackboneDegree, int maxCapacity, + int fixedChargeCost, int seed, + NetworkRoutingData data) { + int size = numBackbones + numClients; + string name = + $"mp_c{numClients}_b{numBackbones}_d{numDemands}.t{trafficMin}-{trafficMax}.cd{minClientDegree}-{maxClientDegree}.bd{minBackboneDegree}-{maxBackboneDegree}.mc{maxCapacity}.fc{fixedChargeCost}.s{seed}"; + data.Name = name; - private readonly Func<(int, int), long> _graph; - private readonly int[] _predecessor; - private readonly List _elements; - private readonly AdjustablePriorityQueue _frontier; - private readonly List _notVisited = new List(); - private readonly List _addedToFrontier = new List(); - - public DijkstraSP(int nodeCount, int startNode, Func<(int,int), long> graph, long disconnectedDistance) - { - NodeCount = nodeCount; - StartNode = startNode; - this._graph = graph; - DisconnectedDistance = disconnectedDistance; - _predecessor = new int[nodeCount]; - _elements = new List(nodeCount); - _frontier = new AdjustablePriorityQueue(); + data.NumberOfNodes = size; + int numArcs = 0; + for (int i = 0; i < size - 1; i++) { + for (int j = i + 1; j < size; j++) { + if (_network [i] + [j]) { + data.AddArc(i, j, maxCapacity); + numArcs++; + } } + } - public int NodeCount { get; } - public int StartNode { get; } - public long DisconnectedDistance { get; } - - public bool ShortestPath(int endNode, List nodes) - { - initialize(); - bool found = false; - while (!_frontier.IsEmpty) - { - long distance; - int node = selectClosestNode(out distance); - if (distance == kInfinity) - { - found = false; - break; - } - else if (node == endNode) - { - found = true; - break; - } - update(node); - } - - if (found) - { - findPath(endNode, nodes); - } - - return found; - - } - - private void initialize() - { - for (int i = 0; i < NodeCount; i++) - { - _elements.Add(new Element {Node = i}); - - if (i == StartNode) - { - _predecessor[i] = -1; - _elements[i].Distance = 0; - _frontier.Add(_elements[i]); - } - else - { - _elements[i].Distance = kInfinity; - _predecessor[i] = StartNode; - _notVisited.Add(i); - } - } - } - - private int selectClosestNode(out long distance) - { - var node = _frontier.Top().Node; - distance = _frontier.Top().Distance; - _frontier.Pop(); - _notVisited.Remove(node); - _addedToFrontier.Remove(node); - return node; - } - - private void update(int node) - { - foreach (var otherNode in _notVisited) - { - var graphNode = _graph((node, otherNode)); - - if (graphNode != DisconnectedDistance) - { - if (!_addedToFrontier.Contains(otherNode)) - { - _frontier.Add(_elements[otherNode]); - _addedToFrontier.Add(otherNode); - } - - var otherDistance = _elements[node].Distance + graphNode; - - if (_elements[otherNode].Distance > otherDistance) - { - _elements[otherNode].Distance = otherDistance; - _frontier.NoteChangedPriority(_elements[otherNode]); - _predecessor[otherNode] = node; - } - } - } - } - - private void findPath(int dest, List nodes) - { - var j = dest; - nodes.Add(j); - while (_predecessor[j] != -1) - { - nodes.Add(_predecessor[j]); - j = _predecessor[j]; - } - } + data.MaximumCapacity = maxCapacity; + data.FixedChargeCost = fixedChargeCost; } - public static bool DijkstraShortestPath(int nodeCount, int startNode, int endNode, Func<(int, int), long> graph, - long disconnectedDistance, List nodes) - { - DijkstraSP bf = new DijkstraSP(nodeCount, startNode, graph, disconnectedDistance); - return bf.ShortestPath(endNode, nodes); + private void addEdge(int i, int j) { + _degrees[i]++; + _degrees[j]++; + _network [i] + [j] = true; + _network [j] + [i] = true; } - [DebuggerDisplay("Node = {Node}, HeapIndex = {HeapIndex}, Distance = {Distance}")] - private class Element : IHasHeapIndex, IComparable - { - public int HeapIndex { get; set; } = -1; - public long Distance { get; set; } = 0; - public int Node { get; set; } = -1; - - public int CompareTo(Element other) - { - if (this.Distance > other.Distance) - return -1; - - if (this.Distance < other.Distance) - return 1; - - return 0; - } + private int randomInInterval(int intervalMin, int intervalMax) { + var p = randomUniform(intervalMax - intervalMin + 1) + intervalMin; + return p; } - private class AdjustablePriorityQueue where T: class, IHasHeapIndex, IComparable - { - private readonly List _elems = new List(); - - public void Add(T val) - { - _elems.Add(val); - adjustUpwards(_elems.Count - 1); - } - - public void Remove(T val) - { - var i = val.HeapIndex; - if (i == _elems.Count - 1) - { - _elems.RemoveAt(_elems.Count - 1); - return; - } - - _elems[i] = _elems.Last(); - _elems[i].HeapIndex = i; - _elems.RemoveAt(_elems.Count - 1); - NoteChangedPriority(_elems[i]); - } - - public bool Contains(T val) - { - var i = val.HeapIndex; - if (i < 0 || i >= _elems.Count || _elems[i].CompareTo(val) != 0) - return false; - - return true; - } - - public T Top() - { - return _elems[0]; - } - - public void Pop() - { - Remove(Top()); - } - - public int Size() - { - return _elems.Count; - } - - public bool IsEmpty - { - get { return !_elems.Any(); } - } - - public void Clear() - { - _elems.Clear(); - } - - public void CheckValid() - { - for (int i = 0; i < _elems.Count; i++) - { - var leftChild = 1 + 2 * i; - if (leftChild < _elems.Count) - { - var compare = _elems[i].CompareTo(_elems[leftChild]); - Debug.Assert(compare >=0); - } - - int rightChild = leftChild + 1; - if (rightChild < _elems.Count) - { - var compare = _elems[i].CompareTo(_elems[rightChild]); - Debug.Assert(compare >= 0); - } - } - } - - public void NoteChangedPriority(T val) - { - if (_elems.Count == 0) - return; - - var i = val.HeapIndex; - var parent = (i - 1) / 2; - if (_elems[parent].CompareTo(val) == -1) - { - adjustUpwards(i); - } - else - { - adjustDownwards(i); - } - } - - private void adjustUpwards(int i) - { - var t = _elems[i]; - while (i > 0) - { - var parent = (i - 1) / 2; - if (_elems[parent].CompareTo(t) != -1) - { - break; - } - - _elems[i] = _elems[parent]; - _elems[i].HeapIndex = i; - i = parent; - } - - _elems[i] = t; - t.HeapIndex = i; - } - - private void adjustDownwards(int i) - { - var t = _elems[i]; - while (true) - { - var leftChild = 1 + 2 * i; - if (leftChild >= _elems.Count) - { - break; - } - - var rightChild = leftChild + 1; - var next = (rightChild < _elems.Count && _elems[leftChild].CompareTo(_elems[rightChild]) == -1) - ? rightChild - : leftChild; - - if (t.CompareTo(_elems[next]) != -1) - { - break; - } - - _elems[i] = _elems[next]; - _elems[i].HeapIndex = i; - i = next; - } - - _elems[i] = t; - t.HeapIndex = i; - } + private int randomClient(int numClients, int numBackbones) { + var p = (numClients == 0) ? randomUniform(numBackbones) + : randomUniform(numClients) + numBackbones; + return p; } - public interface IHasHeapIndex - { - int HeapIndex { get; set; } + private int randomUniform(int max) { + var r = _random.Next(max); + return r; + } + } + + [DebuggerDisplay( + "Source {Source} Destination {Destination} Traffic {Traffic}")] + public struct Demand { + public Demand(int source, int destination, int traffic) { + Source = source; + Destination = destination; + Traffic = traffic; } - private class FeasibleSolutionChecker : CpSolverSolutionCallback - { - public FeasibleSolutionChecker(int demandIndex, ref List>> allPaths, int maxLength, List arcVars, int maxPaths, List nodeVars) - { - DemandIndex = demandIndex; - AllPaths = allPaths; - MaxLength = maxLength; - ArcVars = arcVars; - MaxPaths = maxPaths; - NodeVars = nodeVars; - } + public int Source { get; } + public int Destination { get; } + public int Traffic { get; } + } - public int DemandIndex { get; } - public List>> AllPaths { get; } - public int MaxLength { get; } - public List ArcVars { get; } - public int MaxPaths { get; } - public List NodeVars { get; } + public class NetworkRoutingSolver { + private List<(long source, long destination, int arcId)> _arcsData = + new List<(long source, long destination, int arcId)>(); + private List _arcCapacity = new List(); + private List _demands = new List(); + private List _allMinPathLengths = new List(); + private List> _capacity; + private List>> _allPaths; - public override void OnSolutionCallback() - { - if(AllPaths.Count < DemandIndex + 1) - AllPaths.Add(new List>()); + public int NumberOfNodes { + get; + private set; + } + = -1; - int pathId = AllPaths[DemandIndex].Count; - AllPaths[DemandIndex].Add(new HashSet()); - - for (int i = 0; i < MaxLength - 1; i++) - { - int arc = (int) this.SolutionIntegerValue(ArcVars[i].GetIndex()); - AllPaths[DemandIndex][pathId].Add(arc); - } - - if (AllPaths[DemandIndex].Count() >= MaxPaths) - { - StopSearch(); - } - } + private int countArcs { + get { return _arcsData.Count / 2; } } - private class FeasibleSolutionChecker2 : CpSolverSolutionCallback - { - public IntVar MaxUsageCost { get; } - public List ComfortableTrafficVars { get; } - public List TrafficVars { get; } - private int _numSolutions = 0; + public void ComputeAllPathsForOneDemandAndOnePathLength(int demandIndex, + int maxLength, + int maxPaths) { + // We search for paths of length exactly 'maxLength'. + CpModel cpModel = new CpModel(); + var arcVars = new List(); + var nodeVars = new List(); - public FeasibleSolutionChecker2(IntVar maxUsageCost, List comfortableTrafficVars, List trafficVars) - { - MaxUsageCost = maxUsageCost; - ComfortableTrafficVars = comfortableTrafficVars; - TrafficVars = trafficVars; - } + for (int i = 0; i < maxLength; i++) { + nodeVars.Add(cpModel.NewIntVar(0, NumberOfNodes - 1, string.Empty)); + } - public override void OnSolutionCallback() - { - Console.WriteLine($"Solution {_numSolutions}"); - var percent = SolutionIntegerValue(MaxUsageCost.GetIndex()) / 10.0; - int numNonComfortableArcs = 0; + for (int i = 0; i < maxLength - 1; i++) { + arcVars.Add(cpModel.NewIntVar(-1, countArcs - 1, string.Empty)); + } - foreach (var comfort in ComfortableTrafficVars) - { - numNonComfortableArcs += SolutionBooleanValue(comfort.GetIndex()) ? 1 : 0; - } + var arcs = getArcsData(); - if (numNonComfortableArcs > 0) - { - Console.WriteLine($"*** Found a solution with a max usage of {percent}%, and {numNonComfortableArcs} links above the comfort zone"); - } - else - { - Console.WriteLine($"*** Found a solution with a max usage of {percent}%"); - } + for (int i = 0; i < maxLength - 1; i++) { + var tmpVars = new List(); + tmpVars.Add(nodeVars[i]); + tmpVars.Add(nodeVars[i + 1]); + tmpVars.Add(arcVars[i]); + var table = cpModel.AddAllowedAssignments(tmpVars, arcs); + } - _numSolutions++; - } + var demand = _demands[demandIndex]; + cpModel.Add(nodeVars[0] == demand.Source); + cpModel.Add(nodeVars[maxLength - 1] == demand.Destination); + cpModel.AddAllDifferent(arcVars); + cpModel.AddAllDifferent(nodeVars); + + var solver = new CpSolver(); + + var solutionPrinter = new FeasibleSolutionChecker( + demandIndex, ref _allPaths, maxLength, arcVars, maxPaths, nodeVars); + var status = solver.SearchAllSolutions(cpModel, solutionPrinter); } + + private long[, ] getArcsData() { + long[, ] arcs = new long[_arcsData.Count, 3]; + + for (int i = 0; i < _arcsData.Count; i++) { + var data = _arcsData[i]; + arcs[i, 0] = data.source; + arcs[i, 1] = data.destination; + arcs[i, 2] = data.arcId; + } + + return arcs; + } + + public int ComputeAllPaths(int extraHops, int maxPaths) { + int numPaths = 0; + for (int demandIndex = 0; demandIndex < _demands.Count; demandIndex++) { + int minPathLength = _allMinPathLengths[demandIndex]; + + for (int maxLength = minPathLength + 1; + maxLength <= minPathLength + extraHops + 1; maxLength++) { + ComputeAllPathsForOneDemandAndOnePathLength(demandIndex, maxLength, + maxPaths); + + if (_allPaths[demandIndex].Count >= maxPaths) break; + } + + numPaths += _allPaths[demandIndex].Count; + } + + return numPaths; + } + + public void AddArcData(long source, long destination, int arcId) { + _arcsData.Add((source, destination, arcId)); + } + + public void InitArcInfo(NetworkRoutingData data) { + int numArcs = data.NumberOfArcs; + _capacity = new List>(NumberOfNodes); + + for (int nodeIndex = 0; nodeIndex < NumberOfNodes; nodeIndex++) { + _capacity.Add(new List(NumberOfNodes)); + for (int i = 0; i < NumberOfNodes; i++) { + _capacity [nodeIndex] + .Add(0); + } + } + + int arcId = 0; + for (int i = 0; i < NumberOfNodes - 1; i++) { + for (int j = i + 1; j < NumberOfNodes; j++) { + int capacity = data.Capacity(i, j); + if (capacity > 0) { + AddArcData(i, j, arcId); + AddArcData(j, i, arcId); + arcId++; + _arcCapacity.Add(capacity); + _capacity [i] + [j] = capacity; + _capacity [j] + [i] = capacity; + + if (printModel) { + Console.WriteLine($"Arc {i} <-> {j} with capacity {capacity}"); + } + } + } + } + + Debug.Assert(arcId == numArcs); + } + + public int InitDemandInfo(NetworkRoutingData data) { + int numDemands = data.NumberOfDemands; + int totalDemand = 0; + for (int i = 0; i < NumberOfNodes; i++) { + for (int j = 0; j < NumberOfNodes; j++) { + int traffic = data.Demand(i, j); + if (traffic > 0) { + _demands.Add(new Demand(i, j, traffic)); + totalDemand += traffic; + } + } + } + + Debug.Assert(numDemands == _demands.Count); + + return totalDemand; + } + + public long InitShortestPaths(NetworkRoutingData data) { + int numDemands = data.NumberOfDemands; + long totalCumulatedTraffic = 0L; + _allMinPathLengths.Clear(); + var paths = new List(); + + for (int demandIndex = 0; demandIndex < numDemands; demandIndex++) { + paths.Clear(); + var demand = _demands[demandIndex]; + var r = DijkstraShortestPath(NumberOfNodes, demand.Source, + demand.Destination, + ((int x, int y) p) => hasArc(p.x, p.y), + kDisconnectedDistance, paths); + + _allMinPathLengths.Add(paths.Count - 1); + var minPathLength = _allMinPathLengths[demandIndex]; + totalCumulatedTraffic += minPathLength * demand.Traffic; + } + + return totalCumulatedTraffic; + } + + public int InitPaths(NetworkRoutingData data, int extraHops, int maxPaths) { + var numDemands = data.NumberOfDemands; + Console.WriteLine("Computing all possible paths "); + Console.WriteLine($" - extra hops = {extraHops}"); + Console.WriteLine($" - max paths per demand = {maxPaths}"); + + _allPaths = new List>>(numDemands); + + var numPaths = ComputeAllPaths(extraHops, maxPaths); + + for (int demandIndex = 0; demandIndex < numDemands; demandIndex++) { + var demand = _demands[demandIndex]; + Console.WriteLine( + $"Demand from {demand.Source} to {demand.Destination} with traffic {demand.Traffic}, amd {_allPaths[demandIndex].Count} possible paths."); + } + + return numPaths; + } + + public void Init(NetworkRoutingData data, int extraHops, int maxPaths) { + Console.WriteLine($"Model {data.Name}"); + NumberOfNodes = data.NumberOfNodes; + var numArcs = data.NumberOfArcs; + var numDemands = data.NumberOfDemands; + + InitArcInfo(data); + var totalDemand = InitDemandInfo(data); + var totalAccumulatedTraffic = InitShortestPaths(data); + var numPaths = InitPaths(data, extraHops, maxPaths); + + Console.WriteLine("Model created:"); + Console.WriteLine($" - {NumberOfNodes} nodes"); + Console.WriteLine($" - {numArcs} arcs"); + Console.WriteLine($" - {numDemands} demands"); + Console.WriteLine($" - a total traffic of {totalDemand}"); + Console.WriteLine( + $" - a minimum cumulated traffic of {totalAccumulatedTraffic}"); + Console.WriteLine($" - {numPaths} possible paths for all demands"); + } + + private long hasArc(int i, int j) { + if (_capacity [i] + [j] > 0) + return 1; + else + return kDisconnectedDistance; + } + + public long Solve() { + Console.WriteLine("Solving model"); + var numDemands = _demands.Count; + var numArcs = countArcs; + + CpModel cpModel = new CpModel(); + + var pathVars = new List>(numDemands); + + for (int demandIndex = 0; demandIndex < numDemands; demandIndex++) { + pathVars.Add(new List()); + + for (int arc = 0; arc < numArcs; arc++) { + pathVars [demandIndex] + .Add(cpModel.NewBoolVar("")); + } + + long[, ] tuples = new long[_allPaths[demandIndex].Count, numArcs]; + + int pathCount = 0; + foreach (var set in _allPaths[demandIndex]) { + foreach (var arc in set) { + tuples[pathCount, arc] = 1; + } + + pathCount++; + } + + var pathCt = + cpModel.AddAllowedAssignments(pathVars[demandIndex], tuples); + } + + var trafficVars = new List(numArcs); + var normalizedTrafficVars = new List(numArcs); + var comfortableTrafficVars = new List(numArcs); + + long maxNormalizedTraffic = 0; + + for (int arcIndex = 0; arcIndex < numArcs; arcIndex++) { + long sumOfTraffic = 0; + + var vars = new List(); + var traffics = new List(); + + for (int i = 0; i < pathVars.Count; i++) { + sumOfTraffic += _demands[i].Traffic; + vars.Add(pathVars [i] + [arcIndex]); + traffics.Add(_demands[i].Traffic); + } + + var sum = LinearExpr.ScalProd(vars, traffics); + var trafficVar = + cpModel.NewIntVar(0, sumOfTraffic, $"trafficVar{arcIndex}"); + trafficVars.Add(trafficVar); + cpModel.Add(sum == trafficVar); + + var capacity = _arcCapacity[arcIndex]; + var scaledTraffic = cpModel.NewIntVar(0, sumOfTraffic * 1000, + $"scaledTrafficVar{arcIndex}"); + var scaledTrafficVar = trafficVar * 1000; + cpModel.Add(scaledTrafficVar == scaledTraffic); + + var normalizedTraffic = cpModel.NewIntVar( + 0, sumOfTraffic * 1000 / capacity, $"normalizedTraffic{arcIndex}"); + + maxNormalizedTraffic = + Math.Max(maxNormalizedTraffic, sumOfTraffic * 1000 / capacity); + cpModel.AddDivisionEquality(normalizedTraffic, scaledTraffic, + cpModel.NewConstant(capacity)); + normalizedTrafficVars.Add(normalizedTraffic); + var comfort = cpModel.NewBoolVar($"comfort{arcIndex}"); + var safeCapacity = (long)(capacity * comfortZone); + cpModel.Add(trafficVar > safeCapacity).OnlyEnforceIf(comfort); + cpModel.Add(trafficVar <= safeCapacity).OnlyEnforceIf(comfort.Not()); + comfortableTrafficVars.Add(comfort); + } + + var maxUsageCost = + cpModel.NewIntVar(0, maxNormalizedTraffic, "maxUsageCost"); + cpModel.AddMaxEquality(maxUsageCost, normalizedTrafficVars); + + var obj = new List(){maxUsageCost}; + obj.AddRange(comfortableTrafficVars); + cpModel.Minimize(LinearExpr.Sum(obj)); + + CpSolver solver = new CpSolver(); + solver.StringParameters = parameters; + + CpSolverStatus status = solver.SearchAllSolutions( + cpModel, new FeasibleSolutionChecker2( + maxUsageCost, comfortableTrafficVars, trafficVars)); + + return (long) solver.ObjectiveValue; + } + } + + private class DijkstraSP { + private const long kInfinity = long.MaxValue / 2; + + private readonly Func<(int, int), long> _graph; + private readonly int[] _predecessor; + private readonly List _elements; + private readonly AdjustablePriorityQueue _frontier; + private readonly List _notVisited = new List(); + private readonly List _addedToFrontier = new List(); + + public DijkstraSP(int nodeCount, int startNode, + Func<(int, int), long> graph, long disconnectedDistance) { + NodeCount = nodeCount; + StartNode = startNode; + this._graph = graph; + DisconnectedDistance = disconnectedDistance; + _predecessor = new int[nodeCount]; + _elements = new List(nodeCount); + _frontier = new AdjustablePriorityQueue(); + } + + public int NodeCount { get; } + public int StartNode { get; } + public long DisconnectedDistance { get; } + + public bool ShortestPath(int endNode, List nodes) { + initialize(); + bool found = false; + while (!_frontier.IsEmpty) { + long distance; + int node = selectClosestNode(out distance); + if (distance == kInfinity) { + found = false; + break; + } else if (node == endNode) { + found = true; + break; + } + update(node); + } + + if (found) { + findPath(endNode, nodes); + } + + return found; + } + + private void initialize() { + for (int i = 0; i < NodeCount; i++) { + _elements.Add(new Element{Node = i}); + + if (i == StartNode) { + _predecessor[i] = -1; + _elements[i].Distance = 0; + _frontier.Add(_elements[i]); + } else { + _elements[i].Distance = kInfinity; + _predecessor[i] = StartNode; + _notVisited.Add(i); + } + } + } + + private int selectClosestNode(out long distance) { + var node = _frontier.Top().Node; + distance = _frontier.Top().Distance; + _frontier.Pop(); + _notVisited.Remove(node); + _addedToFrontier.Remove(node); + return node; + } + + private void update(int node) { + foreach (var otherNode in _notVisited) { + var graphNode = _graph((node, otherNode)); + + if (graphNode != DisconnectedDistance) { + if (!_addedToFrontier.Contains(otherNode)) { + _frontier.Add(_elements[otherNode]); + _addedToFrontier.Add(otherNode); + } + + var otherDistance = _elements[node].Distance + graphNode; + + if (_elements[otherNode].Distance > otherDistance) { + _elements[otherNode].Distance = otherDistance; + _frontier.NoteChangedPriority(_elements[otherNode]); + _predecessor[otherNode] = node; + } + } + } + } + + private void findPath(int dest, List nodes) { + var j = dest; + nodes.Add(j); + while (_predecessor[j] != -1) { + nodes.Add(_predecessor[j]); + j = _predecessor[j]; + } + } + } + + public static bool DijkstraShortestPath(int nodeCount, int startNode, + int endNode, + Func<(int, int), long> graph, + long disconnectedDistance, + List nodes) { + DijkstraSP bf = + new DijkstraSP(nodeCount, startNode, graph, disconnectedDistance); + return bf.ShortestPath(endNode, nodes); + } + + [DebuggerDisplay( + "Node = {Node}, HeapIndex = {HeapIndex}, Distance = {Distance}")] + private class Element : IHasHeapIndex, + IComparable { + public int HeapIndex { + get; + set; + } + = -1; + public long Distance { + get; + set; + } + = 0; + public int Node { + get; + set; + } + = -1; + + public int CompareTo(Element other) { + if (this.Distance > other.Distance) return -1; + + if (this.Distance < other.Distance) return 1; + + return 0; + } + } + + private class AdjustablePriorityQueue where T : class, + IHasHeapIndex, + IComparable { + private readonly List _elems = new List(); + + public void Add(T val) { + _elems.Add(val); + adjustUpwards(_elems.Count - 1); + } + + public void Remove(T val) { + var i = val.HeapIndex; + if (i == _elems.Count - 1) { + _elems.RemoveAt(_elems.Count - 1); + return; + } + + _elems[i] = _elems.Last(); + _elems[i].HeapIndex = i; + _elems.RemoveAt(_elems.Count - 1); + NoteChangedPriority(_elems[i]); + } + + public bool Contains(T val) { + var i = val.HeapIndex; + if (i < 0 || i >= _elems.Count || + _elems [i] + .CompareTo(val) != 0) + return false; + + return true; + } + + public T Top() { return _elems[0]; } + + public void Pop() { Remove(Top()); } + + public int Size() { return _elems.Count; } + + public bool IsEmpty { + get { return !_elems.Any(); } + } + + public void Clear() { _elems.Clear(); } + + public void CheckValid() { + for (int i = 0; i < _elems.Count; i++) { + var leftChild = 1 + 2 * i; + if (leftChild < _elems.Count) { + var compare = _elems [i] + .CompareTo(_elems[leftChild]); + Debug.Assert(compare >= 0); + } + + int rightChild = leftChild + 1; + if (rightChild < _elems.Count) { + var compare = _elems [i] + .CompareTo(_elems[rightChild]); + Debug.Assert(compare >= 0); + } + } + } + + public void NoteChangedPriority(T val) { + if (_elems.Count == 0) return; + + var i = val.HeapIndex; + var parent = (i - 1) / 2; + if (_elems [parent] + .CompareTo(val) == -1) { + adjustUpwards(i); + } else { + adjustDownwards(i); + } + } + + private void adjustUpwards(int i) { + var t = _elems[i]; + while (i > 0) { + var parent = (i - 1) / 2; + if (_elems [parent] + .CompareTo(t) != -1) { + break; + } + + _elems[i] = _elems[parent]; + _elems[i].HeapIndex = i; + i = parent; + } + + _elems[i] = t; + t.HeapIndex = i; + } + + private void adjustDownwards(int i) { + var t = _elems[i]; + while (true) { + var leftChild = 1 + 2 * i; + if (leftChild >= _elems.Count) { + break; + } + + var rightChild = leftChild + 1; + var next = (rightChild < _elems.Count && + _elems [leftChild] + .CompareTo(_elems[rightChild]) == -1) + ? rightChild + : leftChild; + + if (t.CompareTo(_elems[next]) != -1) { + break; + } + + _elems[i] = _elems[next]; + _elems[i].HeapIndex = i; + i = next; + } + + _elems[i] = t; + t.HeapIndex = i; + } + } + + public interface IHasHeapIndex { + int HeapIndex { + get; + set; + } + } + + private class FeasibleSolutionChecker : CpSolverSolutionCallback { + public FeasibleSolutionChecker(int demandIndex, + ref List>> allPaths, + int maxLength, List arcVars, + int maxPaths, List nodeVars) { + DemandIndex = demandIndex; + AllPaths = allPaths; + MaxLength = maxLength; + ArcVars = arcVars; + MaxPaths = maxPaths; + NodeVars = nodeVars; + } + + public int DemandIndex { get; } + public List>> AllPaths { get; } + public int MaxLength { get; } + public List ArcVars { get; } + public int MaxPaths { get; } + public List NodeVars { get; } + + public override void OnSolutionCallback() { + if (AllPaths.Count < DemandIndex + 1) + AllPaths.Add(new List>()); + + int pathId = AllPaths[DemandIndex].Count; + AllPaths [DemandIndex] + .Add(new HashSet()); + + for (int i = 0; i < MaxLength - 1; i++) { + int arc = (int) this.SolutionIntegerValue(ArcVars [i] + .GetIndex()); + AllPaths [DemandIndex] + [pathId] + .Add(arc); + } + + if (AllPaths [DemandIndex] + .Count() >= MaxPaths) { + StopSearch(); + } + } + } + + private class FeasibleSolutionChecker2 : CpSolverSolutionCallback { + public IntVar MaxUsageCost { get; } + public List ComfortableTrafficVars { get; } + public List TrafficVars { get; } + private int _numSolutions = 0; + + public FeasibleSolutionChecker2(IntVar maxUsageCost, + List comfortableTrafficVars, + List trafficVars) { + MaxUsageCost = maxUsageCost; + ComfortableTrafficVars = comfortableTrafficVars; + TrafficVars = trafficVars; + } + + public override void OnSolutionCallback() { + Console.WriteLine($"Solution {_numSolutions}"); + var percent = SolutionIntegerValue(MaxUsageCost.GetIndex()) / 10.0; + int numNonComfortableArcs = 0; + + foreach (var comfort in ComfortableTrafficVars) { + numNonComfortableArcs += + SolutionBooleanValue(comfort.GetIndex()) ? 1 : 0; + } + + if (numNonComfortableArcs > 0) { + Console.WriteLine( + $"*** Found a solution with a max usage of {percent}%, and {numNonComfortableArcs} links above the comfort zone"); + } else { + Console.WriteLine( + $"*** Found a solution with a max usage of {percent}%"); + } + + _numSolutions++; + } + } } diff --git a/examples/dotnet/NursesSat.cs b/examples/dotnet/NursesSat.cs index 727ba7eeb7..4b45c34c98 100644 --- a/examples/dotnet/NursesSat.cs +++ b/examples/dotnet/NursesSat.cs @@ -16,10 +16,10 @@ using System.Collections.Generic; using System.Linq; using Google.OrTools.Sat; -public class NurseSolutionObserver : CpSolverSolutionCallback -{ - public NurseSolutionObserver(IntVar[,,] shifts, int num_nurses, int num_days, - int num_shifts, HashSet to_print) { +public class NurseSolutionObserver : CpSolverSolutionCallback { + public NurseSolutionObserver(IntVar[, , ] shifts, int num_nurses, + int num_days, int num_shifts, + HashSet to_print) { shifts_ = shifts; num_nurses_ = num_nurses; num_days_ = num_days; @@ -27,23 +27,16 @@ public class NurseSolutionObserver : CpSolverSolutionCallback to_print_ = to_print; } - public override void OnSolutionCallback() - { + public override void OnSolutionCallback() { solution_count_++; - if (to_print_.Contains(solution_count_)) - { - Console.WriteLine( - String.Format("Solution #{0}: time = {1:.02} s", - solution_count_, WallTime())); - for (int d = 0; d < num_days_; ++d) - { + if (to_print_.Contains(solution_count_)) { + Console.WriteLine(String.Format("Solution #{0}: time = {1:.02} s", + solution_count_, WallTime())); + for (int d = 0; d < num_days_; ++d) { Console.WriteLine(String.Format("Day #{0}", d)); - for (int n = 0; n < num_nurses_; ++n) - { - for (int s = 0; s < num_shifts_; ++s) - { - if (BooleanValue(shifts_[n, d, s])) - { + for (int n = 0; n < num_nurses_; ++n) { + for (int s = 0; s < num_shifts_; ++s) { + if (BooleanValue(shifts_[n, d, s])) { Console.WriteLine( String.Format(" Nurse #{0} is working shift #{1}", n, s)); } @@ -53,23 +46,18 @@ public class NurseSolutionObserver : CpSolverSolutionCallback } } - public int SolutionCount() - { - return solution_count_; - } + public int SolutionCount() { return solution_count_; } private int solution_count_; - private IntVar[,,] shifts_; + private IntVar[, , ] shifts_; private int num_nurses_; private int num_days_; private int num_shifts_; private HashSet to_print_; } -public class NursesSat -{ - static void Main() - { +public class NursesSat { + static void Main() { // Data. int num_nurses = 4; // Nurse assigned to shift 0 means not working that day. @@ -86,13 +74,10 @@ public class NursesSat // Creates shift variables. // shift[n, d, s]: nurse "n" works shift "s" on day "d". - IntVar[,,] shift = new IntVar[num_nurses, num_days, num_shifts]; - foreach (int n in all_nurses) - { - foreach (int d in all_days) - { - foreach (int s in all_shifts) - { + IntVar[, , ] shift = new IntVar[num_nurses, num_days, num_shifts]; + foreach (int n in all_nurses) { + foreach (int d in all_days) { + foreach (int s in all_shifts) { shift[n, d, s] = model.NewBoolVar(String.Format("shift_n{0}d{1}s{2}", n, d, s)); } @@ -103,13 +88,10 @@ public class NursesSat // assigned at most one nurse. As we have the same number of // nurses and shifts, then each day, each shift is assigned to // exactly one nurse. - foreach (int d in all_days) - { - foreach (int s in all_shifts) - { + foreach (int d in all_days) { + foreach (int s in all_shifts) { IntVar[] tmp = new IntVar[num_nurses]; - foreach (int n in all_nurses) - { + foreach (int n in all_nurses) { tmp[n] = shift[n, d, s]; } model.Add(LinearExpr.Sum(tmp) == 1); @@ -117,13 +99,10 @@ public class NursesSat } // Nurses do 1 shift per day. - foreach (int n in all_nurses) - { - foreach (int d in all_days) - { + foreach (int n in all_nurses) { + foreach (int d in all_days) { IntVar[] tmp = new IntVar[num_shifts]; - foreach (int s in all_shifts) - { + foreach (int s in all_shifts) { tmp[s] = shift[n, d, s]; } model.Add(LinearExpr.Sum(tmp) == 1); @@ -132,11 +111,9 @@ public class NursesSat // Each nurse works 5 or 6 days in a week. // That is each nurse works shift 0 at most 2 times. - foreach (int n in all_nurses) - { + foreach (int n in all_nurses) { IntVar[] tmp = new IntVar[num_days]; - foreach (int d in all_days) - { + foreach (int d in all_days) { tmp[d] = shift[n, d, 0]; } model.AddLinearConstraint(LinearExpr.Sum(tmp), 1, 2); @@ -144,16 +121,13 @@ public class NursesSat // works_shift[(n, s)] is 1 if nurse n works shift s at least one day in // the week. - IntVar[,] works_shift = new IntVar[num_nurses, num_shifts]; - foreach (int n in all_nurses) - { - foreach (int s in all_shifts) - { + IntVar[, ] works_shift = new IntVar[num_nurses, num_shifts]; + foreach (int n in all_nurses) { + foreach (int s in all_shifts) { works_shift[n, s] = model.NewBoolVar(String.Format("works_shift_n{0}s{1}", n, s)); IntVar[] tmp = new IntVar[num_days]; - foreach (int d in all_days) - { + foreach (int d in all_days) { tmp[d] = shift[n, d, s]; } model.AddMaxEquality(works_shift[n, s], tmp); @@ -162,11 +136,9 @@ public class NursesSat // For each working shift, at most 2 nurses are assigned to that shift // during the week. - foreach (int s in all_working_shifts) - { + foreach (int s in all_working_shifts) { IntVar[] tmp = new IntVar[num_nurses]; - foreach (int n in all_nurses) - { + foreach (int n in all_nurses) { tmp[n] = works_shift[n, s]; } model.Add(LinearExpr.Sum(tmp) <= 2); @@ -177,17 +149,15 @@ public class NursesSat // on a given day and shift, either she does not work that shift // on that day, or she works that shift on the day before, or the // day after. - foreach (int n in all_nurses) - { - for (int s = 2; s <= 3; ++s) - { - foreach (int d in all_days) - { + foreach (int n in all_nurses) { + for (int s = 2; s <= 3; ++s) { + foreach (int d in all_days) { int yesterday = d == 0 ? num_days - 1 : d - 1; int tomorrow = d == num_days - 1 ? 0 : d + 1; - model.AddBoolOr(new ILiteral[] { shift[n, yesterday, s], - shift[n, d, s].Not(), - shift[n, tomorrow, s] } ); + model.AddBoolOr(new ILiteral[]{shift[n, yesterday, s], + shift [n, d, s] + .Not(), + shift[n, tomorrow, s]}); } } } diff --git a/examples/dotnet/ShiftSchedulingSat.cs b/examples/dotnet/ShiftSchedulingSat.cs index 3f11d18bd6..73dda58275 100644 --- a/examples/dotnet/ShiftSchedulingSat.cs +++ b/examples/dotnet/ShiftSchedulingSat.cs @@ -16,62 +16,41 @@ using System.Collections.Generic; using System.Linq; using Google.OrTools.Sat; - /// /// Creates a shift scheduling problem and solves it /// -public class ShiftSchedulingSat -{ - static void Main(string[] args) - { - SolveShiftScheduling(); - } +public class ShiftSchedulingSat { + static void Main(string[] args) { SolveShiftScheduling(); } - static void SolveShiftScheduling() - { - int numEmployees = 8; - int numWeeks = 3; - var shifts = new[] { "O", "M", "A", "N" }; + static void SolveShiftScheduling() { + int numEmployees = 8; + int numWeeks = 3; + var shifts = new[]{"O", "M", "A", "N"}; - // Fixed assignment: (employee, shift, day). - // This fixes the first 2 days of the schedule. - var fixedAssignments = new (int Employee, int Shift, int Day)[] - { - (0, 0, 0), - (1, 0, 0), - (2, 1, 0), - (3, 1, 0), - (4, 2, 0), - (5, 2, 0), - (6, 2, 3), - (7, 3, 0), - (0, 1, 1), - (1, 1, 1), - (2, 2, 1), - (3, 2, 1), - (4, 2, 1), - (5, 0, 1), - (6, 0, 1), - (7, 3, 1), - }; + // Fixed assignment: (employee, shift, day). + // This fixes the first 2 days of the schedule. + var fixedAssignments = new (int Employee, int Shift, int Day)[]{ + (0, 0, 0), (1, 0, 0), (2, 1, 0), (3, 1, 0), (4, 2, 0), (5, 2, 0), + (6, 2, 3), (7, 3, 0), (0, 1, 1), (1, 1, 1), (2, 2, 1), (3, 2, 1), + (4, 2, 1), (5, 0, 1), (6, 0, 1), (7, 3, 1), + }; - // Request: (employee, shift, day, weight) - // A negative weight indicates that the employee desire this assignment. - var requests = new (int Employee, int Shift, int Day, int Weight)[] - { - // Employee 3 wants the first Saturday off. - (3, 0, 5, -2), - // Employee 5 wants a night shift on the second Thursday. - (5, 3, 10, -2), - // Employee 2 does not want a night shift on the third Friday. - (2, 3, 4, 4) - }; + // Request: (employee, shift, day, weight) + // A negative weight indicates that the employee desire this assignment. + var requests = new (int Employee, int Shift, int Day, int Weight)[]{ + // Employee 3 wants the first Saturday off. + (3, 0, 5, -2), + // Employee 5 wants a night shift on the second Thursday. + (5, 3, 10, -2), + // Employee 2 does not want a night shift on the third Friday. + (2, 3, 4, 4)}; - // Shift constraints on continuous sequence : - // (shift, hard_min, soft_min, min_penalty, - // soft_max, hard_max, max_penalty) - var shiftConstraints = new (int Shift, int HardMin, int SoftMin, int MinPenalty, int SoftMax, int HardMax, int MaxPenalty)[] - { + // Shift constraints on continuous sequence : + // (shift, hard_min, soft_min, min_penalty, + // soft_max, hard_max, max_penalty) + var shiftConstraints = + new (int Shift, int HardMin, int SoftMin, int MinPenalty, int SoftMax, + int HardMax, int MaxPenalty)[]{ // One or two consecutive days of rest, this is a hard constraint. (0, 1, 1, 0, 2, 2, 0), // Between 2 and 3 consecutive days of night shifts, 1 and 4 are @@ -79,470 +58,427 @@ public class ShiftSchedulingSat (3, 1, 2, 20, 3, 4, 5), }; - // Weekly sum constraints on shifts days: - // (shift, hardMin, softMin, minPenalty, - // softMax, hardMax, maxPenalty) - var weeklySumConstraints = new (int Shift, int HardMin, int SoftMin, int MinPenalty, int SoftMax, int HardMax, int MaxPenalty)[] - { + // Weekly sum constraints on shifts days: + // (shift, hardMin, softMin, minPenalty, + // softMax, hardMax, maxPenalty) + var weeklySumConstraints = + new (int Shift, int HardMin, int SoftMin, int MinPenalty, int SoftMax, + int HardMax, int MaxPenalty)[]{ // Constraints on rests per week. (0, 1, 2, 7, 2, 3, 4), // At least 1 night shift per week (penalized). At most 4 (hard). (3, 0, 1, 3, 4, 4, 0), }; - // Penalized transitions: - // (previous_shift, next_shift, penalty (0 means forbidden)) - var penalizedTransitions = new (int PreviousShift, int NextShift, int Penalty)[] - { + // Penalized transitions: + // (previous_shift, next_shift, penalty (0 means forbidden)) + var penalizedTransitions = + new (int PreviousShift, int NextShift, int Penalty)[]{ // Afternoon to night has a penalty of 4. (2, 3, 4), // Night to morning is forbidden. (3, 1, 0), }; - // daily demands for work shifts (morning, afternon, night) for each day - // of the week starting on Monday. - var weeklyCoverDemands = new int[][] - { - new [] {2, 3, 1}, // Monday - new [] {2, 3, 1}, // Tuesday - new [] {2, 2, 2}, // Wednesday - new [] {2, 3, 1}, // Thursday - new [] {2, 2, 2}, // Friday - new [] {1, 2, 3}, // Saturday - new [] {1, 3, 1}, // Sunday - }; + // daily demands for work shifts (morning, afternon, night) for each day + // of the week starting on Monday. + var weeklyCoverDemands = new int[][]{ + new[]{2, 3, 1}, // Monday + new[]{2, 3, 1}, // Tuesday + new[]{2, 2, 2}, // Wednesday + new[]{2, 3, 1}, // Thursday + new[]{2, 2, 2}, // Friday + new[]{1, 2, 3}, // Saturday + new[]{1, 3, 1}, // Sunday + }; - // Penalty for exceeding the cover constraint per shift type. - var excessCoverPenalties = new[] { 2, 2, 5 }; + // Penalty for exceeding the cover constraint per shift type. + var excessCoverPenalties = new[]{2, 2, 5}; - var numDays = numWeeks * 7; - var numShifts = shifts.Length; + var numDays = numWeeks * 7; + var numShifts = shifts.Length; - var model = new CpModel(); + var model = new CpModel(); - IntVar[,,] work = new IntVar[numEmployees, numShifts, numDays]; + IntVar[, , ] work = new IntVar[numEmployees, numShifts, numDays]; - foreach (int e in Range(numEmployees)) - { - foreach (int s in Range(numShifts)) - { - foreach (int d in Range(numDays)) - { - work[e, s, d] = model.NewBoolVar($"work{e}_{s}_{d}"); - } - } - } - - // Linear terms of the objective in a minimization context. - var objIntVars = new List(); - var objIntCoeffs = new List(); - var objBoolVars = new List(); - var objBoolCoeffs = new List(); - - // Exactly one shift per day. - foreach (int e in Range(numEmployees)) - { - foreach (int d in Range(numDays)) - { - var temp = new IntVar[numShifts]; - foreach (int s in Range(numShifts)) - { - temp[s] = work[e, s, d]; - } - - model.Add(LinearExpr.Sum(temp) == 1); - } - } - - // Fixed assignments. - foreach (var (e, s, d) in fixedAssignments) - { - model.Add(work[e, s, d] == 1); - } - - // Employee requests - foreach (var (e, s, d, w) in requests) - { - objBoolVars.Add(work[e, s, d]); - objBoolCoeffs.Add(w); - } - - // Shift constraints - foreach (var constraint in shiftConstraints) - { - foreach (int e in Range(numEmployees)) - { - var works = new IntVar[numDays]; - foreach (int d in Range(numDays)) - { - works[d] = work[e, constraint.Shift, d]; - } - - var (variables, coeffs) = AddSoftSequenceConstraint( - model, works, - constraint.HardMin, constraint.SoftMin, constraint.MinPenalty, - constraint.SoftMax, constraint.HardMax, constraint.MaxPenalty, - $"shift_constraint(employee {e}, shift {constraint.Shift}"); - - objBoolVars.AddRange(variables); - objBoolCoeffs.AddRange(coeffs); - } - } - - // Weekly sum constraints - foreach (var constraint in weeklySumConstraints) - { - foreach (int e in Range(numEmployees)) - { - foreach (int w in Range(numWeeks)) - { - var works = new IntVar[7]; - - foreach (int d in Range(7)) - { - works[d] = work[e, constraint.Shift, d + w * 7]; - } - - var (variables, coeffs) = AddSoftSumConstraint( - model, works, - constraint.HardMin, constraint.SoftMin, constraint.MinPenalty, - constraint.SoftMax, constraint.HardMax, constraint.MaxPenalty, - $"weekly_sum_constraint(employee {e}, shift {constraint.Shift}, week {w}"); - - objBoolVars.AddRange(variables); - objBoolCoeffs.AddRange(coeffs); - } - } - } - - // Penalized transitions - foreach (var penalizedTransition in penalizedTransitions) - { - foreach (int e in Range(numEmployees)) - { - foreach (int d in Range(numDays - 1)) - { - var transition = new List() - { - work[e, penalizedTransition.PreviousShift, d].Not(), - work[e, penalizedTransition.NextShift, d + 1].Not() - }; - - if (penalizedTransition.Penalty == 0) - { - model.AddBoolOr(transition); - } - else - { - var transVar = model.NewBoolVar($"transition (employee {e}, day={d}"); - transition.Add(transVar); - model.AddBoolOr(transition); - objBoolVars.Add(transVar); - objBoolCoeffs.Add(penalizedTransition.Penalty); - } - } - } - } - - // Cover constraints - foreach (int s in Range(1, numShifts)) - { - foreach (int w in Range(numWeeks)) - { - foreach (int d in Range(7)) - { - var works = new IntVar[numEmployees]; - foreach (int e in Range(numEmployees)) - { - works[e] = work[e, s, w * 7 + d]; - } - - // Ignore off shift - var minDemand = weeklyCoverDemands[d][s - 1]; - var worked = model.NewIntVar(minDemand, numEmployees, ""); - model.Add(LinearExpr.Sum(works) == worked); - - var overPenalty = excessCoverPenalties[s - 1]; - if (overPenalty > 0) - { - var name = $"excess_demand(shift={s}, week={w}, day={d}"; - var excess = model.NewIntVar(0, numEmployees - minDemand, name); - model.Add(excess == worked - minDemand); - objIntVars.Add(excess); - objIntCoeffs.Add(overPenalty); - } - } - } - } - - // Objective - var objBoolSum = LinearExpr.ScalProd(objBoolVars, objBoolCoeffs); - var objIntSum = LinearExpr.ScalProd(objIntVars, objIntCoeffs); - - model.Minimize(objBoolSum + objIntSum); - - // Solve model - var solver = new CpSolver(); - solver.StringParameters = - "num_search_workers:8, log_search_progress: true, max_time_in_seconds:30"; - - var status = solver.Solve(model); - - // Print solution - if (status == CpSolverStatus.Optimal || status == CpSolverStatus.Feasible) - { - Console.WriteLine(); - var header = " "; - for (int w = 0; w < numWeeks; w++) - { - header += "M T W T F S S "; - } - - Console.WriteLine(header); - - foreach (int e in Range(numEmployees)) - { - var schedule = ""; - foreach (int d in Range(numDays)) - { - foreach (int s in Range(numShifts)) - { - if (solver.BooleanValue(work[e, s, d])) - { - schedule += shifts[s] + " "; - } - } - } - - Console.WriteLine($"worker {e}: {schedule}"); - } - - Console.WriteLine(); - Console.WriteLine("Penalties:"); - - foreach (var (i, var) in objBoolVars.Select((x, i) => (i, x))) - { - if (solver.BooleanValue(var)) - { - var penalty = objBoolCoeffs[i]; - if (penalty > 0) - { - Console.WriteLine($" {var.Name()} violated, penalty={penalty}"); - } - else - { - Console.WriteLine($" {var.Name()} fulfilled, gain={-penalty}"); - } - } - } - - foreach (var (i, var) in objIntVars.Select((x, i) => (i, x))) - { - if (solver.Value(var) > 0) - { - Console.WriteLine($" {var.Name()} violated by {solver.Value(var)}, linear penalty={objIntCoeffs[i]}"); - } - } - - Console.WriteLine(); - Console.WriteLine("Statistics"); - Console.WriteLine($" - status : {status}"); - Console.WriteLine($" - conflicts : {solver.NumConflicts()}"); - Console.WriteLine($" - branches : {solver.NumBranches()}"); - Console.WriteLine($" - wall time : {solver.WallTime()}"); + foreach (int e in Range(numEmployees)) { + foreach (int s in Range(numShifts)) { + foreach (int d in Range(numDays)) { + work[e, s, d] = model.NewBoolVar($"work{e}_{s}_{d}"); } + } } - /// - /// Filters an isolated sub-sequence of variables assigned to True. - /// Extract the span of Boolean variables[start, start + length), negate them, - /// and if there is variables to the left / right of this span, surround the span by - /// them in non negated form. - /// - /// A list of variables to extract the span from. - /// The start to the span. - /// The length of the span. - /// An array of variables which conjunction will be false if the sub-list is - /// assigned to True, and correctly bounded by variables assigned to False, - /// or by the start or end of works. - static ILiteral[] NegatedBoundedSpan(IntVar[] works, int start, int length) - { - var sequence = new List(); + // Linear terms of the objective in a minimization context. + var objIntVars = new List(); + var objIntCoeffs = new List(); + var objBoolVars = new List(); + var objBoolCoeffs = new List(); - if (start > 0) - sequence.Add(works[start - 1]); + // Exactly one shift per day. + foreach (int e in Range(numEmployees)) { + foreach (int d in Range(numDays)) { + var temp = new IntVar[numShifts]; + foreach (int s in Range(numShifts)) { + temp[s] = work[e, s, d]; + } - foreach (var i in Range(length)) - sequence.Add(works[start + i].Not()); - - if (start + length < works.Length) - sequence.Add(works[start + length]); - - return sequence.ToArray(); + model.Add(LinearExpr.Sum(temp) == 1); + } } - /// - /// Sequence constraint on true variables with soft and hard bounds. - /// This constraint look at every maximal contiguous sequence of variables - /// assigned to true. If forbids sequence of length < hardMin or > hardMax. - /// Then it creates penalty terms if the length is < softMin or > softMax. - /// - /// The sequence constraint is built on this model. - /// A list of Boolean variables. - /// Any sequence of true variables must have a length of at least hardMin. - /// Any sequence should have a length of at least softMin, or a linear penalty on the delta will be added to the objective. - /// The coefficient of the linear penalty if the length is less than softMin. - /// Any sequence should have a length of at most softMax, or a linear penalty on the delta will be added to the objective. - /// Any sequence of true variables must have a length of at most hardMax. - /// The coefficient of the linear penalty if the length is more than softMax. - /// A base name for penalty literals. - /// A tuple (costLiterals, costCoefficients) containing the different penalties created by the sequence constraint. - static (IntVar[] costLiterals, int[] costCoefficients) AddSoftSequenceConstraint(CpModel model, IntVar[] works, int hardMin, int softMin, int minCost, - int softMax, int hardMax, int maxCost, string prefix) - { - var costLiterals = new List(); - var costCoefficients = new List(); + // Fixed assignments. + foreach (var(e, s, d) in fixedAssignments) { + model.Add(work[e, s, d] == 1); + } - // Forbid sequences that are too short. - foreach (var length in Range(1, hardMin)) - { - foreach (var start in Range(works.Length - length + 1)) - { - model.AddBoolOr(NegatedBoundedSpan(works, start, length)); + // Employee requests + foreach (var(e, s, d, w) in requests) { + objBoolVars.Add(work[e, s, d]); + objBoolCoeffs.Add(w); + } + + // Shift constraints + foreach (var constraint in shiftConstraints) { + foreach (int e in Range(numEmployees)) { + var works = new IntVar[numDays]; + foreach (int d in Range(numDays)) { + works[d] = work[e, constraint.Shift, d]; + } + + var(variables, coeffs) = AddSoftSequenceConstraint( + model, works, constraint.HardMin, constraint.SoftMin, + constraint.MinPenalty, constraint.SoftMax, constraint.HardMax, + constraint.MaxPenalty, + $"shift_constraint(employee {e}, shift {constraint.Shift}"); + + objBoolVars.AddRange(variables); + objBoolCoeffs.AddRange(coeffs); + } + } + + // Weekly sum constraints + foreach (var constraint in weeklySumConstraints) { + foreach (int e in Range(numEmployees)) { + foreach (int w in Range(numWeeks)) { + var works = new IntVar[7]; + + foreach (int d in Range(7)) { + works[d] = work[e, constraint.Shift, d + w * 7]; + } + + var(variables, coeffs) = AddSoftSumConstraint( + model, works, constraint.HardMin, constraint.SoftMin, + constraint.MinPenalty, constraint.SoftMax, constraint.HardMax, + constraint.MaxPenalty, + $"weekly_sum_constraint(employee {e}, shift {constraint.Shift}, week {w}"); + + objBoolVars.AddRange(variables); + objBoolCoeffs.AddRange(coeffs); + } + } + } + + // Penalized transitions + foreach (var penalizedTransition in penalizedTransitions) { + foreach (int e in Range(numEmployees)) { + foreach (int d in Range(numDays - 1)) { + var transition = new List(){ + work [e, penalizedTransition.PreviousShift, d] + .Not(), + work [e, penalizedTransition.NextShift, d + 1] + .Not()}; + + if (penalizedTransition.Penalty == 0) { + model.AddBoolOr(transition); + } else { + var transVar = + model.NewBoolVar($"transition (employee {e}, day={d}"); + transition.Add(transVar); + model.AddBoolOr(transition); + objBoolVars.Add(transVar); + objBoolCoeffs.Add(penalizedTransition.Penalty); + } + } + } + } + + // Cover constraints + foreach (int s in Range(1, numShifts)) { + foreach (int w in Range(numWeeks)) { + foreach (int d in Range(7)) { + var works = new IntVar[numEmployees]; + foreach (int e in Range(numEmployees)) { + works[e] = work[e, s, w * 7 + d]; + } + + // Ignore off shift + var minDemand = weeklyCoverDemands [d] + [s - 1]; + var worked = model.NewIntVar(minDemand, numEmployees, ""); + model.Add(LinearExpr.Sum(works) == worked); + + var overPenalty = excessCoverPenalties[s - 1]; + if (overPenalty > 0) { + var name = $"excess_demand(shift={s}, week={w}, day={d}"; + var excess = model.NewIntVar(0, numEmployees - minDemand, name); + model.Add(excess == worked - minDemand); + objIntVars.Add(excess); + objIntCoeffs.Add(overPenalty); + } + } + } + } + + // Objective + var objBoolSum = LinearExpr.ScalProd(objBoolVars, objBoolCoeffs); + var objIntSum = LinearExpr.ScalProd(objIntVars, objIntCoeffs); + + model.Minimize(objBoolSum + objIntSum); + + // Solve model + var solver = new CpSolver(); + solver.StringParameters = + "num_search_workers:8, log_search_progress: true, max_time_in_seconds:30"; + + var status = solver.Solve(model); + + // Print solution + if (status == CpSolverStatus.Optimal || status == CpSolverStatus.Feasible) { + Console.WriteLine(); + var header = " "; + for (int w = 0; w < numWeeks; w++) { + header += "M T W T F S S "; + } + + Console.WriteLine(header); + + foreach (int e in Range(numEmployees)) { + var schedule = ""; + foreach (int d in Range(numDays)) { + foreach (int s in Range(numShifts)) { + if (solver.BooleanValue(work[e, s, d])) { + schedule += shifts[s] + " "; } + } } - // Penalize sequences that are below the soft limit. + Console.WriteLine($"worker {e}: {schedule}"); + } - if (minCost > 0) - { - foreach (var length in Range(hardMin, softMin)) - { - foreach (var start in Range(works.Length - length + 1)) - { - var span = NegatedBoundedSpan(works, start, length).ToList(); - var name = $": under_span(start={start}, length={length})"; - var lit = model.NewBoolVar(prefix + name); - span.Add(lit); - model.AddBoolOr(span); - costLiterals.Add(lit); - // We filter exactly the sequence with a short length. - // The penalty is proportional to the delta with softMin. - costCoefficients.Add(minCost * (softMin - length)); - } - } + Console.WriteLine(); + Console.WriteLine("Penalties:"); + + foreach (var(i, var) in objBoolVars.Select((x, i) =>(i, x))) { + if (solver.BooleanValue(var)) { + var penalty = objBoolCoeffs[i]; + if (penalty > 0) { + Console.WriteLine($" {var.Name()} violated, penalty={penalty}"); + } else { + Console.WriteLine($" {var.Name()} fulfilled, gain={-penalty}"); + } } + } - // Penalize sequences that are above the soft limit. - if (maxCost > 0) - { - foreach (var length in Range(softMax + 1, hardMax + 1)) - { - foreach (var start in Range(works.Length - length + 1)) - { - var span = NegatedBoundedSpan(works, start, length).ToList(); - var name = $": over_span(start={start}, length={length})"; - var lit = model.NewBoolVar(prefix + name); - span.Add(lit); - model.AddBoolOr(span); - costLiterals.Add(lit); - // Cost paid is max_cost * excess length. - costCoefficients.Add(maxCost * (length - softMax)); - } - } + foreach (var(i, var) in objIntVars.Select((x, i) =>(i, x))) { + if (solver.Value(var) > 0) { + Console.WriteLine( + $" {var.Name()} violated by {solver.Value(var)}, linear penalty={objIntCoeffs[i]}"); } + } - // Just forbid any sequence of true variables with length hardMax + 1 - foreach (var start in Range(works.Length - hardMax)) - { - var temp = new List(); + Console.WriteLine(); + Console.WriteLine("Statistics"); + Console.WriteLine($" - status : {status}"); + Console.WriteLine($" - conflicts : {solver.NumConflicts()}"); + Console.WriteLine($" - branches : {solver.NumBranches()}"); + Console.WriteLine($" - wall time : {solver.WallTime()}"); + } + } - foreach (var i in Range(start, start + hardMax + 1)) - { - temp.Add(works[i].Not()); - } + /// + /// Filters an isolated sub-sequence of variables assigned to True. + /// Extract the span of Boolean variables[start, start + length), negate them, + /// and if there is variables to the left / right of this span, surround the + /// span by them in non negated form. + /// + /// A list of variables to extract the span from. + /// The start to the span. + /// The length of the span. + /// An array of variables which conjunction will be false if the + /// sub-list is assigned to True, and correctly bounded by variables assigned + /// to False, or by the start or end of works. + static ILiteral[] NegatedBoundedSpan(IntVar[] works, int start, int length) { + var sequence = new List(); - model.AddBoolOr(temp); - } + if (start > 0) sequence.Add(works[start - 1]); - return (costLiterals.ToArray(), costCoefficients.ToArray()); + foreach (var i in Range(length)) + sequence.Add(works [start + i] + .Not()); + + if (start + length < works.Length) sequence.Add(works[start + length]); + + return sequence.ToArray(); + } + + /// + /// Sequence constraint on true variables with soft and hard bounds. + /// This constraint look at every maximal contiguous sequence of variables + /// assigned to true. If forbids sequence of length < hardMin or > + /// hardMax. Then it creates penalty terms if the length is < softMin or + /// > softMax. + /// + /// The sequence constraint is built on this + /// model. A list of Boolean variables. + /// Any sequence of true variables must have a length of + /// at least hardMin. Any sequence should have a + /// length of at least softMin, or a linear penalty on the delta will be added + /// to the objective. The coefficient of the + /// linear penalty if the length is less than softMin. Any sequence should have a length of at most softMax, or a + /// linear penalty on the delta will be added to the objective. Any sequence of true variables must have a length of at + /// most hardMax. The coefficient of the linear + /// penalty if the length is more than softMax. A + /// base name for penalty literals. A tuple (costLiterals, + /// costCoefficients) containing the different penalties created by the + /// sequence constraint. + static(IntVar[] costLiterals, int[] costCoefficients) + AddSoftSequenceConstraint(CpModel model, IntVar[] works, int hardMin, + int softMin, int minCost, int softMax, + int hardMax, int maxCost, string prefix) { + var costLiterals = new List(); + var costCoefficients = new List(); + + // Forbid sequences that are too short. + foreach (var length in Range(1, hardMin)) { + foreach (var start in Range(works.Length - length + 1)) { + model.AddBoolOr(NegatedBoundedSpan(works, start, length)); + } } - /// - /// Sum constraint with soft and hard bounds. - /// This constraint counts the variables assigned to true from works. - /// If forbids sum < hardMin or > hardMax. - /// Then it creates penalty terms if the sum is < softMin or > softMax. - /// - /// The sequence constraint is built on this model. - /// A list of Boolean variables. - /// Any sequence of true variables must have a length of at least hardMin. - /// Any sequence should have a length of at least softMin, or a linear penalty on the delta will be added to the objective. - /// The coefficient of the linear penalty if the length is less than softMin. - /// Any sequence should have a length of at most softMax, or a linear penalty on the delta will be added to the objective. - /// Any sequence of true variables must have a length of at most hardMax. - /// The coefficient of the linear penalty if the length is more than softMax. - /// A base name for penalty literals. - /// A tuple (costVariables, costCoefficients) containing the different - /// penalties created by the sequence constraint. - static (IntVar[] costVariables, int[] costCoefficients) AddSoftSumConstraint(CpModel model, IntVar[] works, - int hardMin, int softMin, int minCost, - int softMax, int hardMax, int maxCost, string prefix) - { - var costVariables = new List(); - var costCoefficients = new List(); - var sumVar = model.NewIntVar(hardMin, hardMax, ""); - // This adds the hard constraints on the sum. - model.Add(sumVar == LinearExpr.Sum(works)); + // Penalize sequences that are below the soft limit. - var zero = model.NewConstant(0); - - // Penalize sums below the soft_min target. - - if (softMin > hardMin && minCost > 0) - { - var delta = model.NewIntVar(-works.Length, works.Length, ""); - model.Add(delta == (softMin - sumVar)); - var excess = model.NewIntVar(0, works.Length, prefix + ": under_sum"); - model.AddMaxEquality(excess, new[] { delta, zero }); - costVariables.Add(excess); - costCoefficients.Add(minCost); + if (minCost > 0) { + foreach (var length in Range(hardMin, softMin)) { + foreach (var start in Range(works.Length - length + 1)) { + var span = NegatedBoundedSpan(works, start, length).ToList(); + var name = $": under_span(start={start}, length={length})"; + var lit = model.NewBoolVar(prefix + name); + span.Add(lit); + model.AddBoolOr(span); + costLiterals.Add(lit); + // We filter exactly the sequence with a short length. + // The penalty is proportional to the delta with softMin. + costCoefficients.Add(minCost * (softMin - length)); } + } + } - // Penalize sums above the soft_max target. - if (softMax < hardMax && maxCost > 0) - { - var delta = model.NewIntVar(-works.Length, works.Length, ""); - model.Add(delta == sumVar - softMax); - var excess = model.NewIntVar(0, works.Length, prefix + ": over_sum"); - model.AddMaxEquality(excess, new[] { delta, zero }); - costVariables.Add(excess); - costCoefficients.Add(maxCost); + // Penalize sequences that are above the soft limit. + if (maxCost > 0) { + foreach (var length in Range(softMax + 1, hardMax + 1)) { + foreach (var start in Range(works.Length - length + 1)) { + var span = NegatedBoundedSpan(works, start, length).ToList(); + var name = $": over_span(start={start}, length={length})"; + var lit = model.NewBoolVar(prefix + name); + span.Add(lit); + model.AddBoolOr(span); + costLiterals.Add(lit); + // Cost paid is max_cost * excess length. + costCoefficients.Add(maxCost * (length - softMax)); } - - return (costVariables.ToArray(), costCoefficients.ToArray()); + } } - /// - /// C# equivalent of Python range (start, stop) - /// - /// The inclusive start. - /// The exclusive stop. - /// A sequence of integers. - static IEnumerable Range(int start, int stop) - { - foreach (var i in Enumerable.Range(start, stop - start)) - yield return i; + // Just forbid any sequence of true variables with length hardMax + 1 + foreach (var start in Range(works.Length - hardMax)) { + var temp = new List(); + + foreach (var i in Range(start, start + hardMax + 1)) { + temp.Add(works [i] + .Not()); + } + + model.AddBoolOr(temp); } - /// - /// C# equivalent of Python range (stop) - /// - /// The exclusive stop. - /// A sequence of integers. - static IEnumerable Range(int stop) - { - return Range(0, stop); + return (costLiterals.ToArray(), costCoefficients.ToArray()); + } + + /// + /// Sum constraint with soft and hard bounds. + /// This constraint counts the variables assigned to true from works. + /// If forbids sum < hardMin or > hardMax. + /// Then it creates penalty terms if the sum is < softMin or > softMax. + /// + /// The sequence constraint is built on this + /// model. A list of Boolean variables. + /// Any sequence of true variables must have a length of + /// at least hardMin. Any sequence should have a + /// length of at least softMin, or a linear penalty on the delta will be added + /// to the objective. The coefficient of the + /// linear penalty if the length is less than softMin. Any sequence should have a length of at most softMax, or a + /// linear penalty on the delta will be added to the objective. Any sequence of true variables must have a length of at + /// most hardMax. The coefficient of the linear + /// penalty if the length is more than softMax. A + /// base name for penalty literals. A tuple (costVariables, + /// costCoefficients) containing the different penalties created by the + /// sequence constraint. + static(IntVar[] costVariables, int[] costCoefficients) + AddSoftSumConstraint(CpModel model, IntVar[] works, int hardMin, + int softMin, int minCost, int softMax, int hardMax, + int maxCost, string prefix) { + var costVariables = new List(); + var costCoefficients = new List(); + var sumVar = model.NewIntVar(hardMin, hardMax, ""); + // This adds the hard constraints on the sum. + model.Add(sumVar == LinearExpr.Sum(works)); + + var zero = model.NewConstant(0); + + // Penalize sums below the soft_min target. + + if (softMin > hardMin && minCost > 0) { + var delta = model.NewIntVar(-works.Length, works.Length, ""); + model.Add(delta == (softMin - sumVar)); + var excess = model.NewIntVar(0, works.Length, prefix + ": under_sum"); + model.AddMaxEquality(excess, new[]{delta, zero}); + costVariables.Add(excess); + costCoefficients.Add(minCost); } + + // Penalize sums above the soft_max target. + if (softMax < hardMax && maxCost > 0) { + var delta = model.NewIntVar(-works.Length, works.Length, ""); + model.Add(delta == sumVar - softMax); + var excess = model.NewIntVar(0, works.Length, prefix + ": over_sum"); + model.AddMaxEquality(excess, new[]{delta, zero}); + costVariables.Add(excess); + costCoefficients.Add(maxCost); + } + + return (costVariables.ToArray(), costCoefficients.ToArray()); + } + + /// + /// C# equivalent of Python range (start, stop) + /// + /// The inclusive start. + /// The exclusive stop. + /// A sequence of integers. + static IEnumerable Range(int start, int stop) { + foreach (var i in Enumerable.Range(start, stop - start)) yield return i; + } + + /// + /// C# equivalent of Python range (stop) + /// + /// The exclusive stop. + /// A sequence of integers. + static IEnumerable Range(int stop) { return Range(0, stop); } } diff --git a/examples/dotnet/SpeakerSchedulingSat.cs b/examples/dotnet/SpeakerSchedulingSat.cs index 8359ad0cc9..9df618fb25 100644 --- a/examples/dotnet/SpeakerSchedulingSat.cs +++ b/examples/dotnet/SpeakerSchedulingSat.cs @@ -17,126 +17,148 @@ using System.Diagnostics; using System.Linq; using System; -class SpeakerScheduling -{ - struct Entry - { +class SpeakerScheduling { + struct Entry { public IntVar var; public int start; - public Entry(IntVar v, int s) - { + public Entry(IntVar v, int s) { var = v; start = s; } } - static void Solve(int first_slot) - { + static void Solve(int first_slot) { Console.WriteLine("----------------------------------------------------"); // the slots each speaker is available int[][] speaker_availability = { - new int[] {1,3,4,6,7,10,12,13,14,15,16,18,19,20,21,22,23,24,25,33,34,35,36,37,38,39,40,41,43,44,45,46,47,48,49,50,51,52,54,55,56,57,58,59}, - new int[] {1,2,7,8,10,11,16,17,18,21,22,23,24,25,33,34,35,36,37,38,39,40,42,43,44,45,46,47,48,49,52,53,54,55,56,57,58,59,60}, - new int[] {5,6,7,10,12,14,16,17,21,22,23,24,33,35,37,38,39,40,41,42,43,44,45,46,51,53,55,56,57,58,59}, - new int[] {1,2,3,4,5,6,7,11,13,14,15,16,20,24,25,33,34,35,37,38,39,40,41,43,44,45,46,47,48,49,50,51,52,53,54,55,56,58,59,60}, - new int[] {4,7,8,9,16,17,19,20,21,22,23,24,25,33,34,35,36,37,38,39,40,41,42,43,49,50,51,53,55,56,57,58,59,60}, - new int[] {4,7,9,11,12,13,14,15,16,17,18,22,23,24,33,34,35,36,38,39,42,44,46,48,49,51,53,54,55,56,57}, - new int[] {1,2,3,4,5,6,7,33,34,35,36,37,38,39,40,41,42,54,55,56,57,58,59,60}, - new int[] {1,3,11,14,15,16,17,21,22,23,24,25,33,35,36,37,39,40,41,42,43,44,45,47,48,49,51,52,53,54,55,56,57,58,59,60}, - new int[] {1,2,3,4,5,7,8,9,10,11,13,18,19,20,21,22,23,24,25,33,34,35,36,37,38,39,40,41,42,43,44,45,46,50,51,52,53,54,55,56,57,59,60}, - new int[] {24,33,34,35,36,37,38,39,40,41,42,43,45,49,50,51,52,53,54,55,56,57,58,59,60}, - new int[] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,16,17,18,19,20,22,23,24,25,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,50,51,52,53,55,56,57,58,59,60}, - new int[] {3,4,5,6,13,15,16,17,18,19,21,22,24,25,33,34,35,36,37,39,40,41,42,43,44,45,47,52,53,55,57,58,59,60}, - new int[] {4,5,6,8,11,12,13,14,17,19,20,22,23,24,25,33,34,35,36,37,39,40,41,42,43,47,48,49,50,51,52,55,56,57}, - new int[] {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60}, - new int[] {12,25,33,35,36,37,39,41,42,43,48,51,52,53,54,57,59,60}, - new int[] {4,8,16,17,19,23,25,33,34,35,37,41,44,45,47,48,49,50}, - new int[] {3,23,24,25,33,35,36,37,38,39,40,42,43,44,49,50,53,54,55,56,57,58,60}, - new int[] {7,13,19,20,22,23,24,25,33,34,35,38,40,41,42,44,45,46,47,48,49,52,53,54,58,59,60} - }; + new int[]{1, 3, 4, 6, 7, 10, 12, 13, 14, 15, 16, 18, 19, 20, 21, + 22, 23, 24, 25, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 54, 55, 56, 57, 58, 59}, + new int[]{1, 2, 7, 8, 10, 11, 16, 17, 18, 21, 22, 23, 24, + 25, 33, 34, 35, 36, 37, 38, 39, 40, 42, 43, 44, 45, + 46, 47, 48, 49, 52, 53, 54, 55, 56, 57, 58, 59, 60}, + new int[]{5, 6, 7, 10, 12, 14, 16, 17, 21, 22, 23, + 24, 33, 35, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 51, 53, 55, 56, 57, 58, 59}, + new int[]{1, 2, 3, 4, 5, 6, 7, 11, 13, 14, 15, 16, 20, 24, + 25, 33, 34, 35, 37, 38, 39, 40, 41, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 58, 59, 60}, + new int[]{4, 7, 8, 9, 16, 17, 19, 20, 21, 22, 23, 24, + 25, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 49, 50, 51, 53, 55, 56, 57, 58, 59, 60}, + new int[]{4, 7, 9, 11, 12, 13, 14, 15, 16, 17, 18, + 22, 23, 24, 33, 34, 35, 36, 38, 39, 42, 44, + 46, 48, 49, 51, 53, 54, 55, 56, 57}, + new int[]{1, 2, 3, 4, 5, 6, 7, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 54, 55, 56, 57, 58, 59, 60}, + new int[]{1, 3, 11, 14, 15, 16, 17, 21, 22, 23, 24, 25, + 33, 35, 36, 37, 39, 40, 41, 42, 43, 44, 45, 47, + 48, 49, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60}, + new int[]{1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 18, 19, 20, 21, + 22, 23, 24, 25, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 50, 51, 52, 53, 54, 55, 56, 57, 59, 60}, + new int[]{24, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60}, + new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 16, 17, 18, 19, 20, 22, 23, 24, 25, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 50, 51, 52, 53, 55, 56, 57, 58, 59, 60}, + new int[]{3, 4, 5, 6, 13, 15, 16, 17, 18, 19, 21, 22, + 24, 25, 33, 34, 35, 36, 37, 39, 40, 41, 42, 43, + 44, 45, 47, 52, 53, 55, 57, 58, 59, 60}, + new int[]{4, 5, 6, 8, 11, 12, 13, 14, 17, 19, 20, 22, + 23, 24, 25, 33, 34, 35, 36, 37, 39, 40, 41, 42, + 43, 47, 48, 49, 50, 51, 52, 55, 56, 57}, + new int[]{2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60}, + new int[]{12, 25, 33, 35, 36, 37, 39, 41, 42, 43, 48, 51, 52, 53, 54, + 57, 59, 60}, + new int[]{4, 8, 16, 17, 19, 23, 25, 33, 34, 35, 37, 41, 44, 45, 47, 48, + 49, 50}, + new int[]{3, 23, 24, 25, 33, 35, 36, 37, 38, 39, 40, 42, + 43, 44, 49, 50, 53, 54, 55, 56, 57, 58, 60}, + new int[]{7, 13, 19, 20, 22, 23, 24, 25, 33, 34, 35, 38, 40, 41, + 42, 44, 45, 46, 47, 48, 49, 52, 53, 54, 58, 59, 60}}; // how long each talk lasts for each speaker - int[] durations = { 1, 2, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; + int[] durations = {1, 2, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1}; int sum_of_durations = durations.Sum(); int number_of_speakers = durations.Length; // calculate the total number of slots (maximum in the availability array) // (and add the max durations) int last_slot = - (from s in Enumerable.Range(0, number_of_speakers) - select speaker_availability[s].Max()).Max(); + (from s in Enumerable + .Range(0, number_of_speakers) select speaker_availability [s] + .Max()) + .Max(); Console.WriteLine( - $"Scheduling {number_of_speakers} speakers, for a total of " + - $"{sum_of_durations} slots, during [{first_slot}..{last_slot}]"); + $"Scheduling {number_of_speakers} speakers, for a total of " + + $"{sum_of_durations} slots, during [{first_slot}..{last_slot}]"); CpModel model = new CpModel(); // We store the possible entries (var, start) for all talks filtered // from the duration and the speaker availability. - List[] entries = new List[number_of_speakers]; - for (int speaker = 0; speaker < number_of_speakers; ++speaker) - { + List[] entries = new List[ number_of_speakers ]; + for (int speaker = 0; speaker < number_of_speakers; ++speaker) { entries[speaker] = new List(); } - List[] contributions_per_slot = new List[last_slot + 1]; - for (int slot = 1; slot <= last_slot; ++slot) - { + List[] contributions_per_slot = new List[ last_slot + 1 ]; + for (int slot = 1; slot <= last_slot; ++slot) { contributions_per_slot[slot] = new List(); } - for (int speaker = 0; speaker < number_of_speakers; ++speaker) - { + for (int speaker = 0; speaker < number_of_speakers; ++speaker) { List all_vars = new List(); int duration = durations[speaker]; // Let's filter the possible starts. int availability = speaker_availability[speaker].Length; - for (int index = 0; index < availability; ++index) - { + for (int index = 0; index < availability; ++index) { bool ok = true; - int slot = speaker_availability[speaker][index]; - if (slot < first_slot) - { + int slot = speaker_availability [speaker] + [index]; + if (slot < first_slot) { continue; } - for (int offset = 1; offset < duration; ++offset) - { - if (index + offset >= availability || - speaker_availability[speaker][index + offset] != slot + offset) - { + for (int offset = 1; offset < duration; ++offset) { + if (index + offset >= availability || speaker_availability [speaker] + [index + offset] != + slot + offset) { // discontinuity. ok = false; break; } } - if (ok) - { - IntVar var = model.NewBoolVar("speaker " + (speaker + 1) + " starts at " + slot); - entries[speaker].Add(new Entry(var, slot)); + if (ok) { + IntVar var = model.NewBoolVar("speaker " + (speaker + 1) + + " starts at " + slot); + entries [speaker] + .Add(new Entry(var, slot)); all_vars.Add(var); - for (int offset = 0; offset < duration; ++offset) - { - contributions_per_slot[slot + offset].Add(var); + for (int offset = 0; offset < duration; ++offset) { + contributions_per_slot [slot + offset] + .Add(var); } } } model.Add(LinearExpr.Sum(all_vars) == 1); } // Force the schedule to be consistent. - for (int slot = first_slot; slot <= last_slot; ++slot) - { + for (int slot = first_slot; slot <= last_slot; ++slot) { model.Add(LinearExpr.Sum(contributions_per_slot[slot]) <= 1); } // Creates last_slot. - IntVar last_slot_var = model.NewIntVar( - first_slot + sum_of_durations - 1, last_slot, "last_slot"); - for (int speaker = 0; speaker < number_of_speakers; speaker++) - { + IntVar last_slot_var = model.NewIntVar(first_slot + sum_of_durations - 1, + last_slot, "last_slot"); + for (int speaker = 0; speaker < number_of_speakers; speaker++) { int duration = durations[speaker]; - foreach (Entry e in entries[speaker]) - { + foreach (Entry e in entries[speaker]) { model.Add(last_slot_var >= e.start + duration - 1).OnlyEnforceIf(e.var); } } @@ -148,20 +170,14 @@ class SpeakerScheduling solver.StringParameters = "num_search_workers:8"; CpSolverStatus status = solver.Solve(model); - if (status == CpSolverStatus.Optimal) - { + if (status == CpSolverStatus.Optimal) { Console.WriteLine("\nLast used slot: " + solver.Value(last_slot_var)); Console.WriteLine("Speakers (start..end):"); - for (int speaker = 0; speaker < number_of_speakers; speaker++) - { - foreach (Entry e in entries[speaker]) - { - if (solver.BooleanValue(e.var)) - { - Console.WriteLine( - " - speaker {0,2}: {1,2}..{2,2}", (speaker + 1), - e.start, (e.start + durations[speaker] - 1)); - + for (int speaker = 0; speaker < number_of_speakers; speaker++) { + foreach (Entry e in entries[speaker]) { + if (solver.BooleanValue(e.var)) { + Console.WriteLine(" - speaker {0,2}: {1,2}..{2,2}", (speaker + 1), + e.start, (e.start + durations[speaker] - 1)); } } } @@ -171,17 +187,14 @@ class SpeakerScheduling Console.WriteLine(solver.ResponseStats()); } - public static void Main(String[] args) - { + public static void Main(String[] args) { int start = 1; - if (args.Length == 1) - { + if (args.Length == 1) { start = int.Parse(args[0]); } Stopwatch s = new Stopwatch(); s.Start(); - for (int i = start; i < 40; i++) - { + for (int i = start; i < 40; i++) { Solve(i); } diff --git a/examples/dotnet/TaskSchedulingSat.cs b/examples/dotnet/TaskSchedulingSat.cs index 72a29f02ad..67932bf75a 100644 --- a/examples/dotnet/TaskSchedulingSat.cs +++ b/examples/dotnet/TaskSchedulingSat.cs @@ -3,11 +3,15 @@ using System.Collections.Generic; using Google.OrTools.Sat; class Job { - public Job(List tasks) { - AlternativeTasks = tasks; + public Job(List tasks) { AlternativeTasks = tasks; } + public Job Successor { + get; + set; + } + public List AlternativeTasks { + get; + set; } - public Job Successor { get; set; } - public List AlternativeTasks { get; set; } } class Task { @@ -17,19 +21,29 @@ class Task { Equipment = equipment; } - public string Name {get; set;} - public long StartTime {get; set;} - public long EndTime { - get { - return StartTime + Duration; - } + public string Name { + get; + set; + } + public long StartTime { + get; + set; + } + public long EndTime { + get { return StartTime + Duration; } + } + public long Duration { + get; + set; + } + public long Equipment { + get; + set; } - public long Duration {get; set;} - public long Equipment { get; set; } public override string ToString() { - return Name + " [ " + Equipment + " ]\tstarts: " + StartTime + " ends:" + - EndTime + ", duration: " + Duration; + return Name + " [ " + Equipment + " ]\tstarts: " + StartTime + + " ends:" + EndTime + ", duration: " + Duration; } } @@ -122,8 +136,7 @@ class TaskSchedulingSat { public static int GetEndTaskCount() { int c = 0; foreach (Job j in myJobList) - if (j.Successor == null) - c += j.AlternativeTasks.Count; + if (j.Successor == null) c += j.AlternativeTasks.Count; return c; } @@ -147,12 +160,13 @@ class TaskSchedulingSat { tmp[i++] = taskChoosed[ti]; IntVar start = model.NewIntVar(0, 10000, t.Name + "_start"); IntVar end = model.NewIntVar(0, 10000, t.Name + "_end"); - tasks[ti] = model.NewIntervalVar(start, t.Duration, end, t.Name + "_interval"); - if (j.Successor == null) - allEnds[endJobCounter++] = end; + tasks[ti] = + model.NewIntervalVar(start, t.Duration, end, t.Name + "_interval"); + if (j.Successor == null) allEnds[endJobCounter++] = end; if (!tasksToEquipment.ContainsKey(t.Equipment)) tasksToEquipment[t.Equipment] = new List(); - tasksToEquipment[t.Equipment].Add(tasks[ti]); + tasksToEquipment [t.Equipment] + .Add(tasks[ti]); } model.Add(LinearExpr.Sum(tmp) == 1); } @@ -172,4 +186,3 @@ class TaskSchedulingSat { Console.WriteLine(solver.ResponseStats()); } } - diff --git a/examples/dotnet/cscvrptw.cs b/examples/dotnet/cscvrptw.cs index 55be6c2dd6..c07314819a 100644 --- a/examples/dotnet/cscvrptw.cs +++ b/examples/dotnet/cscvrptw.cs @@ -21,7 +21,6 @@ using Google.OrTools.ConstraintSolver; /// routing library in src/constraint_solver. /// public class CapacitatedVehicleRoutingProblemWithTimeWindows { - /// /// A position on the map with (x, y) coordinates. /// @@ -64,10 +63,8 @@ public class CapacitatedVehicleRoutingProblemWithTimeWindows { /// positions of two different indices. /// class Manhattan { - public Manhattan( - RoutingIndexManager manager, - Position[] locations, - int coefficient) { + public Manhattan(RoutingIndexManager manager, Position[] locations, + int coefficient) { this.manager_ = manager; this.locations_ = locations; this.coefficient_ = coefficient; @@ -80,10 +77,10 @@ public class CapacitatedVehicleRoutingProblemWithTimeWindows { } int first_node = manager_.IndexToNode(first_index); int second_node = manager_.IndexToNode(second_index); - return (Math.Abs(locations_[first_node].x_ - - locations_[second_node].x_) + + return (Math.Abs(locations_[first_node].x_ - locations_[second_node].x_) + Math.Abs(locations_[first_node].y_ - - locations_[second_node].y_)) * coefficient_; + locations_[second_node].y_)) * + coefficient_; } private readonly RoutingIndexManager manager_; @@ -96,9 +93,7 @@ public class CapacitatedVehicleRoutingProblemWithTimeWindows { /// integer array. /// class Demand { - public Demand( - RoutingIndexManager manager, - int[] order_demands) { + public Demand(RoutingIndexManager manager, int[] order_demands) { this.manager_ = manager; this.order_demands_ = order_demands; } @@ -161,28 +156,22 @@ public class CapacitatedVehicleRoutingProblemWithTimeWindows { /// /// maximum pernalty cost if order is dropped. /// - private void BuildOrders(int number_of_orders, - int number_of_vehicles, - int x_max, int y_max, - int demand_max, - int time_window_max, - int time_window_width, - int penalty_min, - int penalty_max) { + private void BuildOrders(int number_of_orders, int number_of_vehicles, + int x_max, int y_max, int demand_max, + int time_window_max, int time_window_width, + int penalty_min, int penalty_max) { Console.WriteLine("Building orders."); locations_ = new Position[number_of_orders + 2 * number_of_vehicles]; order_demands_ = new int[number_of_orders]; order_time_windows_ = new TimeWindow[number_of_orders]; order_penalties_ = new int[number_of_orders]; for (int order = 0; order < number_of_orders; ++order) { - locations_[order] = - new Position(random_generator.Next(x_max + 1), - random_generator.Next(y_max + 1)); + locations_[order] = new Position(random_generator.Next(x_max + 1), + random_generator.Next(y_max + 1)); order_demands_[order] = random_generator.Next(demand_max + 1); int time_window_start = random_generator.Next(time_window_max + 1); - order_time_windows_[order] = - new TimeWindow(time_window_start, - time_window_start + time_window_width); + order_time_windows_[order] = new TimeWindow( + time_window_start, time_window_start + time_window_width); order_penalties_[order] = random_generator.Next(penalty_max - penalty_min + 1) + penalty_min; } @@ -203,11 +192,8 @@ public class CapacitatedVehicleRoutingProblemWithTimeWindows { /// capacity of a vehicle. /// maximum cost per distance unit of a /// vehicle (minimum is 1) - private void BuildFleet(int number_of_orders, - int number_of_vehicles, - int x_max, int y_max, - int end_time, - int capacity, + private void BuildFleet(int number_of_orders, int number_of_vehicles, + int x_max, int y_max, int end_time, int capacity, int cost_coefficient_max) { Console.WriteLine("Building fleet."); vehicle_capacity_ = capacity; @@ -218,13 +204,11 @@ public class CapacitatedVehicleRoutingProblemWithTimeWindows { for (int vehicle = 0; vehicle < number_of_vehicles; ++vehicle) { int index = 2 * vehicle + number_of_orders; vehicle_starts_[vehicle] = index; - locations_[index] = - new Position(random_generator.Next(x_max + 1), - random_generator.Next(y_max + 1)); + locations_[index] = new Position(random_generator.Next(x_max + 1), + random_generator.Next(y_max + 1)); vehicle_ends_[vehicle] = index + 1; - locations_[index + 1] = - new Position(random_generator.Next(x_max + 1), - random_generator.Next(y_max + 1)); + locations_[index + 1] = new Position(random_generator.Next(x_max + 1), + random_generator.Next(y_max + 1)); vehicle_end_time_[vehicle] = end_time; vehicle_cost_coefficients_[vehicle] = random_generator.Next(cost_coefficient_max) + 1; @@ -248,9 +232,8 @@ public class CapacitatedVehicleRoutingProblemWithTimeWindows { // Setting up dimensions const int big_number = 100000; Manhattan manhattan_callback = new Manhattan(manager, locations_, 1); - model.AddDimension( - model.RegisterTransitCallback(manhattan_callback.Call), - big_number, big_number, false, "time"); + model.AddDimension(model.RegisterTransitCallback(manhattan_callback.Call), + big_number, big_number, false, "time"); RoutingDimension time_dimension = model.GetDimensionOrDie("time"); Demand demand_callback = new Demand(manager, order_demands_); @@ -268,8 +251,8 @@ public class CapacitatedVehicleRoutingProblemWithTimeWindows { int manhattan_cost_index = model.RegisterTransitCallback(manhattan_cost_callback.Call); model.SetArcCostEvaluatorOfVehicle(manhattan_cost_index, vehicle); - time_dimension.CumulVar(model.End(vehicle)).SetMax( - vehicle_end_time_[vehicle]); + time_dimension.CumulVar(model.End(vehicle)) + .SetMax(vehicle_end_time_[vehicle]); } // Setting up orders @@ -308,19 +291,18 @@ public class CapacitatedVehicleRoutingProblemWithTimeWindows { if (model.IsEnd(solution.Value(model.NextVar(order)))) { route += "Empty"; } else { - for (; - !model.IsEnd(order); + for (; !model.IsEnd(order); order = solution.Value(model.NextVar(order))) { IntVar local_load = capacity_dimension.CumulVar(order); IntVar local_time = time_dimension.CumulVar(order); route += order + " Load(" + solution.Value(local_load) + ") " + - "Time(" + solution.Min(local_time) + ", " + - solution.Max(local_time) + ") -> "; + "Time(" + solution.Min(local_time) + ", " + + solution.Max(local_time) + ") -> "; } IntVar load = capacity_dimension.CumulVar(order); IntVar time = time_dimension.CumulVar(order); - route += order + " Load(" + solution.Value(load) + ") " + - "Time(" + solution.Min(time) + ", " + solution.Max(time) + ")"; + route += order + " Load(" + solution.Value(load) + ") " + "Time(" + + solution.Min(time) + ", " + solution.Max(time) + ")"; } output += route + "\n"; } @@ -328,9 +310,7 @@ public class CapacitatedVehicleRoutingProblemWithTimeWindows { } } - - public static void Main(String[] args) - { + public static void Main(String[] args) { CapacitatedVehicleRoutingProblemWithTimeWindows problem = new CapacitatedVehicleRoutingProblemWithTimeWindows(); int x_max = 20; @@ -347,21 +327,10 @@ public class CapacitatedVehicleRoutingProblemWithTimeWindows { int vehicles = 20; int capacity = 50; - problem.BuildOrders(orders, - vehicles, - x_max, - y_max, - demand_max, - time_window_max, - time_window_width, - penalty_min, + problem.BuildOrders(orders, vehicles, x_max, y_max, demand_max, + time_window_max, time_window_width, penalty_min, penalty_max); - problem.BuildFleet(orders, - vehicles, - x_max, - y_max, - end_time, - capacity, + problem.BuildFleet(orders, vehicles, x_max, y_max, end_time, capacity, cost_coefficient_max); problem.Solve(orders, vehicles); } diff --git a/examples/dotnet/csflow.cs b/examples/dotnet/csflow.cs index d327f639df..e732969b89 100644 --- a/examples/dotnet/csflow.cs +++ b/examples/dotnet/csflow.cs @@ -14,10 +14,8 @@ using System; using Google.OrTools.Graph; -public class CsFlow -{ - private static void SolveMaxFlow() - { +public class CsFlow { + private static void SolveMaxFlow() { Console.WriteLine("Max Flow Problem"); int numNodes = 6; int numArcs = 9; @@ -27,8 +25,7 @@ public class CsFlow int[] expectedFlows = {4, 4, 2, 0, 4, 4, 0, 6, 4}; int expectedTotalFlow = 10; MaxFlow maxFlow = new MaxFlow(); - for (int i = 0; i < numArcs; ++i) - { + for (int i = 0; i < numArcs; ++i) { int arc = maxFlow.AddArcWithCapacity(tails[i], heads[i], capacities[i]); if (arc != i) throw new Exception("Internal error"); } @@ -37,71 +34,60 @@ public class CsFlow Console.WriteLine("Solving max flow with " + numNodes + " nodes, and " + numArcs + " arcs, source=" + source + ", sink=" + sink); MaxFlow.Status solveStatus = maxFlow.Solve(source, sink); - if (solveStatus == MaxFlow.Status.OPTIMAL) - { + if (solveStatus == MaxFlow.Status.OPTIMAL) { long totalFlow = maxFlow.OptimalFlow(); Console.WriteLine("total computed flow " + totalFlow + ", expected = " + expectedTotalFlow); - for (int i = 0; i < numArcs; ++i) - { + for (int i = 0; i < numArcs; ++i) { Console.WriteLine("Arc " + i + " (" + maxFlow.Head(i) + " -> " + - maxFlow.Tail(i) + "), capacity = " + - maxFlow.Capacity(i) + ") computed = " + - maxFlow.Flow(i) + ", expected = " + expectedFlows[i]); + maxFlow.Tail(i) + + "), capacity = " + maxFlow.Capacity(i) + + ") computed = " + maxFlow.Flow(i) + + ", expected = " + expectedFlows[i]); } - } - else - { + } else { Console.WriteLine("Solving the max flow problem failed. Solver status: " + solveStatus); } } - private static void SolveMinCostFlow() - { + private static void SolveMinCostFlow() { Console.WriteLine("Min Cost Flow Problem"); int numSources = 4; int numTargets = 4; - int[,] costs = { {90, 75, 75, 80}, + int[, ] costs = {{90, 75, 75, 80}, {35, 85, 55, 65}, {125, 95, 90, 105}, - {45, 110, 95, 115} }; + {45, 110, 95, 115}}; int expectedCost = 275; MinCostFlow minCostFlow = new MinCostFlow(); - for (int source = 0; source < numSources; ++source) - { + for (int source = 0; source < numSources; ++source) { for (int target = 0; target < numTargets; ++target) { minCostFlow.AddArcWithCapacityAndUnitCost( source, /*target=*/numSources + target, /*capacity=*/1, /*flow unit cost=*/costs[source, target]); } } - for (int source = 0; source < numSources; ++source) - { + for (int source = 0; source < numSources; ++source) { minCostFlow.SetNodeSupply(source, 1); } - for (int target = 0; target < numTargets; ++target) - { + for (int target = 0; target < numTargets; ++target) { minCostFlow.SetNodeSupply(numSources + target, -1); } Console.WriteLine("Solving min cost flow with " + numSources + " sources, and " + numTargets + " targets."); MinCostFlow.Status solveStatus = minCostFlow.Solve(); - if (solveStatus == MinCostFlow.Status.OPTIMAL) - { - Console.WriteLine("total computed flow cost = " + - minCostFlow.OptimalCost() + - ", expected = " + expectedCost); - } - else - { + if (solveStatus == MinCostFlow.Status.OPTIMAL) { + Console.WriteLine( + "total computed flow cost = " + minCostFlow.OptimalCost() + + ", expected = " + expectedCost); + } else { Console.WriteLine("Solving the min cost flow problem failed." + " Solver status: " + solveStatus); } } - static void Main() - { + static void Main() { SolveMaxFlow(); SolveMinCostFlow(); } diff --git a/examples/dotnet/csintegerprogramming.cs b/examples/dotnet/csintegerprogramming.cs index 3c38fb4701..cbe0bf349f 100644 --- a/examples/dotnet/csintegerprogramming.cs +++ b/examples/dotnet/csintegerprogramming.cs @@ -14,13 +14,10 @@ using System; using Google.OrTools.LinearSolver; -public class CsIntegerProgramming -{ - private static void RunIntegerProgrammingExample(String solverType) - { +public class CsIntegerProgramming { + private static void RunIntegerProgrammingExample(String solverType) { Solver solver = Solver.CreateSolver(solverType); - if (solver == null) - { + if (solver == null) { Console.WriteLine("Could not create solver " + solverType); return; } @@ -42,8 +39,7 @@ public class CsIntegerProgramming Solver.ResultStatus resultStatus = solver.Solve(); // Check that the problem has an optimal solution. - if (resultStatus != Solver.ResultStatus.OPTIMAL) - { + if (resultStatus != Solver.ResultStatus.OPTIMAL) { Console.WriteLine("The problem does not have an optimal solution!"); return; } @@ -63,11 +59,10 @@ public class CsIntegerProgramming " branch-and-bound nodes"); } - private static void RunIntegerProgrammingExampleNaturalApi(String solverType) - { + private static void RunIntegerProgrammingExampleNaturalApi( + String solverType) { Solver solver = Solver.CreateSolver(solverType); - if (solver == null) - { + if (solver == null) { Console.WriteLine("Could not create solver " + solverType); return; } @@ -81,8 +76,7 @@ public class CsIntegerProgramming Solver.ResultStatus resultStatus = solver.Solve(); // Check that the problem has an optimal solution. - if (resultStatus != Solver.ResultStatus.OPTIMAL) - { + if (resultStatus != Solver.ResultStatus.OPTIMAL) { Console.WriteLine("The problem does not have an optimal solution!"); return; } @@ -103,8 +97,7 @@ public class CsIntegerProgramming " branch-and-bound nodes"); } - static void Main() - { + static void Main() { Console.WriteLine("---- Integer programming example with GLPK ----"); RunIntegerProgrammingExample("GLPK"); Console.WriteLine("---- Linear programming example with CBC ----"); diff --git a/examples/dotnet/csknapsack.cs b/examples/dotnet/csknapsack.cs index 445aa24dda..a23514629a 100644 --- a/examples/dotnet/csknapsack.cs +++ b/examples/dotnet/csknapsack.cs @@ -14,27 +14,24 @@ using System; using Google.OrTools.Algorithms; -public class CsKnapsack -{ - static void Main() - { - KnapsackSolver solver = new KnapsackSolver( - KnapsackSolver.SolverType.KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER, "test"); - long[] profits = { 360, 83, 59, 130, 431, 67, 230, 52, 93, - 125, 670, 892, 600, 38, 48, 147, 78, 256, - 63, 17, 120, 164, 432, 35, 92, 110, 22, - 42, 50, 323, 514, 28, 87, 73, 78, 15, - 26, 78, 210, 36, 85, 189, 274, 43, 33, - 10, 19, 389, 276, 312 }; +public class CsKnapsack { + static void Main() { + KnapsackSolver solver = + new KnapsackSolver(KnapsackSolver.SolverType + .KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER, + "test"); + long[] profits = {360, 83, 59, 130, 431, 67, 230, 52, 93, 125, + 670, 892, 600, 38, 48, 147, 78, 256, 63, 17, + 120, 164, 432, 35, 92, 110, 22, 42, 50, 323, + 514, 28, 87, 73, 78, 15, 26, 78, 210, 36, + 85, 189, 274, 43, 33, 10, 19, 389, 276, 312}; - long[,] weights = { { 7, 0, 30, 22, 80, 94, 11, 81, 70, - 64, 59, 18, 0, 36, 3, 8, 15, 42, - 9, 0, 42, 47, 52, 32, 26, 48, 55, - 6, 29, 84, 2, 4, 18, 56, 7, 29, - 93, 44, 71, 3, 86, 66, 31, 65, 0, - 79, 20, 65, 52, 13 } }; + long[, ] weights = {{7, 0, 30, 22, 80, 94, 11, 81, 70, 64, 59, 18, 0, + 36, 3, 8, 15, 42, 9, 0, 42, 47, 52, 32, 26, 48, + 55, 6, 29, 84, 2, 4, 18, 56, 7, 29, 93, 44, 71, + 3, 86, 66, 31, 65, 0, 79, 20, 65, 52, 13}}; - long[] capacities = { 850 }; + long[] capacities = {850}; long optimalProfit = 7534; @@ -43,7 +40,7 @@ public class CsKnapsack solver.Init(profits, weights, capacities); long computedProfit = solver.Solve(); - Console.WriteLine("Optimal Profit = " + computedProfit + ", expected = " + - optimalProfit); + Console.WriteLine("Optimal Profit = " + computedProfit + + ", expected = " + optimalProfit); } } diff --git a/examples/dotnet/cslinearprogramming.cs b/examples/dotnet/cslinearprogramming.cs index 2b4a160ee7..a55945b7f1 100644 --- a/examples/dotnet/cslinearprogramming.cs +++ b/examples/dotnet/cslinearprogramming.cs @@ -14,15 +14,13 @@ using System; using Google.OrTools.LinearSolver; -public class CsLinearProgramming -{ - private static void RunLinearProgrammingExample(String solverType) - { - Console.WriteLine($"---- Linear programming example with {solverType} ----"); +public class CsLinearProgramming { + private static void RunLinearProgrammingExample(String solverType) { + Console.WriteLine( + $"---- Linear programming example with {solverType} ----"); Solver solver = Solver.CreateSolver(solverType); - if (solver == null) - { + if (solver == null) { Console.WriteLine("Could not create solver " + solverType); return; } @@ -83,7 +81,7 @@ public class CsLinearProgramming double[] activities = solver.ComputeConstraintActivities(); Console.WriteLine("Problem solved in " + solver.Iterations() + - " iterations"); + " iterations"); Console.WriteLine("x1: reduced cost = " + x1.ReducedCost()); Console.WriteLine("x2: reduced cost = " + x2.ReducedCost()); Console.WriteLine("x3: reduced cost = " + x3.ReducedCost()); @@ -95,15 +93,13 @@ public class CsLinearProgramming Console.WriteLine(" activity = " + activities[c2.Index()]); } - private static void RunLinearProgrammingExampleNaturalApi( - String solverType, bool printModel) - { + private static void RunLinearProgrammingExampleNaturalApi(String solverType, + bool printModel) { Console.WriteLine( $"---- Linear programming example (Natural API) with {solverType} ----"); Solver solver = Solver.CreateSolver(solverType); - if (solver == null) - { + if (solver == null) { Console.WriteLine("Could not create solver " + solverType); return; } @@ -148,7 +144,7 @@ public class CsLinearProgramming Console.WriteLine("Advanced usage:"); double[] activities = solver.ComputeConstraintActivities(); Console.WriteLine("Problem solved in " + solver.Iterations() + - " iterations"); + " iterations"); Console.WriteLine("x1: reduced cost = " + x1.ReducedCost()); Console.WriteLine("x2: reduced cost = " + x2.ReducedCost()); Console.WriteLine("x3: reduced cost = " + x3.ReducedCost()); @@ -160,8 +156,7 @@ public class CsLinearProgramming Console.WriteLine(" activity = " + activities[c2.Index()]); } - static void Main() - { + static void Main() { RunLinearProgrammingExample("GLOP"); RunLinearProgrammingExample("GLPK_LP"); RunLinearProgrammingExample("CLP"); diff --git a/examples/dotnet/csls_api.cs b/examples/dotnet/csls_api.cs index 8d9ac8ddf8..c0c82c4f70 100644 --- a/examples/dotnet/csls_api.cs +++ b/examples/dotnet/csls_api.cs @@ -18,26 +18,18 @@ using Google.OrTools.ConstraintSolver; * Shows how to write a custom lns operator. */ -public class OneVarLns : BaseLns -{ +public class OneVarLns : BaseLns { public OneVarLns(IntVar[] vars) : base(vars) {} - public override void InitFragments() - { - index_ = 0; - } + public override void InitFragments() { index_ = 0; } - public override bool NextFragment() - { + public override bool NextFragment() { int size = Size(); - if (index_ < size) - { + if (index_ < size) { AppendToFragment(index_); ++index_; return true; - } - else - { + } else { return false; } } @@ -46,23 +38,18 @@ public class OneVarLns : BaseLns } class MoveOneVar : IntVarLocalSearchOperator { - public MoveOneVar(IntVar[] variables) : base(variables) - { + public MoveOneVar(IntVar[] variables) : base(variables) { variable_index_ = 0; move_up_ = false; } - protected override bool MakeOneNeighbor() - { + protected override bool MakeOneNeighbor() { long current_value = OldValue(variable_index_); - if (move_up_) - { - SetValue(variable_index_, current_value + 1); + if (move_up_) { + SetValue(variable_index_, current_value + 1); variable_index_ = (variable_index_ + 1) % Size(); - } - else - { - SetValue(variable_index_, current_value - 1); + } else { + SetValue(variable_index_, current_value - 1); } move_up_ = !move_up_; return true; @@ -75,36 +62,28 @@ class MoveOneVar : IntVarLocalSearchOperator { }; public class SumFilter : IntVarLocalSearchFilter { - public SumFilter(IntVar[] vars) : base(vars) - { - sum_ = 0; - } + public SumFilter(IntVar[] vars) : base(vars) { sum_ = 0; } - protected override void OnSynchronize(Assignment delta) - { + protected override void OnSynchronize(Assignment delta) { sum_ = 0; - for (int index = 0; index < Size(); ++index) - { + for (int index = 0; index < Size(); ++index) { sum_ += Value(index); } } public override bool Accept(Assignment delta, Assignment unused_deltadelta, long unused_objective_min, - long unused_objective_max) { + long unused_objective_max) { AssignmentIntContainer solution_delta = delta.IntVarContainer(); int solution_delta_size = solution_delta.Size(); - for (int i = 0; i < solution_delta_size; ++i) - { - if (!solution_delta.Element(i).Activated()) - { + for (int i = 0; i < solution_delta_size; ++i) { + if (!solution_delta.Element(i).Activated()) { return true; } } long new_sum = sum_; - for (int index = 0; index < solution_delta_size; ++index) - { + for (int index = 0; index < solution_delta_size; ++index) { int touched_var = Index(solution_delta.Element(index).Var()); long old_value = Value(touched_var); long new_value = solution_delta.Element(index).Value(); @@ -113,20 +92,17 @@ public class SumFilter : IntVarLocalSearchFilter { return new_sum < sum_; } - private long sum_; + private long sum_; }; -public class CsLsApi -{ - private static void BasicLns() - { +public class CsLsApi { + private static void BasicLns() { Console.WriteLine("BasicLns"); Solver solver = new Solver("BasicLns"); IntVar[] vars = solver.MakeIntVarArray(4, 0, 4, "vars"); IntVar sum_var = vars.Sum().Var(); OptimizeVar obj = sum_var.Minimize(1); - DecisionBuilder db = solver.MakePhase(vars, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(vars, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MAX_VALUE); OneVarLns one_var_lns = new OneVarLns(vars); LocalSearchPhaseParameters ls_params = @@ -139,15 +115,13 @@ public class CsLsApi Console.WriteLine("Objective value = {0}", collector.ObjectiveValue(0)); } - private static void BasicLs() - { + private static void BasicLs() { Console.WriteLine("BasicLs"); Solver solver = new Solver("BasicLs"); IntVar[] vars = solver.MakeIntVarArray(4, 0, 4, "vars"); IntVar sum_var = vars.Sum().Var(); OptimizeVar obj = sum_var.Minimize(1); - DecisionBuilder db = solver.MakePhase(vars, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(vars, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MAX_VALUE); MoveOneVar move_one_var = new MoveOneVar(vars); LocalSearchPhaseParameters ls_params = @@ -160,24 +134,22 @@ public class CsLsApi Console.WriteLine("Objective value = {0}", collector.ObjectiveValue(0)); } - private static void BasicLsWithFilter() - { + private static void BasicLsWithFilter() { Console.WriteLine("BasicLsWithFilter"); Solver solver = new Solver("BasicLs"); IntVar[] vars = solver.MakeIntVarArray(4, 0, 4, "vars"); IntVar sum_var = vars.Sum().Var(); OptimizeVar obj = sum_var.Minimize(1); - DecisionBuilder db = solver.MakePhase(vars, - Solver.CHOOSE_FIRST_UNBOUND, + DecisionBuilder db = solver.MakePhase(vars, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MAX_VALUE); MoveOneVar move_one_var = new MoveOneVar(vars); SumFilter filter = new SumFilter(vars); - IntVarLocalSearchFilter[] filters = - new IntVarLocalSearchFilter[] { filter }; - LocalSearchFilterManager filter_manager = new LocalSearchFilterManager(filters); + IntVarLocalSearchFilter[] filters = new IntVarLocalSearchFilter[]{filter}; + LocalSearchFilterManager filter_manager = + new LocalSearchFilterManager(filters); LocalSearchPhaseParameters ls_params = - solver.MakeLocalSearchPhaseParameters(sum_var, move_one_var, db, - null, filter_manager); + solver.MakeLocalSearchPhaseParameters(sum_var, move_one_var, db, null, + filter_manager); DecisionBuilder ls = solver.MakeLocalSearchPhase(vars, db, ls_params); SolutionCollector collector = solver.MakeLastSolutionCollector(); collector.AddObjective(sum_var); @@ -186,9 +158,7 @@ public class CsLsApi Console.WriteLine("Objective value = {0}", collector.ObjectiveValue(0)); } - - public static void Main(String[] args) - { + public static void Main(String[] args) { BasicLns(); BasicLs(); BasicLsWithFilter(); diff --git a/examples/dotnet/csrabbitspheasants.cs b/examples/dotnet/csrabbitspheasants.cs index 536a0b0d26..3a0ffeae39 100644 --- a/examples/dotnet/csrabbitspheasants.cs +++ b/examples/dotnet/csrabbitspheasants.cs @@ -17,19 +17,12 @@ using Google.OrTools.ConstraintSolver; /** * Shows how to write a custom decision builder. */ -public class AssignFirstUnboundToMin : NetDecisionBuilder -{ - public AssignFirstUnboundToMin(IntVar[] vars) - { - vars_ = vars; - } +public class AssignFirstUnboundToMin : NetDecisionBuilder { + public AssignFirstUnboundToMin(IntVar[] vars) { vars_ = vars; } - public override Decision Next(Solver solver) - { - foreach (IntVar var in vars_) - { - if (!var.Bound()) - { + public override Decision Next(Solver solver) { + foreach (IntVar var in vars_) { + if (!var.Bound()) { return solver.MakeAssignVariableValue(var, var.Min()); } } @@ -39,35 +32,29 @@ public class AssignFirstUnboundToMin : NetDecisionBuilder private IntVar[] vars_; } - -public class CsRabbitsPheasants -{ +public class CsRabbitsPheasants { /** * Solves the rabbits + pheasants problem. We are seing 20 heads * and 56 legs. How many rabbits and how many pheasants are we thus * seeing? */ - private static void Solve() - { + private static void Solve() { Solver solver = new Solver("RabbitsPheasants"); IntVar rabbits = solver.MakeIntVar(0, 100, "rabbits"); IntVar pheasants = solver.MakeIntVar(0, 100, "pheasants"); solver.Add(rabbits + pheasants == 20); solver.Add(rabbits * 4 + pheasants * 2 == 56); DecisionBuilder db = - new AssignFirstUnboundToMin(new IntVar[] {rabbits, pheasants}); + new AssignFirstUnboundToMin(new IntVar[]{rabbits, pheasants}); solver.NewSearch(db); solver.NextSolution(); Console.WriteLine( "Solved Rabbits + Pheasants in {0} ms, and {1} search tree branches.", - solver.WallTime(), solver.Branches()); + solver.WallTime(), solver.Branches()); Console.WriteLine(rabbits.ToString()); Console.WriteLine(pheasants.ToString()); solver.EndSearch(); } - public static void Main(String[] args) - { - Solve(); - } + public static void Main(String[] args) { Solve(); } } diff --git a/examples/dotnet/cstsp.cs b/examples/dotnet/cstsp.cs index 76cf52cf76..f48dd50656 100644 --- a/examples/dotnet/cstsp.cs +++ b/examples/dotnet/cstsp.cs @@ -15,17 +15,14 @@ using System; using System.Collections.Generic; using Google.OrTools.ConstraintSolver; -class Tsp -{ +class Tsp { class RandomManhattan { - public RandomManhattan(RoutingIndexManager manager, int size, int seed) - { + public RandomManhattan(RoutingIndexManager manager, int size, int seed) { this.xs_ = new int[size]; this.ys_ = new int[size]; this.manager_ = manager; Random generator = new Random(seed); - for (int i = 0; i < size; ++i) - { + for (int i = 0; i < size; ++i) { xs_[i] = generator.Next(1000); ys_[i] = generator.Next(1000); } @@ -35,7 +32,7 @@ class Tsp int first_node = manager_.IndexToNode(first_index); int second_node = manager_.IndexToNode(second_index); return Math.Abs(xs_[first_node] - xs_[second_node]) + - Math.Abs(ys_[first_node] - ys_[second_node]); + Math.Abs(ys_[first_node] - ys_[second_node]); } private readonly int[] xs_; @@ -43,8 +40,7 @@ class Tsp private readonly RoutingIndexManager manager_; }; - static void Solve(int size, int forbidden, int seed) - { + static void Solve(int size, int forbidden, int seed) { RoutingIndexManager manager = new RoutingIndexManager(size, 1, 0); RoutingModel routing = new RoutingModel(manager); @@ -71,11 +67,8 @@ class Tsp // Add dummy dimension to test API. routing.AddDimension( - routing.RegisterUnaryTransitCallback((long index) => {return 1;}), - size + 1, - size + 1, - true, - "dummy"); + routing.RegisterUnaryTransitCallback((long index) => { return 1; }), + size + 1, size + 1, true, "dummy"); // Solve, returns a solution if any (owned by RoutingModel). RoutingSearchParameters search_parameters = @@ -92,8 +85,7 @@ class Tsp // Inspect solution. // Only one route here; otherwise iterate from 0 to routing.vehicles() - 1 int route_number = 0; - for (long node = routing.Start(route_number); - !routing.IsEnd(node); + for (long node = routing.Start(route_number); !routing.IsEnd(node); node = solution.Value(routing.NextVar(node))) { Console.Write("{0} -> ", node); } @@ -101,8 +93,7 @@ class Tsp } } - public static void Main(String[] args) - { + public static void Main(String[] args) { int size = 10; if (args.Length > 0) { size = Convert.ToInt32(args[0]); diff --git a/examples/tests/ConstraintSolverTests.cs b/examples/tests/ConstraintSolverTests.cs index a3303179b4..11e1c69996 100644 --- a/examples/tests/ConstraintSolverTests.cs +++ b/examples/tests/ConstraintSolverTests.cs @@ -1,681 +1,722 @@ using System; using Xunit; using Google.OrTools.ConstraintSolver; -using static Google.OrTools.ConstraintSolver.operations_research_constraint_solver; +using static Google.OrTools.ConstraintSolver + .operations_research_constraint_solver; namespace Google.OrTools.Tests { public class ConstraintSolverTest { [Fact] - public void IntVectorToInt64Vector() { - int[] input = { 5, 11, 17 }; - long[] output = ToInt64Vector(input); - Assert.Equal(3, output.Length); - Assert.Equal(5, output[0]); - Assert.Equal(11, output[1]); - Assert.Equal(17, output[2]); - } + public void IntVectorToInt64Vector() { + int[] input = {5, 11, 17}; + long[] output = ToInt64Vector(input); + Assert.Equal(3, output.Length); + Assert.Equal(5, output[0]); + Assert.Equal(11, output[1]); + Assert.Equal(17, output[2]); + } [Fact] - public void IntVarConstructor() { - Solver solver = new Solver("Solver"); - IntVar x = solver.MakeIntVar(3, 7, "x"); - Assert.Equal(3, x.Min()); - Assert.Equal(7, x.Max()); - Assert.Equal("x(3..7)", x.ToString()); - } + public void IntVarConstructor() { + Solver solver = new Solver("Solver"); + IntVar x = solver.MakeIntVar(3, 7, "x"); + Assert.Equal(3, x.Min()); + Assert.Equal(7, x.Max()); + Assert.Equal("x(3..7)", x.ToString()); + } [Fact] - public void ConstraintConstructor() { - Solver solver = new Solver("Solver"); - IntVar x = solver.MakeIntVar(3, 7, "x"); - Assert.Equal("x(3..7)", x.ToString()); + public void ConstraintConstructor() { + Solver solver = new Solver("Solver"); + IntVar x = solver.MakeIntVar(3, 7, "x"); + Assert.Equal("x(3..7)", x.ToString()); - // Unary operator - Constraint c0 = (x == 5); - Assert.Equal("(x(3..7) == 5)", c0.ToString()); - IntExpr e1 = -c0; - Assert.Equal("-(Watch(0 .. 1))", e1.ToString()); - IntExpr e2 = c0.Abs(); - Assert.Equal("Watch(0 .. 1)", e2.ToString()); - IntExpr e3 = c0.Square(); - Assert.Equal("IntSquare(Watch(0 .. 1))", e3.ToString()); + // Unary operator + Constraint c0 = (x == 5); + Assert.Equal("(x(3..7) == 5)", c0.ToString()); + IntExpr e1 = -c0; + Assert.Equal("-(Watch(0 .. 1))", e1.ToString()); + IntExpr e2 = c0.Abs(); + Assert.Equal("Watch(0 .. 1)", e2.ToString()); + IntExpr e3 = c0.Square(); + Assert.Equal("IntSquare(Watch(0 .. 1))", e3.ToString()); - // Relational operator with a scalar - Constraint c1 = x == 5; - Assert.Equal("(x(3..7) == 5)", c1.ToString()); - Constraint c2 = x >= 5; - Assert.Equal("(x(3..7) >= 5)", c2.ToString()); - Constraint c3 = x > 5; - Assert.Equal("(x(3..7) >= 6)", c3.ToString()); - Constraint c4 = x <= 5; - Assert.Equal("(x(3..7) <= 5)", c4.ToString()); - Constraint c5 = x < 5; - Assert.Equal("(x(3..7) <= 4)", c5.ToString()); - Constraint c6 = x != 5; - Assert.Equal("(x(3..7) != 5)", c6.ToString()); - Constraint c7 = x == 2; - Assert.Equal("FalseConstraint()", c7.ToString()); - } + // Relational operator with a scalar + Constraint c1 = x == 5; + Assert.Equal("(x(3..7) == 5)", c1.ToString()); + Constraint c2 = x >= 5; + Assert.Equal("(x(3..7) >= 5)", c2.ToString()); + Constraint c3 = x > 5; + Assert.Equal("(x(3..7) >= 6)", c3.ToString()); + Constraint c4 = x <= 5; + Assert.Equal("(x(3..7) <= 5)", c4.ToString()); + Constraint c5 = x < 5; + Assert.Equal("(x(3..7) <= 4)", c5.ToString()); + Constraint c6 = x != 5; + Assert.Equal("(x(3..7) != 5)", c6.ToString()); + Constraint c7 = x == 2; + Assert.Equal("FalseConstraint()", c7.ToString()); + } [Fact] - public void IntExprConstructor() { - Solver solver = new Solver("Solver"); - IntVar x = solver.MakeIntVar(3, 13, "x"); - Assert.Equal(3, x.Min()); - Assert.Equal(13, x.Max()); + public void IntExprConstructor() { + Solver solver = new Solver("Solver"); + IntVar x = solver.MakeIntVar(3, 13, "x"); + Assert.Equal(3, x.Min()); + Assert.Equal(13, x.Max()); - // Unary Operator - IntExpr e1 = -(x == 7); - Assert.Equal("-(Watch(0 .. 1))", e1.ToString()); - IntExpr e2 = (x == 7).Abs(); - Assert.Equal("Watch(0 .. 1)", e2.ToString()); - IntExpr e3 = (x == 7).Square(); - Assert.Equal("IntSquare(Watch(0 .. 1))", e3.ToString()); - } + // Unary Operator + IntExpr e1 = -(x == 7); + Assert.Equal("-(Watch(0 .. 1))", e1.ToString()); + IntExpr e2 = (x == 7).Abs(); + Assert.Equal("Watch(0 .. 1)", e2.ToString()); + IntExpr e3 = (x == 7).Square(); + Assert.Equal("IntSquare(Watch(0 .. 1))", e3.ToString()); + } [Fact] - public void GreaterIntExprConstructor() { - Solver solver = new Solver("Solver"); - IntVar x = solver.MakeIntVar(3, 13, "x"); - Assert.Equal(3, x.Min()); - Assert.Equal(13, x.Max()); + public void GreaterIntExprConstructor() { + Solver solver = new Solver("Solver"); + IntVar x = solver.MakeIntVar(3, 13, "x"); + Assert.Equal(3, x.Min()); + Assert.Equal(13, x.Max()); - // Unary Operator - IntExpr e1 = -(x >= 7); - Assert.Equal("-(Watch= 7>(0 .. 1))", e1.ToString()); - IntExpr e2 = (x >= 7).Abs(); - Assert.Equal("Watch= 7>(0 .. 1)", e2.ToString()); - IntExpr e3 = (x >= 7).Square(); - Assert.Equal("IntSquare(Watch= 7>(0 .. 1))", e3.ToString()); - } + // Unary Operator + IntExpr e1 = -(x >= 7); + Assert.Equal("-(Watch= 7>(0 .. 1))", e1.ToString()); + IntExpr e2 = (x >= 7).Abs(); + Assert.Equal("Watch= 7>(0 .. 1)", e2.ToString()); + IntExpr e3 = (x >= 7).Square(); + Assert.Equal("IntSquare(Watch= 7>(0 .. 1))", e3.ToString()); + } [Fact] - public void ConstraintAndScalar() { - Solver solver = new Solver("Solver"); - IntVar x = solver.MakeIntVar(3, 13, "x"); - Assert.Equal(3, x.Min()); - Assert.Equal(13, x.Max()); + public void ConstraintAndScalar() { + Solver solver = new Solver("Solver"); + IntVar x = solver.MakeIntVar(3, 13, "x"); + Assert.Equal(3, x.Min()); + Assert.Equal(13, x.Max()); - Constraint c1 = (x == 7); - Assert.Equal("(x(3..13) == 7)", c1.ToString()); + Constraint c1 = (x == 7); + Assert.Equal("(x(3..13) == 7)", c1.ToString()); - // Arithmetic operator with a scalar - IntExpr e2a = c1 + 1; - Assert.Equal("(Watch(0 .. 1) + 1)", e2a.ToString()); - IntExpr e2b = 1 + c1; - Assert.Equal("(Watch(0 .. 1) + 1)", e2b.ToString()); + // Arithmetic operator with a scalar + IntExpr e2a = c1 + 1; + Assert.Equal("(Watch(0 .. 1) + 1)", e2a.ToString()); + IntExpr e2b = 1 + c1; + Assert.Equal("(Watch(0 .. 1) + 1)", e2b.ToString()); - IntExpr e2c = c1 - 1; - Assert.Equal("(Watch(0 .. 1) + -1)", e2c.ToString()); - IntExpr e2d = 1 - c1; - Assert.Equal("Not(Watch(0 .. 1))", e2d.ToString()); + IntExpr e2c = c1 - 1; + Assert.Equal("(Watch(0 .. 1) + -1)", e2c.ToString()); + IntExpr e2d = 1 - c1; + Assert.Equal("Not(Watch(0 .. 1))", e2d.ToString()); - IntExpr e2e = c1 * 2; - Assert.Equal("(Watch(0 .. 1) * 2)", e2e.ToString()); - IntExpr e2f = 2 * c1; - Assert.Equal("(Watch(0 .. 1) * 2)", e2f.ToString()); + IntExpr e2e = c1 * 2; + Assert.Equal("(Watch(0 .. 1) * 2)", e2e.ToString()); + IntExpr e2f = 2 * c1; + Assert.Equal("(Watch(0 .. 1) * 2)", e2f.ToString()); - IntExpr e2g = c1 / 4; - Assert.Equal("(Watch(0 .. 1) div 4)", e2g.ToString()); + IntExpr e2g = c1 / 4; + Assert.Equal("(Watch(0 .. 1) div 4)", e2g.ToString()); - // Relational operator with a scalar - Constraint c8a = c1 == 1; - Assert.Equal("(Watch(0 .. 1) == 1)", c8a.ToString()); - Constraint c8b = 1 == c1; - Assert.Equal("(Watch(0 .. 1) == 1)", c8b.ToString()); + // Relational operator with a scalar + Constraint c8a = c1 == 1; + Assert.Equal("(Watch(0 .. 1) == 1)", c8a.ToString()); + Constraint c8b = 1 == c1; + Assert.Equal("(Watch(0 .. 1) == 1)", c8b.ToString()); - Constraint c8c = c1 != 1; - Assert.Equal("(Watch(0 .. 1) != 1)", c8c.ToString()); - Constraint c8d = 1 != c1; - Assert.Equal("(Watch(0 .. 1) != 1)", c8d.ToString()); + Constraint c8c = c1 != 1; + Assert.Equal("(Watch(0 .. 1) != 1)", c8c.ToString()); + Constraint c8d = 1 != c1; + Assert.Equal("(Watch(0 .. 1) != 1)", c8d.ToString()); - Constraint c8e = c1 >= 1; - Assert.Equal("(Watch(0 .. 1) >= 1)", c8e.ToString()); - Constraint c8f = 1 >= c1; - Assert.Equal("TrueConstraint()", c8f.ToString()); + Constraint c8e = c1 >= 1; + Assert.Equal("(Watch(0 .. 1) >= 1)", c8e.ToString()); + Constraint c8f = 1 >= c1; + Assert.Equal("TrueConstraint()", c8f.ToString()); - Constraint c8g = c1 > 1; - Assert.Equal("FalseConstraint()", c8g.ToString()); - Constraint c8h = 1 > c1; - Assert.Equal("(Watch(0 .. 1) <= 0)", c8h.ToString()); + Constraint c8g = c1 > 1; + Assert.Equal("FalseConstraint()", c8g.ToString()); + Constraint c8h = 1 > c1; + Assert.Equal("(Watch(0 .. 1) <= 0)", c8h.ToString()); - Constraint c8i = c1 <= 1; - Assert.Equal("TrueConstraint()", c8i.ToString()); - Constraint c8j = 1 <= c1; - Assert.Equal("(Watch(0 .. 1) >= 1)", c8j.ToString()); + Constraint c8i = c1 <= 1; + Assert.Equal("TrueConstraint()", c8i.ToString()); + Constraint c8j = 1 <= c1; + Assert.Equal("(Watch(0 .. 1) >= 1)", c8j.ToString()); - Constraint c8k = c1 < 1; - Assert.Equal("(Watch(0 .. 1) <= 0)", c8k.ToString()); - Constraint c8l = 1 < c1; - Assert.Equal("FalseConstraint()", c8l.ToString()); - } + Constraint c8k = c1 < 1; + Assert.Equal("(Watch(0 .. 1) <= 0)", c8k.ToString()); + Constraint c8l = 1 < c1; + Assert.Equal("FalseConstraint()", c8l.ToString()); + } [Fact] - public void ConstraintAndIntVar() { - Solver solver = new Solver("Solver"); - IntVar x = solver.MakeIntVar(3, 13, "x"); - Assert.Equal(3, x.Min()); - Assert.Equal(13, x.Max()); + public void ConstraintAndIntVar() { + Solver solver = new Solver("Solver"); + IntVar x = solver.MakeIntVar(3, 13, "x"); + Assert.Equal(3, x.Min()); + Assert.Equal(13, x.Max()); - Constraint c1 = x == 7; - Assert.Equal("(x(3..13) == 7)", c1.ToString()); + Constraint c1 = x == 7; + Assert.Equal("(x(3..13) == 7)", c1.ToString()); - IntVar y = solver.MakeIntVar(5, 17, "y"); - Assert.Equal(5, y.Min()); - Assert.Equal(17, y.Max()); + IntVar y = solver.MakeIntVar(5, 17, "y"); + Assert.Equal(5, y.Min()); + Assert.Equal(17, y.Max()); - // Arithmetic operator with IntVar - IntExpr e3a = c1 + y; - Assert.Equal("(Watch(0 .. 1) + y(5..17))", e3a.ToString()); - IntExpr e3b = y + c1; - Assert.Equal("(Watch(0 .. 1) + y(5..17))", e3b.ToString()); + // Arithmetic operator with IntVar + IntExpr e3a = c1 + y; + Assert.Equal("(Watch(0 .. 1) + y(5..17))", e3a.ToString()); + IntExpr e3b = y + c1; + Assert.Equal("(Watch(0 .. 1) + y(5..17))", e3b.ToString()); - IntExpr e3c = c1 - y; - Assert.Equal("(Watch(0 .. 1) - y(5..17))", e3c.ToString()); - IntExpr e3d = y - c1; - Assert.Equal("(y(5..17) - Watch(0 .. 1))", e3d.ToString()); + IntExpr e3c = c1 - y; + Assert.Equal("(Watch(0 .. 1) - y(5..17))", e3c.ToString()); + IntExpr e3d = y - c1; + Assert.Equal("(y(5..17) - Watch(0 .. 1))", e3d.ToString()); - IntExpr e3e = c1 * y; - Assert.Equal("(Watch(0 .. 1) * y(5..17))", e3e.ToString()); - IntExpr e3f = y * c1; - Assert.Equal("(Watch(0 .. 1) * y(5..17))", e3f.ToString()); + IntExpr e3e = c1 * y; + Assert.Equal("(Watch(0 .. 1) * y(5..17))", e3e.ToString()); + IntExpr e3f = y * c1; + Assert.Equal("(Watch(0 .. 1) * y(5..17))", e3f.ToString()); - // Relational operator with an IntVar - Constraint c9a = c1 == y; - Assert.Equal("Watch(0 .. 1) == y(5..17)", c9a.ToString()); - Constraint c9b = y == c1; - Assert.Equal("y(5..17) == Watch(0 .. 1)", c9b.ToString()); + // Relational operator with an IntVar + Constraint c9a = c1 == y; + Assert.Equal("Watch(0 .. 1) == y(5..17)", c9a.ToString()); + Constraint c9b = y == c1; + Assert.Equal("y(5..17) == Watch(0 .. 1)", c9b.ToString()); - Constraint c9c = c1 != y; - Assert.Equal("Watch(0 .. 1) != y(5..17)", c9c.ToString()); - Constraint c9d = y != c1; - Assert.Equal("y(5..17) != Watch(0 .. 1)", c9d.ToString()); + Constraint c9c = c1 != y; + Assert.Equal("Watch(0 .. 1) != y(5..17)", c9c.ToString()); + Constraint c9d = y != c1; + Assert.Equal("y(5..17) != Watch(0 .. 1)", c9d.ToString()); - Constraint c9e = c1 >= y; - Assert.Equal("y(5..17) <= Watch(0 .. 1)", c9e.ToString()); - Constraint c9f = y >= c1; - Assert.Equal("Watch(0 .. 1) <= y(5..17)", c9f.ToString()); + Constraint c9e = c1 >= y; + Assert.Equal("y(5..17) <= Watch(0 .. 1)", c9e.ToString()); + Constraint c9f = y >= c1; + Assert.Equal("Watch(0 .. 1) <= y(5..17)", c9f.ToString()); - Constraint c9g = c1 > y; - Assert.Equal("y(5..17) < Watch(0 .. 1)", c9g.ToString()); - Constraint c9h = y > c1; - Assert.Equal("Watch(0 .. 1) < y(5..17)", c9h.ToString()); + Constraint c9g = c1 > y; + Assert.Equal("y(5..17) < Watch(0 .. 1)", c9g.ToString()); + Constraint c9h = y > c1; + Assert.Equal("Watch(0 .. 1) < y(5..17)", c9h.ToString()); - Constraint c9i = c1 <= y; - Assert.Equal("Watch(0 .. 1) <= y(5..17)", c9i.ToString()); - Constraint c9j = y <= c1; - Assert.Equal("y(5..17) <= Watch(0 .. 1)", c9j.ToString()); + Constraint c9i = c1 <= y; + Assert.Equal("Watch(0 .. 1) <= y(5..17)", c9i.ToString()); + Constraint c9j = y <= c1; + Assert.Equal("y(5..17) <= Watch(0 .. 1)", c9j.ToString()); - Constraint c9k = c1 < y; - Assert.Equal("Watch(0 .. 1) < y(5..17)", c9k.ToString()); - Constraint c9l = y < c1; - Assert.Equal("y(5..17) < Watch(0 .. 1)", c9l.ToString()); - } + Constraint c9k = c1 < y; + Assert.Equal("Watch(0 .. 1) < y(5..17)", c9k.ToString()); + Constraint c9l = y < c1; + Assert.Equal("y(5..17) < Watch(0 .. 1)", c9l.ToString()); + } [Fact] - public void ConstraintAndIntExpr() { - Solver solver = new Solver("Solver"); - IntVar x = solver.MakeIntVar(3, 13, "x"); - Assert.Equal(3, x.Min()); - Assert.Equal(13, x.Max()); - Constraint c1 = x == 7; - Assert.Equal("(x(3..13) == 7)", c1.ToString()); + public void ConstraintAndIntExpr() { + Solver solver = new Solver("Solver"); + IntVar x = solver.MakeIntVar(3, 13, "x"); + Assert.Equal(3, x.Min()); + Assert.Equal(13, x.Max()); + Constraint c1 = x == 7; + Assert.Equal("(x(3..13) == 7)", c1.ToString()); - IntVar y = solver.MakeIntVar(5, 17, "y"); - Assert.Equal(5, y.Min()); - Assert.Equal(17, y.Max()); + IntVar y = solver.MakeIntVar(5, 17, "y"); + Assert.Equal(5, y.Min()); + Assert.Equal(17, y.Max()); - // Arithmetic operator with an IntExpr - IntExpr e11a = c1 + (y == 11); - Assert.Equal("(Watch(0 .. 1) + Watch(0 .. 1))", e11a.ToString()); - IntExpr e11b = (y == 11) + c1; - Assert.Equal("(Watch(0 .. 1) + Watch(0 .. 1))", e11b.ToString()); - IntExpr e11c = c1 - (y == 11); - Assert.Equal("(Watch(0 .. 1) - Watch(0 .. 1))", e11c.ToString()); - IntExpr e11d = (y == 11) - c1; - Assert.Equal("(Watch(0 .. 1) - Watch(0 .. 1))", e11d.ToString()); - IntExpr e11e = c1 * (y == 11); - Assert.Equal("(Watch(0 .. 1) * Watch(0 .. 1))", e11e.ToString()); - IntExpr e11f = (y == 11) * c1; - Assert.Equal("(Watch(0 .. 1) * Watch(0 .. 1))", e11f.ToString()); + // Arithmetic operator with an IntExpr + IntExpr e11a = c1 + (y == 11); + Assert.Equal("(Watch(0 .. 1) + Watch(0 .. 1))", + e11a.ToString()); + IntExpr e11b = (y == 11) + c1; + Assert.Equal("(Watch(0 .. 1) + Watch(0 .. 1))", + e11b.ToString()); + IntExpr e11c = c1 - (y == 11); + Assert.Equal("(Watch(0 .. 1) - Watch(0 .. 1))", + e11c.ToString()); + IntExpr e11d = (y == 11) - c1; + Assert.Equal("(Watch(0 .. 1) - Watch(0 .. 1))", + e11d.ToString()); + IntExpr e11e = c1 * (y == 11); + Assert.Equal("(Watch(0 .. 1) * Watch(0 .. 1))", + e11e.ToString()); + IntExpr e11f = (y == 11) * c1; + Assert.Equal("(Watch(0 .. 1) * Watch(0 .. 1))", + e11f.ToString()); - // Relational operator with an IntExpr - Constraint c12a = c1 == (y == 11); - Assert.Equal("Watch(0 .. 1) == Watch(0 .. 1)", c12a.ToString()); - Constraint c12b = (y == 11) == c1; - Assert.Equal("Watch(0 .. 1) == Watch(0 .. 1)", c12b.ToString()); - Constraint c12c = c1 != (y == 11); - Assert.Equal("Watch(0 .. 1) != Watch(0 .. 1)", c12c.ToString()); - Constraint c12d = (y == 11) != c1; - Assert.Equal("Watch(0 .. 1) != Watch(0 .. 1)", c12d.ToString()); - Constraint c12e = c1 >= (y == 11); - Assert.Equal("Watch(0 .. 1) <= Watch(0 .. 1)", c12e.ToString()); - Constraint c12f = (y == 11) >= c1; - Assert.Equal("Watch(0 .. 1) <= Watch(0 .. 1)", c12f.ToString()); - Constraint c12g = c1 > (y == 11); - Assert.Equal("Watch(0 .. 1) < Watch(0 .. 1)", c12g.ToString()); - Constraint c12h = (y == 11) > c1; - Assert.Equal("Watch(0 .. 1) < Watch(0 .. 1)", c12h.ToString()); - Constraint c12i = c1 <= (y == 11); - Assert.Equal("Watch(0 .. 1) <= Watch(0 .. 1)", c12i.ToString()); - Constraint c12j = (y == 11) <= c1; - Assert.Equal("Watch(0 .. 1) <= Watch(0 .. 1)", c12j.ToString()); - Constraint c12k = c1 < (y == 11); - Assert.Equal("Watch(0 .. 1) < Watch(0 .. 1)", c12k.ToString()); - Constraint c12l = (y == 11) < c1; - Assert.Equal("Watch(0 .. 1) < Watch(0 .. 1)", c12l.ToString()); - } + // Relational operator with an IntExpr + Constraint c12a = c1 == (y == 11); + Assert.Equal("Watch(0 .. 1) == Watch(0 .. 1)", + c12a.ToString()); + Constraint c12b = (y == 11) == c1; + Assert.Equal("Watch(0 .. 1) == Watch(0 .. 1)", + c12b.ToString()); + Constraint c12c = c1 != (y == 11); + Assert.Equal("Watch(0 .. 1) != Watch(0 .. 1)", + c12c.ToString()); + Constraint c12d = (y == 11) != c1; + Assert.Equal("Watch(0 .. 1) != Watch(0 .. 1)", + c12d.ToString()); + Constraint c12e = c1 >= (y == 11); + Assert.Equal("Watch(0 .. 1) <= Watch(0 .. 1)", + c12e.ToString()); + Constraint c12f = (y == 11) >= c1; + Assert.Equal("Watch(0 .. 1) <= Watch(0 .. 1)", + c12f.ToString()); + Constraint c12g = c1 > (y == 11); + Assert.Equal("Watch(0 .. 1) < Watch(0 .. 1)", + c12g.ToString()); + Constraint c12h = (y == 11) > c1; + Assert.Equal("Watch(0 .. 1) < Watch(0 .. 1)", + c12h.ToString()); + Constraint c12i = c1 <= (y == 11); + Assert.Equal("Watch(0 .. 1) <= Watch(0 .. 1)", + c12i.ToString()); + Constraint c12j = (y == 11) <= c1; + Assert.Equal("Watch(0 .. 1) <= Watch(0 .. 1)", + c12j.ToString()); + Constraint c12k = c1 < (y == 11); + Assert.Equal("Watch(0 .. 1) < Watch(0 .. 1)", + c12k.ToString()); + Constraint c12l = (y == 11) < c1; + Assert.Equal("Watch(0 .. 1) < Watch(0 .. 1)", + c12l.ToString()); + } [Fact] - public void ConstraintAndConstraint() { - Solver solver = new Solver("Solver"); - IntVar x = solver.MakeIntVar(3, 13, "x"); - Assert.Equal(3, x.Min()); - Assert.Equal(13, x.Max()); - Constraint c1 = x == 7; - Assert.Equal("(x(3..13) == 7)", c1.ToString()); + public void ConstraintAndConstraint() { + Solver solver = new Solver("Solver"); + IntVar x = solver.MakeIntVar(3, 13, "x"); + Assert.Equal(3, x.Min()); + Assert.Equal(13, x.Max()); + Constraint c1 = x == 7; + Assert.Equal("(x(3..13) == 7)", c1.ToString()); - IntVar y = solver.MakeIntVar(5, 17, "y"); - Assert.Equal(5, y.Min()); - Assert.Equal(17, y.Max()); - Constraint c2 = y == 11; - Assert.Equal("(y(5..17) == 11)", c2.ToString()); + IntVar y = solver.MakeIntVar(5, 17, "y"); + Assert.Equal(5, y.Min()); + Assert.Equal(17, y.Max()); + Constraint c2 = y == 11; + Assert.Equal("(y(5..17) == 11)", c2.ToString()); - // Relational operator with a Constraint - Constraint c10a = c1 == c2; - Assert.Equal("Watch(0 .. 1) == Watch(0 .. 1)", c10a.ToString()); + // Relational operator with a Constraint + Constraint c10a = c1 == c2; + Assert.Equal("Watch(0 .. 1) == Watch(0 .. 1)", + c10a.ToString()); - Constraint c10b = c1 != c2; - Assert.Equal("Watch(0 .. 1) != Watch(0 .. 1)", c10b.ToString()); + Constraint c10b = c1 != c2; + Assert.Equal("Watch(0 .. 1) != Watch(0 .. 1)", + c10b.ToString()); - Constraint c10c = c1 <= c2; - Assert.Equal("Watch(0 .. 1) <= Watch(0 .. 1)", c10c.ToString()); - Constraint c10d = c1 >= c2; - Assert.Equal("Watch(0 .. 1) <= Watch(0 .. 1)", c10d.ToString()); + Constraint c10c = c1 <= c2; + Assert.Equal("Watch(0 .. 1) <= Watch(0 .. 1)", + c10c.ToString()); + Constraint c10d = c1 >= c2; + Assert.Equal("Watch(0 .. 1) <= Watch(0 .. 1)", + c10d.ToString()); - Constraint c10e = c1 > c2; - Assert.Equal("Watch(0 .. 1) < Watch(0 .. 1)", c10e.ToString()); - Constraint c10f = c1 < c2; - Assert.Equal("Watch(0 .. 1) < Watch(0 .. 1)", c10f.ToString()); - } + Constraint c10e = c1 > c2; + Assert.Equal("Watch(0 .. 1) < Watch(0 .. 1)", + c10e.ToString()); + Constraint c10f = c1 < c2; + Assert.Equal("Watch(0 .. 1) < Watch(0 .. 1)", + c10f.ToString()); + } [Fact] - public void IntExprAndScalar() { - Solver solver = new Solver("Solver"); - IntVar x = solver.MakeIntVar(3, 13, "x"); - Assert.Equal(3, x.Min()); - Assert.Equal(13, x.Max()); + public void IntExprAndScalar() { + Solver solver = new Solver("Solver"); + IntVar x = solver.MakeIntVar(3, 13, "x"); + Assert.Equal(3, x.Min()); + Assert.Equal(13, x.Max()); - // Arithmetic operator with a scalar - IntExpr e2a = (x == 7) + 1; - Assert.Equal("(Watch(0 .. 1) + 1)", e2a.ToString()); - IntExpr e2b = 1 + (x == 7); - Assert.Equal("(Watch(0 .. 1) + 1)", e2b.ToString()); + // Arithmetic operator with a scalar + IntExpr e2a = (x == 7) + 1; + Assert.Equal("(Watch(0 .. 1) + 1)", e2a.ToString()); + IntExpr e2b = 1 + (x == 7); + Assert.Equal("(Watch(0 .. 1) + 1)", e2b.ToString()); - IntExpr e2c = (x == 7) - 1; - Assert.Equal("(Watch(0 .. 1) + -1)", e2c.ToString()); - IntExpr e2d = 1 - (x == 7); - Assert.Equal("Not(Watch(0 .. 1))", e2d.ToString()); + IntExpr e2c = (x == 7) - 1; + Assert.Equal("(Watch(0 .. 1) + -1)", e2c.ToString()); + IntExpr e2d = 1 - (x == 7); + Assert.Equal("Not(Watch(0 .. 1))", e2d.ToString()); - IntExpr e2e = (x == 7) * 2; - Assert.Equal("(Watch(0 .. 1) * 2)", e2e.ToString()); - IntExpr e2f = 2 * (x == 7); - Assert.Equal("(Watch(0 .. 1) * 2)", e2f.ToString()); + IntExpr e2e = (x == 7) * 2; + Assert.Equal("(Watch(0 .. 1) * 2)", e2e.ToString()); + IntExpr e2f = 2 * (x == 7); + Assert.Equal("(Watch(0 .. 1) * 2)", e2f.ToString()); - IntExpr e2g = (x == 7) / 4; - Assert.Equal("(Watch(0 .. 1) div 4)", e2g.ToString()); + IntExpr e2g = (x == 7) / 4; + Assert.Equal("(Watch(0 .. 1) div 4)", e2g.ToString()); - // Relational operator with a scalar - Constraint c8a = (x == 7) == 1; - Assert.Equal("(Watch(0 .. 1) == 1)", c8a.ToString()); - Constraint c8b = 1 == (x == 7); - Assert.Equal("(Watch(0 .. 1) == 1)", c8b.ToString()); + // Relational operator with a scalar + Constraint c8a = (x == 7) == 1; + Assert.Equal("(Watch(0 .. 1) == 1)", c8a.ToString()); + Constraint c8b = 1 == (x == 7); + Assert.Equal("(Watch(0 .. 1) == 1)", c8b.ToString()); - Constraint c8c = (x == 7) != 1; - Assert.Equal("(Watch(0 .. 1) != 1)", c8c.ToString()); - Constraint c8d = 1 != (x == 7); - Assert.Equal("(Watch(0 .. 1) != 1)", c8d.ToString()); + Constraint c8c = (x == 7) != 1; + Assert.Equal("(Watch(0 .. 1) != 1)", c8c.ToString()); + Constraint c8d = 1 != (x == 7); + Assert.Equal("(Watch(0 .. 1) != 1)", c8d.ToString()); - Constraint c8e = (x == 7) >= 1; - Assert.Equal("(Watch(0 .. 1) >= 1)", c8e.ToString()); - Constraint c8f = 1 >= (x == 7); - Assert.Equal("TrueConstraint()", c8f.ToString()); + Constraint c8e = (x == 7) >= 1; + Assert.Equal("(Watch(0 .. 1) >= 1)", c8e.ToString()); + Constraint c8f = 1 >= (x == 7); + Assert.Equal("TrueConstraint()", c8f.ToString()); - Constraint c8g = (x == 7) > 1; - Assert.Equal("FalseConstraint()", c8g.ToString()); - Constraint c8h = 1 > (x == 7); - Assert.Equal("(Watch(0 .. 1) <= 0)", c8h.ToString()); + Constraint c8g = (x == 7) > 1; + Assert.Equal("FalseConstraint()", c8g.ToString()); + Constraint c8h = 1 > (x == 7); + Assert.Equal("(Watch(0 .. 1) <= 0)", c8h.ToString()); - Constraint c8i = (x == 7) <= 1; - Assert.Equal("TrueConstraint()", c8i.ToString()); - Constraint c8j = 1 <= (x == 7); - Assert.Equal("(Watch(0 .. 1) >= 1)", c8j.ToString()); + Constraint c8i = (x == 7) <= 1; + Assert.Equal("TrueConstraint()", c8i.ToString()); + Constraint c8j = 1 <= (x == 7); + Assert.Equal("(Watch(0 .. 1) >= 1)", c8j.ToString()); - Constraint c8k = (x == 7) < 1; - Assert.Equal("(Watch(0 .. 1) <= 0)", c8k.ToString()); - Constraint c8l = 1 < (x == 7); - Assert.Equal("FalseConstraint()", c8l.ToString()); - } + Constraint c8k = (x == 7) < 1; + Assert.Equal("(Watch(0 .. 1) <= 0)", c8k.ToString()); + Constraint c8l = 1 < (x == 7); + Assert.Equal("FalseConstraint()", c8l.ToString()); + } [Fact] - public void IntExprAndIntVar() { - Solver solver = new Solver("Solver"); - IntVar x = solver.MakeIntVar(3, 13, "x"); - Assert.Equal(3, x.Min()); - Assert.Equal(13, x.Max()); + public void IntExprAndIntVar() { + Solver solver = new Solver("Solver"); + IntVar x = solver.MakeIntVar(3, 13, "x"); + Assert.Equal(3, x.Min()); + Assert.Equal(13, x.Max()); - IntVar y = solver.MakeIntVar(5, 17, "y"); - Assert.Equal(5, y.Min()); - Assert.Equal(17, y.Max()); + IntVar y = solver.MakeIntVar(5, 17, "y"); + Assert.Equal(5, y.Min()); + Assert.Equal(17, y.Max()); - // Arithmetic operator with IntVar - IntExpr e3a = (x == 7) + y; - Assert.Equal("(Watch(0 .. 1) + y(5..17))", e3a.ToString()); - IntExpr e3b = y + (x == 7); - Assert.Equal("(Watch(0 .. 1) + y(5..17))", e3b.ToString()); + // Arithmetic operator with IntVar + IntExpr e3a = (x == 7) + y; + Assert.Equal("(Watch(0 .. 1) + y(5..17))", e3a.ToString()); + IntExpr e3b = y + (x == 7); + Assert.Equal("(Watch(0 .. 1) + y(5..17))", e3b.ToString()); - IntExpr e3c = (x == 7) - y; - Assert.Equal("(Watch(0 .. 1) - y(5..17))", e3c.ToString()); - IntExpr e3d = y - (x == 7); - Assert.Equal("(y(5..17) - Watch(0 .. 1))", e3d.ToString()); + IntExpr e3c = (x == 7) - y; + Assert.Equal("(Watch(0 .. 1) - y(5..17))", e3c.ToString()); + IntExpr e3d = y - (x == 7); + Assert.Equal("(y(5..17) - Watch(0 .. 1))", e3d.ToString()); - IntExpr e3e = (x == 7) * y; - Assert.Equal("(Watch(0 .. 1) * y(5..17))", e3e.ToString()); - IntExpr e3f = y * (x == 7); - Assert.Equal("(Watch(0 .. 1) * y(5..17))", e3f.ToString()); + IntExpr e3e = (x == 7) * y; + Assert.Equal("(Watch(0 .. 1) * y(5..17))", e3e.ToString()); + IntExpr e3f = y * (x == 7); + Assert.Equal("(Watch(0 .. 1) * y(5..17))", e3f.ToString()); - // Relational operator with an IntVar - Constraint c9a = (x == 7) == y; - Assert.Equal("Watch(0 .. 1) == y(5..17)", c9a.ToString()); - Constraint c9b = y == (x == 7); - Assert.Equal("y(5..17) == Watch(0 .. 1)", c9b.ToString()); + // Relational operator with an IntVar + Constraint c9a = (x == 7) == y; + Assert.Equal("Watch(0 .. 1) == y(5..17)", c9a.ToString()); + Constraint c9b = y == (x == 7); + Assert.Equal("y(5..17) == Watch(0 .. 1)", c9b.ToString()); - Constraint c9c = (x == 7) != y; - Assert.Equal("Watch(0 .. 1) != y(5..17)", c9c.ToString()); - Constraint c9d = y != (x == 7); - Assert.Equal("y(5..17) != Watch(0 .. 1)", c9d.ToString()); + Constraint c9c = (x == 7) != y; + Assert.Equal("Watch(0 .. 1) != y(5..17)", c9c.ToString()); + Constraint c9d = y != (x == 7); + Assert.Equal("y(5..17) != Watch(0 .. 1)", c9d.ToString()); - Constraint c9e = (x == 7) >= y; - Assert.Equal("y(5..17) <= Watch(0 .. 1)", c9e.ToString()); - Constraint c9f = y >= (x == 7); - Assert.Equal("Watch(0 .. 1) <= y(5..17)", c9f.ToString()); + Constraint c9e = (x == 7) >= y; + Assert.Equal("y(5..17) <= Watch(0 .. 1)", c9e.ToString()); + Constraint c9f = y >= (x == 7); + Assert.Equal("Watch(0 .. 1) <= y(5..17)", c9f.ToString()); - Constraint c9g = (x == 7) > y; - Assert.Equal("y(5..17) < Watch(0 .. 1)", c9g.ToString()); - Constraint c9h = y > (x == 7); - Assert.Equal("Watch(0 .. 1) < y(5..17)", c9h.ToString()); + Constraint c9g = (x == 7) > y; + Assert.Equal("y(5..17) < Watch(0 .. 1)", c9g.ToString()); + Constraint c9h = y > (x == 7); + Assert.Equal("Watch(0 .. 1) < y(5..17)", c9h.ToString()); - Constraint c9i = (x == 7) <= y; - Assert.Equal("Watch(0 .. 1) <= y(5..17)", c9i.ToString()); - Constraint c9j = y <= (x == 7); - Assert.Equal("y(5..17) <= Watch(0 .. 1)", c9j.ToString()); + Constraint c9i = (x == 7) <= y; + Assert.Equal("Watch(0 .. 1) <= y(5..17)", c9i.ToString()); + Constraint c9j = y <= (x == 7); + Assert.Equal("y(5..17) <= Watch(0 .. 1)", c9j.ToString()); - Constraint c9k = (x == 7) < y; - Assert.Equal("Watch(0 .. 1) < y(5..17)", c9k.ToString()); - Constraint c9l = y < (x == 7); - Assert.Equal("y(5..17) < Watch(0 .. 1)", c9l.ToString()); - } + Constraint c9k = (x == 7) < y; + Assert.Equal("Watch(0 .. 1) < y(5..17)", c9k.ToString()); + Constraint c9l = y < (x == 7); + Assert.Equal("y(5..17) < Watch(0 .. 1)", c9l.ToString()); + } [Fact] - public void IntExprAndIntExpr() { - Solver solver = new Solver("Solver"); - IntVar x = solver.MakeIntVar(3, 13, "x"); - Assert.Equal(3, x.Min()); - Assert.Equal(13, x.Max()); + public void IntExprAndIntExpr() { + Solver solver = new Solver("Solver"); + IntVar x = solver.MakeIntVar(3, 13, "x"); + Assert.Equal(3, x.Min()); + Assert.Equal(13, x.Max()); - IntVar y = solver.MakeIntVar(5, 17, "y"); - Assert.Equal(5, y.Min()); - Assert.Equal(17, y.Max()); + IntVar y = solver.MakeIntVar(5, 17, "y"); + Assert.Equal(5, y.Min()); + Assert.Equal(17, y.Max()); - // Relational operator between IntExpr - Constraint c10a = (x == 7) == (y == 11); - Assert.Equal("Watch(0 .. 1) == Watch(0 .. 1)", c10a.ToString()); + // Relational operator between IntExpr + Constraint c10a = (x == 7) == (y == 11); + Assert.Equal("Watch(0 .. 1) == Watch(0 .. 1)", + c10a.ToString()); - Constraint c10b = (x == 7) != (y == 11); - Assert.Equal("Watch(0 .. 1) != Watch(0 .. 1)", c10b.ToString()); + Constraint c10b = (x == 7) != (y == 11); + Assert.Equal("Watch(0 .. 1) != Watch(0 .. 1)", + c10b.ToString()); - Constraint c10c= (x == 7) <= (y == 11); - Assert.Equal("Watch(0 .. 1) <= Watch(0 .. 1)", c10c.ToString()); - Constraint c10d = (x == 7) >= (y == 11); - Assert.Equal("Watch(0 .. 1) <= Watch(0 .. 1)", c10d.ToString()); + Constraint c10c = (x == 7) <= (y == 11); + Assert.Equal("Watch(0 .. 1) <= Watch(0 .. 1)", + c10c.ToString()); + Constraint c10d = (x == 7) >= (y == 11); + Assert.Equal("Watch(0 .. 1) <= Watch(0 .. 1)", + c10d.ToString()); - Constraint c10e = (x == 7) > (y == 11); - Assert.Equal("Watch(0 .. 1) < Watch(0 .. 1)", c10e.ToString()); - Constraint c10f = (x == 7) < (y == 11); - Assert.Equal("Watch(0 .. 1) < Watch(0 .. 1)", c10f.ToString()); - } + Constraint c10e = (x == 7) > (y == 11); + Assert.Equal("Watch(0 .. 1) < Watch(0 .. 1)", + c10e.ToString()); + Constraint c10f = (x == 7) < (y == 11); + Assert.Equal("Watch(0 .. 1) < Watch(0 .. 1)", + c10f.ToString()); + } [Fact] - public void GreaterIntExprAndScalar() { - Solver solver = new Solver("Solver"); - IntVar x = solver.MakeIntVar(3, 13, "x"); - Assert.Equal(3, x.Min()); - Assert.Equal(13, x.Max()); + public void GreaterIntExprAndScalar() { + Solver solver = new Solver("Solver"); + IntVar x = solver.MakeIntVar(3, 13, "x"); + Assert.Equal(3, x.Min()); + Assert.Equal(13, x.Max()); - // Arithmetic operator with a scalar - IntExpr e2a = (x >= 7) + 1; - Assert.Equal("(Watch= 7>(0 .. 1) + 1)", e2a.ToString()); - IntExpr e2b = 1 + (x >= 7); - Assert.Equal("(Watch= 7>(0 .. 1) + 1)", e2b.ToString()); + // Arithmetic operator with a scalar + IntExpr e2a = (x >= 7) + 1; + Assert.Equal("(Watch= 7>(0 .. 1) + 1)", e2a.ToString()); + IntExpr e2b = 1 + (x >= 7); + Assert.Equal("(Watch= 7>(0 .. 1) + 1)", e2b.ToString()); - IntExpr e2c = (x >= 7) - 1; - Assert.Equal("(Watch= 7>(0 .. 1) + -1)", e2c.ToString()); - IntExpr e2d = 1 - (x >= 7); - Assert.Equal("Not(Watch= 7>(0 .. 1))", e2d.ToString()); + IntExpr e2c = (x >= 7) - 1; + Assert.Equal("(Watch= 7>(0 .. 1) + -1)", e2c.ToString()); + IntExpr e2d = 1 - (x >= 7); + Assert.Equal("Not(Watch= 7>(0 .. 1))", e2d.ToString()); - IntExpr e2e = (x >= 7) * 2; - Assert.Equal("(Watch= 7>(0 .. 1) * 2)", e2e.ToString()); - IntExpr e2f = 2 * (x >= 7); - Assert.Equal("(Watch= 7>(0 .. 1) * 2)", e2f.ToString()); + IntExpr e2e = (x >= 7) * 2; + Assert.Equal("(Watch= 7>(0 .. 1) * 2)", e2e.ToString()); + IntExpr e2f = 2 * (x >= 7); + Assert.Equal("(Watch= 7>(0 .. 1) * 2)", e2f.ToString()); - // Relational operator with a scalar - Constraint c8a = (x >= 7) == 1; - Assert.Equal("(Watch= 7>(0 .. 1) == 1)", c8a.ToString()); - Constraint c8b = 1 == (x >= 7); - Assert.Equal("(Watch= 7>(0 .. 1) == 1)", c8b.ToString()); + // Relational operator with a scalar + Constraint c8a = (x >= 7) == 1; + Assert.Equal("(Watch= 7>(0 .. 1) == 1)", c8a.ToString()); + Constraint c8b = 1 == (x >= 7); + Assert.Equal("(Watch= 7>(0 .. 1) == 1)", c8b.ToString()); - Constraint c8c = (x >= 7) != 1; - Assert.Equal("(Watch= 7>(0 .. 1) != 1)", c8c.ToString()); - Constraint c8d = 1 != (x >= 7); - Assert.Equal("(Watch= 7>(0 .. 1) != 1)", c8d.ToString()); + Constraint c8c = (x >= 7) != 1; + Assert.Equal("(Watch= 7>(0 .. 1) != 1)", c8c.ToString()); + Constraint c8d = 1 != (x >= 7); + Assert.Equal("(Watch= 7>(0 .. 1) != 1)", c8d.ToString()); - Constraint c8e = (x >= 7) >= 1; - Assert.Equal("(Watch= 7>(0 .. 1) >= 1)", c8e.ToString()); - Constraint c8f = 1 >= (x >= 7); - Assert.Equal("TrueConstraint()", c8f.ToString()); + Constraint c8e = (x >= 7) >= 1; + Assert.Equal("(Watch= 7>(0 .. 1) >= 1)", c8e.ToString()); + Constraint c8f = 1 >= (x >= 7); + Assert.Equal("TrueConstraint()", c8f.ToString()); - Constraint c8g = (x >= 7) > 1; - Assert.Equal("FalseConstraint()", c8g.ToString()); - Constraint c8h = 1 > (x >= 7); - Assert.Equal("(Watch= 7>(0 .. 1) <= 0)", c8h.ToString()); + Constraint c8g = (x >= 7) > 1; + Assert.Equal("FalseConstraint()", c8g.ToString()); + Constraint c8h = 1 > (x >= 7); + Assert.Equal("(Watch= 7>(0 .. 1) <= 0)", c8h.ToString()); - Constraint c8i = (x >= 7) <= 1; - Assert.Equal("TrueConstraint()", c8i.ToString()); - Constraint c8j = 1 <= (x >= 7); - Assert.Equal("(Watch= 7>(0 .. 1) >= 1)", c8j.ToString()); + Constraint c8i = (x >= 7) <= 1; + Assert.Equal("TrueConstraint()", c8i.ToString()); + Constraint c8j = 1 <= (x >= 7); + Assert.Equal("(Watch= 7>(0 .. 1) >= 1)", c8j.ToString()); - Constraint c8k = (x >= 7) < 1; - Assert.Equal("(Watch= 7>(0 .. 1) <= 0)", c8k.ToString()); - Constraint c8l = 1 < (x >= 7); - Assert.Equal("FalseConstraint()", c8l.ToString()); - } + Constraint c8k = (x >= 7) < 1; + Assert.Equal("(Watch= 7>(0 .. 1) <= 0)", c8k.ToString()); + Constraint c8l = 1 < (x >= 7); + Assert.Equal("FalseConstraint()", c8l.ToString()); + } [Fact] - public void GreaterIntExprAndIntVar() { - Solver solver = new Solver("Solver"); - IntVar x = solver.MakeIntVar(3, 13, "x"); - Assert.Equal(3, x.Min()); - Assert.Equal(13, x.Max()); + public void GreaterIntExprAndIntVar() { + Solver solver = new Solver("Solver"); + IntVar x = solver.MakeIntVar(3, 13, "x"); + Assert.Equal(3, x.Min()); + Assert.Equal(13, x.Max()); - IntVar y = solver.MakeIntVar(5, 17, "y"); - Assert.Equal(5, y.Min()); - Assert.Equal(17, y.Max()); + IntVar y = solver.MakeIntVar(5, 17, "y"); + Assert.Equal(5, y.Min()); + Assert.Equal(17, y.Max()); - // Arithmetic operator with IntVar - IntExpr e3a = (x >= 7) + y; - Assert.Equal("(Watch= 7>(0 .. 1) + y(5..17))", e3a.ToString()); - IntExpr e3b = y + (x >= 7); - Assert.Equal("(Watch= 7>(0 .. 1) + y(5..17))", e3b.ToString()); + // Arithmetic operator with IntVar + IntExpr e3a = (x >= 7) + y; + Assert.Equal("(Watch= 7>(0 .. 1) + y(5..17))", e3a.ToString()); + IntExpr e3b = y + (x >= 7); + Assert.Equal("(Watch= 7>(0 .. 1) + y(5..17))", e3b.ToString()); - IntExpr e3c = (x >= 7) - y; - Assert.Equal("(Watch= 7>(0 .. 1) - y(5..17))", e3c.ToString()); - IntExpr e3d = y - (x >= 7); - Assert.Equal("(y(5..17) - Watch= 7>(0 .. 1))", e3d.ToString()); + IntExpr e3c = (x >= 7) - y; + Assert.Equal("(Watch= 7>(0 .. 1) - y(5..17))", e3c.ToString()); + IntExpr e3d = y - (x >= 7); + Assert.Equal("(y(5..17) - Watch= 7>(0 .. 1))", e3d.ToString()); - IntExpr e3e = (x >= 7) * y; - Assert.Equal("(Watch= 7>(0 .. 1) * y(5..17))", e3e.ToString()); - IntExpr e3f = y * (x >= 7); - Assert.Equal("(Watch= 7>(0 .. 1) * y(5..17))", e3f.ToString()); + IntExpr e3e = (x >= 7) * y; + Assert.Equal("(Watch= 7>(0 .. 1) * y(5..17))", e3e.ToString()); + IntExpr e3f = y * (x >= 7); + Assert.Equal("(Watch= 7>(0 .. 1) * y(5..17))", e3f.ToString()); - // Relational operator with an IntVar - Constraint c9a = (x >= 7) == y; - Assert.Equal("Watch= 7>(0 .. 1) == y(5..17)", c9a.ToString()); - Constraint c9b = y == (x >= 7); - Assert.Equal("y(5..17) == Watch= 7>(0 .. 1)", c9b.ToString()); + // Relational operator with an IntVar + Constraint c9a = (x >= 7) == y; + Assert.Equal("Watch= 7>(0 .. 1) == y(5..17)", c9a.ToString()); + Constraint c9b = y == (x >= 7); + Assert.Equal("y(5..17) == Watch= 7>(0 .. 1)", c9b.ToString()); - Constraint c9c = (x >= 7) != y; - Assert.Equal("Watch= 7>(0 .. 1) != y(5..17)", c9c.ToString()); - Constraint c9d = y != (x >= 7); - Assert.Equal("y(5..17) != Watch= 7>(0 .. 1)", c9d.ToString()); + Constraint c9c = (x >= 7) != y; + Assert.Equal("Watch= 7>(0 .. 1) != y(5..17)", c9c.ToString()); + Constraint c9d = y != (x >= 7); + Assert.Equal("y(5..17) != Watch= 7>(0 .. 1)", c9d.ToString()); - Constraint c9e = (x >= 7) >= y; - Assert.Equal("y(5..17) <= Watch= 7>(0 .. 1)", c9e.ToString()); - Constraint c9f = y >= (x >= 7); - Assert.Equal("Watch= 7>(0 .. 1) <= y(5..17)", c9f.ToString()); + Constraint c9e = (x >= 7) >= y; + Assert.Equal("y(5..17) <= Watch= 7>(0 .. 1)", c9e.ToString()); + Constraint c9f = y >= (x >= 7); + Assert.Equal("Watch= 7>(0 .. 1) <= y(5..17)", c9f.ToString()); - Constraint c9g = (x >= 7) > y; - Assert.Equal("y(5..17) < Watch= 7>(0 .. 1)", c9g.ToString()); - Constraint c9h = y > (x >= 7); - Assert.Equal("Watch= 7>(0 .. 1) < y(5..17)", c9h.ToString()); + Constraint c9g = (x >= 7) > y; + Assert.Equal("y(5..17) < Watch= 7>(0 .. 1)", c9g.ToString()); + Constraint c9h = y > (x >= 7); + Assert.Equal("Watch= 7>(0 .. 1) < y(5..17)", c9h.ToString()); - Constraint c9i = (x >= 7) <= y; - Assert.Equal("Watch= 7>(0 .. 1) <= y(5..17)", c9i.ToString()); - Constraint c9j = y <= (x >= 7); - Assert.Equal("y(5..17) <= Watch= 7>(0 .. 1)", c9j.ToString()); + Constraint c9i = (x >= 7) <= y; + Assert.Equal("Watch= 7>(0 .. 1) <= y(5..17)", c9i.ToString()); + Constraint c9j = y <= (x >= 7); + Assert.Equal("y(5..17) <= Watch= 7>(0 .. 1)", c9j.ToString()); - Constraint c9k = (x >= 7) < y; - Assert.Equal("Watch= 7>(0 .. 1) < y(5..17)", c9k.ToString()); - Constraint c9l = y < (x >= 7); - Assert.Equal("y(5..17) < Watch= 7>(0 .. 1)", c9l.ToString()); - } + Constraint c9k = (x >= 7) < y; + Assert.Equal("Watch= 7>(0 .. 1) < y(5..17)", c9k.ToString()); + Constraint c9l = y < (x >= 7); + Assert.Equal("y(5..17) < Watch= 7>(0 .. 1)", c9l.ToString()); + } [Fact] - public void GreaterIntExprAndGreaterIntExpr() { - Solver solver = new Solver("Solver"); - IntVar x = solver.MakeIntVar(3, 13, "x"); - Assert.Equal(3, x.Min()); - Assert.Equal(13, x.Max()); + public void GreaterIntExprAndGreaterIntExpr() { + Solver solver = new Solver("Solver"); + IntVar x = solver.MakeIntVar(3, 13, "x"); + Assert.Equal(3, x.Min()); + Assert.Equal(13, x.Max()); - IntVar y = solver.MakeIntVar(5, 17, "y"); - Assert.Equal(5, y.Min()); - Assert.Equal(17, y.Max()); + IntVar y = solver.MakeIntVar(5, 17, "y"); + Assert.Equal(5, y.Min()); + Assert.Equal(17, y.Max()); - // Relational operator between IntExpr - Constraint c10a = (x >= 7) == (y >= 11); - Assert.Equal("Watch= 7>(0 .. 1) == Watch= 11>(0 .. 1)", c10a.ToString()); + // Relational operator between IntExpr + Constraint c10a = (x >= 7) == (y >= 11); + Assert.Equal("Watch= 7>(0 .. 1) == Watch= 11>(0 .. 1)", + c10a.ToString()); - Constraint c10b = (x >= 7) != (y >= 11); - Assert.Equal("Watch= 7>(0 .. 1) != Watch= 11>(0 .. 1)", c10b.ToString()); + Constraint c10b = (x >= 7) != (y >= 11); + Assert.Equal("Watch= 7>(0 .. 1) != Watch= 11>(0 .. 1)", + c10b.ToString()); - Constraint c10c= (x >= 7) <= (y >= 11); - Assert.Equal("Watch= 7>(0 .. 1) <= Watch= 11>(0 .. 1)", c10c.ToString()); - Constraint c10d = (x >= 7) >= (y >= 11); - Assert.Equal("Watch= 11>(0 .. 1) <= Watch= 7>(0 .. 1)", c10d.ToString()); + Constraint c10c = (x >= 7) <= (y >= 11); + Assert.Equal("Watch= 7>(0 .. 1) <= Watch= 11>(0 .. 1)", + c10c.ToString()); + Constraint c10d = (x >= 7) >= (y >= 11); + Assert.Equal("Watch= 11>(0 .. 1) <= Watch= 7>(0 .. 1)", + c10d.ToString()); - Constraint c10e = (x >= 7) > (y >= 11); - Assert.Equal("Watch= 11>(0 .. 1) < Watch= 7>(0 .. 1)", c10e.ToString()); - Constraint c10f = (x >= 7) < (y >= 11); - Assert.Equal("Watch= 7>(0 .. 1) < Watch= 11>(0 .. 1)", c10f.ToString()); - } + Constraint c10e = (x >= 7) > (y >= 11); + Assert.Equal("Watch= 11>(0 .. 1) < Watch= 7>(0 .. 1)", + c10e.ToString()); + Constraint c10f = (x >= 7) < (y >= 11); + Assert.Equal("Watch= 7>(0 .. 1) < Watch= 11>(0 .. 1)", + c10f.ToString()); + } [Fact] - public void Downcast() { - Solver solver = new Solver("Solver"); - IntVar x = solver.MakeIntVar(2, 17, "x"); - IntExpr e = x + 5; - IntVar y = e.Var(); - Assert.Equal("(x(2..17) + 5)", y.ToString()); - } + public void Downcast() { + Solver solver = new Solver("Solver"); + IntVar x = solver.MakeIntVar(2, 17, "x"); + IntExpr e = x + 5; + IntVar y = e.Var(); + Assert.Equal("(x(2..17) + 5)", y.ToString()); + } [Fact] - public void Sequence() { - Solver solver = new Solver("Solver"); - IntervalVar[] intervals = + public void Sequence() { + Solver solver = new Solver("Solver"); + IntervalVar[] intervals = solver.MakeFixedDurationIntervalVarArray(10, 0, 10, 5, false, "task"); - DisjunctiveConstraint disjunctive = intervals.Disjunctive("Sequence"); - SequenceVar var = disjunctive.SequenceVar(); - Assignment ass = solver.MakeAssignment(); - ass.Add(var); - ass.SetForwardSequence(var, new int[] { 1, 3, 5 }); - int[] seq = ass.ForwardSequence(var); - Assert.Equal(3, seq.Length); - Assert.Equal(1, seq[0]); - Assert.Equal(3, seq[1]); - Assert.Equal(5, seq[2]); - } + DisjunctiveConstraint disjunctive = intervals.Disjunctive("Sequence"); + SequenceVar var = disjunctive.SequenceVar(); + Assignment ass = solver.MakeAssignment(); + ass.Add(var); + ass.SetForwardSequence(var, new int[]{1, 3, 5}); + int[] seq = ass.ForwardSequence(var); + Assert.Equal(3, seq.Length); + Assert.Equal(1, seq[0]); + Assert.Equal(3, seq[1]); + Assert.Equal(5, seq[2]); + } // A simple demon that simply sets the maximum of a fixed IntVar to 10 when // it's being called. class SetMaxDemon : NetDemon { - public SetMaxDemon(IntVar x) {x_ = x;} - public override void Run(Solver s) {x_.SetMax(10);} + public SetMaxDemon(IntVar x) { x_ = x; } + public override void Run(Solver s) { x_.SetMax(10); } private IntVar x_; } [Fact] - public void Demon() { - Solver solver = new Solver("DemonTest"); - IntVar x = solver.MakeIntVar(new int[] {2, 4, -1, 6, 11, 10}, "x"); - NetDemon demon = new SetMaxDemon(x); - Assert.Equal(11, x.Max()); - demon.Run(solver); - Assert.Equal(10, x.Max()); - } + public void Demon() { + Solver solver = new Solver("DemonTest"); + IntVar x = solver.MakeIntVar(new int[]{2, 4, -1, 6, 11, 10}, "x"); + NetDemon demon = new SetMaxDemon(x); + Assert.Equal(11, x.Max()); + demon.Run(solver); + Assert.Equal(10, x.Max()); + } // This constraint has a single target variable x. It enforces x >= 5 upon // InitialPropagate() and invokes the SetMaxDemon when x changes its range. class SetMinAndMaxConstraint : NetConstraint { - public SetMinAndMaxConstraint(Solver solver, IntVar x) : base(solver) {x_ = x;} + public SetMinAndMaxConstraint(Solver solver, IntVar x) : base(solver) { + x_ = x; + } public override void Post() { // Always store the demon in the constraint to avoid it being reclaimed // by the GC. demon_ = new SetMaxDemon(x_); x_.WhenBound(demon_); } - public override void InitialPropagate() {x_.SetMin(5);} + public override void InitialPropagate() { x_.SetMin(5); } private IntVar x_; private Demon demon_; } [Fact] - public void MinAndMaxConstraint() { - Solver solver = new Solver("TestConstraint"); - IntVar x = solver.MakeIntVar(new int[] {2, 4, -1, 6, 11, 10}, "x"); - Constraint ct = new SetMinAndMaxConstraint(solver, x); - solver.Add(ct); - DecisionBuilder db = solver.MakePhase( - x, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); - solver.NewSearch(db); - Assert.Equal(-1, x.Min()); - Assert.Equal(11, x.Max()); + public void MinAndMaxConstraint() { + Solver solver = new Solver("TestConstraint"); + IntVar x = solver.MakeIntVar(new int[]{2, 4, -1, 6, 11, 10}, "x"); + Constraint ct = new SetMinAndMaxConstraint(solver, x); + solver.Add(ct); + DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, + Solver.ASSIGN_MIN_VALUE); + solver.NewSearch(db); + Assert.Equal(-1, x.Min()); + Assert.Equal(11, x.Max()); - Assert.True(solver.NextSolution()); - Assert.Equal(6, x.Min()); - Assert.Equal(6, x.Max()); + Assert.True(solver.NextSolution()); + Assert.Equal(6, x.Min()); + Assert.Equal(6, x.Max()); - Assert.True(solver.NextSolution()); - Assert.Equal(10, x.Min()); - Assert.Equal(10, x.Max()); + Assert.True(solver.NextSolution()); + Assert.Equal(10, x.Min()); + Assert.Equal(10, x.Max()); - Assert.False(solver.NextSolution()); - solver.EndSearch(); - } + Assert.False(solver.NextSolution()); + solver.EndSearch(); + } // // This constraint has a single target variable x. It enforces x >= 5, // but only at the leaf of the search tree: it doesn't change x's bounds, // and simply fails if x is bound and is < 5. class DumbGreaterOrEqualToFive : NetConstraint { - public DumbGreaterOrEqualToFive(Solver solver, IntVar x) : base(solver) {x_ = x;} + public DumbGreaterOrEqualToFive(Solver solver, IntVar x) : base(solver) { + x_ = x; + } public override void Post() { demon_ = solver().MakeConstraintInitialPropagateCallback(this); x_.WhenRange(demon_); @@ -692,65 +733,72 @@ namespace Google.OrTools.Tests { } [Fact] - public void FailingConstraint() { - Solver solver = new Solver("TestConstraint"); - IntVar x = solver.MakeIntVar(new int[] {2, 4, -1, 6, 11, 10}, "x"); - Constraint ct = new DumbGreaterOrEqualToFive(solver, x); - solver.Add(ct); - DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, - Solver.ASSIGN_MIN_VALUE); - solver.NewSearch(db); - Assert.True(solver.NextSolution()); - Assert.Equal(6, x.Min()); - solver.EndSearch(); - } + public void FailingConstraint() { + Solver solver = new Solver("TestConstraint"); + IntVar x = solver.MakeIntVar(new int[]{2, 4, -1, 6, 11, 10}, "x"); + Constraint ct = new DumbGreaterOrEqualToFive(solver, x); + solver.Add(ct); + DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, + Solver.ASSIGN_MIN_VALUE); + solver.NewSearch(db); + Assert.True(solver.NextSolution()); + Assert.Equal(6, x.Min()); + solver.EndSearch(); + } [Fact] - public void DomainIterator() { - Solver solver = new Solver("TestConstraint"); - IntVar x = solver.MakeIntVar(new int[] {2, 4, -1, 6, 11, 10}, "x"); - ulong count = 0; - foreach (long value in x.GetDomain()) { - count++; - } - Assert.Equal(count, x.Size()); + public void DomainIterator() { + Solver solver = new Solver("TestConstraint"); + IntVar x = solver.MakeIntVar(new int[]{2, 4, -1, 6, 11, 10}, "x"); + ulong count = 0; + foreach (long value in x.GetDomain()) { + count++; } + Assert.Equal(count, x.Size()); + } class CountHoles : NetDemon { - public CountHoles(IntVar x) {x_ = x; count_ = 0;} + public CountHoles(IntVar x) { + x_ = x; + count_ = 0; + } public override void Run(Solver s) { foreach (long removed in x_.GetHoles()) { count_++; } } - public int count() {return count_;} + public int count() { return count_; } private IntVar x_; private int count_; } class RemoveThreeValues : NetConstraint { - public RemoveThreeValues(Solver solver, IntVar x) : base(solver) {x_ = x;} + public RemoveThreeValues(Solver solver, IntVar x) : base(solver) { + x_ = x; + } public override void Post() { demon_ = new CountHoles(x_); x_.WhenDomain(demon_); } - public override void InitialPropagate() {x_.RemoveValues(new long[] {3, 5, 7});} - public int count() {return demon_.count();} + public override void InitialPropagate() { + x_.RemoveValues(new long[]{3, 5, 7}); + } + public int count() { return demon_.count(); } private IntVar x_; private CountHoles demon_; } [Fact] - public void HoleIteratorTest() { - Solver solver = new Solver("TestConstraint"); - IntVar x = solver.MakeIntVar(0, 10, "x"); - RemoveThreeValues ct = new RemoveThreeValues(solver, x); - solver.Add(ct); - DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, - Solver.ASSIGN_MIN_VALUE); - solver.Solve(db); - Assert.Equal(3, ct.count()); - } + public void HoleIteratorTest() { + Solver solver = new Solver("TestConstraint"); + IntVar x = solver.MakeIntVar(0, 10, "x"); + RemoveThreeValues ct = new RemoveThreeValues(solver, x); + solver.Add(ct); + DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, + Solver.ASSIGN_MIN_VALUE); + solver.Solve(db); + Assert.Equal(3, ct.count()); + } // TODO(mizux): Improve search log tests; currently only tests coverage. void RunSearchLog(in SearchMonitor searchlog) { @@ -765,78 +813,84 @@ namespace Google.OrTools.Tests { } [Fact] - public void SearchLog() { - Solver solver = new Solver("TestSearchLog"); - IntVar var = solver.MakeIntVar(1, 1, "Variable"); - OptimizeVar objective = solver.MakeMinimize(var, 1); - SearchMonitor searchlog = solver.MakeSearchLog(0); - RunSearchLog(in searchlog); - GC.KeepAlive(solver); - } + public void SearchLog() { + Solver solver = new Solver("TestSearchLog"); + IntVar var = solver.MakeIntVar(1, 1, "Variable"); + OptimizeVar objective = solver.MakeMinimize(var, 1); + SearchMonitor searchlog = solver.MakeSearchLog(0); + RunSearchLog(in searchlog); + GC.KeepAlive(solver); + } - [Theory][InlineData(false)][InlineData(true)] - public void SearchLogWithCallback(bool callGC) { - Solver solver = new Solver("TestSearchLog"); - IntVar var = solver.MakeIntVar(1, 1, "Variable"); - OptimizeVar objective = solver.MakeMinimize(var, 1); - int count = 0; - SearchMonitor searchlog = solver.MakeSearchLog( - 0, // branch period - () => { - count++; - return "display callback..."; - }); - if (callGC) { - GC.Collect(); - GC.WaitForPendingFinalizers(); - } - RunSearchLog(in searchlog); - GC.KeepAlive(solver); - Assert.Equal(1, count); + [Theory] + [InlineData(false)] + [InlineData(true)] + public void SearchLogWithCallback(bool callGC) { + Solver solver = new Solver("TestSearchLog"); + IntVar var = solver.MakeIntVar(1, 1, "Variable"); + OptimizeVar objective = solver.MakeMinimize(var, 1); + int count = 0; + SearchMonitor searchlog = + solver.MakeSearchLog(0, // branch period + () => { + count++; + return "display callback..."; + }); + if (callGC) { + GC.Collect(); + GC.WaitForPendingFinalizers(); } + RunSearchLog(in searchlog); + GC.KeepAlive(solver); + Assert.Equal(1, count); + } - [Theory][InlineData(false)][InlineData(true)] - public void SearchLogWithObjectiveAndCallback(bool callGC) { - Solver solver = new Solver("TestSearchLog"); - IntVar var = solver.MakeIntVar(1, 1, "Variable"); - OptimizeVar objective = solver.MakeMinimize(var, 1); - int count = 0; - SearchMonitor searchlog = solver.MakeSearchLog( - 0, // branch period - objective, // objective var to monitor - () => { - count++; - return "OptimizeVar display callback"; - }); - if (callGC) { - GC.Collect(); - GC.WaitForPendingFinalizers(); - } - RunSearchLog(in searchlog); - GC.KeepAlive(solver); - Assert.Equal(1, count); + [Theory] + [InlineData(false)] + [InlineData(true)] + public void SearchLogWithObjectiveAndCallback(bool callGC) { + Solver solver = new Solver("TestSearchLog"); + IntVar var = solver.MakeIntVar(1, 1, "Variable"); + OptimizeVar objective = solver.MakeMinimize(var, 1); + int count = 0; + SearchMonitor searchlog = + solver.MakeSearchLog(0, // branch period + objective, // objective var to monitor + () => { + count++; + return "OptimizeVar display callback"; + }); + if (callGC) { + GC.Collect(); + GC.WaitForPendingFinalizers(); } + RunSearchLog(in searchlog); + GC.KeepAlive(solver); + Assert.Equal(1, count); + } - [Theory][InlineData(false)][InlineData(true)] - public void SearchLogWithIntVarAndCallback(bool callGC) { - Solver solver = new Solver("TestSearchLog"); - IntVar var = solver.MakeIntVar(1, 1, "Variable"); - OptimizeVar objective = solver.MakeMinimize(var, 1); - int count = 0; - SearchMonitor searchlog = solver.MakeSearchLog( - 0, // branch period - var, // int var to monitor - () => { - count++; - return "IntVar display callback"; - }); - if (callGC) { - GC.Collect(); - GC.WaitForPendingFinalizers(); - } - RunSearchLog(in searchlog); - GC.KeepAlive(solver); - Assert.Equal(1, count); + [Theory] + [InlineData(false)] + [InlineData(true)] + public void SearchLogWithIntVarAndCallback(bool callGC) { + Solver solver = new Solver("TestSearchLog"); + IntVar var = solver.MakeIntVar(1, 1, "Variable"); + OptimizeVar objective = solver.MakeMinimize(var, 1); + int count = 0; + SearchMonitor searchlog = + solver.MakeSearchLog(0, // branch period + var, // int var to monitor + () => { + count++; + return "IntVar display callback"; + }); + if (callGC) { + GC.Collect(); + GC.WaitForPendingFinalizers(); } + RunSearchLog(in searchlog); + GC.KeepAlive(solver); + Assert.Equal(1, count); + } } } // namespace Google.OrTools.Tests diff --git a/examples/tests/LinearSolverTests.cs b/examples/tests/LinearSolverTests.cs index 4f27edd9af..36b63452dc 100644 --- a/examples/tests/LinearSolverTests.cs +++ b/examples/tests/LinearSolverTests.cs @@ -185,7 +185,7 @@ namespace Google.OrTools.Tests { Constraint ct2 = solver.Add(-2 * x.Sum() == 3); Assert.Equal(-2.0, ct2.GetCoefficient(x[0])); - LinearExpr[] array = new LinearExpr[] { x[0] + 2.0, x[0] + 3, x[0] + 4 }; + LinearExpr[] array = new LinearExpr[]{x[0] + 2.0, x[0] + 3, x[0] + 4}; Constraint ct3 = solver.Add(array.Sum() == 1); Assert.Equal(3.0, ct3.GetCoefficient(x[0])); Assert.Equal(-8.0, ct3.Lb()); @@ -215,7 +215,8 @@ namespace Google.OrTools.Tests { Assert.True(solver.Objective().Minimization()); } - void SolveAndPrint(in Solver solver, in Variable[] variables, in Constraint[] constraints) { + void SolveAndPrint(in Solver solver, in Variable[] variables, + in Constraint[] constraints) { Console.WriteLine($"Number of variables = {solver.NumVariables()}"); Console.WriteLine($"Number of constraints = {solver.NumConstraints()}"); @@ -228,26 +229,29 @@ namespace Google.OrTools.Tests { foreach (Variable var in variables) { Console.WriteLine($"{var.Name()} = {var.SolutionValue()}"); } - Console.WriteLine($"Optimal objective value = {solver.Objective().Value()}"); + Console.WriteLine( + $"Optimal objective value = {solver.Objective().Value()}"); Console.WriteLine(""); Console.WriteLine("Advanced usage:"); - Console.WriteLine($"Problem solved in {solver.WallTime()} milliseconds"); - Console.WriteLine($"Problem solved in {solver.Iterations()} iterations"); + Console.WriteLine( + $"Problem solved in {solver.WallTime()} milliseconds"); + Console.WriteLine( + $"Problem solved in {solver.Iterations()} iterations"); foreach (Variable var in variables) { Console.WriteLine($"{var.Name()}: reduced cost {var.ReducedCost()}"); } double[] activities = solver.ComputeConstraintActivities(); foreach (Constraint ct in constraints) { - Console.WriteLine( - $"{ct.Name()}: dual value = {ct.DualValue()}", - $" activity = {activities[ct.Index()]}"); + Console.WriteLine($"{ct.Name()}: dual value = {ct.DualValue()}", + $" activity = {activities[ct.Index()]}"); } } } void RunLinearProgrammingExample(in String problemType) { - Console.WriteLine($"------ Linear programming example with {problemType} ------"); + Console.WriteLine( + $"------ Linear programming example with {problemType} ------"); Solver solver = Solver.CreateSolver(problemType); if (solver == null) return; @@ -263,7 +267,8 @@ namespace Google.OrTools.Tests { objective.SetMaximization(); // x + 2y <= 14. - Constraint c0 = solver.MakeConstraint(double.NegativeInfinity, 14.0, "c0"); + Constraint c0 = + solver.MakeConstraint(double.NegativeInfinity, 14.0, "c0"); c0.SetCoefficient(x, 1); c0.SetCoefficient(y, 2); @@ -277,10 +282,11 @@ namespace Google.OrTools.Tests { c2.SetCoefficient(x, 1); c2.SetCoefficient(y, -1); - SolveAndPrint(solver, new Variable[] { x, y }, new Constraint[] { c0, c1, c2 }); + SolveAndPrint(solver, new Variable[]{x, y}, new Constraint[]{c0, c1, c2}); } void RunMixedIntegerProgrammingExample(in String problemType) { - Console.WriteLine($"------ Mixed integer programming example with {problemType} ------"); + Console.WriteLine( + $"------ Mixed integer programming example with {problemType} ------"); Solver solver = Solver.CreateSolver(problemType); if (solver == null) return; @@ -296,7 +302,8 @@ namespace Google.OrTools.Tests { objective.SetMaximization(); // x + 7 * y <= 17.5. - Constraint c0 = solver.MakeConstraint(double.NegativeInfinity, 17.5, "c0"); + Constraint c0 = + solver.MakeConstraint(double.NegativeInfinity, 17.5, "c0"); c0.SetCoefficient(x, 1); c0.SetCoefficient(y, 7); @@ -305,10 +312,11 @@ namespace Google.OrTools.Tests { c1.SetCoefficient(x, 1); c1.SetCoefficient(y, 0); - SolveAndPrint(solver, new Variable[] { x, y }, new Constraint[] { c0, c1 }); + SolveAndPrint(solver, new Variable[]{x, y}, new Constraint[]{c0, c1}); } void RunBooleanProgrammingExample(in String problemType) { - Console.WriteLine($"------ Boolean programming example with {problemType} ------"); + Console.WriteLine( + $"------ Boolean programming example with {problemType} ------"); Solver solver = Solver.CreateSolver(problemType); if (solver == null) return; @@ -328,7 +336,7 @@ namespace Google.OrTools.Tests { c0.SetCoefficient(x, 1); c0.SetCoefficient(y, 2); - SolveAndPrint(solver, new Variable[] { x, y }, new Constraint[] { c0 }); + SolveAndPrint(solver, new Variable[]{x, y}, new Constraint[]{c0}); } [Fact] @@ -362,7 +370,8 @@ namespace Google.OrTools.Tests { objective.SetMaximization(); // x + 7 * y <= 17.5. - Constraint c0 = solver.MakeConstraint(double.NegativeInfinity, 17.5, "c0"); + Constraint c0 = + solver.MakeConstraint(double.NegativeInfinity, 17.5, "c0"); c0.SetCoefficient(x, 1); c0.SetCoefficient(y, 7); @@ -376,7 +385,7 @@ namespace Google.OrTools.Tests { Variable[] variables = solver.variables(); Assert.Equal(variables.Length, 2); - solver.SetHint(new Variable[] { x, y }, new double[] { 2.0, 3.0 }); + solver.SetHint(new Variable[]{x, y}, new double[]{2.0, 3.0}); } } -} // namespace Google.OrTools.Tests \ No newline at end of file +} // namespace Google.OrTools.Tests \ No newline at end of file diff --git a/examples/tests/RoutingSolverTests.cs b/examples/tests/RoutingSolverTests.cs index 23fcc56d86..1de7acee63 100644 --- a/examples/tests/RoutingSolverTests.cs +++ b/examples/tests/RoutingSolverTests.cs @@ -9,17 +9,17 @@ namespace Google.OrTools.Tests { [InlineData(true)] public void SimpleLambdaCallback(bool callGC) { // Create Routing Index Manager - RoutingIndexManager manager = new RoutingIndexManager( - 5/*locations*/, 1/*vehicle*/, 0/*depot*/); + RoutingIndexManager manager = + new RoutingIndexManager(5 /*locations*/, 1 /*vehicle*/, 0 /*depot*/); // Create Routing Model. RoutingModel routing = new RoutingModel(manager); // Create a distance callback. - int transitCallbackIndex = routing.RegisterTransitCallback( - (long fromIndex, long toIndex) => { - // Convert from routing variable Index to distance matrix NodeIndex. - var fromNode = manager.IndexToNode(fromIndex); - var toNode = manager.IndexToNode(toIndex); - return Math.Abs(toNode - fromNode); + int transitCallbackIndex = + routing.RegisterTransitCallback((long fromIndex, long toIndex) => { + // Convert from routing variable Index to distance matrix NodeIndex. + var fromNode = manager.IndexToNode(fromIndex); + var toNode = manager.IndexToNode(toIndex); + return Math.Abs(toNode - fromNode); }); // Define cost of each arc. routing.SetArcCostEvaluatorOfAllVehicles(transitCallbackIndex); @@ -28,13 +28,13 @@ namespace Google.OrTools.Tests { } // Setting first solution heuristic. RoutingSearchParameters searchParameters = - operations_research_constraint_solver.DefaultRoutingSearchParameters(); + operations_research_constraint_solver + .DefaultRoutingSearchParameters(); searchParameters.FirstSolutionStrategy = - FirstSolutionStrategy.Types.Value.PathCheapestArc; + FirstSolutionStrategy.Types.Value.PathCheapestArc; Assignment solution = routing.SolveWithParameters(searchParameters); // 0 --(+1)-> 1 --(+1)-> 2 --(+1)-> 3 --(+1)-> 4 --(+4)-> 0 := +8 Assert.Equal(8, solution.ObjectiveValue()); } } -} // namespace Google.OrTools.Tests - +} // namespace Google.OrTools.Tests diff --git a/examples/tests/SatSolverTests.cs b/examples/tests/SatSolverTests.cs index fd1089fd30..6cf78dc484 100644 --- a/examples/tests/SatSolverTests.cs +++ b/examples/tests/SatSolverTests.cs @@ -12,10 +12,8 @@ namespace Google.OrTools.Tests { return var; } - static ConstraintProto NewLinear2( - int v1, int v2, - long c1, long c2, - long lb, long ub) { + static ConstraintProto NewLinear2(int v1, int v2, long c1, long c2, long lb, + long ub) { LinearConstraintProto linear = new LinearConstraintProto(); linear.Vars.Add(v1); linear.Vars.Add(v2); @@ -28,10 +26,8 @@ namespace Google.OrTools.Tests { return ct; } - static ConstraintProto NewLinear3( - int v1, int v2, int v3, - long c1, long c2, long c3, - long lb, long ub) { + static ConstraintProto NewLinear3(int v1, int v2, int v3, long c1, long c2, + long c3, long lb, long ub) { LinearConstraintProto linear = new LinearConstraintProto(); linear.Vars.Add(v1); linear.Vars.Add(v2); @@ -73,198 +69,197 @@ namespace Google.OrTools.Tests { // CpModelProto [Fact] - public void SimpleLinearModelProto() { - CpModelProto model = new CpModelProto(); - model.Variables.Add(NewIntegerVariable(-10, 10)); - model.Variables.Add(NewIntegerVariable(-10, 10)); - model.Variables.Add(NewIntegerVariable(-1000000, 1000000)); - model.Constraints.Add(NewLinear2(0, 1 , 1, 1, -1000000, 100000)); - model.Constraints.Add(NewLinear3(0, 1, 2, 1, 2, -1, 0, 100000)); - model.Objective = NewMaximize1(2, 1); - //Console.WriteLine("model = " + model.ToString()); + public void SimpleLinearModelProto() { + CpModelProto model = new CpModelProto(); + model.Variables.Add(NewIntegerVariable(-10, 10)); + model.Variables.Add(NewIntegerVariable(-10, 10)); + model.Variables.Add(NewIntegerVariable(-1000000, 1000000)); + model.Constraints.Add(NewLinear2(0, 1, 1, 1, -1000000, 100000)); + model.Constraints.Add(NewLinear3(0, 1, 2, 1, 2, -1, 0, 100000)); + model.Objective = NewMaximize1(2, 1); + // Console.WriteLine("model = " + model.ToString()); - CpSolverResponse response = SatHelper.Solve(model); - Assert.Equal(CpSolverStatus.Optimal, response.Status); - Assert.Equal(30, response.ObjectiveValue); - Assert.Equal(new long[] {10, 10, 30}, response.Solution); - //Console.WriteLine("response = " + response.ToString()); - } + CpSolverResponse response = SatHelper.Solve(model); + Assert.Equal(CpSolverStatus.Optimal, response.Status); + Assert.Equal(30, response.ObjectiveValue); + Assert.Equal(new long[]{10, 10, 30}, response.Solution); + // Console.WriteLine("response = " + response.ToString()); + } [Fact] - public void SimpleLinearModelProto2() { - CpModelProto model = new CpModelProto(); - model.Variables.Add(NewIntegerVariable(-10, 10)); - model.Variables.Add(NewIntegerVariable(-10, 10)); - model.Constraints.Add(NewLinear2(0, 1 , 1, 1, -1000000, 100000)); - model.Objective = NewMaximize2(0, 1, 1, -2); - //Console.WriteLine("model = " + model.ToString()); + public void SimpleLinearModelProto2() { + CpModelProto model = new CpModelProto(); + model.Variables.Add(NewIntegerVariable(-10, 10)); + model.Variables.Add(NewIntegerVariable(-10, 10)); + model.Constraints.Add(NewLinear2(0, 1, 1, 1, -1000000, 100000)); + model.Objective = NewMaximize2(0, 1, 1, -2); + // Console.WriteLine("model = " + model.ToString()); - CpSolverResponse response = SatHelper.Solve(model); - Assert.Equal(CpSolverStatus.Optimal, response.Status); - Assert.Equal(30, response.ObjectiveValue); - Assert.Equal(new long[] {10, -10}, response.Solution); - //Console.WriteLine("response = " + response.ToString()); - } + CpSolverResponse response = SatHelper.Solve(model); + Assert.Equal(CpSolverStatus.Optimal, response.Status); + Assert.Equal(30, response.ObjectiveValue); + Assert.Equal(new long[]{10, -10}, response.Solution); + // Console.WriteLine("response = " + response.ToString()); + } // CpModel [Fact] - public void SimpleLinearModel() { - CpModel model = new CpModel(); - IntVar v1 = model.NewIntVar(-10, 10, "v1"); - IntVar v2 = model.NewIntVar(-10, 10, "v2"); - IntVar v3 = model.NewIntVar(-100000, 100000, "v3"); - model.AddLinearConstraint(v1 + v2, -1000000, 100000); - model.AddLinearConstraint(v1 + 2 * v2 - v3, 0, 100000); - model.Maximize(v3); - Assert.Equal(v1.Domain.FlattenedIntervals(), - new long[] { -10, 10 }); - //Console.WriteLine("model = " + model.Model.ToString()); + public void SimpleLinearModel() { + CpModel model = new CpModel(); + IntVar v1 = model.NewIntVar(-10, 10, "v1"); + IntVar v2 = model.NewIntVar(-10, 10, "v2"); + IntVar v3 = model.NewIntVar(-100000, 100000, "v3"); + model.AddLinearConstraint(v1 + v2, -1000000, 100000); + model.AddLinearConstraint(v1 + 2 * v2 - v3, 0, 100000); + model.Maximize(v3); + Assert.Equal(v1.Domain.FlattenedIntervals(), new long[]{-10, 10}); + // Console.WriteLine("model = " + model.Model.ToString()); - CpSolver solver = new CpSolver(); - CpSolverStatus status = solver.Solve(model); - Assert.Equal(CpSolverStatus.Optimal, status); + CpSolver solver = new CpSolver(); + CpSolverStatus status = solver.Solve(model); + Assert.Equal(CpSolverStatus.Optimal, status); - CpSolverResponse response = solver.Response; - Assert.Equal(30, response.ObjectiveValue); - Assert.Equal(new long[] {10, 10, 30}, response.Solution); - //Console.WriteLine("response = " + reponse.ToString()); - } + CpSolverResponse response = solver.Response; + Assert.Equal(30, response.ObjectiveValue); + Assert.Equal(new long[]{10, 10, 30}, response.Solution); + // Console.WriteLine("response = " + reponse.ToString()); + } [Fact] - public void SimpleLinearModel2() { - CpModel model = new CpModel(); - IntVar v1 = model.NewIntVar(-10, 10, "v1"); - IntVar v2 = model.NewIntVar(-10, 10, "v2"); - model.AddLinearConstraint(v1 + v2, -1000000, 100000); - model.Maximize(v1 - 2 * v2); - //Console.WriteLine("model = " + model.Model.ToString()); + public void SimpleLinearModel2() { + CpModel model = new CpModel(); + IntVar v1 = model.NewIntVar(-10, 10, "v1"); + IntVar v2 = model.NewIntVar(-10, 10, "v2"); + model.AddLinearConstraint(v1 + v2, -1000000, 100000); + model.Maximize(v1 - 2 * v2); + // Console.WriteLine("model = " + model.Model.ToString()); - CpSolver solver = new CpSolver(); - CpSolverStatus status = solver.Solve(model); - Assert.Equal(CpSolverStatus.Optimal, status); + CpSolver solver = new CpSolver(); + CpSolverStatus status = solver.Solve(model); + Assert.Equal(CpSolverStatus.Optimal, status); - CpSolverResponse response = solver.Response; - Assert.Equal(30, response.ObjectiveValue); - Assert.Equal(new long[] {10, -10}, response.Solution); - //Console.WriteLine("response = " + reponse.ToString()); - } + CpSolverResponse response = solver.Response; + Assert.Equal(30, response.ObjectiveValue); + Assert.Equal(new long[]{10, -10}, response.Solution); + // Console.WriteLine("response = " + reponse.ToString()); + } [Fact] - public void SimpleLinearModel3() { - CpModel model = new CpModel(); - IntVar v1 = model.NewIntVar(-10, 10, "v1"); - IntVar v2 = model.NewIntVar(-10, 10, "v2"); - model.Add(-100000 <= v1 + 2 * v2 <= 100000); - model.Minimize(v1 - 2 * v2); - //Console.WriteLine("model = " + model.Model.ToString()); + public void SimpleLinearModel3() { + CpModel model = new CpModel(); + IntVar v1 = model.NewIntVar(-10, 10, "v1"); + IntVar v2 = model.NewIntVar(-10, 10, "v2"); + model.Add(-100000 <= v1 + 2 * v2 <= 100000); + model.Minimize(v1 - 2 * v2); + // Console.WriteLine("model = " + model.Model.ToString()); - CpSolver solver = new CpSolver(); - CpSolverStatus status = solver.Solve(model); - Assert.Equal(CpSolverStatus.Optimal, status); + CpSolver solver = new CpSolver(); + CpSolverStatus status = solver.Solve(model); + Assert.Equal(CpSolverStatus.Optimal, status); - CpSolverResponse response = solver.Response; - Assert.Equal(-10, solver.Value(v1)); - Assert.Equal(10, solver.Value(v2)); - Assert.Equal(new long[] {-10, 10}, response.Solution); - Assert.Equal(-30, solver.Value(v1 - 2 * v2)); - Assert.Equal(-30, response.ObjectiveValue); - //Console.WriteLine("response = " + reponse.ToString()); - } + CpSolverResponse response = solver.Response; + Assert.Equal(-10, solver.Value(v1)); + Assert.Equal(10, solver.Value(v2)); + Assert.Equal(new long[]{-10, 10}, response.Solution); + Assert.Equal(-30, solver.Value(v1 - 2 * v2)); + Assert.Equal(-30, response.ObjectiveValue); + // Console.WriteLine("response = " + reponse.ToString()); + } [Fact] - public void NegativeIntVar() { - CpModel model = new CpModel(); - IntVar boolvar = model.NewBoolVar("boolvar"); - IntVar x = model.NewIntVar(0,10, "x"); - IntVar delta = model.NewIntVar(-5, 5,"delta"); - IntVar squaredDelta = model.NewIntVar(0, 25,"squaredDelta"); - model.Add(x == boolvar * 4); - model.Add(delta == x - 5 ); - model.AddProdEquality(squaredDelta, new IntVar[] {delta, delta}); - model.Minimize(squaredDelta); - //Console.WriteLine("model = " + model.Model.ToString()); + public void NegativeIntVar() { + CpModel model = new CpModel(); + IntVar boolvar = model.NewBoolVar("boolvar"); + IntVar x = model.NewIntVar(0, 10, "x"); + IntVar delta = model.NewIntVar(-5, 5, "delta"); + IntVar squaredDelta = model.NewIntVar(0, 25, "squaredDelta"); + model.Add(x == boolvar * 4); + model.Add(delta == x - 5); + model.AddProdEquality(squaredDelta, new IntVar[]{delta, delta}); + model.Minimize(squaredDelta); + // Console.WriteLine("model = " + model.Model.ToString()); - CpSolver solver = new CpSolver(); - CpSolverStatus status = solver.Solve(model); - CpSolverResponse response = solver.Response; - Console.WriteLine("response = " + response.ToString()); + CpSolver solver = new CpSolver(); + CpSolverStatus status = solver.Solve(model); + CpSolverResponse response = solver.Response; + Console.WriteLine("response = " + response.ToString()); - Assert.Equal(CpSolverStatus.Optimal, status); + Assert.Equal(CpSolverStatus.Optimal, status); - Assert.Equal(1, solver.Value(boolvar)); - Assert.Equal(4, solver.Value(x)); - Assert.Equal(-1, solver.Value(delta)); - Assert.Equal(1, solver.Value(squaredDelta)); - Assert.Equal(new long[] {1, 4, -1, 1}, response.Solution); - Assert.Equal(1.0, response.ObjectiveValue, 5); - } + Assert.Equal(1, solver.Value(boolvar)); + Assert.Equal(4, solver.Value(x)); + Assert.Equal(-1, solver.Value(delta)); + Assert.Equal(1, solver.Value(squaredDelta)); + Assert.Equal(new long[]{1, 4, -1, 1}, response.Solution); + Assert.Equal(1.0, response.ObjectiveValue, 5); + } [Fact] - public void NegativeSquareVar() { - CpModel model = new CpModel(); - IntVar boolvar = model.NewBoolVar("boolvar"); - IntVar x = model.NewIntVar(0,10, "x"); - IntVar delta = model.NewIntVar(-5, 5,"delta"); - IntVar squaredDelta = model.NewIntVar(0, 25,"squaredDelta"); - model.Add(x == 4).OnlyEnforceIf(boolvar); - model.Add(x == 0).OnlyEnforceIf(boolvar.Not()); - model.Add(delta == x - 5 ); - long[,] tuples = { {-5, 25}, {-4, 16}, {-3, 9}, {-2, 4}, {-1, 1}, {0, 0}, - {1, 1}, {2, 4}, {3, 9}, {4, 16}, {5, 25} }; - model.AddAllowedAssignments(new IntVar[] {delta, squaredDelta}, tuples); - model.Minimize(squaredDelta); + public void NegativeSquareVar() { + CpModel model = new CpModel(); + IntVar boolvar = model.NewBoolVar("boolvar"); + IntVar x = model.NewIntVar(0, 10, "x"); + IntVar delta = model.NewIntVar(-5, 5, "delta"); + IntVar squaredDelta = model.NewIntVar(0, 25, "squaredDelta"); + model.Add(x == 4).OnlyEnforceIf(boolvar); + model.Add(x == 0).OnlyEnforceIf(boolvar.Not()); + model.Add(delta == x - 5); + long[, ] tuples = {{-5, 25}, {-4, 16}, {-3, 9}, {-2, 4}, {-1, 1}, {0, 0}, + {1, 1}, {2, 4}, {3, 9}, {4, 16}, {5, 25}}; + model.AddAllowedAssignments(new IntVar[]{delta, squaredDelta}, tuples); + model.Minimize(squaredDelta); - CpSolver solver = new CpSolver(); - CpSolverStatus status = solver.Solve(model); + CpSolver solver = new CpSolver(); + CpSolverStatus status = solver.Solve(model); - CpSolverResponse response = solver.Response; - Assert.Equal(1, solver.Value(boolvar)); - Assert.Equal(4, solver.Value(x)); - Assert.Equal(-1, solver.Value(delta)); - Assert.Equal(1, solver.Value(squaredDelta)); - Assert.Equal(new long[] {1, 4, -1, 1}, response.Solution); - Assert.Equal(1.0, response.ObjectiveValue, 6); - } + CpSolverResponse response = solver.Response; + Assert.Equal(1, solver.Value(boolvar)); + Assert.Equal(4, solver.Value(x)); + Assert.Equal(-1, solver.Value(delta)); + Assert.Equal(1, solver.Value(squaredDelta)); + Assert.Equal(new long[]{1, 4, -1, 1}, response.Solution); + Assert.Equal(1.0, response.ObjectiveValue, 6); + } [Fact] - public void Division() { - CpModel model = new CpModel(); - IntVar v1 = model.NewIntVar(0, 10, "v1"); - IntVar v2 = model.NewIntVar(1, 10, "v2"); - model.AddDivisionEquality(3, v1, v2); - //Console.WriteLine(model.Model); + public void Division() { + CpModel model = new CpModel(); + IntVar v1 = model.NewIntVar(0, 10, "v1"); + IntVar v2 = model.NewIntVar(1, 10, "v2"); + model.AddDivisionEquality(3, v1, v2); + // Console.WriteLine(model.Model); - CpSolver solver = new CpSolver(); - CpSolverStatus status = solver.Solve(model); - Assert.Equal(CpSolverStatus.Optimal, status); + CpSolver solver = new CpSolver(); + CpSolverStatus status = solver.Solve(model); + Assert.Equal(CpSolverStatus.Optimal, status); - CpSolverResponse response = solver.Response; - Assert.Equal(3, solver.Value(v1)); - Assert.Equal(1, solver.Value(v2)); - Assert.Equal(new long[] {3, 1, 3}, response.Solution); - Assert.Equal(0, response.ObjectiveValue); - //Console.WriteLine("response = " + reponse.ToString()); - } + CpSolverResponse response = solver.Response; + Assert.Equal(3, solver.Value(v1)); + Assert.Equal(1, solver.Value(v2)); + Assert.Equal(new long[]{3, 1, 3}, response.Solution); + Assert.Equal(0, response.ObjectiveValue); + // Console.WriteLine("response = " + reponse.ToString()); + } [Fact] - public void Modulo() { - CpModel model = new CpModel(); - IntVar v1 = model.NewIntVar(1, 10, "v1"); - IntVar v2 = model.NewIntVar(1, 10, "v2"); - model.AddModuloEquality(3, v1, v2); - //Console.WriteLine(model.Model); + public void Modulo() { + CpModel model = new CpModel(); + IntVar v1 = model.NewIntVar(1, 10, "v1"); + IntVar v2 = model.NewIntVar(1, 10, "v2"); + model.AddModuloEquality(3, v1, v2); + // Console.WriteLine(model.Model); - CpSolver solver = new CpSolver(); - CpSolverStatus status = solver.Solve(model); - Assert.Equal(CpSolverStatus.Optimal, status); + CpSolver solver = new CpSolver(); + CpSolverStatus status = solver.Solve(model); + Assert.Equal(CpSolverStatus.Optimal, status); - CpSolverResponse response = solver.Response; - Assert.Equal(3, solver.Value(v1)); - Assert.Equal(4, solver.Value(v2)); - Assert.Equal(new long[] {3, 4, 3}, response.Solution); - Assert.Equal(0, response.ObjectiveValue); - //Console.WriteLine("response = " + reponse.ToString()); - } + CpSolverResponse response = solver.Response; + Assert.Equal(3, solver.Value(v1)); + Assert.Equal(4, solver.Value(v2)); + Assert.Equal(new long[]{3, 4, 3}, response.Solution); + Assert.Equal(0, response.ObjectiveValue); + // Console.WriteLine("response = " + reponse.ToString()); + } [Fact] public void LargeScalProdLong() { @@ -350,4 +345,4 @@ namespace Google.OrTools.Tests { Console.WriteLine("Model written to file"); } } -} // namespace Google.OrTools.Tests +} // namespace Google.OrTools.Tests diff --git a/examples/tests/issue18.cs b/examples/tests/issue18.cs index 7e74f1d5bb..002ea32dd4 100644 --- a/examples/tests/issue18.cs +++ b/examples/tests/issue18.cs @@ -31,8 +31,7 @@ namespace Google.OrTools.Tests { IntExpr globalSum = solver.MakeSum(vars.ToArray()); DecisionBuilder db = solver.MakePhase( - vars.ToArray(), - Google.OrTools.ConstraintSolver.Solver.INT_VAR_SIMPLE, + vars.ToArray(), Google.OrTools.ConstraintSolver.Solver.INT_VAR_SIMPLE, Google.OrTools.ConstraintSolver.Solver.INT_VALUE_SIMPLE); solver.NewSearch(db, new OptimizeVar(solver, true, globalSum.Var(), 100)); @@ -45,7 +44,7 @@ namespace Google.OrTools.Tests { int count = 0; while (solver.NextSolution()) { count++; - //Console.WriteLine("solution " + globalSum.Var().Value()); + // Console.WriteLine("solution " + globalSum.Var().Value()); } Console.WriteLine("Solutions: " + count); } diff --git a/examples/tests/issue22.cs b/examples/tests/issue22.cs index b784dbb75c..2ca6910bfd 100644 --- a/examples/tests/issue22.cs +++ b/examples/tests/issue22.cs @@ -20,59 +20,58 @@ using Xunit; using Google.OrTools.ConstraintSolver; namespace Google.OrTools.Tests { -public class Issue22Test { - private long Solve(long num_buses_check = 0) { - ConstraintSolverParameters sPrm = Solver.DefaultSolverParameters(); - sPrm.CompressTrail = 0; - Solver solver = new Solver("OrTools",sPrm); + public class Issue22Test { + private long Solve(long num_buses_check = 0) { + ConstraintSolverParameters sPrm = Solver.DefaultSolverParameters(); + sPrm.CompressTrail = 0; + Solver solver = new Solver("OrTools", sPrm); - //this works - // IntVar[,] x = solver.MakeIntVarMatrix(2,2, new int[] {-2,0,1,2}, "x"); + // this works + // IntVar[,] x = solver.MakeIntVarMatrix(2,2, new int[] {-2,0,1,2}, "x"); - //this doesn't work - IntVar[,] x = solver.MakeIntVarMatrix(2, 2, new int[] { 0, 1, 2 }, "x"); + // this doesn't work + IntVar[, ] x = solver.MakeIntVarMatrix(2, 2, new int[]{0, 1, 2}, "x"); - for (int w = 0; w < 2; w++) { - IntVar[] b = new IntVar[2]; - for (int i = 0; i < 2; i++) { - b[i] = solver.MakeIsEqualCstVar(x[w, i], 0); - } - solver.Add(solver.MakeSumGreaterOrEqual(b, 2)); - } - - IntVar[] x_flat = x.Flatten(); - DecisionBuilder db = solver.MakePhase( - x_flat, - Solver.CHOOSE_FIRST_UNBOUND, - Solver.ASSIGN_MIN_VALUE); - solver.NewSearch(db); - while (solver.NextSolution()) { - Console.WriteLine("x: "); - for (int j = 0; j < 2; j++) { - Console.Write("worker" + (j + 1).ToString() + ":"); + for (int w = 0; w < 2; w++) { + IntVar[] b = new IntVar[2]; for (int i = 0; i < 2; i++) { - Console.Write(" {0,2} ", x[j, i].Value()); + b[i] = solver.MakeIsEqualCstVar(x[w, i], 0); } - Console.Write("\n"); + solver.Add(solver.MakeSumGreaterOrEqual(b, 2)); } - Console.WriteLine("End at---->" + DateTime.Now); + + IntVar[] x_flat = x.Flatten(); + DecisionBuilder db = solver.MakePhase(x_flat, Solver.CHOOSE_FIRST_UNBOUND, + Solver.ASSIGN_MIN_VALUE); + solver.NewSearch(db); + while (solver.NextSolution()) { + Console.WriteLine("x: "); + for (int j = 0; j < 2; j++) { + Console.Write("worker" + (j + 1).ToString() + ":"); + for (int i = 0; i < 2; i++) { + Console.Write(" {0,2} ", x [j, i] + .Value()); + } + Console.Write("\n"); + } + Console.WriteLine("End at---->" + DateTime.Now); + } + + Console.WriteLine("\nSolutions: {0}", solver.Solutions()); + Console.WriteLine("WallTime: {0}ms", solver.WallTime()); + Console.WriteLine("Failures: {0}", solver.Failures()); + Console.WriteLine("Branches: {0} ", solver.Branches()); + + solver.EndSearch(); + return 1; } - Console.WriteLine("\nSolutions: {0}", solver.Solutions()); - Console.WriteLine("WallTime: {0}ms", solver.WallTime()); - Console.WriteLine("Failures: {0}", solver.Failures()); - Console.WriteLine("Branches: {0} ", solver.Branches()); - - solver.EndSearch(); - return 1; + [Fact] + public void InitialPropagateTest() { + Console.WriteLine("Check for minimum number of buses: "); + long num_buses = Solve(); + Console.WriteLine("\n... got {0} as minimal value.", num_buses); + Console.WriteLine("\nAll solutions: ", num_buses); + } } - - [Fact] - public void InitialPropagateTest() { - Console.WriteLine("Check for minimum number of buses: "); - long num_buses = Solve(); - Console.WriteLine("\n... got {0} as minimal value.", num_buses); - Console.WriteLine("\nAll solutions: ", num_buses); - } -} } // namespace Google.OrTools.Tests diff --git a/examples/tests/issue33.cs b/examples/tests/issue33.cs index 91545bb930..780d46c934 100644 --- a/examples/tests/issue33.cs +++ b/examples/tests/issue33.cs @@ -24,14 +24,29 @@ using Xunit; namespace Google.OrTools.Test { public class Task { - public int Id { get; private set; } - public int TaskType { get; private set; } - public int LocationId { get; private set; } - public Dictionary Durations { get; private set; } - public int TaskPosition { get; private set; } + public int Id { + get; + private set; + } + public int TaskType { + get; + private set; + } + public int LocationId { + get; + private set; + } + public Dictionary Durations { + get; + private set; + } + public int TaskPosition { + get; + private set; + } public Task(int id, int taskType, int locationIndex, int taskPosition, - Dictionary durations) { + Dictionary durations) { Id = id; TaskType = taskType; LocationId = locationIndex; @@ -44,29 +59,50 @@ namespace Google.OrTools.Test { TaskType = taskType; LocationId = locationIndex; TaskPosition = taskPosition; - Durations = new Dictionary(); + Durations = new Dictionary(); } } public class WorkLocation { - public int Id { get; private set; } + public int Id { + get; + private set; + } public int NbTasks { - get { Debug.Assert(Tasks != null); return Tasks.Length; } - set { Debug.Assert(Tasks == null); Tasks = new Task[value]; } + get { + Debug.Assert(Tasks != null); + return Tasks.Length; + } + set { + Debug.Assert(Tasks == null); + Tasks = new Task[value]; + } + } + public Task[] Tasks { + get; + private set; } - public Task[] Tasks { get; private set; } - public WorkLocation(int index) - { - Id = index; - } + public WorkLocation(int index) { Id = index; } } public class Tool { - public int Id { get; private set; } - public HashSet TaskTypes { get; set; } - public int[,] TravellingTime { get; set; } - public int InitialLocationId { get; set; } + public int Id { + get; + private set; + } + public HashSet TaskTypes { + get; + set; + } + public int[, ] TravellingTime { + get; + set; + } + public int InitialLocationId { + get; + set; + } public Tool(int index, int initialLocation = 0) { Id = index; @@ -74,9 +110,7 @@ namespace Google.OrTools.Test { TaskTypes = new HashSet(); } - public void AddTaskType(int t) { - TaskTypes.Add(t); - } + public void AddTaskType(int t) { TaskTypes.Add(t); } public bool CanPerformTaskType(int taskType) { return TaskTypes.Contains(taskType); @@ -84,24 +118,46 @@ namespace Google.OrTools.Test { } public class FactoryDescription { - public Tool[] Tools { get; private set; } - public WorkLocation[] Locations { get; private set; } + public Tool[] Tools { + get; + private set; + } + public WorkLocation[] Locations { + get; + private set; + } - public int NbWorkLocations { get { return Locations.Length; } } - public int NbTools { get { return Tools.Length; } } + public int NbWorkLocations { + get { return Locations.Length; } + } + public int NbTools { + get { return Tools.Length; } + } - public int NbTaskPerCycle { get; private set; } + public int NbTaskPerCycle { + get; + private set; + } // TaskType go typically from 0 to 6. InspectionType indicates which // is the TaskType that correspond to Inspection. - public int Inspection { get; private set; } + public int Inspection { + get; + private set; + } // All the time within the schedule horizon in which the blast can start. - public long[] InspectionStarts { get; private set; } + public long[] InspectionStarts { + get; + private set; + } - public int Horizon { get; private set; } + public int Horizon { + get; + private set; + } // horizon equal to 2 weeks (in minutes). public FactoryDescription(int nbTools, int nbLocations, int nbTaskPerCycle, - int horizon = 14*24*60) { + int horizon = 14 * 24 * 60) { Debug.Assert(nbTools > 0); Debug.Assert(nbLocations > 0); Debug.Assert(nbTaskPerCycle > 0); @@ -110,36 +166,32 @@ namespace Google.OrTools.Test { Inspection = NbTaskPerCycle - 1; Tools = new Tool[nbTools]; Horizon = horizon; - for (int i = 0; i < nbTools; i++) - Tools[i] = new Tool(i); + for (int i = 0; i < nbTools; i++) Tools[i] = new Tool(i); Locations = new WorkLocation[nbLocations]; - for (int i = 0; i < nbLocations; i++) - Locations[i] = new WorkLocation(i); + for (int i = 0; i < nbLocations; i++) Locations[i] = new WorkLocation(i); - InspectionStarts = new long[] { -1, 600, 1200, 1800, 2400, 2800 }; + InspectionStarts = new long[]{-1, 600, 1200, 1800, 2400, 2800}; } public Tool[] getToolPerTaskType(int taskType) { - var elements = from tool in Tools - where tool.CanPerformTaskType(taskType) - select tool; + var elements = from tool in Tools where tool.CanPerformTaskType(taskType) + select tool; return elements.ToArray(); } public Task[] getFlatTaskList() { - return (from location in Locations - from task in location.Tasks - orderby task.Id - select task).ToArray(); + return (from location in Locations from task in + location.Tasks orderby task.Id select task) + .ToArray(); } public int[] getTaskTypes() { - return (from location in Locations - from task in location.Tasks - select task.TaskType).Distinct().ToArray(); + return (from location in Locations from task in location.Tasks select + task.TaskType) + .Distinct() + .ToArray(); } - // TODO: This should be enhanced public void SanityCheck() { foreach (Tool tool in Tools) { @@ -156,7 +208,6 @@ namespace Google.OrTools.Test { } public class SmallSyntheticData : DataReader { - public SmallSyntheticData() {} public FactoryDescription FetchData() { @@ -168,8 +219,8 @@ namespace Google.OrTools.Test { // Travelling time and distance are temporarily identical and they // are no different for different tools - int[,] travellingTime = new int[factoryDescription.NbWorkLocations, - factoryDescription.NbWorkLocations]; + int[, ] travellingTime = new int[factoryDescription.NbWorkLocations, + factoryDescription.NbWorkLocations]; for (int i = 0; i < travellingTime.GetLength(0); i++) { for (int j = 0; j < travellingTime.GetLength(1); j++) { if (i == j) @@ -179,12 +230,24 @@ namespace Google.OrTools.Test { } } - factoryDescription.Tools[0].AddTaskType(0); - factoryDescription.Tools[1].AddTaskType(0); - factoryDescription.Tools[2].AddTaskType(1); - factoryDescription.Tools[3].AddTaskType(1); - factoryDescription.Tools[4].AddTaskType(2); - factoryDescription.Tools[1].AddTaskType(1); + factoryDescription + .Tools [0] + .AddTaskType(0); + factoryDescription + .Tools [1] + .AddTaskType(0); + factoryDescription + .Tools [2] + .AddTaskType(1); + factoryDescription + .Tools [3] + .AddTaskType(1); + factoryDescription + .Tools [4] + .AddTaskType(2); + factoryDescription + .Tools [1] + .AddTaskType(1); foreach (Tool tool in factoryDescription.Tools) tool.TravellingTime = travellingTime; @@ -194,15 +257,17 @@ namespace Google.OrTools.Test { int[] boll = new int[100]; for (int i = 0; i < factoryDescription.NbWorkLocations; i++) { factoryDescription.Locations[i].NbTasks = - nbCyclePerWorkLocation * factoryDescription.NbTaskPerCycle; + nbCyclePerWorkLocation * factoryDescription.NbTaskPerCycle; for (int j = 0; j < nbCyclePerWorkLocation; j++) { for (int k = 0; k < factoryDescription.NbTaskPerCycle; k++) { - Task t = new Task(c, k, i, k + j * factoryDescription.NbTaskPerCycle); + Task t = + new Task(c, k, i, k + j * factoryDescription.NbTaskPerCycle); // Filling in tool-dependent durations Tool[] compatibleTools = factoryDescription.getToolPerTaskType(k); foreach (Tool tool in compatibleTools) { - boll[c] = randomDuration.Next(13, 17) * 10; ; + boll[c] = randomDuration.Next(13, 17) * 10; + ; t.Durations[tool.Id] = boll[c]; } factoryDescription.Locations[i].Tasks[t.TaskPosition] = t; @@ -217,12 +282,11 @@ namespace Google.OrTools.Test { } public class RandomSelectToolHeuristic : NetDecisionBuilder { - private FactoryScheduling factoryScheduling; private Random rnd; public RandomSelectToolHeuristic(FactoryScheduling factoryScheduling, - int seed) { + int seed) { this.factoryScheduling = factoryScheduling; // deterministic seed for result reproducibility this.rnd = new Random(seed); @@ -234,8 +298,7 @@ namespace Google.OrTools.Test { int min = (int) var.Min(); int max = (int) var.Max(); int rndVal = rnd.Next(min, max + 1); - while (!var.Contains(rndVal)) - rndVal = rnd.Next(min, max + 1); + while (!var.Contains(rndVal)) rndVal = rnd.Next(min, max + 1); return solver.MakeAssignVariableValue(var, rndVal); } } @@ -244,9 +307,18 @@ namespace Google.OrTools.Test { } class TaskAlternative { - public Task Task { get; private set; } - public IntVar ToolVar { get; set; } - public List Intervals { get; private set; } + public Task Task { + get; + private set; + } + public IntVar ToolVar { + get; + set; + } + public List Intervals { + get; + private set; + } public TaskAlternative(Task t) { Task = t; @@ -290,12 +362,15 @@ namespace Google.OrTools.Test { /* For each task which tools is performed upon */ private List selectedTool; - public List SelectedTool { get { return selectedTool; } } + public List SelectedTool { + get { return selectedTool; } + } /* Sequence of task for each tool */ private SequenceVar[] allToolSequences; - public SequenceVar[] AllToolSequences { get { return allToolSequences; } } - + public SequenceVar[] AllToolSequences { + get { return allToolSequences; } + } /* Makespan var */ private IntVar makespan; @@ -310,10 +385,7 @@ namespace Google.OrTools.Test { IntVar[][] startingTimes; IntVar[][] endTimes; - - public FactoryScheduling(FactoryDescription data) { - factoryData = data; - } + public FactoryScheduling(FactoryDescription data) { factoryData = data; } private void Init() { horizon = factoryData.Horizon; @@ -321,21 +393,24 @@ namespace Google.OrTools.Test { tasks = factoryData.getFlatTaskList(); taskTypes = factoryData.getTaskTypes(); taskStructures = new TaskAlternative[tasks.Length]; - location2Task = new TaskAlternative[factoryData.NbWorkLocations][]; - tool2Task = new List[factoryData.NbTools]; - toolIntervalVar2TaskId = new List[factoryData.NbTools]; - tool2TransitionTimes = new List[factoryData.NbTools]; + location2Task = new TaskAlternative [factoryData.NbWorkLocations] + []; + tool2Task = new List[ factoryData.NbTools ]; + toolIntervalVar2TaskId = new List[ factoryData.NbTools ]; + tool2TransitionTimes = new List[ factoryData.NbTools ]; - taskType2Tool = new List[taskTypes.Length]; + taskType2Tool = new List[ taskTypes.Length ]; selectedTool = new List(); for (int tt = 0; tt < taskTypes.Length; tt++) taskType2Tool[tt] = new List(); foreach (Tool tool in factoryData.Tools) foreach (int taskType in tool.TaskTypes) - taskType2Tool[taskType].Add(tool); + taskType2Tool [taskType] + .Add(tool); for (int d = 0; d < factoryData.NbWorkLocations; d++) - location2Task[d] = new TaskAlternative[factoryData.Locations[d].NbTasks]; + location2Task[d] = + new TaskAlternative[factoryData.Locations[d].NbTasks]; for (int t = 0; t < factoryData.NbTools; t++) { tool2Task[t] = new List(); toolIntervalVar2TaskId[t] = new List(); @@ -344,20 +419,21 @@ namespace Google.OrTools.Test { allToolSequences = new SequenceVar[factoryData.NbTools - 1]; - startingTimes = new IntVar[factoryData.NbTools - 1][]; - endTimes = new IntVar[factoryData.NbTools - 1][]; - - + startingTimes = new IntVar [factoryData.NbTools - 1] + []; + endTimes = new IntVar [factoryData.NbTools - 1] + []; } private void PostTransitionTimeConstraints( int t, bool postTransitionsConstraint = true) { Tool tool = factoryData.Tools[t]; - //if it is a inspection, we make sure there are no transitiontimes + // if it is a inspection, we make sure there are no transitiontimes if (tool.CanPerformTaskType(factoryData.Inspection)) - tool2TransitionTimes[t].Add(null); + tool2TransitionTimes [t] + .Add(null); else { - int[,] tt = tool.TravellingTime; + int[, ] tt = tool.TravellingTime; SequenceVar seq = allToolSequences[t]; long s = seq.Size(); @@ -382,43 +458,55 @@ namespace Google.OrTools.Test { int[] taskIndex2locationId = new int[s + 2]; taskIndex2locationId[0] = -10; for (int i = 0; i < s; i++) - taskIndex2locationId[i+1] = - tasks[toolIntervalVar2TaskId[t][i]].LocationId; + taskIndex2locationId[i + 1] = tasks [toolIntervalVar2TaskId [t] + [i] + ] + .LocationId; // this is the virtual location for unperformed tasks taskIndex2locationId[s + 1] = factoryData.NbWorkLocations; // Build the travelling time matrix with the additional virtual location int[][] ttWithVirtualLocation = - new int[factoryData.NbWorkLocations + 1][]; + new int [factoryData.NbWorkLocations + 1] + []; for (int d1 = 0; d1 < ttWithVirtualLocation.Length; d1++) { ttWithVirtualLocation[d1] = new int[factoryData.NbWorkLocations + 1]; for (int d2 = 0; d2 < ttWithVirtualLocation.Length; d2++) if (d1 == factoryData.NbWorkLocations) { - ttWithVirtualLocation[d1][d2] = 0; + ttWithVirtualLocation [d1] + [d2] = 0; } else { - ttWithVirtualLocation[d1][d2] = - (d2 == factoryData.NbWorkLocations) ? 0 : tt[d1, d2]; + ttWithVirtualLocation [d1] + [d2] = (d2 == factoryData.NbWorkLocations) ? 0 : tt[d1, d2]; } } for (int i = 0; i < nextLocation.Length; i++) { // this is the next-location associated with the i-th task nextLocation[i] = - solver.MakeElement(taskIndex2locationId, seq.Next(i )).Var(); + solver.MakeElement(taskIndex2locationId, seq.Next(i)).Var(); int d = (i == 0) ? tool.InitialLocationId - : tasks[toolIntervalVar2TaskId[t][i - 1]].LocationId; + : tasks [toolIntervalVar2TaskId [t] + [i - 1] + ] + .LocationId; if (i == 0) { // To be changed - right now we don't have meaningful indata // of previous location Ugly way of setting initial travel // time to = 0, as this is how we find common grounds // between benchmark algorithm and this - tool2TransitionTimes[t].Add(solver.MakeElement( - new int[ttWithVirtualLocation[d].Length], nextLocation[i]).Var()); + tool2TransitionTimes [t] + .Add(solver + .MakeElement(new int[ttWithVirtualLocation[d].Length], + nextLocation[i]) + .Var()); } else { - tool2TransitionTimes[t].Add(solver.MakeElement( - ttWithVirtualLocation[d], nextLocation[i]).Var()); + tool2TransitionTimes [t] + .Add(solver + .MakeElement(ttWithVirtualLocation[d], nextLocation[i]) + .Var()); } } @@ -427,26 +515,41 @@ namespace Google.OrTools.Test { startingTimes[t] = new IntVar[s + 2]; endTimes[t] = new IntVar[s + 2]; - startingTimes[t][0] = solver.MakeIntConst(0); + startingTimes [t] + [0] = solver.MakeIntConst(0); // Tbd: Set this endtime to the estimated time of finishing // previous task for the current tool - endTimes[t][0] = solver.MakeIntConst(0); + endTimes [t] + [0] = solver.MakeIntConst(0); for (int i = 0; i < s; i++) { - startingTimes[t][i + 1] = tool2Task[t][i].SafeStartExpr(-1).Var(); - endTimes[t][i + 1] = tool2Task[t][i].SafeEndExpr(-1).Var(); + startingTimes [t] + [i + 1] = tool2Task [t] + [i] + .SafeStartExpr(-1) + .Var(); + endTimes [t] + [i + 1] = tool2Task [t] + [i] + .SafeEndExpr(-1) + .Var(); } - startingTimes[t][s + 1] = solver.MakeIntConst(factoryData.Horizon); - endTimes[t][s + 1] = solver.MakeIntConst(factoryData.Horizon); - + startingTimes [t] + [s + 1] = solver.MakeIntConst(factoryData.Horizon); + endTimes [t] + [s + 1] = solver.MakeIntConst(factoryData.Horizon); // Enforce (or not) that each task is separated by the // transition time to the next task for (int i = 0; i < nextLocation.Length; i++) { IntVar nextStart = - solver.MakeElement(startingTimes[t], seq.Next(i).Var()).Var(); - if(postTransitionsConstraint) - solver.Add(endTimes[t][i] + tool2TransitionTimes[t][i] <= nextStart); + solver.MakeElement(startingTimes[t], seq.Next(i).Var()).Var(); + if (postTransitionsConstraint) + solver.Add(endTimes [t] + [i] + + tool2TransitionTimes [t] + [i] <= + nextStart); } } } @@ -454,14 +557,13 @@ namespace Google.OrTools.Test { private void Model() { /* Building basic task data structures */ for (int i = 0; i < tasks.Length; i++) { - /* Create a new set of possible IntervalVars & IntVar to decide * which one (and only 1) is performed */ taskStructures[i] = new TaskAlternative(tasks[i]); /* Container to use when posting constraints */ location2Task[tasks[i].LocationId][tasks[i].TaskPosition] = - taskStructures[i]; + taskStructures[i]; /* Get task type */ int taskType = tasks[i].TaskType; @@ -497,8 +599,10 @@ namespace Google.OrTools.Test { } taskStructures[i].Intervals.Add(intervalVar); - tool2Task[toolId].Add(intervalVar); - toolIntervalVar2TaskId[toolId].Add(i); + tool2Task [toolId] + .Add(intervalVar); + toolIntervalVar2TaskId [toolId] + .Add(i); /* Collecting all the bool vars, even if they are optional */ performedOnTool.Add(intervalVar.PerformedExpr().Var()); @@ -508,13 +612,13 @@ namespace Google.OrTools.Test { /* if alternativeToolVar == t <=> performedOnTool[t] == true */ string alternativeName = "J " + tasks[i].Id; IntVar alternativeToolVar = - solver.MakeIntVar(0, tools.Count - 1, alternativeName); + solver.MakeIntVar(0, tools.Count - 1, alternativeName); taskStructures[i].ToolVar = alternativeToolVar; - solver.Add( - solver.MakeMapDomain(alternativeToolVar, performedOnTool.ToArray())); - Debug.Assert( - performedOnTool.ToArray().Length == alternativeToolVar.Max()+1); + solver.Add(solver.MakeMapDomain(alternativeToolVar, + performedOnTool.ToArray())); + Debug.Assert(performedOnTool.ToArray().Length == + alternativeToolVar.Max() + 1); selectedTool.Add(alternativeToolVar); } @@ -524,13 +628,15 @@ namespace Google.OrTools.Test { */ for (int d = 0; d < location2Task.Length; d++) { for (int i = 0; i < location2Task[d].Length - 1; i++) { - TaskAlternative task1 = location2Task[d][i]; - TaskAlternative task2 = location2Task[d][i + 1]; + TaskAlternative task1 = location2Task [d] + [i]; + TaskAlternative task2 = location2Task [d] + [i + 1]; /* task1 must end before task2 starts */ /* Adding precedence for each possible alternative pair */ for (int t1 = 0; t1 < task1.Intervals.Count(); t1++) { IntervalVar task1Alternative = task1.Intervals[t1]; - for (int t2 = 0; t2 < task2.Intervals.Count(); t2++){ + for (int t2 = 0; t2 < task2.Intervals.Count(); t2++) { IntervalVar task2Alternative = task2.Intervals[t2]; Constraint precedence = solver.MakeIntervalVarRelation( task2Alternative, Solver.STARTS_AFTER_END, task1Alternative); @@ -545,38 +651,40 @@ namespace Google.OrTools.Test { for (int t = 0; t < factoryData.NbTools; t++) { string name = "Tool " + t; - if (!factoryData.Tools[t].CanPerformTaskType(factoryData.Inspection)) { + if (!factoryData + .Tools [t] + .CanPerformTaskType(factoryData.Inspection)) { DisjunctiveConstraint ct = - solver.MakeDisjunctiveConstraint(tool2Task[t].ToArray(), name); + solver.MakeDisjunctiveConstraint(tool2Task [t] + .ToArray(), + name); solver.Add(ct); allToolSequences[t] = ct.SequenceVar(); } PostTransitionTimeConstraints(t, true); } - /* Collecting all tasks end for makespan objective function */ List intervalEnds = new List(); for (int i = 0; i < tasks.Length; i++) foreach (IntervalVar var in taskStructures[i].Intervals) intervalEnds.Add(var.SafeEndExpr(-1).Var()); - /* Objective: minimize the makespan (maximum end times of all tasks) */ makespan = solver.MakeMax(intervalEnds.ToArray()).Var(); objective = solver.MakeMinimize(makespan, 1); } - private void Search(){ - int seed = 2; //This is a good seed to show the crash + private void Search() { + int seed = 2; // This is a good seed to show the crash /* Assigning first tools */ DecisionBuilder myToolAssignmentPhase = - new RandomSelectToolHeuristic(this, seed); + new RandomSelectToolHeuristic(this, seed); /* Ranking of the tools */ DecisionBuilder sequencingPhase = - solver.MakePhase(allToolSequences, Solver.SEQUENCE_DEFAULT); + solver.MakePhase(allToolSequences, Solver.SEQUENCE_DEFAULT); /* Then fixing time of tasks as early as possible */ DecisionBuilder timingPhase = solver.MakePhase( @@ -584,7 +692,7 @@ namespace Google.OrTools.Test { /* Overall phase */ DecisionBuilder mainPhase = - solver.Compose(myToolAssignmentPhase, sequencingPhase, timingPhase); + solver.Compose(myToolAssignmentPhase, sequencingPhase, timingPhase); /* Logging */ const int logFrequency = 1000000; @@ -594,15 +702,15 @@ namespace Google.OrTools.Test { SearchMonitor searchRestart = solver.MakeLubyRestart(100); /* Search Limit in ms */ - SearchLimit limit = solver.MakeTimeLimit(180*1000); + SearchLimit limit = solver.MakeTimeLimit(180 * 1000); /* Collecting best solution */ SolutionCollector collector = solver.MakeLastSolutionCollector(); collector.AddObjective(makespan); - //collector.Add( pile.ToArray() ); + // collector.Add( pile.ToArray() ); solver.NewSearch(mainPhase, searchLog, searchRestart, objective, limit); - while (solver.NextSolution()){ + while (solver.NextSolution()) { Console.WriteLine("MAKESPAN: " + makespan.Value()); } } @@ -618,7 +726,7 @@ namespace Google.OrTools.Test { [Fact] public void FactorySchedulingTest() { FactoryScheduling scheduling = - new FactoryScheduling(new SmallSyntheticData().FetchData()); + new FactoryScheduling(new SmallSyntheticData().FetchData()); scheduling.Solve(); } } diff --git a/ortools/algorithms/samples/Knapsack.cs b/ortools/algorithms/samples/Knapsack.cs index 9422119efe..d7aa3b09be 100644 --- a/ortools/algorithms/samples/Knapsack.cs +++ b/ortools/algorithms/samples/Knapsack.cs @@ -17,32 +17,28 @@ using System; using Google.OrTools.Algorithms; // [END import] -public class Knapsack -{ - static void Main() - { +public class Knapsack { + static void Main() { // [START solver] - KnapsackSolver solver = new KnapsackSolver( - KnapsackSolver.SolverType.KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER, - "KnapsackExample"); + KnapsackSolver solver = + new KnapsackSolver(KnapsackSolver.SolverType + .KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER, + "KnapsackExample"); // [END solver] // [START data] - long[] values = { 360, 83, 59, 130, 431, 67, 230, 52, 93, - 125, 670, 892, 600, 38, 48, 147, 78, 256, - 63, 17, 120, 164, 432, 35, 92, 110, 22, - 42, 50, 323, 514, 28, 87, 73, 78, 15, - 26, 78, 210, 36, 85, 189, 274, 43, 33, - 10, 19, 389, 276, 312 }; + long[] values = {360, 83, 59, 130, 431, 67, 230, 52, 93, 125, + 670, 892, 600, 38, 48, 147, 78, 256, 63, 17, + 120, 164, 432, 35, 92, 110, 22, 42, 50, 323, + 514, 28, 87, 73, 78, 15, 26, 78, 210, 36, + 85, 189, 274, 43, 33, 10, 19, 389, 276, 312}; - long[,] weights = { { 7, 0, 30, 22, 80, 94, 11, 81, 70, - 64, 59, 18, 0, 36, 3, 8, 15, 42, - 9, 0, 42, 47, 52, 32, 26, 48, 55, - 6, 29, 84, 2, 4, 18, 56, 7, 29, - 93, 44, 71, 3, 86, 66, 31, 65, 0, - 79, 20, 65, 52, 13 } }; + long[, ] weights = {{7, 0, 30, 22, 80, 94, 11, 81, 70, 64, 59, 18, 0, + 36, 3, 8, 15, 42, 9, 0, 42, 47, 52, 32, 26, 48, + 55, 6, 29, 84, 2, 4, 18, 56, 7, 29, 93, 44, 71, + 3, 86, 66, 31, 65, 0, 79, 20, 65, 52, 13}}; - long[] capacities = { 850 }; + long[] capacities = {850}; // [END data] // [START solve] diff --git a/ortools/constraint_solver/csharp/IntArrayHelper.cs b/ortools/constraint_solver/csharp/IntArrayHelper.cs index 4cf047409a..f542ae5594 100644 --- a/ortools/constraint_solver/csharp/IntArrayHelper.cs +++ b/ortools/constraint_solver/csharp/IntArrayHelper.cs @@ -12,17 +12,17 @@ // limitations under the License. namespace Google.OrTools.ConstraintSolver { -using System; -using System.Collections.Generic; + using System; + using System.Collections.Generic; -// int[] and long[] helper class. -public static class IntArrayHelper { - public static IntExpr Element(this int[] array, IntExpr index) { - return index.solver().MakeElement(array, index.Var()); + // int[] and long[] helper class. + public static class IntArrayHelper { + public static IntExpr Element(this int[] array, IntExpr index) { + return index.solver().MakeElement(array, index.Var()); + } + public static IntExpr Element(this long[] array, IntExpr index) { + return index.solver().MakeElement(array, index.Var()); + } } - public static IntExpr Element(this long[] array, IntExpr index) { - return index.solver().MakeElement(array, index.Var()); - } -} } // namespace Google.OrTools.ConstraintSolver diff --git a/ortools/constraint_solver/csharp/IntVarArrayHelper.cs b/ortools/constraint_solver/csharp/IntVarArrayHelper.cs index ee0969e751..b8d7bbd2d2 100644 --- a/ortools/constraint_solver/csharp/IntVarArrayHelper.cs +++ b/ortools/constraint_solver/csharp/IntVarArrayHelper.cs @@ -11,360 +11,362 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Google.OrTools.ConstraintSolver -{ -using System; -using System.Collections.Generic; +namespace Google.OrTools.ConstraintSolver { + using System; + using System.Collections.Generic; -// IntVar[] helper class. -public static class IntVarArrayHelper -{ - // All Different - public static Constraint AllDifferent(this IntVar[] vars) - { - Solver solver = GetSolver(vars); - return solver.MakeAllDifferent(vars); - } - // Allowed assignment - public static Constraint AllowedAssignments(this IntVar[] vars, - IntTupleSet tuples) - { - Solver solver = GetSolver(vars); - return solver.MakeAllowedAssignments(vars, tuples); - } - // sum of all vars. - public static IntExpr Sum(this IntVar[] vars) - { - Solver solver = GetSolver(vars); - return solver.MakeSum(vars); - } - // sum of all constraints. - public static IntExpr Sum(this IConstraintWithStatus[] cts) - { - Solver solver = GetSolver(cts); - IntVar[] vars = new IntVar[cts.Length]; - for (int i = 0; i < cts.Length; ++i) - { - vars[i] = cts[i].Var(); + // IntVar[] helper class. + public static class IntVarArrayHelper { + // All Different + public static Constraint AllDifferent(this IntVar[] vars) { + Solver solver = GetSolver(vars); + return solver.MakeAllDifferent(vars); } - return solver.MakeSum(vars); - } - public static IntExpr Sum(this IntExpr[] exprs) - { - Solver solver = GetSolver(exprs); - IntVar[] vars = new IntVar[exprs.Length]; - for (int i = 0; i < exprs.Length; ++i) - { - vars[i] = exprs[i].Var(); + // Allowed assignment + public static Constraint AllowedAssignments(this IntVar[] vars, + IntTupleSet tuples) { + Solver solver = GetSolver(vars); + return solver.MakeAllowedAssignments(vars, tuples); } - return solver.MakeSum(vars); - } - - // scalar product - public static IntExpr ScalProd(this IntVar[] vars, long[] coefs) - { - Solver solver = GetSolver(vars); - return solver.MakeScalProd(vars, coefs); - } - - // scalar product - public static IntExpr ScalProd(this IntVar[] vars, int[] coefs) - { - Solver solver = GetSolver(vars); - return solver.MakeScalProd(vars, coefs); - } - - // get solver from array of integer variables - private static Solver GetSolver(IntVar[] vars) - { - if (vars == null || vars.Length <= 0) - throw new ArgumentException("Array cannot be null or empty"); - - return vars[0].solver(); - } - // get solver from array of integer expressions - private static Solver GetSolver(IntExpr[] expressions) - { - if (expressions == null || expressions.Length <= 0) - throw new ArgumentException("Array cannot be null or empty"); - - return expressions[0].solver(); - } - private static Solver GetSolver(IConstraintWithStatus[] cts) - { - if (cts == null || cts.Length <= 0) - throw new ArgumentException("Array cannot be null or empty"); - - return cts[0].solver(); - } - public static IntExpr Element(this IntVar[] array, IntExpr index) { - return index.solver().MakeElement(array, index.Var()); - } - // min of all vars. - public static IntExpr Min(this IntVar[] vars) - { - Solver solver = GetSolver(vars); - return solver.MakeMin(vars); - } - // min of all vars. - public static IntExpr Max(this IntVar[] vars) - { - Solver solver = GetSolver(vars); - return solver.MakeMax(vars); - } - // count of all vars. - public static Constraint Count(this IntVar[] vars, long value, long count) - { - Solver solver = GetSolver(vars); - return solver.MakeCount(vars, value, count); - } - // count of all vars. - public static Constraint Count(this IntVar[] vars, - long value, - IntExpr count) - { - Solver solver = GetSolver(vars); - return solver.MakeCount(vars, value, count.Var()); - } - public static Constraint Distribute(this IntVar[] vars, - long[] values, - IntVar[] cards) - { - Solver solver = GetSolver(vars); - return solver.MakeDistribute(vars, values, cards); - } - public static Constraint Distribute(this IntVar[] vars, - int[] values, - IntVar[] cards) - { - Solver solver = GetSolver(vars); - return solver.MakeDistribute(vars, values, cards); - } - public static Constraint Distribute(this IntVar[] vars, - IntVar[] cards) - { - Solver solver = GetSolver(vars); - return solver.MakeDistribute(vars, cards); - } - public static Constraint Distribute(this IntVar[] vars, - long card_min, - long card_max, - long card_size) - { - Solver solver = GetSolver(vars); - return solver.MakeDistribute(vars, card_min, card_max, card_size); - } - public static Constraint Transition(this IntVar[] vars, - IntTupleSet transitions, - long initial_state, - long[] final_states) { - Solver solver = GetSolver(vars); - return solver.MakeTransitionConstraint(vars, - transitions, - initial_state, - final_states); - } - public static Constraint Transition(this IntVar[] vars, - IntTupleSet transitions, - long initial_state, - int[] final_states) { - Solver solver = GetSolver(vars); - return solver.MakeTransitionConstraint(vars, - transitions, - initial_state, - final_states); - } - - // Matrix API - public static IntVar[] Flatten(this IntVar[,] vars) - { - int rows = vars.GetLength(0); - int cols = vars.GetLength(1); - IntVar[] flat = new IntVar[cols * rows]; - for(int i = 0; i < rows; i++) { - for(int j = 0; j < cols; j++) { - flat[i * cols + j] = vars[i, j]; + // sum of all vars. + public static IntExpr Sum(this IntVar[] vars) { + Solver solver = GetSolver(vars); + return solver.MakeSum(vars); + } + // sum of all constraints. + public static IntExpr Sum(this IConstraintWithStatus[] cts) { + Solver solver = GetSolver(cts); + IntVar[] vars = new IntVar[cts.Length]; + for (int i = 0; i < cts.Length; ++i) { + vars[i] = cts [i] + .Var(); } + return solver.MakeSum(vars); + } + public static IntExpr Sum(this IntExpr[] exprs) { + Solver solver = GetSolver(exprs); + IntVar[] vars = new IntVar[exprs.Length]; + for (int i = 0; i < exprs.Length; ++i) { + vars[i] = exprs [i] + .Var(); + } + return solver.MakeSum(vars); + } + + // scalar product + public static IntExpr ScalProd(this IntVar[] vars, long[] coefs) { + Solver solver = GetSolver(vars); + return solver.MakeScalProd(vars, coefs); + } + + // scalar product + public static IntExpr ScalProd(this IntVar[] vars, int[] coefs) { + Solver solver = GetSolver(vars); + return solver.MakeScalProd(vars, coefs); + } + + // get solver from array of integer variables + private static Solver GetSolver(IntVar[] vars) { + if (vars == null || vars.Length <= 0) + throw new ArgumentException("Array cannot be null or empty"); + + return vars [0] + .solver(); + } + // get solver from array of integer expressions + private static Solver GetSolver(IntExpr[] expressions) { + if (expressions == null || expressions.Length <= 0) + throw new ArgumentException("Array cannot be null or empty"); + + return expressions [0] + .solver(); + } + private static Solver GetSolver(IConstraintWithStatus[] cts) { + if (cts == null || cts.Length <= 0) + throw new ArgumentException("Array cannot be null or empty"); + + return cts [0] + .solver(); + } + public static IntExpr Element(this IntVar[] array, IntExpr index) { + return index.solver().MakeElement(array, index.Var()); + } + // min of all vars. + public static IntExpr Min(this IntVar[] vars) { + Solver solver = GetSolver(vars); + return solver.MakeMin(vars); + } + // min of all vars. + public static IntExpr Max(this IntVar[] vars) { + Solver solver = GetSolver(vars); + return solver.MakeMax(vars); + } + // count of all vars. + public static Constraint Count(this IntVar[] vars, long value, long count) { + Solver solver = GetSolver(vars); + return solver.MakeCount(vars, value, count); + } + // count of all vars. + public static Constraint Count(this IntVar[] vars, long value, + IntExpr count) { + Solver solver = GetSolver(vars); + return solver.MakeCount(vars, value, count.Var()); + } + public static Constraint Distribute(this IntVar[] vars, long[] values, + IntVar[] cards) { + Solver solver = GetSolver(vars); + return solver.MakeDistribute(vars, values, cards); + } + public static Constraint Distribute(this IntVar[] vars, int[] values, + IntVar[] cards) { + Solver solver = GetSolver(vars); + return solver.MakeDistribute(vars, values, cards); + } + public static Constraint Distribute(this IntVar[] vars, IntVar[] cards) { + Solver solver = GetSolver(vars); + return solver.MakeDistribute(vars, cards); + } + public static Constraint Distribute(this IntVar[] vars, long card_min, + long card_max, long card_size) { + Solver solver = GetSolver(vars); + return solver.MakeDistribute(vars, card_min, card_max, card_size); + } + public static Constraint Transition(this IntVar[] vars, + IntTupleSet transitions, + long initial_state, + long[] final_states) { + Solver solver = GetSolver(vars); + return solver.MakeTransitionConstraint(vars, transitions, initial_state, + final_states); + } + public static Constraint Transition(this IntVar[] vars, + IntTupleSet transitions, + long initial_state, + int[] final_states) { + Solver solver = GetSolver(vars); + return solver.MakeTransitionConstraint(vars, transitions, initial_state, + final_states); + } + + // Matrix API + public static IntVar[] Flatten(this IntVar[, ] vars) { + int rows = vars.GetLength(0); + int cols = vars.GetLength(1); + IntVar[] flat = new IntVar[cols * rows]; + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + flat[i * cols + j] = vars[i, j]; + } + } + return flat; } - return flat; } -} - -// TODO(user): Try to move this code back to the .swig with @define macros. -public partial class IntVarVector: IDisposable, System.Collections.IEnumerable + // TODO(user): Try to move this code back to the .swig with @define macros. + public partial class IntVarVector : IDisposable, + System.Collections.IEnumerable #if !SWIG_DOTNET_1 - , System.Collections.Generic.IList + , + System.Collections.Generic.IList #endif -{ - // cast from C# IntVar array - public static implicit operator IntVarVector(IntVar[] inVal) { - var outVal= new IntVarVector(); - foreach (IntVar element in inVal) { - outVal.Add(element); + { + // cast from C# IntVar array + public static implicit operator IntVarVector(IntVar[] inVal) { + var outVal = new IntVarVector(); + foreach (IntVar element in inVal) { + outVal.Add(element); + } + return outVal; + } + + // cast to C# IntVar array + public static implicit operator IntVar[](IntVarVector inVal) { + var outVal = new IntVar[inVal.Count]; + inVal.CopyTo(outVal); + return outVal; } - return outVal; } - // cast to C# IntVar array - public static implicit operator IntVar[](IntVarVector inVal) { - var outVal= new IntVar[inVal.Count]; - inVal.CopyTo(outVal); - return outVal; - } -} - -public partial class SearchMonitorVector: IDisposable, System.Collections.IEnumerable + public partial class SearchMonitorVector + : IDisposable, + System.Collections.IEnumerable #if !SWIG_DOTNET_1 - , System.Collections.Generic.IList + , + System.Collections.Generic.IList #endif -{ - // cast from C# SearchMonitor array - public static implicit operator SearchMonitorVector(SearchMonitor[] inVal) { - var outVal= new SearchMonitorVector(); - foreach (SearchMonitor element in inVal) { - outVal.Add(element); + { + // cast from C# SearchMonitor array + public static implicit operator SearchMonitorVector(SearchMonitor[] inVal) { + var outVal = new SearchMonitorVector(); + foreach (SearchMonitor element in inVal) { + outVal.Add(element); + } + return outVal; + } + + // cast to C# SearchMonitor array + public static implicit operator SearchMonitor[](SearchMonitorVector inVal) { + var outVal = new SearchMonitor[inVal.Count]; + inVal.CopyTo(outVal); + return outVal; } - return outVal; } - // cast to C# SearchMonitor array - public static implicit operator SearchMonitor[](SearchMonitorVector inVal) { - var outVal= new SearchMonitor[inVal.Count]; - inVal.CopyTo(outVal); - return outVal; - } -} - -public partial class DecisionBuilderVector: IDisposable, System.Collections.IEnumerable + public partial class DecisionBuilderVector + : IDisposable, + System.Collections.IEnumerable #if !SWIG_DOTNET_1 - , System.Collections.Generic.IList + , + System.Collections.Generic.IList #endif -{ - // cast from C# DecisionBuilder array - public static implicit operator DecisionBuilderVector(DecisionBuilder[] inVal) { - var outVal= new DecisionBuilderVector(); - foreach (DecisionBuilder element in inVal) { - outVal.Add(element); + { + // cast from C# DecisionBuilder array + public static implicit operator DecisionBuilderVector( + DecisionBuilder[] inVal) { + var outVal = new DecisionBuilderVector(); + foreach (DecisionBuilder element in inVal) { + outVal.Add(element); + } + return outVal; + } + + // cast to C# DecisionBuilder array + public static implicit operator DecisionBuilder[]( + DecisionBuilderVector inVal) { + var outVal = new DecisionBuilder[inVal.Count]; + inVal.CopyTo(outVal); + return outVal; } - return outVal; } - // cast to C# DecisionBuilder array - public static implicit operator DecisionBuilder[](DecisionBuilderVector inVal) { - var outVal= new DecisionBuilder[inVal.Count]; - inVal.CopyTo(outVal); - return outVal; - } -} - -public partial class IntervalVarVector: IDisposable, System.Collections.IEnumerable + public partial class IntervalVarVector + : IDisposable, + System.Collections.IEnumerable #if !SWIG_DOTNET_1 - , System.Collections.Generic.IList + , + System.Collections.Generic.IList #endif -{ - // cast from C# IntervalVar array - public static implicit operator IntervalVarVector(IntervalVar[] inVal) { - var outVal= new IntervalVarVector(); - foreach (IntervalVar element in inVal) { - outVal.Add(element); + { + // cast from C# IntervalVar array + public static implicit operator IntervalVarVector(IntervalVar[] inVal) { + var outVal = new IntervalVarVector(); + foreach (IntervalVar element in inVal) { + outVal.Add(element); + } + return outVal; + } + + // cast to C# IntervalVar array + public static implicit operator IntervalVar[](IntervalVarVector inVal) { + var outVal = new IntervalVar[inVal.Count]; + inVal.CopyTo(outVal); + return outVal; } - return outVal; } - // cast to C# IntervalVar array - public static implicit operator IntervalVar[](IntervalVarVector inVal) { - var outVal= new IntervalVar[inVal.Count]; - inVal.CopyTo(outVal); - return outVal; - } -} - -public partial class SequenceVarVector: IDisposable, System.Collections.IEnumerable + public partial class SequenceVarVector + : IDisposable, + System.Collections.IEnumerable #if !SWIG_DOTNET_1 - , System.Collections.Generic.IList + , + System.Collections.Generic.IList #endif -{ - // cast from C# SequenceVar array - public static implicit operator SequenceVarVector(SequenceVar[] inVal) { - var outVal= new SequenceVarVector(); - foreach (SequenceVar element in inVal) { - outVal.Add(element); + { + // cast from C# SequenceVar array + public static implicit operator SequenceVarVector(SequenceVar[] inVal) { + var outVal = new SequenceVarVector(); + foreach (SequenceVar element in inVal) { + outVal.Add(element); + } + return outVal; + } + + // cast to C# SequenceVar array + public static implicit operator SequenceVar[](SequenceVarVector inVal) { + var outVal = new SequenceVar[inVal.Count]; + inVal.CopyTo(outVal); + return outVal; } - return outVal; } - // cast to C# SequenceVar array - public static implicit operator SequenceVar[](SequenceVarVector inVal) { - var outVal= new SequenceVar[inVal.Count]; - inVal.CopyTo(outVal); - return outVal; - } -} - -public partial class LocalSearchOperatorVector: IDisposable, System.Collections.IEnumerable + public partial class LocalSearchOperatorVector + : IDisposable, + System.Collections.IEnumerable #if !SWIG_DOTNET_1 - , System.Collections.Generic.IList + , + System.Collections.Generic.IList #endif -{ - // cast from C# LocalSearchOperator array - public static implicit operator LocalSearchOperatorVector(LocalSearchOperator[] inVal) { - var outVal= new LocalSearchOperatorVector(); - foreach (LocalSearchOperator element in inVal) { - outVal.Add(element); + { + // cast from C# LocalSearchOperator array + public static implicit operator LocalSearchOperatorVector( + LocalSearchOperator[] inVal) { + var outVal = new LocalSearchOperatorVector(); + foreach (LocalSearchOperator element in inVal) { + outVal.Add(element); + } + return outVal; + } + + // cast to C# LocalSearchOperator array + public static implicit operator LocalSearchOperator[]( + LocalSearchOperatorVector inVal) { + var outVal = new LocalSearchOperator[inVal.Count]; + inVal.CopyTo(outVal); + return outVal; } - return outVal; } - // cast to C# LocalSearchOperator array - public static implicit operator LocalSearchOperator[](LocalSearchOperatorVector inVal) { - var outVal= new LocalSearchOperator[inVal.Count]; - inVal.CopyTo(outVal); - return outVal; - } -} - -public partial class LocalSearchFilterVector: IDisposable, System.Collections.IEnumerable + public partial class LocalSearchFilterVector + : IDisposable, + System.Collections.IEnumerable #if !SWIG_DOTNET_1 - , System.Collections.Generic.IList + , + System.Collections.Generic.IList #endif -{ - // cast from C# LocalSearchFilter array - public static implicit operator LocalSearchFilterVector(LocalSearchFilter[] inVal) { - var outVal= new LocalSearchFilterVector(); - foreach (LocalSearchFilter element in inVal) { - outVal.Add(element); + { + // cast from C# LocalSearchFilter array + public static implicit operator LocalSearchFilterVector( + LocalSearchFilter[] inVal) { + var outVal = new LocalSearchFilterVector(); + foreach (LocalSearchFilter element in inVal) { + outVal.Add(element); + } + return outVal; + } + + // cast to C# LocalSearchFilter array + public static implicit operator LocalSearchFilter[]( + LocalSearchFilterVector inVal) { + var outVal = new LocalSearchFilter[inVal.Count]; + inVal.CopyTo(outVal); + return outVal; } - return outVal; } - // cast to C# LocalSearchFilter array - public static implicit operator LocalSearchFilter[](LocalSearchFilterVector inVal) { - var outVal= new LocalSearchFilter[inVal.Count]; - inVal.CopyTo(outVal); - return outVal; - } -} - -public partial class SymmetryBreakerVector: IDisposable, System.Collections.IEnumerable + public partial class SymmetryBreakerVector + : IDisposable, + System.Collections.IEnumerable #if !SWIG_DOTNET_1 - , System.Collections.Generic.IList + , + System.Collections.Generic.IList #endif -{ - // cast from C# SymmetryBreaker array - public static implicit operator SymmetryBreakerVector(SymmetryBreaker[] inVal) { - var outVal= new SymmetryBreakerVector(); - foreach (SymmetryBreaker element in inVal) { - outVal.Add(element); + { + // cast from C# SymmetryBreaker array + public static implicit operator SymmetryBreakerVector( + SymmetryBreaker[] inVal) { + var outVal = new SymmetryBreakerVector(); + foreach (SymmetryBreaker element in inVal) { + outVal.Add(element); + } + return outVal; } - return outVal; - } - // cast to C# SymmetryBreaker array - public static implicit operator SymmetryBreaker[](SymmetryBreakerVector inVal) { - var outVal= new SymmetryBreaker[inVal.Count]; - inVal.CopyTo(outVal); - return outVal; + // cast to C# SymmetryBreaker array + public static implicit operator SymmetryBreaker[]( + SymmetryBreakerVector inVal) { + var outVal = new SymmetryBreaker[inVal.Count]; + inVal.CopyTo(outVal); + return outVal; + } } -} } // namespace Google.OrTools.ConstraintSolver diff --git a/ortools/constraint_solver/csharp/IntervalVarArrayHelper.cs b/ortools/constraint_solver/csharp/IntervalVarArrayHelper.cs index e4f7750e6a..faf903fcf4 100644 --- a/ortools/constraint_solver/csharp/IntervalVarArrayHelper.cs +++ b/ortools/constraint_solver/csharp/IntervalVarArrayHelper.cs @@ -11,41 +11,32 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Google.OrTools.ConstraintSolver -{ +namespace Google.OrTools.ConstraintSolver { using System; using System.Collections.Generic; // IntervalVar[] helper class. - public static class IntervalVarArrayHelper - { + public static class IntervalVarArrayHelper { // get solver from array of interval variables - private static Solver GetSolver(IntervalVar[] vars) - { + private static Solver GetSolver(IntervalVar[] vars) { if (vars == null || vars.Length <= 0) throw new ArgumentException("Array cannot be null or empty"); - return vars[0].solver(); + return vars [0] + .solver(); } public static DisjunctiveConstraint Disjunctive(this IntervalVar[] vars, - String name) - { + String name) { Solver solver = GetSolver(vars); return solver.MakeDisjunctiveConstraint(vars, name); } - public static Constraint Cumulative(this IntervalVar[] vars, - long[] demands, - long capacity, - String name) - { + public static Constraint Cumulative(this IntervalVar[] vars, long[] demands, + long capacity, String name) { Solver solver = GetSolver(vars); return solver.MakeCumulative(vars, demands, capacity, name); } - public static Constraint Cumulative(this IntervalVar[] vars, - int[] demands, - long capacity, - String name) - { + public static Constraint Cumulative(this IntervalVar[] vars, int[] demands, + long capacity, String name) { Solver solver = GetSolver(vars); return solver.MakeCumulative(vars, demands, capacity, name); } diff --git a/ortools/constraint_solver/csharp/NetDecisionBuilder.cs b/ortools/constraint_solver/csharp/NetDecisionBuilder.cs index 3452b4126c..aff34795f1 100644 --- a/ortools/constraint_solver/csharp/NetDecisionBuilder.cs +++ b/ortools/constraint_solver/csharp/NetDecisionBuilder.cs @@ -14,192 +14,154 @@ using System; using System.Collections; -namespace Google.OrTools.ConstraintSolver -{ -/** - * This class acts as a intermediate step between a c++ decision builder and a - * .Net one. Its main purpose is to catch the .Net application exception - * launched when a failure occurs during the Next() call, and to return - * silently a System.ApplicationException that will propagate the failure back - * to the C++ code. - * - */ -public class NetDecisionBuilder : DecisionBuilder -{ +namespace Google.OrTools.ConstraintSolver { /** - * This methods wraps the calls to next() and catches fail exceptions. - * It currently catches all application exceptions. + * This class acts as a intermediate step between a c++ decision builder and a + * .Net one. Its main purpose is to catch the .Net application exception + * launched when a failure occurs during the Next() call, and to return + * silently a System.ApplicationException that will propagate the failure back + * to the C++ code. + * */ - public override Decision NextWrapper(Solver solver) - { - try - { - return Next(solver); - } - catch (ApplicationException /*e*/) - { - // TODO(user): Catch only fail exceptions. - return solver.MakeFailDecision(); + public class NetDecisionBuilder : DecisionBuilder { + /** + * This methods wraps the calls to next() and catches fail exceptions. + * It currently catches all application exceptions. + */ + public override Decision NextWrapper(Solver solver) { + try { + return Next(solver); + } catch (ApplicationException /*e*/) { + // TODO(user): Catch only fail exceptions. + return solver.MakeFailDecision(); + } } + /** + * This is the new method to subclass when defining a .Net decision builder. + */ + public virtual Decision Next(Solver solver) { return null; } } + /** - * This is the new method to subclass when defining a .Net decision builder. + * This class acts as a intermediate step between a c++ decision and a + * .Net one. Its main purpose is to catch the .Net application + * exception launched when a failure occurs during the + * Apply()/Refute() calls, and to set the ShouldFail() flag on the + * solver that will propagate the failure back to the C++ code. + * */ - public virtual Decision Next(Solver solver) - { - return null; - } -} - -/** - * This class acts as a intermediate step between a c++ decision and a - * .Net one. Its main purpose is to catch the .Net application - * exception launched when a failure occurs during the - * Apply()/Refute() calls, and to set the ShouldFail() flag on the - * solver that will propagate the failure back to the C++ code. - * - */ -public class NetDecision : Decision -{ - /** - * This methods wraps the calls to Apply() and catches fail exceptions. - * It currently catches all application exceptions. - */ - public override void ApplyWrapper(Solver solver) - { - try - { - Apply(solver); + public class NetDecision : Decision { + /** + * This methods wraps the calls to Apply() and catches fail exceptions. + * It currently catches all application exceptions. + */ + public override void ApplyWrapper(Solver solver) { + try { + Apply(solver); + } catch (ApplicationException /*e*/) { + // TODO(user): Catch only fail exceptions. + solver.ShouldFail(); + } } - catch (ApplicationException /*e*/) - { - // TODO(user): Catch only fail exceptions. - solver.ShouldFail(); + /** + * This is a new method to subclass when defining a .Net decision. + */ + public virtual void Apply(Solver solver) { + // By default, do nothing } - } - /** - * This is a new method to subclass when defining a .Net decision. - */ - public virtual void Apply(Solver solver) - { - // By default, do nothing - } - public override void RefuteWrapper(Solver solver) - { - try - { - Refute(solver); + public override void RefuteWrapper(Solver solver) { + try { + Refute(solver); + } catch (ApplicationException /*e*/) { + // TODO(user): Catch only fail exceptions. + solver.ShouldFail(); + } } - catch (ApplicationException /*e*/) - { - // TODO(user): Catch only fail exceptions. - solver.ShouldFail(); + /** + * This is a new method to subclass when defining a .Net decision. + */ + public virtual void Refute(Solver solver) {} + } + + public class NetDemon : Demon { + /** + * This methods wraps the calls to next() and catches fail exceptions. + */ + public override void RunWrapper(Solver solver) { + try { + Run(solver); + } catch (ApplicationException /*e*/) { + // TODO(user): Check that this is indeed a fail. Try implementing + // custom exceptions (hard). + solver.ShouldFail(); + } } + /** + * This is the new method to subclass when defining a .Net decision builder. + */ + public virtual void Run(Solver solver) {} + public override int Priority() { return Solver.NORMAL_PRIORITY; } + public override string ToString() { return "NetDemon"; } } - /** - * This is a new method to subclass when defining a .Net decision. - */ - public virtual void Refute(Solver solver) - { - } -} -public class NetDemon : Demon -{ - /** - * This methods wraps the calls to next() and catches fail exceptions. - */ - public override void RunWrapper(Solver solver) - { - try - { - Run(solver); + public class NetConstraint : Constraint { + public NetConstraint(Solver s) : base(s) {} + + public override void InitialPropagateWrapper() { + try { + InitialPropagate(); + } catch (ApplicationException /*e*/) { + solver().ShouldFail(); + } } - catch (ApplicationException /*e*/) - { - // TODO(user): Check that this is indeed a fail. Try implementing - // custom exceptions (hard). - solver.ShouldFail(); - } - } - /** - * This is the new method to subclass when defining a .Net decision builder. - */ - public virtual void Run(Solver solver) {} - public override int Priority() { - return Solver.NORMAL_PRIORITY; - } - public override string ToString() { - return "NetDemon"; - } -} - -public class NetConstraint : Constraint { - public NetConstraint(Solver s) : base(s) {} - - public override void InitialPropagateWrapper() { - try { - InitialPropagate(); - } catch (ApplicationException /*e*/) { - solver().ShouldFail(); - } - } - public virtual void InitialPropagate() {} - public override string ToString() { - return "NetConstraint"; - } -} - -public class IntVarEnumerator : IEnumerator { - private IntVarIterator iterator_; - - // Enumerators are positioned before the first element - // until the first MoveNext() call. - private bool first_ = true; - - public IntVarEnumerator(IntVarIterator iterator) { - iterator_ = iterator; + public virtual void InitialPropagate() {} + public override string ToString() { return "NetConstraint"; } } - public bool MoveNext() { - if (first_) { - iterator_.Init(); - first_ = false; - } else { - iterator_.Next(); - } - return iterator_.Ok(); - } + public class IntVarEnumerator : IEnumerator { + private IntVarIterator iterator_; - public void Reset() { - first_ = true; - } + // Enumerators are positioned before the first element + // until the first MoveNext() call. + private bool first_ = true; - object IEnumerator.Current { - get { - return Current; - } - } + public IntVarEnumerator(IntVarIterator iterator) { iterator_ = iterator; } - public long Current { - get { - if (!first_ && iterator_.Ok()) { - return iterator_.Value(); + public bool MoveNext() { + if (first_) { + iterator_.Init(); + first_ = false; } else { - throw new InvalidOperationException(); + iterator_.Next(); + } + return iterator_.Ok(); + } + + public void Reset() { first_ = true; } + + object IEnumerator.Current { + get { return Current; } + } + + public long Current { + get { + if (!first_ && iterator_.Ok()) { + return iterator_.Value(); + } else { + throw new InvalidOperationException(); + } } } } -} -public partial class IntVarIterator : BaseObject, IEnumerable { - IEnumerator IEnumerable.GetEnumerator() { - return (IEnumerator) GetEnumerator(); - } + public partial class IntVarIterator : BaseObject, IEnumerable { + IEnumerator IEnumerable.GetEnumerator() { + return (IEnumerator) GetEnumerator(); + } - public IntVarEnumerator GetEnumerator() { - return new IntVarEnumerator(this); + public IntVarEnumerator GetEnumerator() { + return new IntVarEnumerator(this); + } } -} } // namespace Google.OrTools.ConstraintSolver diff --git a/ortools/constraint_solver/csharp/SolverHelper.cs b/ortools/constraint_solver/csharp/SolverHelper.cs index d2ac15e88f..30eeeaf9d9 100644 --- a/ortools/constraint_solver/csharp/SolverHelper.cs +++ b/ortools/constraint_solver/csharp/SolverHelper.cs @@ -12,506 +12,490 @@ // limitations under the License. namespace Google.OrTools.ConstraintSolver { -using System; -using System.Collections.Generic; + using System; + using System.Collections.Generic; -public partial class Solver : IDisposable { - public IntVar[] MakeIntVarArray(int count, long min, long max) { - IntVar[] array = new IntVar[count]; - for (int i = 0; i < count; ++i) { - array[i] = MakeIntVar(min, max); - } - return array; - } - - public IntVar[] MakeIntVarArray(int count, long min, long max, string name) { - IntVar[] array = new IntVar[count]; - for (int i = 0; i < count; ++i) { - string var_name = name + i; - array[i] = MakeIntVar(min, max, var_name); - } - return array; - } - - public IntVar[] MakeIntVarArray(int count, long[] values) { - IntVar[] array = new IntVar[count]; - for (int i = 0; i < count; ++i) { - array[i] = MakeIntVar(values); - } - return array; - } - - public IntVar[] MakeIntVarArray(int count, long[] values, string name) { - IntVar[] array = new IntVar[count]; - for (int i = 0; i < count; ++i) { - string var_name = name + i; - array[i] = MakeIntVar(values, var_name); - } - return array; - } - - public IntVar[] MakeIntVarArray(int count, int[] values) { - IntVar[] array = new IntVar[count]; - for (int i = 0; i < count; ++i) { - array[i] = MakeIntVar(values); - } - return array; - } - - public IntVar[] MakeIntVarArray(int count, int[] values, string name) { - IntVar[] array = new IntVar[count]; - for (int i = 0; i < count; ++i) { - string var_name = name + i; - array[i] = MakeIntVar(values, var_name); - } - return array; - } - - public IntVar[] MakeBoolVarArray(int count) { - IntVar[] array = new IntVar[count]; - for (int i = 0; i < count; ++i) { - array[i] = MakeBoolVar(); - } - return array; - } - - public IntVar[] MakeBoolVarArray(int count, string name) { - IntVar[] array = new IntVar[count]; - for (int i = 0; i < count; ++i) { - string var_name = name + i; - array[i] = MakeBoolVar(var_name); - } - return array; - } - - public IntVar[,] MakeIntVarMatrix(int rows, int cols, long min, long max) { - IntVar[,] array = new IntVar[rows, cols]; - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < cols; ++j) { - array[i,j] = MakeIntVar(min, max); + public partial class Solver : IDisposable { + public IntVar[] MakeIntVarArray(int count, long min, long max) { + IntVar[] array = new IntVar[count]; + for (int i = 0; i < count; ++i) { + array [i] + = MakeIntVar(min, max); } + return array; } - return array; - } - public IntVar[,] MakeIntVarMatrix(int rows, int cols, - long min, long max, string name) { - IntVar[,] array = new IntVar[rows, cols]; - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < cols; ++j) { - string var_name = name + "["+ i + ", " + j +"]"; - array[i,j] = MakeIntVar(min, max, var_name); + public IntVar[] MakeIntVarArray(int count, long min, long max, + string name) { + IntVar[] array = new IntVar[count]; + for (int i = 0; i < count; ++i) { + string var_name = name + i; + array [i] + = MakeIntVar(min, max, var_name); } + return array; } - return array; - } - public IntVar[,] MakeIntVarMatrix(int rows, int cols, long[] values) { - IntVar[,] array = new IntVar[rows, cols]; - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < cols; ++j) { - array[i,j] = MakeIntVar(values); + public IntVar[] MakeIntVarArray(int count, long[] values) { + IntVar[] array = new IntVar[count]; + for (int i = 0; i < count; ++i) { + array [i] + = MakeIntVar(values); } + return array; } - return array; - } - public IntVar[,] MakeIntVarMatrix(int rows, int cols, - long[] values, string name) { - IntVar[,] array = new IntVar[rows, cols]; - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < cols; ++j) { - string var_name = name + "["+ i + ", " + j +"]"; - array[i,j] = MakeIntVar(values, var_name); + public IntVar[] MakeIntVarArray(int count, long[] values, string name) { + IntVar[] array = new IntVar[count]; + for (int i = 0; i < count; ++i) { + string var_name = name + i; + array [i] + = MakeIntVar(values, var_name); } + return array; } - return array; - } - public IntVar[,] MakeIntVarMatrix(int rows, int cols, int[] values) { - IntVar[,] array = new IntVar[rows, cols]; - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < cols; ++j) { - array[i,j] = MakeIntVar(values); + public IntVar[] MakeIntVarArray(int count, int[] values) { + IntVar[] array = new IntVar[count]; + for (int i = 0; i < count; ++i) { + array [i] + = MakeIntVar(values); } + return array; } - return array; - } - public IntVar[,] MakeIntVarMatrix(int rows, int cols, - int[] values, string name) { - IntVar[,] array = new IntVar[rows, cols]; - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < cols; ++j) { - string var_name = name + "["+ i + ", " + j +"]"; - array[i,j] = MakeIntVar(values, var_name); + public IntVar[] MakeIntVarArray(int count, int[] values, string name) { + IntVar[] array = new IntVar[count]; + for (int i = 0; i < count; ++i) { + string var_name = name + i; + array [i] + = MakeIntVar(values, var_name); } + return array; } - return array; - } - public IntVar[,] MakeBoolVarMatrix(int rows, int cols) { - IntVar[,] array = new IntVar[rows, cols]; - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < cols; ++j) { - array[i,j] = MakeBoolVar(); + public IntVar[] MakeBoolVarArray(int count) { + IntVar[] array = new IntVar[count]; + for (int i = 0; i < count; ++i) { + array [i] + = MakeBoolVar(); } + return array; } - return array; - } - public IntVar[,] MakeBoolVarMatrix(int rows, int cols, string name) { - IntVar[,] array = new IntVar[rows, cols]; - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < cols; ++j) { - string var_name = name + "["+ i + ", " + j +"]"; - array[i,j] = MakeBoolVar(var_name); + public IntVar[] MakeBoolVarArray(int count, string name) { + IntVar[] array = new IntVar[count]; + for (int i = 0; i < count; ++i) { + string var_name = name + i; + array [i] + = MakeBoolVar(var_name); } + return array; } - return array; - } - public IntervalVar[] MakeFixedDurationIntervalVarArray(int count, - long start_min, - long start_max, - long duration, - bool optional) { - IntervalVar[] array = new IntervalVar[count]; - for (int i = 0; i < count; ++i) { - array[i] = MakeFixedDurationIntervalVar(start_min, - start_max, - duration, - optional, - ""); + public IntVar[, ] MakeIntVarMatrix(int rows, int cols, long min, long max) { + IntVar[, ] array = new IntVar[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + array [i, j] + = MakeIntVar(min, max); + } + } + return array; } - return array; - } - public IntervalVar[] MakeFixedDurationIntervalVarArray(int count, - long start_min, - long start_max, - long duration, - bool optional, - string name) { - IntervalVar[] array = new IntervalVar[count]; - for (int i = 0; i < count; ++i) { - array[i] = MakeFixedDurationIntervalVar(start_min, - start_max, - duration, - optional, - name + i); + public IntVar[, ] MakeIntVarMatrix(int rows, int cols, long min, long max, + string name) { + IntVar[, ] array = new IntVar[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + string var_name = name + "[" + i + ", " + j + "]"; + array [i, j] + = MakeIntVar(min, max, var_name); + } + } + return array; } - return array; - } - public IntervalVar[] MakeFixedDurationIntervalVarArray(int count, - long[] start_min, - long[] start_max, - long[] duration, - bool optional, - string name) { - IntervalVar[] array = new IntervalVar[count]; - for (int i = 0; i < count; ++i) { - array[i] = MakeFixedDurationIntervalVar(start_min[i], - start_max[i], - duration[i], - optional, - name + i); + public IntVar[, ] MakeIntVarMatrix(int rows, int cols, long[] values) { + IntVar[, ] array = new IntVar[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + array [i, j] + = MakeIntVar(values); + } + } + return array; } - return array; - } - public IntervalVar[] MakeFixedDurationIntervalVarArray(int count, - int[] start_min, - int[] start_max, - int[] duration, - bool optional, - string name) { - IntervalVar[] array = new IntervalVar[count]; - for (int i = 0; i < count; ++i) { - array[i] = MakeFixedDurationIntervalVar(start_min[i], - start_max[i], - duration[i], - optional, - name + i); + public IntVar[, ] MakeIntVarMatrix(int rows, int cols, long[] values, + string name) { + IntVar[, ] array = new IntVar[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + string var_name = name + "[" + i + ", " + j + "]"; + array [i, j] + = MakeIntVar(values, var_name); + } + } + return array; } - return array; - } - public IntervalVar[] MakeFixedDurationIntervalVarArray(IntVar[] starts, - int[] durations, - string name) { - int count = starts.Length; - IntervalVar[] array = new IntervalVar[count]; - for (int i = 0; i < count; ++i) { - array[i] = MakeFixedDurationIntervalVar(starts[i], - durations[i], - name + i); + + public IntVar[, ] MakeIntVarMatrix(int rows, int cols, int[] values) { + IntVar[, ] array = new IntVar[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + array [i, j] + = MakeIntVar(values); + } + } + return array; } - return array; - } - public IntervalVar[] MakeFixedDurationIntervalVarArray(IntVar[] starts, - long[] durations, - string name) { - int count = starts.Length; - IntervalVar[] array = new IntervalVar[count]; - for (int i = 0; i < count; ++i) { - array[i] = MakeFixedDurationIntervalVar(starts[i], - durations[i], - name + i); + + public IntVar[, ] MakeIntVarMatrix(int rows, int cols, int[] values, + string name) { + IntVar[, ] array = new IntVar[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + string var_name = name + "[" + i + ", " + j + "]"; + array [i, j] + = MakeIntVar(values, var_name); + } + } + return array; } - return array; - } - public void NewSearch(DecisionBuilder db) { - pinned_decision_builder_ = db; - pinned_search_monitors_.Clear(); - NewSearchAux(db); + + public IntVar[, ] MakeBoolVarMatrix(int rows, int cols) { + IntVar[, ] array = new IntVar[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + array [i, j] + = MakeBoolVar(); + } + } + return array; + } + + public IntVar[, ] MakeBoolVarMatrix(int rows, int cols, string name) { + IntVar[, ] array = new IntVar[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + string var_name = name + "[" + i + ", " + j + "]"; + array [i, j] + = MakeBoolVar(var_name); + } + } + return array; + } + + public IntervalVar[] MakeFixedDurationIntervalVarArray(int count, + long start_min, + long start_max, + long duration, + bool optional) { + IntervalVar[] array = new IntervalVar[count]; + for (int i = 0; i < count; ++i) { + array [i] + = MakeFixedDurationIntervalVar(start_min, start_max, duration, optional, + ""); + } + return array; + } + + public IntervalVar[] MakeFixedDurationIntervalVarArray( + int count, long start_min, long start_max, long duration, bool optional, + string name) { + IntervalVar[] array = new IntervalVar[count]; + for (int i = 0; i < count; ++i) { + array [i] + = MakeFixedDurationIntervalVar(start_min, start_max, duration, optional, + name + i); + } + return array; + } + + public IntervalVar[] MakeFixedDurationIntervalVarArray( + int count, long[] start_min, long[] start_max, long[] duration, + bool optional, string name) { + IntervalVar[] array = new IntervalVar[count]; + for (int i = 0; i < count; ++i) { + array [i] + = MakeFixedDurationIntervalVar(start_min[i], start_max[i], duration[i], + optional, name + i); + } + return array; + } + + public IntervalVar[] MakeFixedDurationIntervalVarArray( + int count, int[] start_min, int[] start_max, int[] duration, + bool optional, string name) { + IntervalVar[] array = new IntervalVar[count]; + for (int i = 0; i < count; ++i) { + array [i] + = MakeFixedDurationIntervalVar(start_min[i], start_max[i], duration[i], + optional, name + i); + } + return array; + } + public IntervalVar[] MakeFixedDurationIntervalVarArray(IntVar[] starts, + int[] durations, + string name) { + int count = starts.Length; + IntervalVar[] array = new IntervalVar[count]; + for (int i = 0; i < count; ++i) { + array [i] + = MakeFixedDurationIntervalVar(starts[i], durations[i], name + i); + } + return array; + } + public IntervalVar[] MakeFixedDurationIntervalVarArray(IntVar[] starts, + long[] durations, + string name) { + int count = starts.Length; + IntervalVar[] array = new IntervalVar[count]; + for (int i = 0; i < count; ++i) { + array [i] + = MakeFixedDurationIntervalVar(starts[i], durations[i], name + i); + } + return array; + } + public void NewSearch(DecisionBuilder db) { + pinned_decision_builder_ = db; + pinned_search_monitors_.Clear(); + NewSearchAux(db); + } + + public void NewSearch(DecisionBuilder db, SearchMonitor sm1) { + pinned_decision_builder_ = db; + pinned_search_monitors_.Clear(); + pinned_search_monitors_.Add(sm1); + NewSearchAux(db, sm1); + } + + public void NewSearch(DecisionBuilder db, SearchMonitor sm1, + SearchMonitor sm2) { + pinned_decision_builder_ = db; + pinned_search_monitors_.Clear(); + pinned_search_monitors_.Add(sm1); + pinned_search_monitors_.Add(sm2); + NewSearchAux(db, sm1, sm2); + } + + public void NewSearch(DecisionBuilder db, SearchMonitor sm1, + SearchMonitor sm2, SearchMonitor sm3) { + pinned_decision_builder_ = db; + pinned_search_monitors_.Clear(); + pinned_search_monitors_.Add(sm1); + pinned_search_monitors_.Add(sm2); + pinned_search_monitors_.Add(sm3); + NewSearchAux(db, sm1, sm2, sm3); + } + + public void NewSearch(DecisionBuilder db, SearchMonitor sm1, + SearchMonitor sm2, SearchMonitor sm3, + SearchMonitor sm4) { + pinned_decision_builder_ = db; + pinned_search_monitors_.Clear(); + pinned_search_monitors_.Add(sm1); + pinned_search_monitors_.Add(sm2); + pinned_search_monitors_.Add(sm3); + pinned_search_monitors_.Add(sm4); + NewSearchAux(db, sm1, sm2, sm3, sm4); + } + + public void NewSearch(DecisionBuilder db, SearchMonitor[] monitors) { + pinned_decision_builder_ = db; + pinned_search_monitors_.Clear(); + pinned_search_monitors_.AddRange(monitors); + NewSearchAux(db, monitors); + } + + public void EndSearch() { + pinned_decision_builder_ = null; + pinned_search_monitors_.Clear(); + EndSearchAux(); + } + + private System.Collections.Generic + .List pinned_search_monitors_ = + new System.Collections.Generic.List(); + private DecisionBuilder pinned_decision_builder_; } - public void NewSearch(DecisionBuilder db, SearchMonitor sm1) { - pinned_decision_builder_ = db; - pinned_search_monitors_.Clear(); - pinned_search_monitors_.Add(sm1); - NewSearchAux(db, sm1); + public partial class IntExpr : PropagationBaseObject { + public static IntExpr operator +(IntExpr a, IntExpr b) { + return a.solver().MakeSum(a, b); + } + public static IntExpr operator +(IntExpr a, long v) { + return a.solver().MakeSum(a, v); + } + public static IntExpr operator +(long v, IntExpr a) { + return a.solver().MakeSum(a, v); + } + public static IntExpr operator -(IntExpr a, IntExpr b) { + return a.solver().MakeDifference(a, b); + } + public static IntExpr operator -(IntExpr a, long v) { + return a.solver().MakeSum(a, -v); + } + public static IntExpr operator -(long v, IntExpr a) { + return a.solver().MakeDifference(v, a); + } + public static IntExpr operator*(IntExpr a, IntExpr b) { + return a.solver().MakeProd(a, b); + } + public static IntExpr operator*(IntExpr a, long v) { + return a.solver().MakeProd(a, v); + } + public static IntExpr operator*(long v, IntExpr a) { + return a.solver().MakeProd(a, v); + } + public static IntExpr operator /(IntExpr a, long v) { + return a.solver().MakeDiv(a, v); + } + public static IntExpr operator %(IntExpr a, long v) { + return a.solver().MakeModulo(a, v); + } + public static IntExpr operator -(IntExpr a) { + return a.solver().MakeOpposite(a); + } + public IntExpr Abs() { return this.solver().MakeAbs(this); } + public IntExpr Square() { return this.solver().MakeSquare(this); } + public static IntExprEquality operator ==(IntExpr a, IntExpr b) { + return new IntExprEquality(a, b, true); + } + public static IntExprEquality operator !=(IntExpr a, IntExpr b) { + return new IntExprEquality(a, b, false); + } + public static WrappedConstraint operator ==(IntExpr a, long v) { + return new WrappedConstraint(a.solver().MakeEquality(a, v)); + } + public static WrappedConstraint operator !=(IntExpr a, long v) { + return new WrappedConstraint(a.solver().MakeNonEquality(a.Var(), v)); + } + public static WrappedConstraint operator >=(IntExpr a, long v) { + return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a, v)); + } + public static WrappedConstraint operator>(IntExpr a, long v) { + return new WrappedConstraint(a.solver().MakeGreater(a, v)); + } + public static WrappedConstraint operator <=(IntExpr a, long v) { + return new WrappedConstraint(a.solver().MakeLessOrEqual(a, v)); + } + public static WrappedConstraint operator<(IntExpr a, long v) { + return new WrappedConstraint(a.solver().MakeLess(a, v)); + } + public static WrappedConstraint operator >=(IntExpr a, IntExpr b) { + return new WrappedConstraint( + a.solver().MakeGreaterOrEqual(a.Var(), b.Var())); + } + public static WrappedConstraint operator>(IntExpr a, IntExpr b) { + return new WrappedConstraint(a.solver().MakeGreater(a.Var(), b.Var())); + } + public static WrappedConstraint operator <=(IntExpr a, IntExpr b) { + return new WrappedConstraint( + a.solver().MakeLessOrEqual(a.Var(), b.Var())); + } + public static WrappedConstraint operator<(IntExpr a, IntExpr b) { + return new WrappedConstraint(a.solver().MakeLess(a.Var(), b.Var())); + } } + public partial class Constraint : PropagationBaseObject, + IConstraintWithStatus { + public static implicit operator IntVar(Constraint eq) { return eq.Var(); } - public void NewSearch(DecisionBuilder db, - SearchMonitor sm1, - SearchMonitor sm2) { - pinned_decision_builder_ = db; - pinned_search_monitors_.Clear(); - pinned_search_monitors_.Add(sm1); - pinned_search_monitors_.Add(sm2); - NewSearchAux(db, sm1, sm2); + public static implicit operator IntExpr(Constraint eq) { return eq.Var(); } + public static IntExpr operator +(Constraint a, Constraint b) { + return a.solver().MakeSum(a.Var(), b.Var()); + } + public static IntExpr operator +(Constraint a, long v) { + return a.solver().MakeSum(a.Var(), v); + } + public static IntExpr operator +(long v, Constraint a) { + return a.solver().MakeSum(a.Var(), v); + } + public static IntExpr operator -(Constraint a, Constraint b) { + return a.solver().MakeDifference(a.Var(), b.Var()); + } + public static IntExpr operator -(Constraint a, long v) { + return a.solver().MakeSum(a.Var(), -v); + } + public static IntExpr operator -(long v, Constraint a) { + return a.solver().MakeDifference(v, a.Var()); + } + public static IntExpr operator*(Constraint a, Constraint b) { + return a.solver().MakeProd(a.Var(), b.Var()); + } + public static IntExpr operator*(Constraint a, long v) { + return a.solver().MakeProd(a.Var(), v); + } + public static IntExpr operator*(long v, Constraint a) { + return a.solver().MakeProd(a.Var(), v); + } + public static IntExpr operator /(Constraint a, long v) { + return a.solver().MakeDiv(a.Var(), v); + } + public static IntExpr operator -(Constraint a) { + return a.solver().MakeOpposite(a.Var()); + } + public IntExpr Abs() { return this.solver().MakeAbs(this.Var()); } + public IntExpr Square() { return this.solver().MakeSquare(this.Var()); } + public static WrappedConstraint operator ==(Constraint a, long v) { + return new WrappedConstraint(a.solver().MakeEquality(a.Var(), v)); + } + public static WrappedConstraint operator ==(long v, Constraint a) { + return new WrappedConstraint(a.solver().MakeEquality(a.Var(), v)); + } + public static WrappedConstraint operator !=(Constraint a, long v) { + return new WrappedConstraint(a.solver().MakeNonEquality(a.Var(), v)); + } + public static WrappedConstraint operator !=(long v, Constraint a) { + return new WrappedConstraint(a.solver().MakeNonEquality(a.Var(), v)); + } + public static WrappedConstraint operator >=(Constraint a, long v) { + return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a.Var(), v)); + } + public static WrappedConstraint operator >=(long v, Constraint a) { + return new WrappedConstraint(a.solver().MakeLessOrEqual(a.Var(), v)); + } + public static WrappedConstraint operator>(Constraint a, long v) { + return new WrappedConstraint(a.solver().MakeGreater(a.Var(), v)); + } + public static WrappedConstraint operator>(long v, Constraint a) { + return new WrappedConstraint(a.solver().MakeLess(a.Var(), v)); + } + public static WrappedConstraint operator <=(Constraint a, long v) { + return new WrappedConstraint(a.solver().MakeLessOrEqual(a.Var(), v)); + } + public static WrappedConstraint operator <=(long v, Constraint a) { + return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a.Var(), v)); + } + public static WrappedConstraint operator<(Constraint a, long v) { + return new WrappedConstraint(a.solver().MakeLess(a.Var(), v)); + } + public static WrappedConstraint operator<(long v, Constraint a) { + return new WrappedConstraint(a.solver().MakeGreater(a.Var(), v)); + } + public static WrappedConstraint operator >=(Constraint a, Constraint b) { + return new WrappedConstraint( + a.solver().MakeGreaterOrEqual(a.Var(), b.Var())); + } + public static WrappedConstraint operator>(Constraint a, Constraint b) { + return new WrappedConstraint(a.solver().MakeGreater(a.Var(), b.Var())); + } + public static WrappedConstraint operator <=(Constraint a, Constraint b) { + return new WrappedConstraint( + a.solver().MakeLessOrEqual(a.Var(), b.Var())); + } + public static WrappedConstraint operator<(Constraint a, Constraint b) { + return new WrappedConstraint(a.solver().MakeLess(a.Var(), b.Var())); + } + public static ConstraintEquality operator ==(Constraint a, Constraint b) { + return new ConstraintEquality(a, b, true); + } + public static ConstraintEquality operator !=(Constraint a, Constraint b) { + return new ConstraintEquality(a, b, false); + } } - - public void NewSearch(DecisionBuilder db, - SearchMonitor sm1, - SearchMonitor sm2, - SearchMonitor sm3) { - pinned_decision_builder_ = db; - pinned_search_monitors_.Clear(); - pinned_search_monitors_.Add(sm1); - pinned_search_monitors_.Add(sm2); - pinned_search_monitors_.Add(sm3); - NewSearchAux(db, sm1, sm2, sm3); - } - - public void NewSearch(DecisionBuilder db, - SearchMonitor sm1, - SearchMonitor sm2, - SearchMonitor sm3, - SearchMonitor sm4) { - pinned_decision_builder_ = db; - pinned_search_monitors_.Clear(); - pinned_search_monitors_.Add(sm1); - pinned_search_monitors_.Add(sm2); - pinned_search_monitors_.Add(sm3); - pinned_search_monitors_.Add(sm4); - NewSearchAux(db, sm1, sm2, sm3, sm4); - } - - public void NewSearch(DecisionBuilder db, SearchMonitor[] monitors) { - pinned_decision_builder_ = db; - pinned_search_monitors_.Clear(); - pinned_search_monitors_.AddRange(monitors); - NewSearchAux(db, monitors); - } - - public void EndSearch() { - pinned_decision_builder_ = null; - pinned_search_monitors_.Clear(); - EndSearchAux(); - } - - private System.Collections.Generic.List pinned_search_monitors_ - = new System.Collections.Generic.List(); - private DecisionBuilder pinned_decision_builder_; -} - -public partial class IntExpr : PropagationBaseObject { - public static IntExpr operator+(IntExpr a, IntExpr b) { - return a.solver().MakeSum(a, b); - } - public static IntExpr operator+(IntExpr a, long v) { - return a.solver().MakeSum(a, v); - } - public static IntExpr operator+(long v, IntExpr a) { - return a.solver().MakeSum(a, v); - } - public static IntExpr operator-(IntExpr a, IntExpr b) { - return a.solver().MakeDifference(a, b); - } - public static IntExpr operator-(IntExpr a, long v) { - return a.solver().MakeSum(a, -v); - } - public static IntExpr operator-(long v, IntExpr a) { - return a.solver().MakeDifference(v, a); - } - public static IntExpr operator*(IntExpr a, IntExpr b) { - return a.solver().MakeProd(a, b); - } - public static IntExpr operator*(IntExpr a, long v) { - return a.solver().MakeProd(a, v); - } - public static IntExpr operator*(long v, IntExpr a) { - return a.solver().MakeProd(a, v); - } - public static IntExpr operator/(IntExpr a, long v) { - return a.solver().MakeDiv(a, v); - } - public static IntExpr operator%(IntExpr a, long v) { - return a.solver().MakeModulo(a, v); - } - public static IntExpr operator-(IntExpr a) { - return a.solver().MakeOpposite(a); - } - public IntExpr Abs() { - return this.solver().MakeAbs(this); - } - public IntExpr Square() { - return this.solver().MakeSquare(this); - } - public static IntExprEquality operator ==(IntExpr a, IntExpr b) { - return new IntExprEquality(a, b, true); - } - public static IntExprEquality operator !=(IntExpr a, IntExpr b) { - return new IntExprEquality(a, b, false); - } - public static WrappedConstraint operator ==(IntExpr a, long v) { - return new WrappedConstraint(a.solver().MakeEquality(a, v)); - } - public static WrappedConstraint operator !=(IntExpr a, long v) { - return new WrappedConstraint(a.solver().MakeNonEquality(a.Var(), v)); - } - public static WrappedConstraint operator >=(IntExpr a, long v) { - return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a, v)); - } - public static WrappedConstraint operator >(IntExpr a, long v) { - return new WrappedConstraint(a.solver().MakeGreater(a, v)); - } - public static WrappedConstraint operator <=(IntExpr a, long v) { - return new WrappedConstraint(a.solver().MakeLessOrEqual(a, v)); - } - public static WrappedConstraint operator <(IntExpr a, long v) { - return new WrappedConstraint(a.solver().MakeLess(a, v)); - } - public static WrappedConstraint operator >=(IntExpr a, IntExpr b) { - return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a.Var(), b.Var())); - } - public static WrappedConstraint operator >(IntExpr a, IntExpr b) { - return new WrappedConstraint(a.solver().MakeGreater(a.Var(), b.Var())); - } - public static WrappedConstraint operator <=(IntExpr a, IntExpr b) { - return new WrappedConstraint(a.solver().MakeLessOrEqual(a.Var(), b.Var())); - } - public static WrappedConstraint operator <(IntExpr a, IntExpr b) { - return new WrappedConstraint(a.solver().MakeLess(a.Var(), b.Var())); - } -} - -public partial class Constraint : PropagationBaseObject, IConstraintWithStatus { - public static implicit operator IntVar(Constraint eq) - { - return eq.Var(); - } - - public static implicit operator IntExpr(Constraint eq) - { - return eq.Var(); - } - public static IntExpr operator+(Constraint a, Constraint b) { - return a.solver().MakeSum(a.Var(), b.Var()); - } - public static IntExpr operator+(Constraint a, long v) { - return a.solver().MakeSum(a.Var(), v); - } - public static IntExpr operator+(long v, Constraint a) { - return a.solver().MakeSum(a.Var(), v); - } - public static IntExpr operator-(Constraint a, Constraint b) { - return a.solver().MakeDifference(a.Var(), b.Var()); - } - public static IntExpr operator-(Constraint a, long v) { - return a.solver().MakeSum(a.Var(), -v); - } - public static IntExpr operator-(long v, Constraint a) { - return a.solver().MakeDifference(v, a.Var()); - } - public static IntExpr operator*(Constraint a, Constraint b) { - return a.solver().MakeProd(a.Var(), b.Var()); - } - public static IntExpr operator*(Constraint a, long v) { - return a.solver().MakeProd(a.Var(), v); - } - public static IntExpr operator*(long v, Constraint a) { - return a.solver().MakeProd(a.Var(), v); - } - public static IntExpr operator/(Constraint a, long v) { - return a.solver().MakeDiv(a.Var(), v); - } - public static IntExpr operator-(Constraint a) { - return a.solver().MakeOpposite(a.Var()); - } - public IntExpr Abs() { - return this.solver().MakeAbs(this.Var()); - } - public IntExpr Square() { - return this.solver().MakeSquare(this.Var()); - } - public static WrappedConstraint operator ==(Constraint a, long v) { - return new WrappedConstraint(a.solver().MakeEquality(a.Var(), v)); - } - public static WrappedConstraint operator ==(long v, Constraint a) { - return new WrappedConstraint(a.solver().MakeEquality(a.Var(), v)); - } - public static WrappedConstraint operator !=(Constraint a, long v) { - return new WrappedConstraint(a.solver().MakeNonEquality(a.Var(), v)); - } - public static WrappedConstraint operator !=(long v, Constraint a) { - return new WrappedConstraint(a.solver().MakeNonEquality(a.Var(), v)); - } - public static WrappedConstraint operator >=(Constraint a, long v) { - return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a.Var(), v)); - } - public static WrappedConstraint operator >=(long v, Constraint a) { - return new WrappedConstraint(a.solver().MakeLessOrEqual(a.Var(), v)); - } - public static WrappedConstraint operator >(Constraint a, long v) { - return new WrappedConstraint(a.solver().MakeGreater(a.Var(), v)); - } - public static WrappedConstraint operator >(long v, Constraint a) { - return new WrappedConstraint(a.solver().MakeLess(a.Var(), v)); - } - public static WrappedConstraint operator <=(Constraint a, long v) { - return new WrappedConstraint(a.solver().MakeLessOrEqual(a.Var(), v)); - } - public static WrappedConstraint operator <=(long v, Constraint a) { - return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a.Var(), v)); - } - public static WrappedConstraint operator <(Constraint a, long v) { - return new WrappedConstraint(a.solver().MakeLess(a.Var(), v)); - } - public static WrappedConstraint operator <(long v, Constraint a) { - return new WrappedConstraint(a.solver().MakeGreater(a.Var(), v)); - } - public static WrappedConstraint operator >=(Constraint a, Constraint b) { - return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a.Var(), b.Var())); - } - public static WrappedConstraint operator >(Constraint a, Constraint b) { - return new WrappedConstraint(a.solver().MakeGreater(a.Var(), b.Var())); - } - public static WrappedConstraint operator <=(Constraint a, Constraint b) { - return new WrappedConstraint(a.solver().MakeLessOrEqual(a.Var(), b.Var())); - } - public static WrappedConstraint operator <(Constraint a, Constraint b) { - return new WrappedConstraint(a.solver().MakeLess(a.Var(), b.Var())); - } - public static ConstraintEquality operator ==(Constraint a, Constraint b) { - return new ConstraintEquality(a, b, true); - } - public static ConstraintEquality operator !=(Constraint a, Constraint b) { - return new ConstraintEquality(a, b, false); - } -} } // namespace Google.OrTools.ConstraintSolver diff --git a/ortools/constraint_solver/csharp/ValCstPair.cs b/ortools/constraint_solver/csharp/ValCstPair.cs index 24d0bb9355..3497902106 100644 --- a/ortools/constraint_solver/csharp/ValCstPair.cs +++ b/ortools/constraint_solver/csharp/ValCstPair.cs @@ -11,290 +11,255 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Google.OrTools.ConstraintSolver -{ -using System; -using System.Collections.Generic; +namespace Google.OrTools.ConstraintSolver { + using System; + using System.Collections.Generic; -public interface IConstraintWithStatus -{ - Solver solver(); - IntVar Var(); -} - -public abstract class BaseEquality : IConstraintWithStatus -{ - abstract public Solver solver(); - abstract public IntVar Var(); - - public static IntExpr operator+(BaseEquality a, BaseEquality b) { - return a.solver().MakeSum(a.Var(), b.Var()); - } - public static IntExpr operator+(BaseEquality a, long v) { - return a.solver().MakeSum(a.Var(), v); - } - public static IntExpr operator+(long v, BaseEquality a) { - return a.solver().MakeSum(a.Var(), v); - } - public static IntExpr operator-(BaseEquality a, BaseEquality b) { - return a.solver().MakeDifference(a.Var(), b.Var()); - } - public static IntExpr operator-(BaseEquality a, long v) { - return a.solver().MakeSum(a.Var(), -v); - } - public static IntExpr operator-(long v, BaseEquality a) { - return a.solver().MakeDifference(v, a.Var()); - } - public static IntExpr operator*(BaseEquality a, BaseEquality b) { - return a.solver().MakeProd(a.Var(), b.Var()); - } - public static IntExpr operator*(BaseEquality a, long v) { - return a.solver().MakeProd(a.Var(), v); - } - public static IntExpr operator*(long v, BaseEquality a) { - return a.solver().MakeProd(a.Var(), v); - } - public static IntExpr operator/(BaseEquality a, long v) { - return a.solver().MakeDiv(a.Var(), v); - } - public static IntExpr operator-(BaseEquality a) { - return a.solver().MakeOpposite(a.Var()); - } - public IntExpr Abs() { - return this.solver().MakeAbs(this.Var()); - } - public IntExpr Square() { - return this.solver().MakeSquare(this.Var()); - } - public static WrappedConstraint operator ==(BaseEquality a, long v) { - return new WrappedConstraint(a.solver().MakeEquality(a.Var(), v)); - } - public static WrappedConstraint operator ==(long v, BaseEquality a) { - return new WrappedConstraint(a.solver().MakeEquality(a.Var(), v)); - } - public static WrappedConstraint operator !=(BaseEquality a, long v) { - return new WrappedConstraint(a.solver().MakeNonEquality(a.Var(), v)); - } - public static WrappedConstraint operator !=(long v, BaseEquality a) { - return new WrappedConstraint(a.solver().MakeNonEquality(a.Var(), v)); - } - public static WrappedConstraint operator >=(BaseEquality a, long v) { - return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a.Var(), v)); - } - public static WrappedConstraint operator >=(long v, BaseEquality a) { - return new WrappedConstraint(a.solver().MakeLessOrEqual(a.Var(), v)); - } - public static WrappedConstraint operator >(BaseEquality a, long v) { - return new WrappedConstraint(a.solver().MakeGreater(a.Var(), v)); - } - public static WrappedConstraint operator >(long v, BaseEquality a) { - return new WrappedConstraint(a.solver().MakeLess(a.Var(), v)); - } - public static WrappedConstraint operator <=(BaseEquality a, long v) { - return new WrappedConstraint(a.solver().MakeLessOrEqual(a.Var(), v)); - } - public static WrappedConstraint operator <=(long v, BaseEquality a) { - return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a.Var(), v)); - } - public static WrappedConstraint operator <(BaseEquality a, long v) { - return new WrappedConstraint(a.solver().MakeLess(a.Var(), v)); - } - public static WrappedConstraint operator <(long v, BaseEquality a) { - return new WrappedConstraint(a.solver().MakeGreater(a.Var(), v)); - } - public static WrappedConstraint operator >=(BaseEquality a, BaseEquality b) { - return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a.Var(), - b.Var())); - } - public static WrappedConstraint operator >(BaseEquality a, BaseEquality b) { - return new WrappedConstraint(a.solver().MakeGreater(a.Var(), b.Var())); - } - public static WrappedConstraint operator <=(BaseEquality a, BaseEquality b) { - return new WrappedConstraint(a.solver().MakeLessOrEqual(a.Var(), b.Var())); - } - public static WrappedConstraint operator <(BaseEquality a, BaseEquality b) { - return new WrappedConstraint(a.solver().MakeLess(a.Var(), b.Var())); - } - public static ConstraintEquality operator ==(BaseEquality a, BaseEquality b) { - return new ConstraintEquality(a, b, true); - } - public static ConstraintEquality operator !=(BaseEquality a, BaseEquality b) { - return new ConstraintEquality(a, b, false); - } -} - -public class WrappedConstraint : BaseEquality -{ - public bool Val { get; set; } - - public Constraint Cst { get; set; } - - public WrappedConstraint(Constraint cst) : this(true, cst) {} - - public WrappedConstraint(bool val) : this(val, null) {} - - public WrappedConstraint(bool val, Constraint cst) - { - this.Val = val; - this.Cst = cst; + public interface IConstraintWithStatus { + Solver solver(); + IntVar Var(); } - public static implicit operator bool(WrappedConstraint valCstPair) - { - return valCstPair.Val; + public abstract class BaseEquality : IConstraintWithStatus { + abstract public Solver solver(); + abstract public IntVar Var(); + + public static IntExpr operator +(BaseEquality a, BaseEquality b) { + return a.solver().MakeSum(a.Var(), b.Var()); + } + public static IntExpr operator +(BaseEquality a, long v) { + return a.solver().MakeSum(a.Var(), v); + } + public static IntExpr operator +(long v, BaseEquality a) { + return a.solver().MakeSum(a.Var(), v); + } + public static IntExpr operator -(BaseEquality a, BaseEquality b) { + return a.solver().MakeDifference(a.Var(), b.Var()); + } + public static IntExpr operator -(BaseEquality a, long v) { + return a.solver().MakeSum(a.Var(), -v); + } + public static IntExpr operator -(long v, BaseEquality a) { + return a.solver().MakeDifference(v, a.Var()); + } + public static IntExpr operator*(BaseEquality a, BaseEquality b) { + return a.solver().MakeProd(a.Var(), b.Var()); + } + public static IntExpr operator*(BaseEquality a, long v) { + return a.solver().MakeProd(a.Var(), v); + } + public static IntExpr operator*(long v, BaseEquality a) { + return a.solver().MakeProd(a.Var(), v); + } + public static IntExpr operator /(BaseEquality a, long v) { + return a.solver().MakeDiv(a.Var(), v); + } + public static IntExpr operator -(BaseEquality a) { + return a.solver().MakeOpposite(a.Var()); + } + public IntExpr Abs() { return this.solver().MakeAbs(this.Var()); } + public IntExpr Square() { return this.solver().MakeSquare(this.Var()); } + public static WrappedConstraint operator ==(BaseEquality a, long v) { + return new WrappedConstraint(a.solver().MakeEquality(a.Var(), v)); + } + public static WrappedConstraint operator ==(long v, BaseEquality a) { + return new WrappedConstraint(a.solver().MakeEquality(a.Var(), v)); + } + public static WrappedConstraint operator !=(BaseEquality a, long v) { + return new WrappedConstraint(a.solver().MakeNonEquality(a.Var(), v)); + } + public static WrappedConstraint operator !=(long v, BaseEquality a) { + return new WrappedConstraint(a.solver().MakeNonEquality(a.Var(), v)); + } + public static WrappedConstraint operator >=(BaseEquality a, long v) { + return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a.Var(), v)); + } + public static WrappedConstraint operator >=(long v, BaseEquality a) { + return new WrappedConstraint(a.solver().MakeLessOrEqual(a.Var(), v)); + } + public static WrappedConstraint operator>(BaseEquality a, long v) { + return new WrappedConstraint(a.solver().MakeGreater(a.Var(), v)); + } + public static WrappedConstraint operator>(long v, BaseEquality a) { + return new WrappedConstraint(a.solver().MakeLess(a.Var(), v)); + } + public static WrappedConstraint operator <=(BaseEquality a, long v) { + return new WrappedConstraint(a.solver().MakeLessOrEqual(a.Var(), v)); + } + public static WrappedConstraint operator <=(long v, BaseEquality a) { + return new WrappedConstraint(a.solver().MakeGreaterOrEqual(a.Var(), v)); + } + public static WrappedConstraint operator<(BaseEquality a, long v) { + return new WrappedConstraint(a.solver().MakeLess(a.Var(), v)); + } + public static WrappedConstraint operator<(long v, BaseEquality a) { + return new WrappedConstraint(a.solver().MakeGreater(a.Var(), v)); + } + public static WrappedConstraint operator >=(BaseEquality a, + BaseEquality b) { + return new WrappedConstraint( + a.solver().MakeGreaterOrEqual(a.Var(), b.Var())); + } + public static WrappedConstraint operator>(BaseEquality a, BaseEquality b) { + return new WrappedConstraint(a.solver().MakeGreater(a.Var(), b.Var())); + } + public static WrappedConstraint operator <=(BaseEquality a, + BaseEquality b) { + return new WrappedConstraint( + a.solver().MakeLessOrEqual(a.Var(), b.Var())); + } + public static WrappedConstraint operator<(BaseEquality a, BaseEquality b) { + return new WrappedConstraint(a.solver().MakeLess(a.Var(), b.Var())); + } + public static ConstraintEquality operator ==(BaseEquality a, + BaseEquality b) { + return new ConstraintEquality(a, b, true); + } + public static ConstraintEquality operator !=(BaseEquality a, + BaseEquality b) { + return new ConstraintEquality(a, b, false); + } } - public static implicit operator Constraint(WrappedConstraint valCstPair) - { - return valCstPair.Cst; + public class WrappedConstraint : BaseEquality { + public bool Val { + get; + set; + } + + public Constraint Cst { + get; + set; + } + + public WrappedConstraint(Constraint cst) : this(true, cst) {} + + public WrappedConstraint(bool val) : this(val, null) {} + + public WrappedConstraint(bool val, Constraint cst) { + this.Val = val; + this.Cst = cst; + } + + public static implicit operator bool(WrappedConstraint valCstPair) { + return valCstPair.Val; + } + + public static implicit operator Constraint(WrappedConstraint valCstPair) { + return valCstPair.Cst; + } + + public static implicit operator IntVar(WrappedConstraint eq) { + return eq.Var(); + } + + public static implicit operator IntExpr(WrappedConstraint eq) { + return eq.Var(); + } + + public override Solver solver() { return this.Cst.solver(); } + + public override IntVar Var() { return Cst.Var(); } } - public static implicit operator IntVar(WrappedConstraint eq) - { - return eq.Var(); + public class IntExprEquality : BaseEquality { + public IntExprEquality(IntExpr a, IntExpr b, bool equality) { + this.left_ = a; + this.right_ = b; + this.equality_ = equality; + } + + bool IsTrue() { + return (object) left_ == (object) right_ ? equality_ : !equality_; + } + + Constraint ToConstraint() { + return equality_ ? left_.solver() + .MakeEquality(left_.Var(), right_.Var()) + : left_.solver() + .MakeNonEquality(left_.Var(), right_.Var()); + } + + public static bool operator true(IntExprEquality eq) { return eq.IsTrue(); } + + public static bool operator false(IntExprEquality eq) { + return !eq.IsTrue(); + } + + public static implicit operator Constraint(IntExprEquality eq) { + return eq.ToConstraint(); + } + + public override IntVar Var() { + return equality_ ? left_.solver().MakeIsEqualVar(left_, right_) + : left_.solver().MakeIsDifferentVar(left_, right_); + } + + public static implicit operator IntVar(IntExprEquality eq) { + return eq.Var(); + } + + public static implicit operator IntExpr(IntExprEquality eq) { + return eq.Var(); + } + + public override Solver solver() { return left_.solver(); } + + private IntExpr left_; + private IntExpr right_; + private bool equality_; } - public static implicit operator IntExpr(WrappedConstraint eq) - { - return eq.Var(); + public class ConstraintEquality : BaseEquality { + public ConstraintEquality(IConstraintWithStatus a, IConstraintWithStatus b, + bool equality) { + this.left_ = a; + this.right_ = b; + this.equality_ = equality; + } + + bool IsTrue() { + return (object) left_ == (object) right_ ? equality_ : !equality_; + } + + Constraint ToConstraint() { + return equality_ ? left_.solver() + .MakeEquality(left_.Var(), right_.Var()) + : left_.solver() + .MakeNonEquality(left_.Var(), right_.Var()); + } + + public static bool operator true(ConstraintEquality eq) { + return eq.IsTrue(); + } + + public static bool operator false(ConstraintEquality eq) { + return !eq.IsTrue(); + } + + public static implicit operator Constraint(ConstraintEquality eq) { + return eq.ToConstraint(); + } + + public override IntVar Var() { + return equality_ ? left_.solver() + .MakeIsEqualVar(left_.Var(), right_.Var()) + : left_.solver() + .MakeIsDifferentVar(left_.Var(), right_.Var()); + } + + public static implicit operator IntVar(ConstraintEquality eq) { + return eq.Var(); + } + + public static implicit operator IntExpr(ConstraintEquality eq) { + return eq.Var(); + } + + public override Solver solver() { return left_.solver(); } + + private IConstraintWithStatus left_; + private IConstraintWithStatus right_; + private bool equality_; } - - public override Solver solver() - { - return this.Cst.solver(); - } - - public override IntVar Var() - { - return Cst.Var(); - } -} - -public class IntExprEquality : BaseEquality -{ - public IntExprEquality(IntExpr a, IntExpr b, bool equality) - { - this.left_ = a; - this.right_ = b; - this.equality_ = equality; - } - - bool IsTrue() - { - return (object)left_ == (object)right_ ? equality_ : !equality_; - } - - Constraint ToConstraint() - { - return equality_ ? - left_.solver().MakeEquality(left_.Var(), right_.Var()) : - left_.solver().MakeNonEquality(left_.Var(), right_.Var()); - } - - public static bool operator true(IntExprEquality eq) - { - return eq.IsTrue(); - } - - public static bool operator false(IntExprEquality eq) - { - return !eq.IsTrue(); - } - - public static implicit operator Constraint(IntExprEquality eq) - { - return eq.ToConstraint(); - } - - public override IntVar Var() - { - return equality_ ? - left_.solver().MakeIsEqualVar(left_, right_) : - left_.solver().MakeIsDifferentVar(left_, right_); - } - - public static implicit operator IntVar(IntExprEquality eq) - { - return eq.Var(); - } - - public static implicit operator IntExpr(IntExprEquality eq) - { - return eq.Var(); - } - - public override Solver solver() - { - return left_.solver(); - } - - private IntExpr left_; - private IntExpr right_; - private bool equality_; -} - -public class ConstraintEquality : BaseEquality -{ - public ConstraintEquality(IConstraintWithStatus a, - IConstraintWithStatus b, - bool equality) - { - this.left_ = a; - this.right_ = b; - this.equality_ = equality; - } - - bool IsTrue() - { - return (object)left_ == (object)right_ ? equality_ : !equality_; - } - - Constraint ToConstraint() - { - return equality_ ? - left_.solver().MakeEquality(left_.Var(), right_.Var()) : - left_.solver().MakeNonEquality(left_.Var(), right_.Var()); - } - - public static bool operator true(ConstraintEquality eq) - { - return eq.IsTrue(); - } - - public static bool operator false(ConstraintEquality eq) - { - return !eq.IsTrue(); - } - - public static implicit operator Constraint(ConstraintEquality eq) - { - return eq.ToConstraint(); - } - - public override IntVar Var() - { - return equality_ ? - left_.solver().MakeIsEqualVar(left_.Var(), right_.Var()) : - left_.solver().MakeIsDifferentVar(left_.Var(), right_.Var()); - } - - public static implicit operator IntVar(ConstraintEquality eq) - { - return eq.Var(); - } - - public static implicit operator IntExpr(ConstraintEquality eq) - { - return eq.Var(); - } - - public override Solver solver() - { - return left_.solver(); - } - - private IConstraintWithStatus left_; - private IConstraintWithStatus right_; - private bool equality_; -} } // namespace Google.OrTools.ConstraintSolver diff --git a/ortools/constraint_solver/samples/SimpleCpProgram.cs b/ortools/constraint_solver/samples/SimpleCpProgram.cs index f5a832fca3..c6dc5812a0 100644 --- a/ortools/constraint_solver/samples/SimpleCpProgram.cs +++ b/ortools/constraint_solver/samples/SimpleCpProgram.cs @@ -43,10 +43,9 @@ public class SimpleCpProgram { // Solve the problem. // [START solve] - DecisionBuilder db = solver.MakePhase( - new IntVar[]{x, y, z}, - Solver.CHOOSE_FIRST_UNBOUND, - Solver.ASSIGN_MIN_VALUE); + DecisionBuilder db = + solver.MakePhase(new IntVar[]{x, y, z}, Solver.CHOOSE_FIRST_UNBOUND, + Solver.ASSIGN_MIN_VALUE); // [END solve] // Print solution on console. @@ -55,7 +54,8 @@ public class SimpleCpProgram { solver.NewSearch(db); while (solver.NextSolution()) { ++count; - Console.WriteLine($"Solution: {count}\n x={x.Value()} y={y.Value()} z={z.Value()}"); + Console.WriteLine( + $"Solution: {count}\n x={x.Value()} y={y.Value()} z={z.Value()}"); } solver.EndSearch(); Console.WriteLine($"Number of solutions found: {solver.Solutions()}"); diff --git a/ortools/constraint_solver/samples/SimpleRoutingProgram.cs b/ortools/constraint_solver/samples/SimpleRoutingProgram.cs index e4d2a6320d..2ace3be674 100644 --- a/ortools/constraint_solver/samples/SimpleRoutingProgram.cs +++ b/ortools/constraint_solver/samples/SimpleRoutingProgram.cs @@ -31,10 +31,8 @@ public class SimpleRoutingProgram { // Create Routing Index Manager // [START index_manager] - RoutingIndexManager manager = new RoutingIndexManager( - numLocation, - numVehicles, - depot); + RoutingIndexManager manager = + new RoutingIndexManager(numLocation, numVehicles, depot); // [END index_manager] // Create Routing Model. @@ -44,13 +42,13 @@ public class SimpleRoutingProgram { // Create and register a transit callback. // [START transit_callback] - int transitCallbackIndex = routing.RegisterTransitCallback( - (long fromIndex, long toIndex) => { - // Convert from routing variable Index to distance matrix NodeIndex. - var fromNode = manager.IndexToNode(fromIndex); - var toNode = manager.IndexToNode(toIndex); - return Math.Abs(toNode - fromNode); - }); + int transitCallbackIndex = + routing.RegisterTransitCallback((long fromIndex, long toIndex) => { + // Convert from routing variable Index to distance matrix NodeIndex. + var fromNode = manager.IndexToNode(fromIndex); + var toNode = manager.IndexToNode(toIndex); + return Math.Abs(toNode - fromNode); + }); // [END transit_callback] // Define cost of each arc. @@ -79,7 +77,7 @@ public class SimpleRoutingProgram { Console.WriteLine("Route for Vehicle 0:"); long route_distance = 0; while (routing.IsEnd(index) == false) { - Console.Write("{0} -> ", manager.IndexToNode((int)index)); + Console.Write("{0} -> ", manager.IndexToNode((int) index)); long previousIndex = index; index = solution.Value(routing.NextVar(index)); route_distance += routing.GetArcCostForVehicle(previousIndex, index, 0); diff --git a/ortools/constraint_solver/samples/Tsp.cs b/ortools/constraint_solver/samples/Tsp.cs index 7e0f805dec..5e78c1c368 100644 --- a/ortools/constraint_solver/samples/Tsp.cs +++ b/ortools/constraint_solver/samples/Tsp.cs @@ -29,22 +29,14 @@ public class Tsp { // Constructor: public DataModel() { // Convert locations in meters using a city block dimension of 114m x 80m. - for (int i=0; i < Locations.GetLength(0); i++) { + for (int i = 0; i < Locations.GetLength(0); i++) { Locations[i, 0] *= 114; Locations[i, 1] *= 80; } } - public int[,] Locations = { - {4, 4}, - {2, 0}, {8, 0}, - {0, 1}, {1, 1}, - {5, 2}, {7, 2}, - {3, 3}, {6, 3}, - {5, 5}, {8, 5}, - {1, 6}, {2, 6}, - {3, 7}, {6, 7}, - {0, 8}, {7, 8} - }; + public int[, ] Locations = {{4, 4}, {2, 0}, {8, 0}, {0, 1}, {1, 1}, {5, 2}, + {7, 2}, {3, 3}, {6, 3}, {5, 5}, {8, 5}, {1, 6}, + {2, 6}, {3, 7}, {6, 7}, {0, 8}, {7, 8}}; public int VehicleNumber = 1; public int Depot = 0; }; @@ -57,9 +49,8 @@ public class Tsp { /// positions of two different indices. /// class ManhattanDistance { - public ManhattanDistance( - in DataModel data, - in RoutingIndexManager manager) { + public ManhattanDistance(in DataModel data, + in RoutingIndexManager manager) { // precompute distance between location to have distance callback in O(1) int locationNumber = data.Locations.GetLength(0); distancesMatrix_ = new long[locationNumber, locationNumber]; @@ -70,8 +61,10 @@ public class Tsp { distancesMatrix_[fromNode, toNode] = 0; else distancesMatrix_[fromNode, toNode] = - Math.Abs(data.Locations[toNode, 0] - data.Locations[fromNode, 0]) + - Math.Abs(data.Locations[toNode, 1] - data.Locations[fromNode, 1]); + Math.Abs(data.Locations[toNode, 0] - + data.Locations[fromNode, 0]) + + Math.Abs(data.Locations[toNode, 1] - + data.Locations[fromNode, 1]); } } } @@ -85,7 +78,7 @@ public class Tsp { int toNode = indexManager_.IndexToNode(toIndex); return distancesMatrix_[fromNode, toNode]; } - private long[,] distancesMatrix_; + private long[, ] distancesMatrix_; private RoutingIndexManager indexManager_; }; // [END manhattan_distance] @@ -94,22 +87,21 @@ public class Tsp { /// /// Print the solution. /// - static void PrintSolution( - in RoutingModel routing, - in RoutingIndexManager manager, - in Assignment solution) { + static void PrintSolution(in RoutingModel routing, + in RoutingIndexManager manager, + in Assignment solution) { Console.WriteLine("Objective: {0}", solution.ObjectiveValue()); // Inspect solution. Console.WriteLine("Route for Vehicle 0:"); long routeDistance = 0; var index = routing.Start(0); while (routing.IsEnd(index) == false) { - Console.Write("{0} -> ", manager.IndexToNode((int)index)); + Console.Write("{0} -> ", manager.IndexToNode((int) index)); var previousIndex = index; index = solution.Value(routing.NextVar(index)); routeDistance += routing.GetArcCostForVehicle(previousIndex, index, 0); } - Console.WriteLine("{0}", manager.IndexToNode((int)index)); + Console.WriteLine("{0}", manager.IndexToNode((int) index)); Console.WriteLine("Distance of the route: {0}m", routeDistance); } // [END solution_printer] @@ -123,9 +115,7 @@ public class Tsp { // Create Routing Index Manager // [START index_manager] RoutingIndexManager manager = new RoutingIndexManager( - data.Locations.GetLength(0), - data.VehicleNumber, - data.Depot); + data.Locations.GetLength(0), data.VehicleNumber, data.Depot); // [END index_manager] // Create Routing Model. @@ -136,7 +126,8 @@ public class Tsp { // Create and register a transit callback. // [START transit_callback] var distanceCallback = new ManhattanDistance(data, manager); - int transitCallbackIndex = routing.RegisterTransitCallback(distanceCallback.Call); + int transitCallbackIndex = + routing.RegisterTransitCallback(distanceCallback.Call); // [END transit_callback] // Define cost of each arc. @@ -147,9 +138,9 @@ public class Tsp { // Setting first solution heuristic. // [START parameters] RoutingSearchParameters searchParameters = - operations_research_constraint_solver.DefaultRoutingSearchParameters(); + operations_research_constraint_solver.DefaultRoutingSearchParameters(); searchParameters.FirstSolutionStrategy = - FirstSolutionStrategy.Types.Value.PathCheapestArc; + FirstSolutionStrategy.Types.Value.PathCheapestArc; // [END parameters] // Solve the problem. diff --git a/ortools/constraint_solver/samples/TspCircuitBoard.cs b/ortools/constraint_solver/samples/TspCircuitBoard.cs index cea3c63366..f45db0071c 100644 --- a/ortools/constraint_solver/samples/TspCircuitBoard.cs +++ b/ortools/constraint_solver/samples/TspCircuitBoard.cs @@ -26,52 +26,54 @@ using Google.OrTools.ConstraintSolver; public class TspCircuitBoard { // [START data_model] class DataModel { - public int[,] Locations = { - {288, 149}, {288, 129}, {270, 133}, {256, 141}, {256, 157}, {246, 157}, - {236, 169}, {228, 169}, {228, 161}, {220, 169}, {212, 169}, {204, 169}, - {196, 169}, {188, 169}, {196, 161}, {188, 145}, {172, 145}, {164, 145}, - {156, 145}, {148, 145}, {140, 145}, {148, 169}, {164, 169}, {172, 169}, - {156, 169}, {140, 169}, {132, 169}, {124, 169}, {116, 161}, {104, 153}, - {104, 161}, {104, 169}, {90, 165}, {80, 157}, {64, 157}, {64, 165}, - {56, 169}, {56, 161}, {56, 153}, {56, 145}, {56, 137}, {56, 129}, - {56, 121}, {40, 121}, {40, 129}, {40, 137}, {40, 145}, {40, 153}, - {40, 161}, {40, 169}, {32, 169}, {32, 161}, {32, 153}, {32, 145}, - {32, 137}, {32, 129}, {32, 121}, {32, 113}, {40, 113}, {56, 113}, - {56, 105}, {48, 99}, {40, 99}, {32, 97}, {32, 89}, {24, 89}, {16, 97}, - {16, 109}, {8, 109}, {8, 97}, {8, 89}, {8, 81}, {8, 73}, {8, 65}, - {8, 57}, {16, 57}, {8, 49}, {8, 41}, {24, 45}, {32, 41}, {32, 49}, - {32, 57}, {32, 65}, {32, 73}, {32, 81}, {40, 83}, {40, 73}, {40, 63}, - {40, 51}, {44, 43}, {44, 35}, {44, 27}, {32, 25}, {24, 25}, {16, 25}, - {16, 17}, {24, 17}, {32, 17}, {44, 11}, {56, 9}, {56, 17}, {56, 25}, - {56, 33}, {56, 41}, {64, 41}, {72, 41}, {72, 49}, {56, 49}, {48, 51}, - {56, 57}, {56, 65}, {48, 63}, {48, 73}, {56, 73}, {56, 81}, {48, 83}, - {56, 89}, {56, 97}, {104, 97}, {104, 105}, {104, 113}, {104, 121}, - {104, 129}, {104, 137}, {104, 145}, {116, 145}, {124, 145}, {132, 145}, - {132, 137}, {140, 137}, {148, 137}, {156, 137}, {164, 137}, {172, 125}, - {172, 117}, {172, 109}, {172, 101}, {172, 93}, {172, 85}, {180, 85}, - {180, 77}, {180, 69}, {180, 61}, {180, 53}, {172, 53}, {172, 61}, - {172, 69}, {172, 77}, {164, 81}, {148, 85}, {124, 85}, {124, 93}, - {124, 109}, {124, 125}, {124, 117}, {124, 101}, {104, 89}, {104, 81}, - {104, 73}, {104, 65}, {104, 49}, {104, 41}, {104, 33}, {104, 25}, - {104, 17}, {92, 9}, {80, 9}, {72, 9}, {64, 21}, {72, 25}, {80, 25}, - {80, 25}, {80, 41}, {88, 49}, {104, 57}, {124, 69}, {124, 77}, {132, 81}, - {140, 65}, {132, 61}, {124, 61}, {124, 53}, {124, 45}, {124, 37}, - {124, 29}, {132, 21}, {124, 21}, {120, 9}, {128, 9}, {136, 9}, {148, 9}, - {162, 9}, {156, 25}, {172, 21}, {180, 21}, {180, 29}, {172, 29}, - {172, 37}, {172, 45}, {180, 45}, {180, 37}, {188, 41}, {196, 49}, - {204, 57}, {212, 65}, {220, 73}, {228, 69}, {228, 77}, {236, 77}, - {236, 69}, {236, 61}, {228, 61}, {228, 53}, {236, 53}, {236, 45}, - {228, 45}, {228, 37}, {236, 37}, {236, 29}, {228, 29}, {228, 21}, - {236, 21}, {252, 21}, {260, 29}, {260, 37}, {260, 45}, {260, 53}, - {260, 61}, {260, 69}, {260, 77}, {276, 77}, {276, 69}, {276, 61}, - {276, 53}, {284, 53}, {284, 61}, {284, 69}, {284, 77}, {284, 85}, - {284, 93}, {284, 101}, {288, 109}, {280, 109}, {276, 101}, {276, 93}, - {276, 85}, {268, 97}, {260, 109}, {252, 101}, {260, 93}, {260, 85}, - {236, 85}, {228, 85}, {228, 93}, {236, 93}, {236, 101}, {228, 101}, - {228, 109}, {228, 117}, {228, 125}, {220, 125}, {212, 117}, {204, 109}, - {196, 101}, {188, 93}, {180, 93}, {180, 101}, {180, 109}, {180, 117}, - {180, 125}, {196, 145}, {204, 145}, {212, 145}, {220, 145}, {228, 145}, - {236, 145}, {246, 141}, {252, 125}, {260, 129}, {280, 133}, + public int[, ] Locations = { + {288, 149}, {288, 129}, {270, 133}, {256, 141}, {256, 157}, {246, 157}, + {236, 169}, {228, 169}, {228, 161}, {220, 169}, {212, 169}, {204, 169}, + {196, 169}, {188, 169}, {196, 161}, {188, 145}, {172, 145}, {164, 145}, + {156, 145}, {148, 145}, {140, 145}, {148, 169}, {164, 169}, {172, 169}, + {156, 169}, {140, 169}, {132, 169}, {124, 169}, {116, 161}, {104, 153}, + {104, 161}, {104, 169}, {90, 165}, {80, 157}, {64, 157}, {64, 165}, + {56, 169}, {56, 161}, {56, 153}, {56, 145}, {56, 137}, {56, 129}, + {56, 121}, {40, 121}, {40, 129}, {40, 137}, {40, 145}, {40, 153}, + {40, 161}, {40, 169}, {32, 169}, {32, 161}, {32, 153}, {32, 145}, + {32, 137}, {32, 129}, {32, 121}, {32, 113}, {40, 113}, {56, 113}, + {56, 105}, {48, 99}, {40, 99}, {32, 97}, {32, 89}, {24, 89}, + {16, 97}, {16, 109}, {8, 109}, {8, 97}, {8, 89}, {8, 81}, + {8, 73}, {8, 65}, {8, 57}, {16, 57}, {8, 49}, {8, 41}, + {24, 45}, {32, 41}, {32, 49}, {32, 57}, {32, 65}, {32, 73}, + {32, 81}, {40, 83}, {40, 73}, {40, 63}, {40, 51}, {44, 43}, + {44, 35}, {44, 27}, {32, 25}, {24, 25}, {16, 25}, {16, 17}, + {24, 17}, {32, 17}, {44, 11}, {56, 9}, {56, 17}, {56, 25}, + {56, 33}, {56, 41}, {64, 41}, {72, 41}, {72, 49}, {56, 49}, + {48, 51}, {56, 57}, {56, 65}, {48, 63}, {48, 73}, {56, 73}, + {56, 81}, {48, 83}, {56, 89}, {56, 97}, {104, 97}, {104, 105}, + {104, 113}, {104, 121}, {104, 129}, {104, 137}, {104, 145}, {116, 145}, + {124, 145}, {132, 145}, {132, 137}, {140, 137}, {148, 137}, {156, 137}, + {164, 137}, {172, 125}, {172, 117}, {172, 109}, {172, 101}, {172, 93}, + {172, 85}, {180, 85}, {180, 77}, {180, 69}, {180, 61}, {180, 53}, + {172, 53}, {172, 61}, {172, 69}, {172, 77}, {164, 81}, {148, 85}, + {124, 85}, {124, 93}, {124, 109}, {124, 125}, {124, 117}, {124, 101}, + {104, 89}, {104, 81}, {104, 73}, {104, 65}, {104, 49}, {104, 41}, + {104, 33}, {104, 25}, {104, 17}, {92, 9}, {80, 9}, {72, 9}, + {64, 21}, {72, 25}, {80, 25}, {80, 25}, {80, 41}, {88, 49}, + {104, 57}, {124, 69}, {124, 77}, {132, 81}, {140, 65}, {132, 61}, + {124, 61}, {124, 53}, {124, 45}, {124, 37}, {124, 29}, {132, 21}, + {124, 21}, {120, 9}, {128, 9}, {136, 9}, {148, 9}, {162, 9}, + {156, 25}, {172, 21}, {180, 21}, {180, 29}, {172, 29}, {172, 37}, + {172, 45}, {180, 45}, {180, 37}, {188, 41}, {196, 49}, {204, 57}, + {212, 65}, {220, 73}, {228, 69}, {228, 77}, {236, 77}, {236, 69}, + {236, 61}, {228, 61}, {228, 53}, {236, 53}, {236, 45}, {228, 45}, + {228, 37}, {236, 37}, {236, 29}, {228, 29}, {228, 21}, {236, 21}, + {252, 21}, {260, 29}, {260, 37}, {260, 45}, {260, 53}, {260, 61}, + {260, 69}, {260, 77}, {276, 77}, {276, 69}, {276, 61}, {276, 53}, + {284, 53}, {284, 61}, {284, 69}, {284, 77}, {284, 85}, {284, 93}, + {284, 101}, {288, 109}, {280, 109}, {276, 101}, {276, 93}, {276, 85}, + {268, 97}, {260, 109}, {252, 101}, {260, 93}, {260, 85}, {236, 85}, + {228, 85}, {228, 93}, {236, 93}, {236, 101}, {228, 101}, {228, 109}, + {228, 117}, {228, 125}, {220, 125}, {212, 117}, {204, 109}, {196, 101}, + {188, 93}, {180, 93}, {180, 101}, {180, 109}, {180, 117}, {180, 125}, + {196, 145}, {204, 145}, {212, 145}, {220, 145}, {228, 145}, {236, 145}, + {246, 141}, {252, 125}, {260, 129}, {280, 133}, }; public int VehicleNumber = 1; public int Depot = 0; @@ -84,17 +86,16 @@ public class TspCircuitBoard { /// positions and computes the Euclidean distance between the two /// positions of two different indices. /// - static long[,] ComputeEuclideanDistanceMatrix(in int[,] locations) { + static long[, ] ComputeEuclideanDistanceMatrix(in int[, ] locations) { // Calculate the distance matrix using Euclidean distance. int locationNumber = locations.GetLength(0); - long[,] distanceMatrix = new long[locationNumber, locationNumber]; + long[, ] distanceMatrix = new long[locationNumber, locationNumber]; for (int fromNode = 0; fromNode < locationNumber; fromNode++) { for (int toNode = 0; toNode < locationNumber; toNode++) { if (fromNode == toNode) distanceMatrix[fromNode, toNode] = 0; else - distanceMatrix[fromNode, toNode] = (long) - Math.Sqrt( + distanceMatrix[fromNode, toNode] = (long) Math.Sqrt( Math.Pow(locations[toNode, 0] - locations[fromNode, 0], 2) + Math.Pow(locations[toNode, 1] - locations[fromNode, 1], 2)); } @@ -107,22 +108,21 @@ public class TspCircuitBoard { /// /// Print the solution. /// - static void PrintSolution( - in RoutingModel routing, - in RoutingIndexManager manager, - in Assignment solution) { + static void PrintSolution(in RoutingModel routing, + in RoutingIndexManager manager, + in Assignment solution) { Console.WriteLine("Objective: {0}", solution.ObjectiveValue()); // Inspect solution. Console.WriteLine("Route:"); long routeDistance = 0; var index = routing.Start(0); while (routing.IsEnd(index) == false) { - Console.Write("{0} -> ", manager.IndexToNode((int)index)); + Console.Write("{0} -> ", manager.IndexToNode((int) index)); var previousIndex = index; index = solution.Value(routing.NextVar(index)); routeDistance += routing.GetArcCostForVehicle(previousIndex, index, 0); } - Console.WriteLine("{0}", manager.IndexToNode((int)index)); + Console.WriteLine("{0}", manager.IndexToNode((int) index)); Console.WriteLine("Route distance: {0}m", routeDistance); } // [END solution_printer] @@ -136,9 +136,7 @@ public class TspCircuitBoard { // Create Routing Index Manager // [START index_manager] RoutingIndexManager manager = new RoutingIndexManager( - data.Locations.GetLength(0), - data.VehicleNumber, - data.Depot); + data.Locations.GetLength(0), data.VehicleNumber, data.Depot); // [END index_manager] // Create Routing Model. @@ -148,14 +146,14 @@ public class TspCircuitBoard { // Define cost of each arc. // [START transit_callback] - long[,] distanceMatrix = ComputeEuclideanDistanceMatrix(data.Locations); - int transitCallbackIndex = routing.RegisterTransitCallback( - (long fromIndex, long toIndex) => { - // Convert from routing variable Index to distance matrix NodeIndex. - var fromNode = manager.IndexToNode(fromIndex); - var toNode = manager.IndexToNode(toIndex); - return distanceMatrix[fromNode, toNode]; } - ); + long[, ] distanceMatrix = ComputeEuclideanDistanceMatrix(data.Locations); + int transitCallbackIndex = + routing.RegisterTransitCallback((long fromIndex, long toIndex) => { + // Convert from routing variable Index to distance matrix NodeIndex. + var fromNode = manager.IndexToNode(fromIndex); + var toNode = manager.IndexToNode(toIndex); + return distanceMatrix[fromNode, toNode]; + }); // [END transit_callback] // [START arc_cost] @@ -165,9 +163,9 @@ public class TspCircuitBoard { // Setting first solution heuristic. // [START parameters] RoutingSearchParameters searchParameters = - operations_research_constraint_solver.DefaultRoutingSearchParameters(); + operations_research_constraint_solver.DefaultRoutingSearchParameters(); searchParameters.FirstSolutionStrategy = - FirstSolutionStrategy.Types.Value.PathCheapestArc; + FirstSolutionStrategy.Types.Value.PathCheapestArc; // [END parameters] // Solve the problem. diff --git a/ortools/constraint_solver/samples/TspCities.cs b/ortools/constraint_solver/samples/TspCities.cs index 48a2a5bc3b..146438e0d8 100644 --- a/ortools/constraint_solver/samples/TspCities.cs +++ b/ortools/constraint_solver/samples/TspCities.cs @@ -24,20 +24,23 @@ using Google.OrTools.ConstraintSolver; public class TspCities { // [START data_model] class DataModel { - public long[,] DistanceMatrix = { - {0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972}, - {2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579}, - {713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260}, - {1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987}, - {1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371}, - {1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999}, - {2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701}, - {213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099}, - {2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600}, - {875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162}, - {1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200}, - {2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504}, - {1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0}, + public long[, ] DistanceMatrix = { + {0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, + 1972}, + {2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579}, + {713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260}, + {1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987}, + {1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371}, + {1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999}, + {2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, + 701}, + {213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, + 2099}, + {2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600}, + {875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162}, + {1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200}, + {2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504}, + {1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0}, }; public int VehicleNumber = 1; public int Depot = 0; @@ -48,22 +51,21 @@ public class TspCities { /// /// Print the solution. /// - static void PrintSolution( - in RoutingModel routing, - in RoutingIndexManager manager, - in Assignment solution) { + static void PrintSolution(in RoutingModel routing, + in RoutingIndexManager manager, + in Assignment solution) { Console.WriteLine("Objective: {0} miles", solution.ObjectiveValue()); // Inspect solution. Console.WriteLine("Route:"); long routeDistance = 0; var index = routing.Start(0); while (routing.IsEnd(index) == false) { - Console.Write("{0} -> ", manager.IndexToNode((int)index)); + Console.Write("{0} -> ", manager.IndexToNode((int) index)); var previousIndex = index; index = solution.Value(routing.NextVar(index)); routeDistance += routing.GetArcCostForVehicle(previousIndex, index, 0); } - Console.WriteLine("{0}", manager.IndexToNode((int)index)); + Console.WriteLine("{0}", manager.IndexToNode((int) index)); Console.WriteLine("Route distance: {0}miles", routeDistance); } // [END solution_printer] @@ -77,9 +79,7 @@ public class TspCities { // Create Routing Index Manager // [START index_manager] RoutingIndexManager manager = new RoutingIndexManager( - data.DistanceMatrix.GetLength(0), - data.VehicleNumber, - data.Depot); + data.DistanceMatrix.GetLength(0), data.VehicleNumber, data.Depot); // [END index_manager] // Create Routing Model. @@ -88,13 +88,13 @@ public class TspCities { // [END routing_model] // [START transit_callback] - int transitCallbackIndex = routing.RegisterTransitCallback( - (long fromIndex, long toIndex) => { - // Convert from routing variable Index to distance matrix NodeIndex. - var fromNode = manager.IndexToNode(fromIndex); - var toNode = manager.IndexToNode(toIndex); - return data.DistanceMatrix[fromNode, toNode]; } - ); + int transitCallbackIndex = + routing.RegisterTransitCallback((long fromIndex, long toIndex) => { + // Convert from routing variable Index to distance matrix NodeIndex. + var fromNode = manager.IndexToNode(fromIndex); + var toNode = manager.IndexToNode(toIndex); + return data.DistanceMatrix[fromNode, toNode]; + }); // [END transit_callback] // Define cost of each arc. @@ -105,9 +105,9 @@ public class TspCities { // Setting first solution heuristic. // [START parameters] RoutingSearchParameters searchParameters = - operations_research_constraint_solver.DefaultRoutingSearchParameters(); + operations_research_constraint_solver.DefaultRoutingSearchParameters(); searchParameters.FirstSolutionStrategy = - FirstSolutionStrategy.Types.Value.PathCheapestArc; + FirstSolutionStrategy.Types.Value.PathCheapestArc; // [END parameters] // Solve the problem. diff --git a/ortools/constraint_solver/samples/TspDistanceMatrix.cs b/ortools/constraint_solver/samples/TspDistanceMatrix.cs index d4dda047d3..de6dfed9c8 100644 --- a/ortools/constraint_solver/samples/TspDistanceMatrix.cs +++ b/ortools/constraint_solver/samples/TspDistanceMatrix.cs @@ -24,25 +24,41 @@ using Google.OrTools.ConstraintSolver; public class TspDistanceMatrix { // [START data_model] class DataModel { - public long[,] DistanceMatrix = { - {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662}, - {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210}, - {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754}, - {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358}, - {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244}, - {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708}, - {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480}, - {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856}, - {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514}, - {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468}, - {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354}, - {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844}, - {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730}, - {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536}, - {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194}, - {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798}, - {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0} - }; + public long[, ] DistanceMatrix = { + {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, + 468, 776, 662}, + {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, + 1016, 868, 1210}, + {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, + 788, 1552, 754}, + {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, + 1164, 560, 1358}, + {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, + 1050, 674, 1244}, + {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, + 514, 1050, 708}, + {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, + 514, 1278, 480}, + {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, + 662, 742, 856}, + {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, + 320, 1084, 514}, + {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, + 274, 810, 468}, + {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, + 388, 1152, 354}, + {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, + 650, 274, 844}, + {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, + 536, 388, 730}, + {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, + 342, 422, 536}, + {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, + 342, 0, 764, 194}, + {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, + 422, 764, 0, 798}, + {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, + 536, 194, 798, 0}}; public int VehicleNumber = 1; public int Depot = 0; }; @@ -52,22 +68,21 @@ public class TspDistanceMatrix { /// /// Print the solution. /// - static void PrintSolution( - in RoutingModel routing, - in RoutingIndexManager manager, - in Assignment solution) { + static void PrintSolution(in RoutingModel routing, + in RoutingIndexManager manager, + in Assignment solution) { Console.WriteLine("Objective: {0}", solution.ObjectiveValue()); // Inspect solution. Console.WriteLine("Route for Vehicle 0:"); long routeDistance = 0; var index = routing.Start(0); while (routing.IsEnd(index) == false) { - Console.Write("{0} -> ", manager.IndexToNode((int)index)); + Console.Write("{0} -> ", manager.IndexToNode((int) index)); var previousIndex = index; index = solution.Value(routing.NextVar(index)); routeDistance += routing.GetArcCostForVehicle(previousIndex, index, 0); } - Console.WriteLine("{0}", manager.IndexToNode((int)index)); + Console.WriteLine("{0}", manager.IndexToNode((int) index)); Console.WriteLine("Distance of the route: {0}m", routeDistance); } // [END solution_printer] @@ -81,9 +96,7 @@ public class TspDistanceMatrix { // Create Routing Index Manager // [START index_manager] RoutingIndexManager manager = new RoutingIndexManager( - data.DistanceMatrix.GetLength(0), - data.VehicleNumber, - data.Depot); + data.DistanceMatrix.GetLength(0), data.VehicleNumber, data.Depot); // [END index_manager] // Create Routing Model. @@ -93,13 +106,13 @@ public class TspDistanceMatrix { // Create and register a transit callback. // [START transit_callback] - int transitCallbackIndex = routing.RegisterTransitCallback( - (long fromIndex, long toIndex) => { - // Convert from routing variable Index to distance matrix NodeIndex. - var fromNode = manager.IndexToNode(fromIndex); - var toNode = manager.IndexToNode(toIndex); - return data.DistanceMatrix[fromNode, toNode]; } - ); + int transitCallbackIndex = + routing.RegisterTransitCallback((long fromIndex, long toIndex) => { + // Convert from routing variable Index to distance matrix NodeIndex. + var fromNode = manager.IndexToNode(fromIndex); + var toNode = manager.IndexToNode(toIndex); + return data.DistanceMatrix[fromNode, toNode]; + }); // [END transit_callback] // Define cost of each arc. @@ -110,9 +123,9 @@ public class TspDistanceMatrix { // Setting first solution heuristic. // [START parameters] RoutingSearchParameters searchParameters = - operations_research_constraint_solver.DefaultRoutingSearchParameters(); + operations_research_constraint_solver.DefaultRoutingSearchParameters(); searchParameters.FirstSolutionStrategy = - FirstSolutionStrategy.Types.Value.PathCheapestArc; + FirstSolutionStrategy.Types.Value.PathCheapestArc; // [END parameters] // Solve the problem. diff --git a/ortools/constraint_solver/samples/Vrp.cs b/ortools/constraint_solver/samples/Vrp.cs index 89b9b59819..35f58ec6a6 100644 --- a/ortools/constraint_solver/samples/Vrp.cs +++ b/ortools/constraint_solver/samples/Vrp.cs @@ -24,25 +24,41 @@ using Google.OrTools.ConstraintSolver; public class Vrp { // [START data_model] class DataModel { - public long[,] DistanceMatrix = { - {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662}, - {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210}, - {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754}, - {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358}, - {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244}, - {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708}, - {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480}, - {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856}, - {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514}, - {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468}, - {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354}, - {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844}, - {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730}, - {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536}, - {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194}, - {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798}, - {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0} - }; + public long[, ] DistanceMatrix = { + {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, + 468, 776, 662}, + {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, + 1016, 868, 1210}, + {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, + 788, 1552, 754}, + {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, + 1164, 560, 1358}, + {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, + 1050, 674, 1244}, + {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, + 514, 1050, 708}, + {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, + 514, 1278, 480}, + {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, + 662, 742, 856}, + {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, + 320, 1084, 514}, + {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, + 274, 810, 468}, + {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, + 388, 1152, 354}, + {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, + 650, 274, 844}, + {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, + 536, 388, 730}, + {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, + 342, 422, 536}, + {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, + 342, 0, 764, 194}, + {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, + 422, 764, 0, 798}, + {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, + 536, 194, 798, 0}}; public int VehicleNumber = 4; public int Depot = 0; }; @@ -52,11 +68,9 @@ public class Vrp { /// /// Print the solution. /// - static void PrintSolution( - in DataModel data, - in RoutingModel routing, - in RoutingIndexManager manager, - in Assignment solution) { + static void PrintSolution(in DataModel data, in RoutingModel routing, + in RoutingIndexManager manager, + in Assignment solution) { Console.WriteLine("Objective: {0}", solution.ObjectiveValue()); // Inspect solution. long totalDistance = 0; @@ -65,12 +79,12 @@ public class Vrp { long routeDistance = 0; var index = routing.Start(i); while (routing.IsEnd(index) == false) { - Console.Write("{0} -> ", manager.IndexToNode((int)index)); + Console.Write("{0} -> ", manager.IndexToNode((int) index)); var previousIndex = index; index = solution.Value(routing.NextVar(index)); routeDistance += routing.GetArcCostForVehicle(previousIndex, index, 0); } - Console.WriteLine("{0}", manager.IndexToNode((int)index)); + Console.WriteLine("{0}", manager.IndexToNode((int) index)); Console.WriteLine("Distance of the route: {0}m", routeDistance); totalDistance += routeDistance; } @@ -87,9 +101,7 @@ public class Vrp { // Create Routing Index Manager // [START index_manager] RoutingIndexManager manager = new RoutingIndexManager( - data.DistanceMatrix.GetLength(0), - data.VehicleNumber, - data.Depot); + data.DistanceMatrix.GetLength(0), data.VehicleNumber, data.Depot); // [END index_manager] // Create Routing Model. @@ -99,13 +111,13 @@ public class Vrp { // Create and register a transit callback. // [START transit_callback] - int transitCallbackIndex = routing.RegisterTransitCallback( - (long fromIndex, long toIndex) => { - // Convert from routing variable Index to distance matrix NodeIndex. - var fromNode = manager.IndexToNode(fromIndex); - var toNode = manager.IndexToNode(toIndex); - return data.DistanceMatrix[fromNode, toNode]; } - ); + int transitCallbackIndex = + routing.RegisterTransitCallback((long fromIndex, long toIndex) => { + // Convert from routing variable Index to distance matrix NodeIndex. + var fromNode = manager.IndexToNode(fromIndex); + var toNode = manager.IndexToNode(toIndex); + return data.DistanceMatrix[fromNode, toNode]; + }); // [END transit_callback] // Define cost of each arc. @@ -116,9 +128,9 @@ public class Vrp { // Setting first solution heuristic. // [START parameters] RoutingSearchParameters searchParameters = - operations_research_constraint_solver.DefaultRoutingSearchParameters(); + operations_research_constraint_solver.DefaultRoutingSearchParameters(); searchParameters.FirstSolutionStrategy = - FirstSolutionStrategy.Types.Value.PathCheapestArc; + FirstSolutionStrategy.Types.Value.PathCheapestArc; // [END parameters] // Solve the problem. diff --git a/ortools/constraint_solver/samples/VrpCapacity.cs b/ortools/constraint_solver/samples/VrpCapacity.cs index ccb2253e7b..c8e3fe7752 100644 --- a/ortools/constraint_solver/samples/VrpCapacity.cs +++ b/ortools/constraint_solver/samples/VrpCapacity.cs @@ -16,7 +16,7 @@ using System; using System.Collections.Generic; using Google.OrTools.ConstraintSolver; -using Google.Protobuf.WellKnownTypes; // Duration +using Google.Protobuf.WellKnownTypes; // Duration // [END import] /// @@ -25,25 +25,41 @@ using Google.Protobuf.WellKnownTypes; // Duration public class VrpCapacity { // [START data_model] class DataModel { - public long[,] DistanceMatrix = { - {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662}, - {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210}, - {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754}, - {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358}, - {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244}, - {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708}, - {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480}, - {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856}, - {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514}, - {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468}, - {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354}, - {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844}, - {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730}, - {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536}, - {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194}, - {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798}, - {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0} - }; + public long[, ] DistanceMatrix = { + {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, + 468, 776, 662}, + {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, + 1016, 868, 1210}, + {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, + 788, 1552, 754}, + {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, + 1164, 560, 1358}, + {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, + 1050, 674, 1244}, + {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, + 514, 1050, 708}, + {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, + 514, 1278, 480}, + {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, + 662, 742, 856}, + {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, + 320, 1084, 514}, + {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, + 274, 810, 468}, + {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, + 388, 1152, 354}, + {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, + 650, 274, 844}, + {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, + 536, 388, 730}, + {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, + 342, 422, 536}, + {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, + 342, 0, 764, 194}, + {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, + 422, 764, 0, 798}, + {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, + 536, 194, 798, 0}}; // [START demands_capacities] public long[] Demands = {0, 1, 1, 2, 4, 2, 4, 8, 8, 1, 2, 1, 2, 4, 4, 8, 8}; public long[] VehicleCapacities = {15, 15, 15, 15}; @@ -57,11 +73,9 @@ public class VrpCapacity { /// /// Print the solution. /// - static void PrintSolution( - in DataModel data, - in RoutingModel routing, - in RoutingIndexManager manager, - in Assignment solution) { + static void PrintSolution(in DataModel data, in RoutingModel routing, + in RoutingIndexManager manager, + in Assignment solution) { // Inspect solution. long totalDistance = 0; long totalLoad = 0; @@ -78,7 +92,7 @@ public class VrpCapacity { index = solution.Value(routing.NextVar(index)); routeDistance += routing.GetArcCostForVehicle(previousIndex, index, 0); } - Console.WriteLine("{0}", manager.IndexToNode((int)index)); + Console.WriteLine("{0}", manager.IndexToNode((int) index)); Console.WriteLine("Distance of the route: {0}m", routeDistance); totalDistance += routeDistance; totalLoad += routeLoad; @@ -97,9 +111,7 @@ public class VrpCapacity { // Create Routing Index Manager // [START index_manager] RoutingIndexManager manager = new RoutingIndexManager( - data.DistanceMatrix.GetLength(0), - data.VehicleNumber, - data.Depot); + data.DistanceMatrix.GetLength(0), data.VehicleNumber, data.Depot); // [END index_manager] // Create Routing Model. @@ -109,13 +121,13 @@ public class VrpCapacity { // Create and register a transit callback. // [START transit_callback] - int transitCallbackIndex = routing.RegisterTransitCallback( - (long fromIndex, long toIndex) => { - // Convert from routing variable Index to distance matrix NodeIndex. - var fromNode = manager.IndexToNode(fromIndex); - var toNode = manager.IndexToNode(toIndex); - return data.DistanceMatrix[fromNode, toNode]; } - ); + int transitCallbackIndex = + routing.RegisterTransitCallback((long fromIndex, long toIndex) => { + // Convert from routing variable Index to distance matrix NodeIndex. + var fromNode = manager.IndexToNode(fromIndex); + var toNode = manager.IndexToNode(toIndex); + return data.DistanceMatrix[fromNode, toNode]; + }); // [END transit_callback] // Define cost of each arc. @@ -125,27 +137,28 @@ public class VrpCapacity { // Add Capacity constraint. // [START capacity_constraint] - int demandCallbackIndex = routing.RegisterUnaryTransitCallback( - (long fromIndex) => { - // Convert from routing variable Index to demand NodeIndex. - var fromNode = manager.IndexToNode(fromIndex); - return data.Demands[fromNode]; } - ); + int demandCallbackIndex = + routing.RegisterUnaryTransitCallback((long fromIndex) => { + // Convert from routing variable Index to demand NodeIndex. + var fromNode = manager.IndexToNode(fromIndex); + return data.Demands[fromNode]; + }); routing.AddDimensionWithVehicleCapacity( - demandCallbackIndex, 0, // null capacity slack - data.VehicleCapacities, // vehicle maximum capacities - true, // start cumul to zero - "Capacity"); + demandCallbackIndex, 0, // null capacity slack + data.VehicleCapacities, // vehicle maximum capacities + true, // start cumul to zero + "Capacity"); // [END capacity_constraint] // Setting first solution heuristic. // [START parameters] RoutingSearchParameters searchParameters = - operations_research_constraint_solver.DefaultRoutingSearchParameters(); + operations_research_constraint_solver.DefaultRoutingSearchParameters(); searchParameters.FirstSolutionStrategy = - FirstSolutionStrategy.Types.Value.PathCheapestArc; - searchParameters.LocalSearchMetaheuristic = LocalSearchMetaheuristic.Types.Value.GuidedLocalSearch; - searchParameters.TimeLimit = new Duration { Seconds = 1 }; + FirstSolutionStrategy.Types.Value.PathCheapestArc; + searchParameters.LocalSearchMetaheuristic = + LocalSearchMetaheuristic.Types.Value.GuidedLocalSearch; + searchParameters.TimeLimit = new Duration{Seconds = 1}; // [END parameters] // Solve the problem. diff --git a/ortools/constraint_solver/samples/VrpDropNodes.cs b/ortools/constraint_solver/samples/VrpDropNodes.cs index 085fdb158c..d87207a78c 100644 --- a/ortools/constraint_solver/samples/VrpDropNodes.cs +++ b/ortools/constraint_solver/samples/VrpDropNodes.cs @@ -16,7 +16,7 @@ using System; using System.Collections.Generic; using Google.OrTools.ConstraintSolver; -using Google.Protobuf.WellKnownTypes; // Duration +using Google.Protobuf.WellKnownTypes; // Duration // [END import] /// @@ -25,25 +25,41 @@ using Google.Protobuf.WellKnownTypes; // Duration public class VrpDropNodes { // [START data_model] class DataModel { - public long[,] DistanceMatrix = { - {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662}, - {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210}, - {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754}, - {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358}, - {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244}, - {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708}, - {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480}, - {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856}, - {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514}, - {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468}, - {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354}, - {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844}, - {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730}, - {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536}, - {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194}, - {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798}, - {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0} - }; + public long[, ] DistanceMatrix = { + {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, + 468, 776, 662}, + {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, + 1016, 868, 1210}, + {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, + 788, 1552, 754}, + {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, + 1164, 560, 1358}, + {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, + 1050, 674, 1244}, + {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, + 514, 1050, 708}, + {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, + 514, 1278, 480}, + {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, + 662, 742, 856}, + {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, + 320, 1084, 514}, + {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, + 274, 810, 468}, + {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, + 388, 1152, 354}, + {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, + 650, 274, 844}, + {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, + 536, 388, 730}, + {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, + 342, 422, 536}, + {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, + 342, 0, 764, 194}, + {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, + 422, 764, 0, 798}, + {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, + 536, 194, 798, 0}}; // [START demands_capacities] public long[] Demands = {0, 1, 1, 3, 6, 3, 6, 8, 8, 1, 2, 1, 2, 6, 6, 8, 8}; public long[] VehicleCapacities = {15, 15, 15, 15}; @@ -57,11 +73,9 @@ public class VrpDropNodes { /// /// Print the solution. /// - static void PrintSolution( - in DataModel data, - in RoutingModel routing, - in RoutingIndexManager manager, - in Assignment solution) { + static void PrintSolution(in DataModel data, in RoutingModel routing, + in RoutingIndexManager manager, + in Assignment solution) { // Display dropped nodes. string droppedNodes = "Dropped nodes:"; for (int index = 0; index < routing.Size(); ++index) { @@ -89,7 +103,7 @@ public class VrpDropNodes { index = solution.Value(routing.NextVar(index)); routeDistance += routing.GetArcCostForVehicle(previousIndex, index, 0); } - Console.WriteLine("{0}", manager.IndexToNode((int)index)); + Console.WriteLine("{0}", manager.IndexToNode((int) index)); Console.WriteLine("Distance of the route: {0}m", routeDistance); totalDistance += routeDistance; totalLoad += routeLoad; @@ -108,9 +122,7 @@ public class VrpDropNodes { // Create Routing Index Manager // [START index_manager] RoutingIndexManager manager = new RoutingIndexManager( - data.DistanceMatrix.GetLength(0), - data.VehicleNumber, - data.Depot); + data.DistanceMatrix.GetLength(0), data.VehicleNumber, data.Depot); // [END index_manager] // Create Routing Model. @@ -120,13 +132,13 @@ public class VrpDropNodes { // Create and register a transit callback. // [START transit_callback] - int transitCallbackIndex = routing.RegisterTransitCallback( - (long fromIndex, long toIndex) => { - // Convert from routing variable Index to distance matrix NodeIndex. - var fromNode = manager.IndexToNode(fromIndex); - var toNode = manager.IndexToNode(toIndex); - return data.DistanceMatrix[fromNode, toNode]; } - ); + int transitCallbackIndex = + routing.RegisterTransitCallback((long fromIndex, long toIndex) => { + // Convert from routing variable Index to distance matrix NodeIndex. + var fromNode = manager.IndexToNode(fromIndex); + var toNode = manager.IndexToNode(toIndex); + return data.DistanceMatrix[fromNode, toNode]; + }); // [END transit_callback] // Define cost of each arc. @@ -136,33 +148,33 @@ public class VrpDropNodes { // Add Capacity constraint. // [START capacity_constraint] - int demandCallbackIndex = routing.RegisterUnaryTransitCallback( - (long fromIndex) => { - // Convert from routing variable Index to demand NodeIndex. - var fromNode = manager.IndexToNode(fromIndex); - return data.Demands[fromNode]; } - ); + int demandCallbackIndex = + routing.RegisterUnaryTransitCallback((long fromIndex) => { + // Convert from routing variable Index to demand NodeIndex. + var fromNode = manager.IndexToNode(fromIndex); + return data.Demands[fromNode]; + }); routing.AddDimensionWithVehicleCapacity( demandCallbackIndex, 0, // null capacity slack - data.VehicleCapacities, // vehicle maximum capacities - true, // start cumul to zero + data.VehicleCapacities, // vehicle maximum capacities + true, // start cumul to zero "Capacity"); // Allow to drop nodes. long penalty = 1000; for (int i = 1; i < data.DistanceMatrix.GetLength(0); ++i) { - routing.AddDisjunction( - new long[] {manager.NodeToIndex(i)}, penalty); + routing.AddDisjunction(new long[]{manager.NodeToIndex(i)}, penalty); } // [END capacity_constraint] // Setting first solution heuristic. // [START parameters] RoutingSearchParameters searchParameters = - operations_research_constraint_solver.DefaultRoutingSearchParameters(); + operations_research_constraint_solver.DefaultRoutingSearchParameters(); searchParameters.FirstSolutionStrategy = - FirstSolutionStrategy.Types.Value.PathCheapestArc; - searchParameters.LocalSearchMetaheuristic = LocalSearchMetaheuristic.Types.Value.GuidedLocalSearch; - searchParameters.TimeLimit = new Duration { Seconds = 1 }; + FirstSolutionStrategy.Types.Value.PathCheapestArc; + searchParameters.LocalSearchMetaheuristic = + LocalSearchMetaheuristic.Types.Value.GuidedLocalSearch; + searchParameters.TimeLimit = new Duration{Seconds = 1}; // [END parameters] // Solve the problem. diff --git a/ortools/constraint_solver/samples/VrpGlobalSpan.cs b/ortools/constraint_solver/samples/VrpGlobalSpan.cs index bf061ce509..165081985f 100644 --- a/ortools/constraint_solver/samples/VrpGlobalSpan.cs +++ b/ortools/constraint_solver/samples/VrpGlobalSpan.cs @@ -24,25 +24,41 @@ using Google.OrTools.ConstraintSolver; public class VrpGlobalSpan { // [START data_model] class DataModel { - public long[,] DistanceMatrix = { - {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662}, - {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210}, - {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754}, - {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358}, - {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244}, - {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708}, - {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480}, - {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856}, - {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514}, - {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468}, - {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354}, - {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844}, - {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730}, - {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536}, - {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194}, - {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798}, - {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0} - }; + public long[, ] DistanceMatrix = { + {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, + 468, 776, 662}, + {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, + 1016, 868, 1210}, + {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, + 788, 1552, 754}, + {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, + 1164, 560, 1358}, + {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, + 1050, 674, 1244}, + {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, + 514, 1050, 708}, + {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, + 514, 1278, 480}, + {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, + 662, 742, 856}, + {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, + 320, 1084, 514}, + {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, + 274, 810, 468}, + {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, + 388, 1152, 354}, + {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, + 650, 274, 844}, + {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, + 536, 388, 730}, + {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, + 342, 422, 536}, + {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, + 342, 0, 764, 194}, + {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, + 422, 764, 0, 798}, + {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, + 536, 194, 798, 0}}; public int VehicleNumber = 4; public int Depot = 0; }; @@ -52,11 +68,9 @@ public class VrpGlobalSpan { /// /// Print the solution. /// - static void PrintSolution( - in DataModel data, - in RoutingModel routing, - in RoutingIndexManager manager, - in Assignment solution) { + static void PrintSolution(in DataModel data, in RoutingModel routing, + in RoutingIndexManager manager, + in Assignment solution) { // Inspect solution. long maxRouteDistance = 0; for (int i = 0; i < data.VehicleNumber; ++i) { @@ -64,12 +78,12 @@ public class VrpGlobalSpan { long routeDistance = 0; var index = routing.Start(i); while (routing.IsEnd(index) == false) { - Console.Write("{0} -> ", manager.IndexToNode((int)index)); + Console.Write("{0} -> ", manager.IndexToNode((int) index)); var previousIndex = index; index = solution.Value(routing.NextVar(index)); routeDistance += routing.GetArcCostForVehicle(previousIndex, index, 0); } - Console.WriteLine("{0}", manager.IndexToNode((int)index)); + Console.WriteLine("{0}", manager.IndexToNode((int) index)); Console.WriteLine("Distance of the route: {0}m", routeDistance); maxRouteDistance = Math.Max(routeDistance, maxRouteDistance); } @@ -86,9 +100,7 @@ public class VrpGlobalSpan { // Create Routing Index Manager // [START index_manager] RoutingIndexManager manager = new RoutingIndexManager( - data.DistanceMatrix.GetLength(0), - data.VehicleNumber, - data.Depot); + data.DistanceMatrix.GetLength(0), data.VehicleNumber, data.Depot); // [END index_manager] @@ -99,13 +111,13 @@ public class VrpGlobalSpan { // Create and register a transit callback. // [START transit_callback] - int transitCallbackIndex = routing.RegisterTransitCallback( - (long fromIndex, long toIndex) => { - // Convert from routing variable Index to distance matrix NodeIndex. - var fromNode = manager.IndexToNode(fromIndex); - var toNode = manager.IndexToNode(toIndex); - return data.DistanceMatrix[fromNode, toNode]; } - ); + int transitCallbackIndex = + routing.RegisterTransitCallback((long fromIndex, long toIndex) => { + // Convert from routing variable Index to distance matrix NodeIndex. + var fromNode = manager.IndexToNode(fromIndex); + var toNode = manager.IndexToNode(toIndex); + return data.DistanceMatrix[fromNode, toNode]; + }); // [END transit_callback] // Define cost of each arc. @@ -116,18 +128,19 @@ public class VrpGlobalSpan { // Add Distance constraint. // [START distance_constraint] routing.AddDimension(transitCallbackIndex, 0, 3000, - true, // start cumul to zero - "Distance"); - RoutingDimension distanceDimension = routing.GetMutableDimension("Distance"); + true, // start cumul to zero + "Distance"); + RoutingDimension distanceDimension = + routing.GetMutableDimension("Distance"); distanceDimension.SetGlobalSpanCostCoefficient(100); // [END distance_constraint] // Setting first solution heuristic. // [START parameters] RoutingSearchParameters searchParameters = - operations_research_constraint_solver.DefaultRoutingSearchParameters(); + operations_research_constraint_solver.DefaultRoutingSearchParameters(); searchParameters.FirstSolutionStrategy = - FirstSolutionStrategy.Types.Value.PathCheapestArc; + FirstSolutionStrategy.Types.Value.PathCheapestArc; // [END parameters] // Solve the problem. diff --git a/ortools/constraint_solver/samples/VrpInitialRoutes.cs b/ortools/constraint_solver/samples/VrpInitialRoutes.cs index 1e73f54449..3812edca94 100644 --- a/ortools/constraint_solver/samples/VrpInitialRoutes.cs +++ b/ortools/constraint_solver/samples/VrpInitialRoutes.cs @@ -24,33 +24,50 @@ using Google.OrTools.ConstraintSolver; public class InitialRoutes { // [START data_model] class DataModel { - public long[,] DistanceMatrix = { - {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662}, - {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210}, - {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754}, - {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358}, - {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244}, - {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708}, - {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480}, - {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856}, - {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514}, - {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468}, - {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354}, - {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844}, - {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730}, - {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536}, - {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194}, - {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798}, - {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0}, + public long[, ] DistanceMatrix = { + {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, + 468, 776, 662}, + {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, + 1016, 868, 1210}, + {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, + 788, 1552, 754}, + {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, + 1164, 560, 1358}, + {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, + 1050, 674, 1244}, + {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, + 514, 1050, 708}, + {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, + 514, 1278, 480}, + {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, + 662, 742, 856}, + {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, + 320, 1084, 514}, + {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, + 274, 810, 468}, + {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, + 388, 1152, 354}, + {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, + 650, 274, 844}, + {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, + 536, 388, 730}, + {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, + 342, 422, 536}, + {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, + 342, 0, 764, 194}, + {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, + 422, 764, 0, 798}, + {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, + 536, 194, 798, 0}, }; // [START initial_routes] public long[][] InitialRoutes = { - new long[] {8, 16, 14, 13, 12, 11}, - new long[] {3, 4, 9, 10}, - new long[] {15, 1}, - new long[] {7, 5, 2, 6}, - }; - // [END initial_routes] + new long[]{8, 16, 14, 13, 12, 11}, + new long[]{3, 4, 9, 10}, + new long[]{15, 1}, + new long[]{7, 5, 2, 6}, + }; + // [END initial_routes] public int VehicleNumber = 4; public int Depot = 0; }; @@ -60,11 +77,9 @@ public class InitialRoutes { /// /// Print the solution. /// - static void PrintSolution( - in DataModel data, - in RoutingModel routing, - in RoutingIndexManager manager, - in Assignment solution) { + static void PrintSolution(in DataModel data, in RoutingModel routing, + in RoutingIndexManager manager, + in Assignment solution) { // Inspect solution. long maxRouteDistance = 0; for (int i = 0; i < data.VehicleNumber; ++i) { @@ -72,12 +87,12 @@ public class InitialRoutes { long routeDistance = 0; var index = routing.Start(i); while (routing.IsEnd(index) == false) { - Console.Write("{0} -> ", manager.IndexToNode((int)index)); + Console.Write("{0} -> ", manager.IndexToNode((int) index)); var previousIndex = index; index = solution.Value(routing.NextVar(index)); routeDistance += routing.GetArcCostForVehicle(previousIndex, index, 0); } - Console.WriteLine("{0}", manager.IndexToNode((int)index)); + Console.WriteLine("{0}", manager.IndexToNode((int) index)); Console.WriteLine("Distance of the route: {0}", routeDistance); maxRouteDistance = Math.Max(routeDistance, maxRouteDistance); } @@ -94,9 +109,7 @@ public class InitialRoutes { // Create Routing Index Manager // [START index_manager] RoutingIndexManager manager = new RoutingIndexManager( - data.DistanceMatrix.GetLength(0), - data.VehicleNumber, - data.Depot); + data.DistanceMatrix.GetLength(0), data.VehicleNumber, data.Depot); // [END index_manager] // Create Routing Model. @@ -106,13 +119,13 @@ public class InitialRoutes { // Create and register a transit callback. // [START transit_callback] - int transitCallbackIndex = routing.RegisterTransitCallback( - (long fromIndex, long toIndex) => { - // Convert from routing variable Index to distance matrix NodeIndex. - var fromNode = manager.IndexToNode(fromIndex); - var toNode = manager.IndexToNode(toIndex); - return data.DistanceMatrix[fromNode, toNode]; } - ); + int transitCallbackIndex = + routing.RegisterTransitCallback((long fromIndex, long toIndex) => { + // Convert from routing variable Index to distance matrix NodeIndex. + var fromNode = manager.IndexToNode(fromIndex); + var toNode = manager.IndexToNode(toIndex); + return data.DistanceMatrix[fromNode, toNode]; + }); // [END transit_callback] // Define cost of each arc. @@ -123,16 +136,17 @@ public class InitialRoutes { // Add Distance constraint. // [START distance_constraint] routing.AddDimension(transitCallbackIndex, 0, 3000, - true, // start cumul to zero - "Distance"); - RoutingDimension distanceDimension = routing.GetMutableDimension("Distance"); + true, // start cumul to zero + "Distance"); + RoutingDimension distanceDimension = + routing.GetMutableDimension("Distance"); distanceDimension.SetGlobalSpanCostCoefficient(100); // [END distance_constraint] // Get inital solution from routes. // [START print_initial_solution] - Assignment initialSolution = routing.ReadAssignmentFromRoutes( - data.InitialRoutes, true); + Assignment initialSolution = + routing.ReadAssignmentFromRoutes(data.InitialRoutes, true); // Print initial solution on console. Console.WriteLine("Initial solution:"); PrintSolution(data, routing, manager, initialSolution); @@ -141,7 +155,7 @@ public class InitialRoutes { // Setting first solution heuristic. // [START parameters] RoutingSearchParameters searchParameters = - operations_research_constraint_solver.DefaultRoutingSearchParameters(); + operations_research_constraint_solver.DefaultRoutingSearchParameters(); // [END parameters] // Solve the problem. diff --git a/ortools/constraint_solver/samples/VrpPickupDelivery.cs b/ortools/constraint_solver/samples/VrpPickupDelivery.cs index 72b380134e..c5b9279822 100644 --- a/ortools/constraint_solver/samples/VrpPickupDelivery.cs +++ b/ortools/constraint_solver/samples/VrpPickupDelivery.cs @@ -24,35 +24,46 @@ using Google.OrTools.ConstraintSolver; public class VrpPickupDelivery { // [START data_model] class DataModel { - public long[,] DistanceMatrix = { - {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662}, - {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210}, - {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754}, - {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358}, - {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244}, - {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708}, - {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480}, - {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856}, - {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514}, - {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468}, - {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354}, - {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844}, - {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730}, - {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536}, - {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194}, - {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798}, - {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0} - }; + public long[, ] DistanceMatrix = { + {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, + 468, 776, 662}, + {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, + 1016, 868, 1210}, + {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, + 788, 1552, 754}, + {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, + 1164, 560, 1358}, + {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, + 1050, 674, 1244}, + {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, + 514, 1050, 708}, + {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, + 514, 1278, 480}, + {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, + 662, 742, 856}, + {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, + 320, 1084, 514}, + {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, + 274, 810, 468}, + {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, + 388, 1152, 354}, + {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, + 650, 274, 844}, + {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, + 536, 388, 730}, + {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, + 342, 422, 536}, + {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, + 342, 0, 764, 194}, + {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, + 422, 764, 0, 798}, + {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, + 536, 194, 798, 0}}; // [START pickups_deliveries] public int[][] PickupsDeliveries = { - new int[] {1, 6}, - new int[] {2, 10}, - new int[] {4, 3}, - new int[] {5, 9}, - new int[] {7, 8}, - new int[] {15, 11}, - new int[] {13, 12}, - new int[] {16, 14}, + new int[]{1, 6}, new int[]{2, 10}, new int[]{4, 3}, + new int[]{5, 9}, new int[]{7, 8}, new int[]{15, 11}, + new int[]{13, 12}, new int[]{16, 14}, }; // [END pickups_deliveries] public int VehicleNumber = 4; @@ -64,23 +75,21 @@ public class VrpPickupDelivery { /// /// Print the solution. /// - static void PrintSolution( - in DataModel data, - in RoutingModel routing, - in RoutingIndexManager manager, - in Assignment solution) { + static void PrintSolution(in DataModel data, in RoutingModel routing, + in RoutingIndexManager manager, + in Assignment solution) { long totalDistance = 0; for (int i = 0; i < data.VehicleNumber; ++i) { Console.WriteLine("Route for Vehicle {0}:", i); long routeDistance = 0; var index = routing.Start(i); while (routing.IsEnd(index) == false) { - Console.Write("{0} -> ", manager.IndexToNode((int)index)); + Console.Write("{0} -> ", manager.IndexToNode((int) index)); var previousIndex = index; index = solution.Value(routing.NextVar(index)); routeDistance += routing.GetArcCostForVehicle(previousIndex, index, 0); } - Console.WriteLine("{0}", manager.IndexToNode((int)index)); + Console.WriteLine("{0}", manager.IndexToNode((int) index)); Console.WriteLine("Distance of the route: {0}m", routeDistance); totalDistance += routeDistance; } @@ -97,9 +106,7 @@ public class VrpPickupDelivery { // Create Routing Index Manager // [START index_manager] RoutingIndexManager manager = new RoutingIndexManager( - data.DistanceMatrix.GetLength(0), - data.VehicleNumber, - data.Depot); + data.DistanceMatrix.GetLength(0), data.VehicleNumber, data.Depot); // [END index_manager] @@ -110,13 +117,13 @@ public class VrpPickupDelivery { // Create and register a transit callback. // [START transit_callback] - int transitCallbackIndex = routing.RegisterTransitCallback( - (long fromIndex, long toIndex) => { - // Convert from routing variable Index to distance matrix NodeIndex. - var fromNode = manager.IndexToNode(fromIndex); - var toNode = manager.IndexToNode(toIndex); - return data.DistanceMatrix[fromNode, toNode]; } - ); + int transitCallbackIndex = + routing.RegisterTransitCallback((long fromIndex, long toIndex) => { + // Convert from routing variable Index to distance matrix NodeIndex. + var fromNode = manager.IndexToNode(fromIndex); + var toNode = manager.IndexToNode(toIndex); + return data.DistanceMatrix[fromNode, toNode]; + }); // [END transit_callback] // Define cost of each arc. @@ -127,34 +134,36 @@ public class VrpPickupDelivery { // Add Distance constraint. // [START distance_constraint] routing.AddDimension(transitCallbackIndex, 0, 3000, - true, // start cumul to zero - "Distance"); - RoutingDimension distanceDimension = routing.GetMutableDimension("Distance"); + true, // start cumul to zero + "Distance"); + RoutingDimension distanceDimension = + routing.GetMutableDimension("Distance"); distanceDimension.SetGlobalSpanCostCoefficient(100); // [END distance_constraint] // Define Transportation Requests. // [START pickup_delivery_constraint] Solver solver = routing.solver(); - for(int i=0; i < data.PickupsDeliveries.GetLength(0); i++) { - long pickupIndex = manager.NodeToIndex(data.PickupsDeliveries[i][0]); - long deliveryIndex = manager.NodeToIndex(data.PickupsDeliveries[i][1]); + for (int i = 0; i < data.PickupsDeliveries.GetLength(0); i++) { + long pickupIndex = manager.NodeToIndex(data.PickupsDeliveries [i] + [0]); + long deliveryIndex = manager.NodeToIndex(data.PickupsDeliveries [i] + [1]); routing.AddPickupAndDelivery(pickupIndex, deliveryIndex); - solver.Add(solver.MakeEquality( - routing.VehicleVar(pickupIndex), - routing.VehicleVar(deliveryIndex))); - solver.Add(solver.MakeLessOrEqual( - distanceDimension.CumulVar(pickupIndex), - distanceDimension.CumulVar(deliveryIndex))); + solver.Add(solver.MakeEquality(routing.VehicleVar(pickupIndex), + routing.VehicleVar(deliveryIndex))); + solver.Add( + solver.MakeLessOrEqual(distanceDimension.CumulVar(pickupIndex), + distanceDimension.CumulVar(deliveryIndex))); } // [END pickup_delivery_constraint] // Setting first solution heuristic. // [START parameters] RoutingSearchParameters searchParameters = - operations_research_constraint_solver.DefaultRoutingSearchParameters(); + operations_research_constraint_solver.DefaultRoutingSearchParameters(); searchParameters.FirstSolutionStrategy = - FirstSolutionStrategy.Types.Value.PathCheapestArc; + FirstSolutionStrategy.Types.Value.PathCheapestArc; // [END parameters] // Solve the problem. diff --git a/ortools/constraint_solver/samples/VrpPickupDeliveryFifo.cs b/ortools/constraint_solver/samples/VrpPickupDeliveryFifo.cs index 3dcd7b07fe..751bf8f8d0 100644 --- a/ortools/constraint_solver/samples/VrpPickupDeliveryFifo.cs +++ b/ortools/constraint_solver/samples/VrpPickupDeliveryFifo.cs @@ -24,35 +24,46 @@ using Google.OrTools.ConstraintSolver; public class VrpPickupDeliveryFifo { // [START data_model] class DataModel { - public long[,] DistanceMatrix = { - {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662}, - {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210}, - {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754}, - {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358}, - {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244}, - {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708}, - {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480}, - {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856}, - {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514}, - {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468}, - {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354}, - {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844}, - {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730}, - {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536}, - {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194}, - {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798}, - {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0} - }; + public long[, ] DistanceMatrix = { + {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, + 468, 776, 662}, + {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, + 1016, 868, 1210}, + {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, + 788, 1552, 754}, + {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, + 1164, 560, 1358}, + {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, + 1050, 674, 1244}, + {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, + 514, 1050, 708}, + {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, + 514, 1278, 480}, + {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, + 662, 742, 856}, + {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, + 320, 1084, 514}, + {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, + 274, 810, 468}, + {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, + 388, 1152, 354}, + {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, + 650, 274, 844}, + {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, + 536, 388, 730}, + {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, + 342, 422, 536}, + {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, + 342, 0, 764, 194}, + {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, + 422, 764, 0, 798}, + {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, + 536, 194, 798, 0}}; // [START pickups_deliveries] public int[][] PickupsDeliveries = { - new int[] {1, 6}, - new int[] {2, 10}, - new int[] {4, 3}, - new int[] {5, 9}, - new int[] {7, 8}, - new int[] {15, 11}, - new int[] {13, 12}, - new int[] {16, 14}, + new int[]{1, 6}, new int[]{2, 10}, new int[]{4, 3}, + new int[]{5, 9}, new int[]{7, 8}, new int[]{15, 11}, + new int[]{13, 12}, new int[]{16, 14}, }; // [END pickups_deliveries] public int VehicleNumber = 4; @@ -64,23 +75,21 @@ public class VrpPickupDeliveryFifo { /// /// Print the solution. /// - static void PrintSolution( - in DataModel data, - in RoutingModel routing, - in RoutingIndexManager manager, - in Assignment solution) { + static void PrintSolution(in DataModel data, in RoutingModel routing, + in RoutingIndexManager manager, + in Assignment solution) { long totalDistance = 0; for (int i = 0; i < data.VehicleNumber; ++i) { Console.WriteLine("Route for Vehicle {0}:", i); long routeDistance = 0; var index = routing.Start(i); while (routing.IsEnd(index) == false) { - Console.Write("{0} -> ", manager.IndexToNode((int)index)); + Console.Write("{0} -> ", manager.IndexToNode((int) index)); var previousIndex = index; index = solution.Value(routing.NextVar(index)); routeDistance += routing.GetArcCostForVehicle(previousIndex, index, 0); } - Console.WriteLine("{0}", manager.IndexToNode((int)index)); + Console.WriteLine("{0}", manager.IndexToNode((int) index)); Console.WriteLine("Distance of the route: {0}m", routeDistance); totalDistance += routeDistance; } @@ -97,9 +106,7 @@ public class VrpPickupDeliveryFifo { // Create Routing Index Manager // [START index_manager] RoutingIndexManager manager = new RoutingIndexManager( - data.DistanceMatrix.GetLength(0), - data.VehicleNumber, - data.Depot); + data.DistanceMatrix.GetLength(0), data.VehicleNumber, data.Depot); // [END index_manager] @@ -110,13 +117,13 @@ public class VrpPickupDeliveryFifo { // Create and register a transit callback. // [START transit_callback] - int transitCallbackIndex = routing.RegisterTransitCallback( - (long fromIndex, long toIndex) => { - // Convert from routing variable Index to distance matrix NodeIndex. - var fromNode = manager.IndexToNode(fromIndex); - var toNode = manager.IndexToNode(toIndex); - return data.DistanceMatrix[fromNode, toNode]; } - ); + int transitCallbackIndex = + routing.RegisterTransitCallback((long fromIndex, long toIndex) => { + // Convert from routing variable Index to distance matrix NodeIndex. + var fromNode = manager.IndexToNode(fromIndex); + var toNode = manager.IndexToNode(toIndex); + return data.DistanceMatrix[fromNode, toNode]; + }); // [END transit_callback] // Define cost of each arc. @@ -129,34 +136,36 @@ public class VrpPickupDeliveryFifo { routing.AddDimension(transitCallbackIndex, 0, 3000, true, // start cumul to zero "Distance"); - RoutingDimension distanceDimension = routing.GetMutableDimension("Distance"); + RoutingDimension distanceDimension = + routing.GetMutableDimension("Distance"); distanceDimension.SetGlobalSpanCostCoefficient(100); // [END distance_constraint] // Define Transportation Requests. // [START pickup_delivery_constraint] Solver solver = routing.solver(); - for(int i=0; i < data.PickupsDeliveries.GetLength(0); i++) { - long pickupIndex = manager.NodeToIndex(data.PickupsDeliveries[i][0]); - long deliveryIndex = manager.NodeToIndex(data.PickupsDeliveries[i][1]); + for (int i = 0; i < data.PickupsDeliveries.GetLength(0); i++) { + long pickupIndex = manager.NodeToIndex(data.PickupsDeliveries [i] + [0]); + long deliveryIndex = manager.NodeToIndex(data.PickupsDeliveries [i] + [1]); routing.AddPickupAndDelivery(pickupIndex, deliveryIndex); - solver.Add(solver.MakeEquality( - routing.VehicleVar(pickupIndex), - routing.VehicleVar(deliveryIndex))); - solver.Add(solver.MakeLessOrEqual( - distanceDimension.CumulVar(pickupIndex), - distanceDimension.CumulVar(deliveryIndex))); + solver.Add(solver.MakeEquality(routing.VehicleVar(pickupIndex), + routing.VehicleVar(deliveryIndex))); + solver.Add( + solver.MakeLessOrEqual(distanceDimension.CumulVar(pickupIndex), + distanceDimension.CumulVar(deliveryIndex))); } routing.SetPickupAndDeliveryPolicyOfAllVehicles( - RoutingModel.PICKUP_AND_DELIVERY_FIFO); + RoutingModel.PICKUP_AND_DELIVERY_FIFO); // [END pickup_delivery_constraint] // Setting first solution heuristic. // [START parameters] RoutingSearchParameters searchParameters = - operations_research_constraint_solver.DefaultRoutingSearchParameters(); + operations_research_constraint_solver.DefaultRoutingSearchParameters(); searchParameters.FirstSolutionStrategy = - FirstSolutionStrategy.Types.Value.PathCheapestArc; + FirstSolutionStrategy.Types.Value.PathCheapestArc; // [END parameters] // Solve the problem. diff --git a/ortools/constraint_solver/samples/VrpPickupDeliveryLifo.cs b/ortools/constraint_solver/samples/VrpPickupDeliveryLifo.cs index aedf0c09ee..2e6ee8d249 100644 --- a/ortools/constraint_solver/samples/VrpPickupDeliveryLifo.cs +++ b/ortools/constraint_solver/samples/VrpPickupDeliveryLifo.cs @@ -24,35 +24,46 @@ using Google.OrTools.ConstraintSolver; public class VrpPickupDeliveryLifo { // [START data_model] class DataModel { - public long[,] DistanceMatrix = { - {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662}, - {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210}, - {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754}, - {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358}, - {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244}, - {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708}, - {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480}, - {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856}, - {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514}, - {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468}, - {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354}, - {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844}, - {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730}, - {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536}, - {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194}, - {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798}, - {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0} - }; + public long[, ] DistanceMatrix = { + {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, + 468, 776, 662}, + {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, + 1016, 868, 1210}, + {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, + 788, 1552, 754}, + {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, + 1164, 560, 1358}, + {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, + 1050, 674, 1244}, + {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, + 514, 1050, 708}, + {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, + 514, 1278, 480}, + {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, + 662, 742, 856}, + {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, + 320, 1084, 514}, + {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, + 274, 810, 468}, + {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, + 388, 1152, 354}, + {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, + 650, 274, 844}, + {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, + 536, 388, 730}, + {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, + 342, 422, 536}, + {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, + 342, 0, 764, 194}, + {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, + 422, 764, 0, 798}, + {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, + 536, 194, 798, 0}}; // [START pickups_deliveries] public int[][] PickupsDeliveries = { - new int[] {1, 6}, - new int[] {2, 10}, - new int[] {4, 3}, - new int[] {5, 9}, - new int[] {7, 8}, - new int[] {15, 11}, - new int[] {13, 12}, - new int[] {16, 14}, + new int[]{1, 6}, new int[]{2, 10}, new int[]{4, 3}, + new int[]{5, 9}, new int[]{7, 8}, new int[]{15, 11}, + new int[]{13, 12}, new int[]{16, 14}, }; // [END pickups_deliveries] public int VehicleNumber = 4; @@ -64,23 +75,21 @@ public class VrpPickupDeliveryLifo { /// /// Print the solution. /// - static void PrintSolution( - in DataModel data, - in RoutingModel routing, - in RoutingIndexManager manager, - in Assignment solution) { + static void PrintSolution(in DataModel data, in RoutingModel routing, + in RoutingIndexManager manager, + in Assignment solution) { long totalDistance = 0; for (int i = 0; i < data.VehicleNumber; ++i) { Console.WriteLine("Route for Vehicle {0}:", i); long routeDistance = 0; var index = routing.Start(i); while (routing.IsEnd(index) == false) { - Console.Write("{0} -> ", manager.IndexToNode((int)index)); + Console.Write("{0} -> ", manager.IndexToNode((int) index)); var previousIndex = index; index = solution.Value(routing.NextVar(index)); routeDistance += routing.GetArcCostForVehicle(previousIndex, index, 0); } - Console.WriteLine("{0}", manager.IndexToNode((int)index)); + Console.WriteLine("{0}", manager.IndexToNode((int) index)); Console.WriteLine("Distance of the route: {0}m", routeDistance); totalDistance += routeDistance; } @@ -97,9 +106,7 @@ public class VrpPickupDeliveryLifo { // Create Routing Index Manager // [START index_manager] RoutingIndexManager manager = new RoutingIndexManager( - data.DistanceMatrix.GetLength(0), - data.VehicleNumber, - data.Depot); + data.DistanceMatrix.GetLength(0), data.VehicleNumber, data.Depot); // [END index_manager] // Create Routing Model. @@ -109,13 +116,13 @@ public class VrpPickupDeliveryLifo { // Create and register a transit callback. // [START transit_callback] - int transitCallbackIndex = routing.RegisterTransitCallback( - (long fromIndex, long toIndex) => { - // Convert from routing variable Index to distance matrix NodeIndex. - var fromNode = manager.IndexToNode(fromIndex); - var toNode = manager.IndexToNode(toIndex); - return data.DistanceMatrix[fromNode, toNode]; } - ); + int transitCallbackIndex = + routing.RegisterTransitCallback((long fromIndex, long toIndex) => { + // Convert from routing variable Index to distance matrix NodeIndex. + var fromNode = manager.IndexToNode(fromIndex); + var toNode = manager.IndexToNode(toIndex); + return data.DistanceMatrix[fromNode, toNode]; + }); // [END transit_callback] // Define cost of each arc. @@ -128,34 +135,36 @@ public class VrpPickupDeliveryLifo { routing.AddDimension(transitCallbackIndex, 0, 3000, true, // start cumul to zero "Distance"); - RoutingDimension distanceDimension = routing.GetMutableDimension("Distance"); + RoutingDimension distanceDimension = + routing.GetMutableDimension("Distance"); distanceDimension.SetGlobalSpanCostCoefficient(100); // [END distance_constraint] // Define Transportation Requests. // [START pickup_delivery_constraint] Solver solver = routing.solver(); - for(int i=0; i < data.PickupsDeliveries.GetLength(0); i++) { - long pickupIndex = manager.NodeToIndex(data.PickupsDeliveries[i][0]); - long deliveryIndex = manager.NodeToIndex(data.PickupsDeliveries[i][1]); + for (int i = 0; i < data.PickupsDeliveries.GetLength(0); i++) { + long pickupIndex = manager.NodeToIndex(data.PickupsDeliveries [i] + [0]); + long deliveryIndex = manager.NodeToIndex(data.PickupsDeliveries [i] + [1]); routing.AddPickupAndDelivery(pickupIndex, deliveryIndex); - solver.Add(solver.MakeEquality( - routing.VehicleVar(pickupIndex), - routing.VehicleVar(deliveryIndex))); - solver.Add(solver.MakeLessOrEqual( - distanceDimension.CumulVar(pickupIndex), - distanceDimension.CumulVar(deliveryIndex))); + solver.Add(solver.MakeEquality(routing.VehicleVar(pickupIndex), + routing.VehicleVar(deliveryIndex))); + solver.Add( + solver.MakeLessOrEqual(distanceDimension.CumulVar(pickupIndex), + distanceDimension.CumulVar(deliveryIndex))); } routing.SetPickupAndDeliveryPolicyOfAllVehicles( - RoutingModel.PICKUP_AND_DELIVERY_LIFO); + RoutingModel.PICKUP_AND_DELIVERY_LIFO); // [END pickup_delivery_constraint] // Setting first solution heuristic. // [START parameters] RoutingSearchParameters searchParameters = - operations_research_constraint_solver.DefaultRoutingSearchParameters(); + operations_research_constraint_solver.DefaultRoutingSearchParameters(); searchParameters.FirstSolutionStrategy = - FirstSolutionStrategy.Types.Value.PathCheapestArc; + FirstSolutionStrategy.Types.Value.PathCheapestArc; // [END parameters] // Solve the problem. diff --git a/ortools/constraint_solver/samples/VrpResources.cs b/ortools/constraint_solver/samples/VrpResources.cs index 1d53bfc5b7..8352af66bf 100644 --- a/ortools/constraint_solver/samples/VrpResources.cs +++ b/ortools/constraint_solver/samples/VrpResources.cs @@ -25,43 +25,43 @@ using Google.OrTools.ConstraintSolver; public class VrpResources { // [START data_model] class DataModel { - public long[,] TimeMatrix = { - {0, 6, 9, 8, 7, 3, 6, 2, 3, 2, 6, 6, 4, 4, 5, 9, 7}, - {6, 0, 8, 3, 2, 6, 8, 4, 8, 8, 13, 7, 5, 8, 12, 10, 14}, - {9, 8, 0, 11, 10, 6, 3, 9, 5, 8, 4, 15, 14, 13, 9, 18, 9}, - {8, 3, 11, 0, 1, 7, 10, 6, 10, 10, 14, 6, 7, 9, 14, 6, 16}, - {7, 2, 10, 1, 0, 6, 9, 4, 8, 9, 13, 4, 6, 8, 12, 8, 14}, - {3, 6, 6, 7, 6, 0, 2, 3, 2, 2, 7, 9, 7, 7, 6, 12, 8}, - {6, 8, 3, 10, 9, 2, 0, 6, 2, 5, 4, 12, 10, 10, 6, 15, 5}, - {2, 4, 9, 6, 4, 3, 6, 0, 4, 4, 8, 5, 4, 3, 7, 8, 10}, - {3, 8, 5, 10, 8, 2, 2, 4, 0, 3, 4, 9, 8, 7, 3, 13, 6}, - {2, 8, 8, 10, 9, 2, 5, 4, 3, 0, 4, 6, 5, 4, 3, 9, 5}, - {6, 13, 4, 14, 13, 7, 4, 8, 4, 4, 0, 10, 9, 8, 4, 13, 4}, - {6, 7, 15, 6, 4, 9, 12, 5, 9, 6, 10, 0, 1, 3, 7, 3, 10}, - {4, 5, 14, 7, 6, 7, 10, 4, 8, 5, 9, 1, 0, 2, 6, 4, 8}, - {4, 8, 13, 9, 8, 7, 10, 3, 7, 4, 8, 3, 2, 0, 4, 5, 6}, - {5, 12, 9, 14, 12, 6, 6, 7, 3, 3, 4, 7, 6, 4, 0, 9, 2}, - {9, 10, 18, 6, 8, 12, 15, 8, 13, 9, 13, 3, 4, 5, 9, 0, 9}, - {7, 14, 9, 16, 14, 8, 5, 10, 6, 5, 4, 10, 8, 6, 2, 9, 0}, + public long[, ] TimeMatrix = { + {0, 6, 9, 8, 7, 3, 6, 2, 3, 2, 6, 6, 4, 4, 5, 9, 7}, + {6, 0, 8, 3, 2, 6, 8, 4, 8, 8, 13, 7, 5, 8, 12, 10, 14}, + {9, 8, 0, 11, 10, 6, 3, 9, 5, 8, 4, 15, 14, 13, 9, 18, 9}, + {8, 3, 11, 0, 1, 7, 10, 6, 10, 10, 14, 6, 7, 9, 14, 6, 16}, + {7, 2, 10, 1, 0, 6, 9, 4, 8, 9, 13, 4, 6, 8, 12, 8, 14}, + {3, 6, 6, 7, 6, 0, 2, 3, 2, 2, 7, 9, 7, 7, 6, 12, 8}, + {6, 8, 3, 10, 9, 2, 0, 6, 2, 5, 4, 12, 10, 10, 6, 15, 5}, + {2, 4, 9, 6, 4, 3, 6, 0, 4, 4, 8, 5, 4, 3, 7, 8, 10}, + {3, 8, 5, 10, 8, 2, 2, 4, 0, 3, 4, 9, 8, 7, 3, 13, 6}, + {2, 8, 8, 10, 9, 2, 5, 4, 3, 0, 4, 6, 5, 4, 3, 9, 5}, + {6, 13, 4, 14, 13, 7, 4, 8, 4, 4, 0, 10, 9, 8, 4, 13, 4}, + {6, 7, 15, 6, 4, 9, 12, 5, 9, 6, 10, 0, 1, 3, 7, 3, 10}, + {4, 5, 14, 7, 6, 7, 10, 4, 8, 5, 9, 1, 0, 2, 6, 4, 8}, + {4, 8, 13, 9, 8, 7, 10, 3, 7, 4, 8, 3, 2, 0, 4, 5, 6}, + {5, 12, 9, 14, 12, 6, 6, 7, 3, 3, 4, 7, 6, 4, 0, 9, 2}, + {9, 10, 18, 6, 8, 12, 15, 8, 13, 9, 13, 3, 4, 5, 9, 0, 9}, + {7, 14, 9, 16, 14, 8, 5, 10, 6, 5, 4, 10, 8, 6, 2, 9, 0}, }; - public long[,] TimeWindows = { - {0, 5}, // depot - {7, 12}, // 1 - {10, 15}, // 2 - {5, 14}, // 3 - {5, 13}, // 4 - {0, 5}, // 5 - {5, 10}, // 6 - {0, 10}, // 7 - {5, 10}, // 8 - {0, 5}, // 9 - {10, 16}, // 10 - {10, 15}, // 11 - {0, 5}, // 12 - {5, 10}, // 13 - {7, 12}, // 14 - {10, 15}, // 15 - {5, 15}, // 16 + public long[, ] TimeWindows = { + {0, 5}, // depot + {7, 12}, // 1 + {10, 15}, // 2 + {5, 14}, // 3 + {5, 13}, // 4 + {0, 5}, // 5 + {5, 10}, // 6 + {0, 10}, // 7 + {5, 10}, // 8 + {0, 5}, // 9 + {10, 16}, // 10 + {10, 15}, // 11 + {0, 5}, // 12 + {5, 10}, // 13 + {7, 12}, // 14 + {10, 15}, // 15 + {5, 15}, // 16 }; public int VehicleNumber = 4; // [START resources_data] @@ -77,11 +77,9 @@ public class VrpResources { /// /// Print the solution. /// - static void PrintSolution( - in DataModel data, - in RoutingModel routing, - in RoutingIndexManager manager, - in Assignment solution) { + static void PrintSolution(in DataModel data, in RoutingModel routing, + in RoutingIndexManager manager, + in Assignment solution) { RoutingDimension timeDimension = routing.GetMutableDimension("Time"); // Inspect solution. long totalTime = 0; @@ -90,17 +88,13 @@ public class VrpResources { var index = routing.Start(i); while (routing.IsEnd(index) == false) { var timeVar = timeDimension.CumulVar(index); - Console.Write("{0} Time({1},{2}) -> ", - manager.IndexToNode(index), - solution.Min(timeVar), - solution.Max(timeVar)); + Console.Write("{0} Time({1},{2}) -> ", manager.IndexToNode(index), + solution.Min(timeVar), solution.Max(timeVar)); index = solution.Value(routing.NextVar(index)); } var endTimeVar = timeDimension.CumulVar(index); - Console.WriteLine("{0} Time({1},{2})", - manager.IndexToNode(index), - solution.Min(endTimeVar), - solution.Max(endTimeVar)); + Console.WriteLine("{0} Time({1},{2})", manager.IndexToNode(index), + solution.Min(endTimeVar), solution.Max(endTimeVar)); Console.WriteLine("Time of the route: {0}min", solution.Min(endTimeVar)); totalTime += solution.Min(endTimeVar); } @@ -117,9 +111,7 @@ public class VrpResources { // Create Routing Index Manager // [START index_manager] RoutingIndexManager manager = new RoutingIndexManager( - data.TimeMatrix.GetLength(0), - data.VehicleNumber, - data.Depot); + data.TimeMatrix.GetLength(0), data.VehicleNumber, data.Depot); // [END index_manager] // Create Routing Model. @@ -129,13 +121,13 @@ public class VrpResources { // Create and register a transit callback. // [START transit_callback] - int transitCallbackIndex = routing.RegisterTransitCallback( - (long fromIndex, long toIndex) => { - // Convert from routing variable Index to distance matrix NodeIndex. - var fromNode = manager.IndexToNode(fromIndex); - var toNode = manager.IndexToNode(toIndex); - return data.TimeMatrix[fromNode, toNode]; } - ); + int transitCallbackIndex = + routing.RegisterTransitCallback((long fromIndex, long toIndex) => { + // Convert from routing variable Index to distance matrix NodeIndex. + var fromNode = manager.IndexToNode(fromIndex); + var toNode = manager.IndexToNode(toIndex); + return data.TimeMatrix[fromNode, toNode]; + }); // [END transit_callback] // Define cost of each arc. @@ -145,49 +137,46 @@ public class VrpResources { // Add Distance constraint. // [START time_constraint] - routing.AddDimension( - transitCallbackIndex, // transit callback - 30, // allow waiting time - 30, // vehicle maximum capacities - false, // start cumul to zero - "Time"); + routing.AddDimension(transitCallbackIndex, // transit callback + 30, // allow waiting time + 30, // vehicle maximum capacities + false, // start cumul to zero + "Time"); RoutingDimension timeDimension = routing.GetMutableDimension("Time"); // Add time window constraints for each location except depot. for (int i = 1; i < data.TimeWindows.GetLength(0); ++i) { long index = manager.NodeToIndex(i); - timeDimension.CumulVar(index).SetRange( - data.TimeWindows[i, 0], - data.TimeWindows[i, 1]); + timeDimension.CumulVar(index).SetRange(data.TimeWindows[i, 0], + data.TimeWindows[i, 1]); } // Add time window constraints for each vehicle start node. for (int i = 0; i < data.VehicleNumber; ++i) { long index = routing.Start(i); - timeDimension.CumulVar(index).SetRange( - data.TimeWindows[0, 0], - data.TimeWindows[0, 1]); + timeDimension.CumulVar(index).SetRange(data.TimeWindows[0, 0], + data.TimeWindows[0, 1]); } // [END time_constraint] // Add resource constraints at the depot. // [START depot_load_time] Solver solver = routing.solver(); - IntervalVar[] intervals = new IntervalVar[ data.VehicleNumber * 2 ]; + IntervalVar[] intervals = new IntervalVar[data.VehicleNumber * 2]; for (int i = 0; i < data.VehicleNumber; ++i) { // Add load duration at start of routes - intervals[2*i] = solver.MakeFixedDurationIntervalVar( - timeDimension.CumulVar(routing.Start(i)), data.VehicleLoadTime, - "depot_interval"); + intervals[2 * i] = solver.MakeFixedDurationIntervalVar( + timeDimension.CumulVar(routing.Start(i)), data.VehicleLoadTime, + "depot_interval"); // Add unload duration at end of routes. - intervals[2*i+1] = solver.MakeFixedDurationIntervalVar( - timeDimension.CumulVar(routing.End(i)), data.VehicleUnloadTime, - "depot_interval"); + intervals[2 * i + 1] = solver.MakeFixedDurationIntervalVar( + timeDimension.CumulVar(routing.End(i)), data.VehicleUnloadTime, + "depot_interval"); } // [END depot_load_time] // [START depot_capacity] long[] depot_usage = Enumerable.Repeat(1, intervals.Length).ToArray(); - solver.Add(solver.MakeCumulative(intervals, depot_usage, - data.DepotCapacity, "depot")); + solver.Add(solver.MakeCumulative(intervals, depot_usage, data.DepotCapacity, + "depot")); // [END depot_capacity] // Instantiate route start and end times to produce feasible times. @@ -203,9 +192,9 @@ public class VrpResources { // Setting first solution heuristic. // [START parameters] RoutingSearchParameters searchParameters = - operations_research_constraint_solver.DefaultRoutingSearchParameters(); + operations_research_constraint_solver.DefaultRoutingSearchParameters(); searchParameters.FirstSolutionStrategy = - FirstSolutionStrategy.Types.Value.PathCheapestArc; + FirstSolutionStrategy.Types.Value.PathCheapestArc; // [END parameters] // Solve the problem. diff --git a/ortools/constraint_solver/samples/VrpStartsEnds.cs b/ortools/constraint_solver/samples/VrpStartsEnds.cs index 3f29f4c7a0..59aad0aa58 100644 --- a/ortools/constraint_solver/samples/VrpStartsEnds.cs +++ b/ortools/constraint_solver/samples/VrpStartsEnds.cs @@ -24,25 +24,41 @@ using Google.OrTools.ConstraintSolver; public class VrpStartsEnds { // [START data_model] class DataModel { - public long[,] DistanceMatrix = { - {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662}, - {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210}, - {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754}, - {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358}, - {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244}, - {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708}, - {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480}, - {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856}, - {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514}, - {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468}, - {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354}, - {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844}, - {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730}, - {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536}, - {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194}, - {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798}, - {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0} - }; + public long[, ] DistanceMatrix = { + {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, + 468, 776, 662}, + {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, + 1016, 868, 1210}, + {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, + 788, 1552, 754}, + {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, + 1164, 560, 1358}, + {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, + 1050, 674, 1244}, + {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, + 514, 1050, 708}, + {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, + 514, 1278, 480}, + {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, + 662, 742, 856}, + {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, + 320, 1084, 514}, + {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, + 274, 810, 468}, + {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, + 388, 1152, 354}, + {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, + 650, 274, 844}, + {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, + 536, 388, 730}, + {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, + 342, 422, 536}, + {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, + 342, 0, 764, 194}, + {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, + 422, 764, 0, 798}, + {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, + 536, 194, 798, 0}}; public int VehicleNumber = 4; // [START starts_ends] public int[] Starts = {1, 2, 15, 16}; @@ -55,11 +71,9 @@ public class VrpStartsEnds { /// /// Print the solution. /// - static void PrintSolution( - in DataModel data, - in RoutingModel routing, - in RoutingIndexManager manager, - in Assignment solution) { + static void PrintSolution(in DataModel data, in RoutingModel routing, + in RoutingIndexManager manager, + in Assignment solution) { // Inspect solution. long maxRouteDistance = 0; for (int i = 0; i < data.VehicleNumber; ++i) { @@ -67,12 +81,12 @@ public class VrpStartsEnds { long routeDistance = 0; var index = routing.Start(i); while (routing.IsEnd(index) == false) { - Console.Write("{0} -> ", manager.IndexToNode((int)index)); + Console.Write("{0} -> ", manager.IndexToNode((int) index)); var previousIndex = index; index = solution.Value(routing.NextVar(index)); routeDistance += routing.GetArcCostForVehicle(previousIndex, index, 0); } - Console.WriteLine("{0}", manager.IndexToNode((int)index)); + Console.WriteLine("{0}", manager.IndexToNode((int) index)); Console.WriteLine("Distance of the route: {0}m", routeDistance); maxRouteDistance = Math.Max(routeDistance, maxRouteDistance); } @@ -88,11 +102,9 @@ public class VrpStartsEnds { // Create Routing Index Manager // [START index_manager] - RoutingIndexManager manager = new RoutingIndexManager( - data.DistanceMatrix.GetLength(0), - data.VehicleNumber, - data.Starts, - data.Ends); + RoutingIndexManager manager = + new RoutingIndexManager(data.DistanceMatrix.GetLength(0), + data.VehicleNumber, data.Starts, data.Ends); // [END index_manager] // Create Routing Model. @@ -102,13 +114,13 @@ public class VrpStartsEnds { // Create and register a transit callback. // [START transit_callback] - int transitCallbackIndex = routing.RegisterTransitCallback( - (long fromIndex, long toIndex) => { - // Convert from routing variable Index to distance matrix NodeIndex. - var fromNode = manager.IndexToNode(fromIndex); - var toNode = manager.IndexToNode(toIndex); - return data.DistanceMatrix[fromNode, toNode]; } - ); + int transitCallbackIndex = + routing.RegisterTransitCallback((long fromIndex, long toIndex) => { + // Convert from routing variable Index to distance matrix NodeIndex. + var fromNode = manager.IndexToNode(fromIndex); + var toNode = manager.IndexToNode(toIndex); + return data.DistanceMatrix[fromNode, toNode]; + }); // [END transit_callback] // Define cost of each arc. @@ -121,16 +133,17 @@ public class VrpStartsEnds { routing.AddDimension(transitCallbackIndex, 0, 2000, true, // start cumul to zero "Distance"); - RoutingDimension distanceDimension = routing.GetMutableDimension("Distance"); + RoutingDimension distanceDimension = + routing.GetMutableDimension("Distance"); distanceDimension.SetGlobalSpanCostCoefficient(100); // [END distance_constraint] // Setting first solution heuristic. // [START parameters] RoutingSearchParameters searchParameters = - operations_research_constraint_solver.DefaultRoutingSearchParameters(); + operations_research_constraint_solver.DefaultRoutingSearchParameters(); searchParameters.FirstSolutionStrategy = - FirstSolutionStrategy.Types.Value.PathCheapestArc; + FirstSolutionStrategy.Types.Value.PathCheapestArc; // [END parameters] // Solve the problem. diff --git a/ortools/constraint_solver/samples/VrpTimeWindows.cs b/ortools/constraint_solver/samples/VrpTimeWindows.cs index 6da928d01e..39f0bc5a91 100644 --- a/ortools/constraint_solver/samples/VrpTimeWindows.cs +++ b/ortools/constraint_solver/samples/VrpTimeWindows.cs @@ -25,43 +25,43 @@ using Google.OrTools.ConstraintSolver; public class VrpTimeWindows { // [START data_model] class DataModel { - public long[,] TimeMatrix = { - {0, 6, 9, 8, 7, 3, 6, 2, 3, 2, 6, 6, 4, 4, 5, 9, 7}, - {6, 0, 8, 3, 2, 6, 8, 4, 8, 8, 13, 7, 5, 8, 12, 10, 14}, - {9, 8, 0, 11, 10, 6, 3, 9, 5, 8, 4, 15, 14, 13, 9, 18, 9}, - {8, 3, 11, 0, 1, 7, 10, 6, 10, 10, 14, 6, 7, 9, 14, 6, 16}, - {7, 2, 10, 1, 0, 6, 9, 4, 8, 9, 13, 4, 6, 8, 12, 8, 14}, - {3, 6, 6, 7, 6, 0, 2, 3, 2, 2, 7, 9, 7, 7, 6, 12, 8}, - {6, 8, 3, 10, 9, 2, 0, 6, 2, 5, 4, 12, 10, 10, 6, 15, 5}, - {2, 4, 9, 6, 4, 3, 6, 0, 4, 4, 8, 5, 4, 3, 7, 8, 10}, - {3, 8, 5, 10, 8, 2, 2, 4, 0, 3, 4, 9, 8, 7, 3, 13, 6}, - {2, 8, 8, 10, 9, 2, 5, 4, 3, 0, 4, 6, 5, 4, 3, 9, 5}, - {6, 13, 4, 14, 13, 7, 4, 8, 4, 4, 0, 10, 9, 8, 4, 13, 4}, - {6, 7, 15, 6, 4, 9, 12, 5, 9, 6, 10, 0, 1, 3, 7, 3, 10}, - {4, 5, 14, 7, 6, 7, 10, 4, 8, 5, 9, 1, 0, 2, 6, 4, 8}, - {4, 8, 13, 9, 8, 7, 10, 3, 7, 4, 8, 3, 2, 0, 4, 5, 6}, - {5, 12, 9, 14, 12, 6, 6, 7, 3, 3, 4, 7, 6, 4, 0, 9, 2}, - {9, 10, 18, 6, 8, 12, 15, 8, 13, 9, 13, 3, 4, 5, 9, 0, 9}, - {7, 14, 9, 16, 14, 8, 5, 10, 6, 5, 4, 10, 8, 6, 2, 9, 0}, + public long[, ] TimeMatrix = { + {0, 6, 9, 8, 7, 3, 6, 2, 3, 2, 6, 6, 4, 4, 5, 9, 7}, + {6, 0, 8, 3, 2, 6, 8, 4, 8, 8, 13, 7, 5, 8, 12, 10, 14}, + {9, 8, 0, 11, 10, 6, 3, 9, 5, 8, 4, 15, 14, 13, 9, 18, 9}, + {8, 3, 11, 0, 1, 7, 10, 6, 10, 10, 14, 6, 7, 9, 14, 6, 16}, + {7, 2, 10, 1, 0, 6, 9, 4, 8, 9, 13, 4, 6, 8, 12, 8, 14}, + {3, 6, 6, 7, 6, 0, 2, 3, 2, 2, 7, 9, 7, 7, 6, 12, 8}, + {6, 8, 3, 10, 9, 2, 0, 6, 2, 5, 4, 12, 10, 10, 6, 15, 5}, + {2, 4, 9, 6, 4, 3, 6, 0, 4, 4, 8, 5, 4, 3, 7, 8, 10}, + {3, 8, 5, 10, 8, 2, 2, 4, 0, 3, 4, 9, 8, 7, 3, 13, 6}, + {2, 8, 8, 10, 9, 2, 5, 4, 3, 0, 4, 6, 5, 4, 3, 9, 5}, + {6, 13, 4, 14, 13, 7, 4, 8, 4, 4, 0, 10, 9, 8, 4, 13, 4}, + {6, 7, 15, 6, 4, 9, 12, 5, 9, 6, 10, 0, 1, 3, 7, 3, 10}, + {4, 5, 14, 7, 6, 7, 10, 4, 8, 5, 9, 1, 0, 2, 6, 4, 8}, + {4, 8, 13, 9, 8, 7, 10, 3, 7, 4, 8, 3, 2, 0, 4, 5, 6}, + {5, 12, 9, 14, 12, 6, 6, 7, 3, 3, 4, 7, 6, 4, 0, 9, 2}, + {9, 10, 18, 6, 8, 12, 15, 8, 13, 9, 13, 3, 4, 5, 9, 0, 9}, + {7, 14, 9, 16, 14, 8, 5, 10, 6, 5, 4, 10, 8, 6, 2, 9, 0}, }; - public long[,] TimeWindows = { - {0, 5}, // depot - {7, 12}, // 1 - {10, 15}, // 2 - {16, 18}, // 3 - {10, 13}, // 4 - {0, 5}, // 5 - {5, 10}, // 6 - {0, 4}, // 7 - {5, 10}, // 8 - {0, 3}, // 9 - {10, 16}, // 10 - {10, 15}, // 11 - {0, 5}, // 12 - {5, 10}, // 13 - {7, 8}, // 14 - {10, 15}, // 15 - {11, 15}, // 16 + public long[, ] TimeWindows = { + {0, 5}, // depot + {7, 12}, // 1 + {10, 15}, // 2 + {16, 18}, // 3 + {10, 13}, // 4 + {0, 5}, // 5 + {5, 10}, // 6 + {0, 4}, // 7 + {5, 10}, // 8 + {0, 3}, // 9 + {10, 16}, // 10 + {10, 15}, // 11 + {0, 5}, // 12 + {5, 10}, // 13 + {7, 8}, // 14 + {10, 15}, // 15 + {11, 15}, // 16 }; public int VehicleNumber = 4; public int Depot = 0; @@ -72,11 +72,9 @@ public class VrpTimeWindows { /// /// Print the solution. /// - static void PrintSolution( - in DataModel data, - in RoutingModel routing, - in RoutingIndexManager manager, - in Assignment solution) { + static void PrintSolution(in DataModel data, in RoutingModel routing, + in RoutingIndexManager manager, + in Assignment solution) { RoutingDimension timeDimension = routing.GetMutableDimension("Time"); // Inspect solution. long totalTime = 0; @@ -85,17 +83,13 @@ public class VrpTimeWindows { var index = routing.Start(i); while (routing.IsEnd(index) == false) { var timeVar = timeDimension.CumulVar(index); - Console.Write("{0} Time({1},{2}) -> ", - manager.IndexToNode(index), - solution.Min(timeVar), - solution.Max(timeVar)); + Console.Write("{0} Time({1},{2}) -> ", manager.IndexToNode(index), + solution.Min(timeVar), solution.Max(timeVar)); index = solution.Value(routing.NextVar(index)); } var endTimeVar = timeDimension.CumulVar(index); - Console.WriteLine("{0} Time({1},{2})", - manager.IndexToNode(index), - solution.Min(endTimeVar), - solution.Max(endTimeVar)); + Console.WriteLine("{0} Time({1},{2})", manager.IndexToNode(index), + solution.Min(endTimeVar), solution.Max(endTimeVar)); Console.WriteLine("Time of the route: {0}min", solution.Min(endTimeVar)); totalTime += solution.Min(endTimeVar); } @@ -112,9 +106,7 @@ public class VrpTimeWindows { // Create Routing Index Manager // [START index_manager] RoutingIndexManager manager = new RoutingIndexManager( - data.TimeMatrix.GetLength(0), - data.VehicleNumber, - data.Depot); + data.TimeMatrix.GetLength(0), data.VehicleNumber, data.Depot); // [END index_manager] // Create Routing Model. @@ -124,13 +116,13 @@ public class VrpTimeWindows { // Create and register a transit callback. // [START transit_callback] - int transitCallbackIndex = routing.RegisterTransitCallback( - (long fromIndex, long toIndex) => { - // Convert from routing variable Index to distance matrix NodeIndex. - var fromNode = manager.IndexToNode(fromIndex); - var toNode = manager.IndexToNode(toIndex); - return data.TimeMatrix[fromNode, toNode]; } - ); + int transitCallbackIndex = + routing.RegisterTransitCallback((long fromIndex, long toIndex) => { + // Convert from routing variable Index to distance matrix NodeIndex. + var fromNode = manager.IndexToNode(fromIndex); + var toNode = manager.IndexToNode(toIndex); + return data.TimeMatrix[fromNode, toNode]; + }); // [END transit_callback] // Define cost of each arc. @@ -140,26 +132,23 @@ public class VrpTimeWindows { // Add Distance constraint. // [START time_constraint] - routing.AddDimension( - transitCallbackIndex, // transit callback - 30, // allow waiting time - 30, // vehicle maximum capacities - false, // start cumul to zero - "Time"); + routing.AddDimension(transitCallbackIndex, // transit callback + 30, // allow waiting time + 30, // vehicle maximum capacities + false, // start cumul to zero + "Time"); RoutingDimension timeDimension = routing.GetMutableDimension("Time"); // Add time window constraints for each location except depot. for (int i = 1; i < data.TimeWindows.GetLength(0); ++i) { long index = manager.NodeToIndex(i); - timeDimension.CumulVar(index).SetRange( - data.TimeWindows[i, 0], - data.TimeWindows[i, 1]); + timeDimension.CumulVar(index).SetRange(data.TimeWindows[i, 0], + data.TimeWindows[i, 1]); } // Add time window constraints for each vehicle start node. for (int i = 0; i < data.VehicleNumber; ++i) { long index = routing.Start(i); - timeDimension.CumulVar(index).SetRange( - data.TimeWindows[0, 0], - data.TimeWindows[0, 1]); + timeDimension.CumulVar(index).SetRange(data.TimeWindows[0, 0], + data.TimeWindows[0, 1]); } // [END time_constraint] @@ -176,9 +165,9 @@ public class VrpTimeWindows { // Setting first solution heuristic. // [START parameters] RoutingSearchParameters searchParameters = - operations_research_constraint_solver.DefaultRoutingSearchParameters(); + operations_research_constraint_solver.DefaultRoutingSearchParameters(); searchParameters.FirstSolutionStrategy = - FirstSolutionStrategy.Types.Value.PathCheapestArc; + FirstSolutionStrategy.Types.Value.PathCheapestArc; // [END parameters] // Solve the problem. diff --git a/ortools/constraint_solver/samples/VrpWithTimeLimit.cs b/ortools/constraint_solver/samples/VrpWithTimeLimit.cs index 1c381785ed..7fa40cf945 100644 --- a/ortools/constraint_solver/samples/VrpWithTimeLimit.cs +++ b/ortools/constraint_solver/samples/VrpWithTimeLimit.cs @@ -16,7 +16,7 @@ using System; using System.Collections.Generic; using Google.OrTools.ConstraintSolver; -using Google.Protobuf.WellKnownTypes; // Duration +using Google.Protobuf.WellKnownTypes; // Duration // [END import] /// @@ -27,10 +27,8 @@ public class Vrp { /// /// Print the solution. /// - static void PrintSolution( - in RoutingIndexManager manager, - in RoutingModel routing, - in Assignment solution) { + static void PrintSolution(in RoutingIndexManager manager, + in RoutingModel routing, in Assignment solution) { // Inspect solution. long maxRouteDistance = 0; for (int i = 0; i < manager.GetNumberOfVehicles(); ++i) { @@ -38,12 +36,12 @@ public class Vrp { long routeDistance = 0; var index = routing.Start(i); while (routing.IsEnd(index) == false) { - Console.Write("{0} -> ", manager.IndexToNode((int)index)); + Console.Write("{0} -> ", manager.IndexToNode((int) index)); var previousIndex = index; index = solution.Value(routing.NextVar(index)); routeDistance += routing.GetArcCostForVehicle(previousIndex, index, 0); } - Console.WriteLine("{0}", manager.IndexToNode((int)index)); + Console.WriteLine("{0}", manager.IndexToNode((int) index)); Console.WriteLine("Distance of the route: {0}m", routeDistance); maxRouteDistance = Math.Max(routeDistance, maxRouteDistance); } @@ -61,10 +59,8 @@ public class Vrp { // Create Routing Index Manager // [START index_manager] - RoutingIndexManager manager = new RoutingIndexManager( - locationNumber, - vehicleNumber, - depot); + RoutingIndexManager manager = + new RoutingIndexManager(locationNumber, vehicleNumber, depot); // [END index_manager] @@ -75,13 +71,13 @@ public class Vrp { // Create and register a transit callback. // [START transit_callback] - int transitCallbackIndex = routing.RegisterTransitCallback( - (long fromIndex, long toIndex) => { - // Convert from routing variable Index to distance matrix NodeIndex. - var fromNode = manager.IndexToNode(fromIndex); - var toNode = manager.IndexToNode(toIndex); - return 1; } - ); + int transitCallbackIndex = + routing.RegisterTransitCallback((long fromIndex, long toIndex) => { + // Convert from routing variable Index to distance matrix NodeIndex. + var fromNode = manager.IndexToNode(fromIndex); + var toNode = manager.IndexToNode(toIndex); + return 1; + }); // [END transit_callback] // Define cost of each arc. @@ -91,24 +87,25 @@ public class Vrp { // Add Distance constraint. // [START distance_constraint] - routing.AddDimension( - transitCallbackIndex, - /*slack=*/0, - /*horizon=*/3000, - /*start_cumul_to_zero=*/true, - "Distance"); - RoutingDimension distanceDimension = routing.GetMutableDimension("Distance"); + routing.AddDimension(transitCallbackIndex, + /*slack=*/0, + /*horizon=*/3000, + /*start_cumul_to_zero=*/true, "Distance"); + RoutingDimension distanceDimension = + routing.GetMutableDimension("Distance"); distanceDimension.SetGlobalSpanCostCoefficient(100); // [END distance_constraint] // Setting first solution heuristic. // [START parameters] RoutingSearchParameters searchParameters = - operations_research_constraint_solver.DefaultRoutingSearchParameters(); - searchParameters.FirstSolutionStrategy = FirstSolutionStrategy.Types.Value.PathCheapestArc; - searchParameters.LocalSearchMetaheuristic = LocalSearchMetaheuristic.Types.Value.GuidedLocalSearch; + operations_research_constraint_solver.DefaultRoutingSearchParameters(); + searchParameters.FirstSolutionStrategy = + FirstSolutionStrategy.Types.Value.PathCheapestArc; + searchParameters.LocalSearchMetaheuristic = + LocalSearchMetaheuristic.Types.Value.GuidedLocalSearch; searchParameters.LogSearch = true; - searchParameters.TimeLimit = new Duration { Seconds = 10 }; + searchParameters.TimeLimit = new Duration{Seconds = 10}; // [END parameters] // Solve the problem. diff --git a/ortools/dotnet/CreateSigningKey/Program.cs b/ortools/dotnet/CreateSigningKey/Program.cs index 6b8fbe08b1..bf447afdec 100644 --- a/ortools/dotnet/CreateSigningKey/Program.cs +++ b/ortools/dotnet/CreateSigningKey/Program.cs @@ -3,22 +3,22 @@ using System.IO; using System.Security.Cryptography; namespace CreateSigningKey { - class Program { - static void Main(string[] args) { - if (args == null || args.Length == 0) { - Console.WriteLine("Key filename not specified."); - return; - } - string path = Directory.GetCurrentDirectory() + args[0]; - Console.WriteLine("Key filename:" + path); - if (Console.Out!=null) Console.Out.Flush(); - File.WriteAllBytes(path, GenerateStrongNameKeyPair()); +class Program { + static void Main(string[] args) { + if (args == null || args.Length == 0) { + Console.WriteLine("Key filename not specified."); + return; } + string path = Directory.GetCurrentDirectory() + args[0]; + Console.WriteLine("Key filename:" + path); + if (Console.Out != null) Console.Out.Flush(); + File.WriteAllBytes(path, GenerateStrongNameKeyPair()); + } - public static byte[] GenerateStrongNameKeyPair() { - using (var provider = new RSACryptoServiceProvider(4096)) { - return provider.ExportCspBlob(!provider.PublicOnly); - } + public static byte[] GenerateStrongNameKeyPair() { + using(var provider = new RSACryptoServiceProvider(4096)) { + return provider.ExportCspBlob(!provider.PublicOnly); } } } +} diff --git a/ortools/graph/samples/SimpleMaxFlowProgram.cs b/ortools/graph/samples/SimpleMaxFlowProgram.cs index ed1360fc30..8b5a58ef58 100644 --- a/ortools/graph/samples/SimpleMaxFlowProgram.cs +++ b/ortools/graph/samples/SimpleMaxFlowProgram.cs @@ -15,10 +15,8 @@ using System; using Google.OrTools.Graph; -public class SimpleMaxFlowProgram -{ - static void Main() - { +public class SimpleMaxFlowProgram { + static void Main() { // [START data] // Define three parallel arrays: start_nodes, end_nodes, and the capacities // between each pair. For instance, the arc from node 0 to node 1 has a @@ -35,10 +33,9 @@ public class SimpleMaxFlowProgram MaxFlow maxFlow = new MaxFlow(); // Add each arc. - for (int i = 0; i < startNodes.Length; ++i) - { - int arc = maxFlow.AddArcWithCapacity(startNodes[i], endNodes[i], - capacities[i]); + for (int i = 0; i < startNodes.Length; ++i) { + int arc = + maxFlow.AddArcWithCapacity(startNodes[i], endNodes[i], capacities[i]); if (arc != i) throw new Exception("Internal error"); } // [END constraints] @@ -49,21 +46,16 @@ public class SimpleMaxFlowProgram // [END solve] // [START print_solution] - if (solveStatus == MaxFlow.Status.OPTIMAL) - { + if (solveStatus == MaxFlow.Status.OPTIMAL) { Console.WriteLine("Max. flow: " + maxFlow.OptimalFlow()); Console.WriteLine(""); Console.WriteLine(" Arc Flow / Capacity"); - for (int i = 0; i < maxFlow.NumArcs(); ++i) - { - Console.WriteLine(maxFlow.Tail(i) + " -> " + - maxFlow.Head(i) + " " + + for (int i = 0; i < maxFlow.NumArcs(); ++i) { + Console.WriteLine(maxFlow.Tail(i) + " -> " + maxFlow.Head(i) + " " + string.Format("{0,3}", maxFlow.Flow(i)) + " / " + string.Format("{0,3}", maxFlow.Capacity(i))); } - } - else - { + } else { Console.WriteLine("Solving the max flow problem failed. Solver status: " + solveStatus); } diff --git a/ortools/graph/samples/SimpleMinCostFlowProgram.cs b/ortools/graph/samples/SimpleMinCostFlowProgram.cs index 254e3a7fa2..6112f74c0b 100644 --- a/ortools/graph/samples/SimpleMinCostFlowProgram.cs +++ b/ortools/graph/samples/SimpleMinCostFlowProgram.cs @@ -11,21 +11,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -// """From Bradley, Hax, and Magnanti, 'Applied Mathematical Programming', figure 8.1.""" -// [START program] +// """From Bradley, Hax, and Magnanti, 'Applied Mathematical Programming', +// figure 8.1.""" [START program] using System; using Google.OrTools.Graph; -public class SimpleMinCostFlowProgram -{ - static void Main() - { +public class SimpleMinCostFlowProgram { + static void Main() { // [START data] - // Define four parallel arrays: sources, destinations, capacities, and unit costs - // between each pair. For instance, the arc from node 0 to node 1 has a - // capacity of 15. - // Problem taken From Taha's 'Introduction to Operations Research', - // example 6.4-2. + // Define four parallel arrays: sources, destinations, capacities, and unit + // costs between each pair. For instance, the arc from node 0 to node 1 has + // a capacity of 15. Problem taken From Taha's 'Introduction to Operations + // Research', example 6.4-2. int[] startNodes = {0, 0, 1, 1, 1, 2, 2, 3, 4}; int[] endNodes = {1, 2, 2, 3, 4, 3, 4, 4, 2}; int[] capacities = {15, 8, 20, 4, 10, 15, 4, 20, 5}; @@ -40,16 +37,14 @@ public class SimpleMinCostFlowProgram MinCostFlow minCostFlow = new MinCostFlow(); // Add each arc. - for (int i = 0; i < startNodes.Length; ++i) - { - int arc = minCostFlow.AddArcWithCapacityAndUnitCost(startNodes[i], endNodes[i], - capacities[i], unitCosts[i]); + for (int i = 0; i < startNodes.Length; ++i) { + int arc = minCostFlow.AddArcWithCapacityAndUnitCost( + startNodes[i], endNodes[i], capacities[i], unitCosts[i]); if (arc != i) throw new Exception("Internal error"); } - // Add node supplies. - for (int i = 0; i < supplies.Length; ++i) - { + // Add node supplies. + for (int i = 0; i < supplies.Length; ++i) { minCostFlow.SetNodeSupply(i, supplies[i]); } @@ -61,25 +56,22 @@ public class SimpleMinCostFlowProgram // [END solve] // [START print_solution] - if (solveStatus == MinCostFlow.Status.OPTIMAL) - { + if (solveStatus == MinCostFlow.Status.OPTIMAL) { Console.WriteLine("Minimum cost: " + minCostFlow.OptimalCost()); Console.WriteLine(""); Console.WriteLine(" Edge Flow / Capacity Cost"); - for (int i = 0; i < minCostFlow.NumArcs(); ++i) - { + for (int i = 0; i < minCostFlow.NumArcs(); ++i) { long cost = minCostFlow.Flow(i) * minCostFlow.UnitCost(i); - Console.WriteLine(minCostFlow.Tail(i) + " -> " + - minCostFlow.Head(i) + " " + - string.Format("{0,3}", minCostFlow.Flow(i)) + " / " + - string.Format ("{0,3}", minCostFlow.Capacity(i)) + " " + - string.Format ("{0,3}", cost)); + Console.WriteLine(minCostFlow.Tail(i) + " -> " + minCostFlow.Head(i) + + " " + string.Format("{0,3}", minCostFlow.Flow(i)) + + " / " + + string.Format("{0,3}", minCostFlow.Capacity(i)) + + " " + string.Format("{0,3}", cost)); } - } - else - { - Console.WriteLine("Solving the min cost flow problem failed. Solver status: " + - solveStatus); + } else { + Console.WriteLine( + "Solving the min cost flow problem failed. Solver status: " + + solveStatus); } // [END print_solution] } diff --git a/ortools/linear_solver/csharp/LinearConstraint.cs b/ortools/linear_solver/csharp/LinearConstraint.cs index bdeeedfc93..2b1ef45606 100644 --- a/ortools/linear_solver/csharp/LinearConstraint.cs +++ b/ortools/linear_solver/csharp/LinearConstraint.cs @@ -11,153 +11,129 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Google.OrTools.LinearSolver -{ +namespace Google.OrTools.LinearSolver { using System; using System.Collections.Generic; -public class LinearConstraint -{ + public class LinearConstraint { + public virtual String ToString() { return "LinearConstraint"; } - public virtual String ToString() - { - return "LinearConstraint"; + public virtual Constraint Extract(Solver solver) { return null; } } - public virtual Constraint Extract(Solver solver) - { - return null; - } -} - -public class RangeConstraint : LinearConstraint -{ - - public RangeConstraint(LinearExpr expr, double lb, double ub) - { - this.expr_ = expr; - this.lb_ = lb; - this.ub_ = ub; - } - - public override String ToString() - { - return "" + lb_ + " <= " + expr_.ToString() + " <= " + ub_; - } - - public override Constraint Extract(Solver solver) - { - Dictionary coefficients = - new Dictionary(); - double constant = expr_.Visit(coefficients); - Constraint ct = solver.MakeConstraint(lb_ - constant, ub_ - constant); - foreach (KeyValuePair pair in coefficients) - { - ct.SetCoefficient(pair.Key, pair.Value); + public class RangeConstraint : LinearConstraint { + public RangeConstraint(LinearExpr expr, double lb, double ub) { + this.expr_ = expr; + this.lb_ = lb; + this.ub_ = ub; } - return ct; - } - public static implicit operator bool(RangeConstraint ct) - { - return false; - } - - private LinearExpr expr_; - private double lb_; - private double ub_; -} - -public class Equality : LinearConstraint -{ - public Equality(LinearExpr left, LinearExpr right, bool equality) - { - this.left_ = left; - this.right_ = right; - this.equality_ = equality; - } - - public override String ToString() - { - return "" + left_.ToString() + " == " + right_.ToString(); - } - - public override Constraint Extract(Solver solver) - { - Dictionary coefficients = - new Dictionary(); - double constant = left_.Visit(coefficients); - constant += right_.DoVisit(coefficients, -1); - Constraint ct = solver.MakeConstraint(-constant, -constant); - foreach (KeyValuePair pair in coefficients) - { - ct.SetCoefficient(pair.Key, pair.Value); + public override String ToString() { + return "" + lb_ + " <= " + expr_.ToString() + " <= " + ub_; } - return ct; + + public override Constraint Extract(Solver solver) { + Dictionary coefficients = + new Dictionary(); + double constant = expr_.Visit(coefficients); + Constraint ct = solver.MakeConstraint(lb_ - constant, ub_ - constant); + foreach (KeyValuePair pair in coefficients) { + ct.SetCoefficient(pair.Key, pair.Value); + } + return ct; + } + + public static implicit operator bool(RangeConstraint ct) { return false; } + + private LinearExpr expr_; + private double lb_; + private double ub_; } - public static implicit operator bool(Equality ct) - { - return (object)ct.left_ == (object)ct.right_ ? ct.equality_ : !ct.equality_; + public class Equality : LinearConstraint { + public Equality(LinearExpr left, LinearExpr right, bool equality) { + this.left_ = left; + this.right_ = right; + this.equality_ = equality; + } + + public override String ToString() { + return "" + left_.ToString() + " == " + right_.ToString(); + } + + public override Constraint Extract(Solver solver) { + Dictionary coefficients = + new Dictionary(); + double constant = left_.Visit(coefficients); + constant += right_.DoVisit(coefficients, -1); + Constraint ct = solver.MakeConstraint(-constant, -constant); + foreach (KeyValuePair pair in coefficients) { + ct.SetCoefficient(pair.Key, pair.Value); + } + return ct; + } + + public static implicit operator bool(Equality ct) { + return (object) ct.left_ == (object) ct.right_ ? ct.equality_ + : !ct.equality_; + } + + private LinearExpr left_; + private LinearExpr right_; + private bool equality_; } - private LinearExpr left_; - private LinearExpr right_; - private bool equality_; -} + public class VarEquality : LinearConstraint { + public VarEquality(Variable left, Variable right, bool equality) { + this.left_ = left; + this.right_ = right; + this.equality_ = equality; + } -public class VarEquality : LinearConstraint -{ - public VarEquality(Variable left, Variable right, bool equality) - { - this.left_ = left; - this.right_ = right; - this.equality_ = equality; + public override String ToString() { + return "" + left_.Name() + " == " + right_.Name(); + } + + public override Constraint Extract(Solver solver) { + Constraint ct = solver.MakeConstraint(0.0, 0.0); + ct.SetCoefficient(left_, 1.0); + ct.SetCoefficient(right_, -1.0); + return ct; + } + + public static implicit operator bool(VarEquality ct) { + return (object) ct.left_ == (object) ct.right_ ? ct.equality_ + : !ct.equality_; + } + + private Variable left_; + private Variable right_; + private bool equality_; } - public override String ToString() - { - return "" + left_.Name() + " == " + right_.Name(); - } - - public override Constraint Extract(Solver solver) - { - Constraint ct = solver.MakeConstraint(0.0, 0.0); - ct.SetCoefficient(left_, 1.0); - ct.SetCoefficient(right_, -1.0); - return ct; - } - - public static implicit operator bool(VarEquality ct) - { - return (object)ct.left_ == (object)ct.right_ ? ct.equality_ : !ct.equality_; - } - - private Variable left_; - private Variable right_; - private bool equality_; -} - -// TODO(user): Try to move this code back to the .swig with @define macros. -public partial class MPConstraintVector: IDisposable, System.Collections.IEnumerable + // TODO(user): Try to move this code back to the .swig with @define macros. + public partial class MPConstraintVector + : IDisposable, + System.Collections.IEnumerable #if !SWIG_DOTNET_1 - , System.Collections.Generic.IList + , + System.Collections.Generic.IList #endif -{ - // cast from C# MPConstraint array - public static implicit operator MPConstraintVector(Constraint[] inVal) { - var outVal= new MPConstraintVector(); - foreach (Constraint element in inVal) { - outVal.Add(element); + { + // cast from C# MPConstraint array + public static implicit operator MPConstraintVector(Constraint[] inVal) { + var outVal = new MPConstraintVector(); + foreach (Constraint element in inVal) { + outVal.Add(element); + } + return outVal; } - return outVal; - } - // cast to C# MPConstraint array - public static implicit operator Constraint[](MPConstraintVector inVal) { - var outVal= new Constraint[inVal.Count]; - inVal.CopyTo(outVal); - return outVal; + // cast to C# MPConstraint array + public static implicit operator Constraint[](MPConstraintVector inVal) { + var outVal = new Constraint[inVal.Count]; + inVal.CopyTo(outVal); + return outVal; + } } -} } // namespace Google.OrTools.LinearSolver diff --git a/ortools/linear_solver/csharp/LinearExpr.cs b/ortools/linear_solver/csharp/LinearExpr.cs index f63f256a91..2fa24d6ad1 100644 --- a/ortools/linear_solver/csharp/LinearExpr.cs +++ b/ortools/linear_solver/csharp/LinearExpr.cs @@ -11,143 +11,115 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Google.OrTools.LinearSolver -{ +namespace Google.OrTools.LinearSolver { using System; using System.Collections.Generic; -public class LinearExpr -{ - public virtual double DoVisit(Dictionary coefficients, - double multiplier) - { - return 0; + public class LinearExpr { + public virtual double DoVisit(Dictionary coefficients, + double multiplier) { + return 0; + } + + public double Visit(Dictionary coefficients) { + return DoVisit(coefficients, 1.0); + } + + public static LinearExpr operator +(LinearExpr a, double v) { + return new SumCst(a, v); + } + + public static LinearExpr operator +(double v, LinearExpr a) { + return new SumCst(a, v); + } + + public static LinearExpr operator +(LinearExpr a, LinearExpr b) { + return new Sum(a, b); + } + + public static LinearExpr operator -(LinearExpr a, double v) { + return new SumCst(a, -v); + } + + public static LinearExpr operator -(double v, LinearExpr a) { + return new SumCst(new ProductCst(a, -1.0), v); + } + + public static LinearExpr operator -(LinearExpr a, LinearExpr b) { + return new Sum(a, new ProductCst(b, -1.0)); + } + + public static LinearExpr operator -(LinearExpr a) { + return new ProductCst(a, -1.0); + } + + public static LinearExpr operator*(LinearExpr a, double v) { + return new ProductCst(a, v); + } + + public static LinearExpr operator /(LinearExpr a, double v) { + return new ProductCst(a, 1 / v); + } + + public static LinearExpr operator*(double v, LinearExpr a) { + return new ProductCst(a, v); + } + + public static RangeConstraint operator ==(LinearExpr a, double v) { + return new RangeConstraint(a, v, v); + } + + public static RangeConstraint operator ==(double v, LinearExpr a) { + return new RangeConstraint(a, v, v); + } + + public static RangeConstraint operator !=(LinearExpr a, double v) { + return new RangeConstraint(a, 1, -1); + } + + public static RangeConstraint operator !=(double v, LinearExpr a) { + return new RangeConstraint(a, 1, -1); + } + + public static Equality operator ==(LinearExpr a, LinearExpr b) { + return new Equality(a, b, true); + } + + public static Equality operator !=(LinearExpr a, LinearExpr b) { + return new Equality(a, b, false); + } + + public static RangeConstraint operator <=(LinearExpr a, double v) { + return new RangeConstraint(a, double.NegativeInfinity, v); + } + + public static RangeConstraint operator >=(LinearExpr a, double v) { + return new RangeConstraint(a, v, double.PositiveInfinity); + } + + public static RangeConstraint operator <=(LinearExpr a, LinearExpr b) { + return a - b <= 0; + } + + public static RangeConstraint operator >=(LinearExpr a, LinearExpr b) { + return a - b >= 0; + } + + public static implicit operator LinearExpr(Variable a) { + return new VarWrapper(a); + } } - public double Visit(Dictionary coefficients) - { - return DoVisit(coefficients, 1.0); - } + public static class LinearExprArrayHelper { + public static LinearExpr Sum(this LinearExpr[] exprs) { + return new SumArray(exprs); + } - public static LinearExpr operator+(LinearExpr a, double v) - { - return new SumCst(a, v); + public static LinearExpr Sum(this Variable[] vars) { + return new SumVarArray(vars); + } } - public static LinearExpr operator+(double v, LinearExpr a) - { - return new SumCst(a, v); - } - - public static LinearExpr operator+(LinearExpr a, LinearExpr b) - { - return new Sum(a, b); - } - - public static LinearExpr operator-(LinearExpr a, double v) - { - return new SumCst(a, -v); - } - - public static LinearExpr operator-(double v, LinearExpr a) - { - return new SumCst(new ProductCst(a, -1.0), v); - } - - public static LinearExpr operator-(LinearExpr a, LinearExpr b) - { - return new Sum(a, new ProductCst(b, -1.0)); - } - - public static LinearExpr operator-(LinearExpr a) - { - return new ProductCst(a, -1.0); - } - - public static LinearExpr operator*(LinearExpr a, double v) - { - return new ProductCst(a, v); - } - - public static LinearExpr operator/(LinearExpr a, double v) - { - return new ProductCst(a, 1 / v); - } - - public static LinearExpr operator*(double v, LinearExpr a) - { - return new ProductCst(a, v); - } - - public static RangeConstraint operator==(LinearExpr a, double v) - { - return new RangeConstraint(a, v, v); - } - - public static RangeConstraint operator==(double v, LinearExpr a) - { - return new RangeConstraint(a, v, v); - } - - public static RangeConstraint operator!=(LinearExpr a, double v) - { - return new RangeConstraint(a, 1, -1); - } - - public static RangeConstraint operator!=(double v, LinearExpr a) - { - return new RangeConstraint(a, 1, -1); - } - - public static Equality operator==(LinearExpr a, LinearExpr b) - { - return new Equality(a, b, true); - } - - public static Equality operator!=(LinearExpr a, LinearExpr b) - { - return new Equality(a, b, false); - } - - public static RangeConstraint operator<=(LinearExpr a, double v) - { - return new RangeConstraint(a, double.NegativeInfinity, v); - } - - public static RangeConstraint operator>=(LinearExpr a, double v) - { - return new RangeConstraint(a, v, double.PositiveInfinity); - } - - public static RangeConstraint operator<=(LinearExpr a, LinearExpr b) - { - return a - b <= 0; - } - - public static RangeConstraint operator>=(LinearExpr a, LinearExpr b) - { - return a - b >= 0; - } - - public static implicit operator LinearExpr(Variable a) - { - return new VarWrapper(a); - } -} - -public static class LinearExprArrayHelper -{ - public static LinearExpr Sum(this LinearExpr[] exprs) - { - return new SumArray(exprs); - } - - public static LinearExpr Sum(this Variable[] vars) - { - return new SumVarArray(vars); - } -} - // def __ge__(self, arg): // if isinstance(arg, (int, long, float)): // return LinearConstraint(self, arg, 1e308) @@ -160,185 +132,133 @@ public static class LinearExprArrayHelper // else: // return LinearConstraint(Sum(self, ProductCst(arg, -1)), -1e308, 0.0) - -class ProductCst : LinearExpr -{ - public ProductCst(LinearExpr expr, double coeff) - { - this.coeff_ = coeff; - this.expr_ = expr; - } - - public override String ToString() - { - return "(" + expr_.ToString() + " * " + coeff_ + ")"; - } - - public override double DoVisit(Dictionary coefficients, - double multiplier) - { - double current_multiplier = multiplier * coeff_; - if (current_multiplier != 0.0) - { - return expr_.DoVisit(coefficients, current_multiplier); + class ProductCst : LinearExpr { + public ProductCst(LinearExpr expr, double coeff) { + this.coeff_ = coeff; + this.expr_ = expr; } - else - { - return 0.0; + + public override String ToString() { + return "(" + expr_.ToString() + " * " + coeff_ + ")"; } - } - private LinearExpr expr_; - private double coeff_; -} - -class SumCst : LinearExpr -{ - public SumCst(LinearExpr expr, double coeff) - { - this.coeff_ = coeff; - this.expr_ = expr; - } - - public override String ToString() - { - return "(" + expr_.ToString() + " + " + coeff_ + ")"; - } - - public override double DoVisit(Dictionary coefficients, - double multiplier) - { - if (multiplier != 0.0) - { - return coeff_ * multiplier + expr_.DoVisit(coefficients, multiplier); - } - else - { - return 0.0; - } - } - - private LinearExpr expr_; - private double coeff_; -} - -class VarWrapper : LinearExpr -{ - public VarWrapper(Variable var) - { - this.var_ = var; - } - - public override String ToString() - { - return var_.Name(); - } - - public override double DoVisit(Dictionary coefficients, - double multiplier) - { - if (multiplier != 0.0) - { - if (coefficients.ContainsKey(var_)) - { - coefficients[var_] += multiplier; - } - else - { - coefficients[var_] = multiplier; + public override double DoVisit(Dictionary coefficients, + double multiplier) { + double current_multiplier = multiplier * coeff_; + if (current_multiplier != 0.0) { + return expr_.DoVisit(coefficients, current_multiplier); + } else { + return 0.0; } } - return 0.0; + + private LinearExpr expr_; + private double coeff_; } - private Variable var_; -} - - -class Sum : LinearExpr -{ - public Sum(LinearExpr left, LinearExpr right) - { - this.left_ = left; - this.right_ = right; - } - - public override String ToString() - { - return "(" + left_.ToString() + " + " + right_.ToString() + ")"; - } - - public override double DoVisit(Dictionary coefficients, - double multiplier) - { - if (multiplier != 0.0) - { - return left_.DoVisit(coefficients, multiplier) + - right_.DoVisit(coefficients, multiplier); + class SumCst : LinearExpr { + public SumCst(LinearExpr expr, double coeff) { + this.coeff_ = coeff; + this.expr_ = expr; } - else - { - return 0.0; + + public override String ToString() { + return "(" + expr_.ToString() + " + " + coeff_ + ")"; } - } - private LinearExpr left_; - private LinearExpr right_; -} - -public class SumArray : LinearExpr -{ - public SumArray(LinearExpr[] array) - { - this.array_ = array; - } - - public override double DoVisit(Dictionary coefficients, - double multiplier) { - if (multiplier != 0.0) - { - double constant = 0.0; - foreach (LinearExpr expr in array_) - { - constant += expr.DoVisit(coefficients, multiplier); + public override double DoVisit(Dictionary coefficients, + double multiplier) { + if (multiplier != 0.0) { + return coeff_ * multiplier + expr_.DoVisit(coefficients, multiplier); + } else { + return 0.0; } - return constant; - } - else - { - return 0.0; } + + private LinearExpr expr_; + private double coeff_; } - private LinearExpr[] array_; -} + class VarWrapper : LinearExpr { + public VarWrapper(Variable var) { this.var_ = var; } -public class SumVarArray : LinearExpr -{ - public SumVarArray(Variable[] array) - { - this.array_ = array; - } + public override String ToString() { return var_.Name(); } - public override double DoVisit(Dictionary coefficients, - double multiplier) { - if (multiplier != 0.0) - { - foreach (Variable var in array_) - { - if (coefficients.ContainsKey(var)) - { - coefficients[var] += multiplier; - } - else - { - coefficients[var] = multiplier; + public override double DoVisit(Dictionary coefficients, + double multiplier) { + if (multiplier != 0.0) { + if (coefficients.ContainsKey(var_)) { + coefficients[var_] += multiplier; + } else { + coefficients[var_] = multiplier; } } + return 0.0; } - return 0.0; + + private Variable var_; } - private Variable[] array_; -} + class Sum : LinearExpr { + public Sum(LinearExpr left, LinearExpr right) { + this.left_ = left; + this.right_ = right; + } + + public override String ToString() { + return "(" + left_.ToString() + " + " + right_.ToString() + ")"; + } + + public override double DoVisit(Dictionary coefficients, + double multiplier) { + if (multiplier != 0.0) { + return left_.DoVisit(coefficients, multiplier) + + right_.DoVisit(coefficients, multiplier); + } else { + return 0.0; + } + } + + private LinearExpr left_; + private LinearExpr right_; + } + + public class SumArray : LinearExpr { + public SumArray(LinearExpr[] array) { this.array_ = array; } + + public override double DoVisit(Dictionary coefficients, + double multiplier) { + if (multiplier != 0.0) { + double constant = 0.0; + foreach (LinearExpr expr in array_) { + constant += expr.DoVisit(coefficients, multiplier); + } + return constant; + } else { + return 0.0; + } + } + + private LinearExpr[] array_; + } + + public class SumVarArray : LinearExpr { + public SumVarArray(Variable[] array) { this.array_ = array; } + + public override double DoVisit(Dictionary coefficients, + double multiplier) { + if (multiplier != 0.0) { + foreach (Variable var in array_) { + if (coefficients.ContainsKey(var)) { + coefficients[var] += multiplier; + } else { + coefficients[var] = multiplier; + } + } + } + return 0.0; + } + + private Variable[] array_; + } } // namespace Google.OrTools.LinearSolver diff --git a/ortools/linear_solver/csharp/SolverHelper.cs b/ortools/linear_solver/csharp/SolverHelper.cs index 9746b39070..33db31d89b 100644 --- a/ortools/linear_solver/csharp/SolverHelper.cs +++ b/ortools/linear_solver/csharp/SolverHelper.cs @@ -12,219 +12,197 @@ // limitations under the License. namespace Google.OrTools.LinearSolver { -using System; -using System.Collections.Generic; + using System; + using System.Collections.Generic; -// Patch the MPSolver class to: -// - support custom versions of the array-based APIs (MakeVarArray, etc). -// - customize the construction, and the OptimizationProblemType enum. -// - support the natural language API. -public partial class Solver { - public Variable[] MakeVarArray(int count, - double lb, - double ub, - bool integer) { - Variable[] array = new Variable[count]; - for (int i = 0; i < count; ++i) { - array[i] = MakeVar(lb, ub, integer, ""); - } - return array; - } - - public Variable[] MakeVarArray(int count, - double lb, - double ub, - bool integer, - string var_name) { - Variable[] array = new Variable[count]; - for (int i = 0; i < count; ++i) { - array[i] = MakeVar(lb, ub, integer, var_name + i); - } - return array; - } - - public Variable[,] MakeVarMatrix(int rows, - int cols, - double lb, - double ub, + // Patch the MPSolver class to: + // - support custom versions of the array-based APIs (MakeVarArray, etc). + // - customize the construction, and the OptimizationProblemType enum. + // - support the natural language API. + public partial class Solver { + public Variable[] MakeVarArray(int count, double lb, double ub, bool integer) { - Variable[,] matrix = new Variable[rows, cols]; - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < cols; ++j) { - matrix[i,j] = MakeVar(lb, ub, integer, ""); + Variable[] array = new Variable[count]; + for (int i = 0; i < count; ++i) { + array [i] + = MakeVar(lb, ub, integer, ""); } + return array; } - return matrix; - } - public Variable[,] MakeVarMatrix(int rows, - int cols, - double lb, - double ub, - bool integer, - string name) { - Variable[,] matrix = new Variable[rows, cols]; - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < cols; ++j) { - string var_name = name + "[" + i + ", " + j +"]"; - matrix[i,j] = MakeVar(lb, ub, integer, var_name); + public Variable[] MakeVarArray(int count, double lb, double ub, + bool integer, string var_name) { + Variable[] array = new Variable[count]; + for (int i = 0; i < count; ++i) { + array [i] + = MakeVar(lb, ub, integer, var_name + i); } + return array; } - return matrix; - } - public Variable[] MakeNumVarArray(int count, double lb, double ub) { - return MakeVarArray(count, lb, ub, false); - } - - public Variable[] MakeNumVarArray(int count, - double lb, - double ub, - string var_name) { - return MakeVarArray(count, lb, ub, false, var_name); - } - - public Variable[,] MakeNumVarMatrix(int rows, - int cols, - double lb, - double ub) { - Variable[,] matrix = new Variable[rows, cols]; - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < cols; ++j) { - matrix[i,j] = MakeNumVar(lb, ub, ""); + public Variable[, ] MakeVarMatrix(int rows, int cols, double lb, double ub, + bool integer) { + Variable[, ] matrix = new Variable[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + matrix [i, j] + = MakeVar(lb, ub, integer, ""); + } } + return matrix; } - return matrix; - } - public Variable[,] MakeNumVarMatrix(int rows, - int cols, - double lb, - double ub, - string name) { - Variable[,] matrix = new Variable[rows, cols]; - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < cols; ++j) { - string var_name = name + "[" + i + ", " + j +"]"; - matrix[i,j] = MakeNumVar(lb, ub, var_name); + public Variable[, ] MakeVarMatrix(int rows, int cols, double lb, double ub, + bool integer, string name) { + Variable[, ] matrix = new Variable[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + string var_name = name + "[" + i + ", " + j + "]"; + matrix [i, j] + = MakeVar(lb, ub, integer, var_name); + } } + return matrix; } - return matrix; - } - public Variable[] MakeIntVarArray(int count, double lb, double ub) { - return MakeVarArray(count, lb, ub, true); - } + public Variable[] MakeNumVarArray(int count, double lb, double ub) { + return MakeVarArray(count, lb, ub, false); + } - public Variable[] MakeIntVarArray(int count, - double lb, - double ub, - string var_name) { - return MakeVarArray(count, lb, ub, true, var_name); - } + public Variable[] MakeNumVarArray(int count, double lb, double ub, + string var_name) { + return MakeVarArray(count, lb, ub, false, var_name); + } - public Variable[,] MakeIntVarMatrix(int rows, - int cols, - double lb, - double ub) { - Variable[,] matrix = new Variable[rows, cols]; - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < cols; ++j) { - matrix[i,j] = MakeIntVar(lb, ub, ""); + public Variable[, ] MakeNumVarMatrix(int rows, int cols, double lb, + double ub) { + Variable[, ] matrix = new Variable[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + matrix [i, j] + = MakeNumVar(lb, ub, ""); + } } + return matrix; } - return matrix; - } - public Variable[,] MakeIntVarMatrix(int rows, - int cols, - double lb, - double ub, - string name) { - Variable[,] matrix = new Variable[rows, cols]; - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < cols; ++j) { - string var_name = name + "[" + i + ", " + j +"]"; - matrix[i,j] = MakeIntVar(lb, ub, var_name); + public Variable[, ] MakeNumVarMatrix(int rows, int cols, double lb, + double ub, string name) { + Variable[, ] matrix = new Variable[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + string var_name = name + "[" + i + ", " + j + "]"; + matrix [i, j] + = MakeNumVar(lb, ub, var_name); + } } + return matrix; } - return matrix; - } - public Variable[] MakeBoolVarArray(int count) { - return MakeVarArray(count, 0.0, 1.0, true); - } + public Variable[] MakeIntVarArray(int count, double lb, double ub) { + return MakeVarArray(count, lb, ub, true); + } - public Variable[] MakeBoolVarArray(int count, string var_name) { - return MakeVarArray(count, 0.0, 1.0, true, var_name); - } + public Variable[] MakeIntVarArray(int count, double lb, double ub, + string var_name) { + return MakeVarArray(count, lb, ub, true, var_name); + } - public Variable[,] MakeBoolVarMatrix(int rows, int cols) { - Variable[,] matrix = new Variable[rows, cols]; - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < cols; ++j) { - matrix[i,j] = MakeBoolVar(""); + public Variable[, ] MakeIntVarMatrix(int rows, int cols, double lb, + double ub) { + Variable[, ] matrix = new Variable[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + matrix [i, j] + = MakeIntVar(lb, ub, ""); + } } + return matrix; } - return matrix; - } - public Variable[,] MakeBoolVarMatrix(int rows, int cols, string name) { - Variable[,] matrix = new Variable[rows, cols]; - for (int i = 0; i < rows; ++i) { - for (int j = 0; j < cols; ++j) { - string var_name = name + "[" + i + ", " + j +"]"; - matrix[i,j] = MakeBoolVar(var_name); + public Variable[, ] MakeIntVarMatrix(int rows, int cols, double lb, + double ub, string name) { + Variable[, ] matrix = new Variable[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + string var_name = name + "[" + i + ", " + j + "]"; + matrix [i, j] + = MakeIntVar(lb, ub, var_name); + } } + return matrix; } - return matrix; - } - public Constraint Add(LinearConstraint constraint) { - return constraint.Extract(this); - } - - public void Minimize(LinearExpr expr) - { - Objective().Clear(); - Objective().SetMinimization(); - Dictionary coefficients = - new Dictionary(); - double constant = expr.Visit(coefficients); - foreach (KeyValuePair pair in coefficients) - { - Objective().SetCoefficient(pair.Key, pair.Value); + public Variable[] MakeBoolVarArray(int count) { + return MakeVarArray(count, 0.0, 1.0, true); } - Objective().SetOffset(constant); - } - public void Maximize(LinearExpr expr) - { - Objective().Clear(); - Objective().SetMaximization(); - Dictionary coefficients = - new Dictionary(); - double constant = expr.Visit(coefficients); - foreach (KeyValuePair pair in coefficients) - { - Objective().SetCoefficient(pair.Key, pair.Value); + public Variable[] MakeBoolVarArray(int count, string var_name) { + return MakeVarArray(count, 0.0, 1.0, true, var_name); } - Objective().SetOffset(constant); - } - public void Minimize(Variable var) - { - Objective().Clear(); - Objective().SetMinimization(); - Objective().SetCoefficient(var, 1.0); - } + public Variable[, ] MakeBoolVarMatrix(int rows, int cols) { + Variable[, ] matrix = new Variable[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + matrix [i, j] + = MakeBoolVar(""); + } + } + return matrix; + } - public void Maximize(Variable var) - { - Objective().Clear(); - Objective().SetMaximization(); - Objective().SetCoefficient(var, 1.0); + public Variable[, ] MakeBoolVarMatrix(int rows, int cols, string name) { + Variable[, ] matrix = new Variable[rows, cols]; + for (int i = 0; i < rows; ++i) { + for (int j = 0; j < cols; ++j) { + string var_name = name + "[" + i + ", " + j + "]"; + matrix [i, j] + = MakeBoolVar(var_name); + } + } + return matrix; + } + + public Constraint Add(LinearConstraint constraint) { + return constraint.Extract(this); + } + + public void Minimize(LinearExpr expr) { + Objective().Clear(); + Objective().SetMinimization(); + Dictionary coefficients = + new Dictionary(); + double constant = expr.Visit(coefficients); + foreach (KeyValuePair pair in coefficients) { + Objective().SetCoefficient(pair.Key, pair.Value); + } + Objective().SetOffset(constant); + } + + public void Maximize(LinearExpr expr) { + Objective().Clear(); + Objective().SetMaximization(); + Dictionary coefficients = + new Dictionary(); + double constant = expr.Visit(coefficients); + foreach (KeyValuePair pair in coefficients) { + Objective().SetCoefficient(pair.Key, pair.Value); + } + Objective().SetOffset(constant); + } + + public void Minimize(Variable var) { + Objective().Clear(); + Objective().SetMinimization(); + Objective().SetCoefficient(var, 1.0); + } + + public void Maximize(Variable var) { + Objective().Clear(); + Objective().SetMaximization(); + Objective().SetCoefficient(var, 1.0); + } } -} } // namespace Google.OrTools.LinearSolver diff --git a/ortools/linear_solver/csharp/VariableHelper.cs b/ortools/linear_solver/csharp/VariableHelper.cs index 8088919aff..dd01d313bd 100644 --- a/ortools/linear_solver/csharp/VariableHelper.cs +++ b/ortools/linear_solver/csharp/VariableHelper.cs @@ -12,203 +12,170 @@ // limitations under the License. namespace Google.OrTools.LinearSolver { -using System; -using System.Collections.Generic; + using System; + using System.Collections.Generic; -// Patch the MPVariable class to support the natural language API. -public partial class Variable { - public static LinearExpr operator+(Variable a, double v) - { - return new VarWrapper(a) + v; - } - - public static LinearExpr operator+(double v, Variable a) - { - return a + v; - } - - public static LinearExpr operator+(Variable a, LinearExpr b) - { - return new VarWrapper(a) + b; - } - - public static LinearExpr operator+(Variable a, Variable b) - { - return new VarWrapper(a) + new VarWrapper(b); - } - - public static LinearExpr operator+(LinearExpr a, Variable b) - { - return a + new VarWrapper(b); - } - - public static LinearExpr operator-(Variable a, double v) - { - return new VarWrapper(a) - v; - } - - public static LinearExpr operator-(double v, Variable a) - { - return v - new VarWrapper(a); - } - - public static LinearExpr operator-(Variable a, LinearExpr b) - { - return new VarWrapper(a) - b; - } - - public static LinearExpr operator-(LinearExpr a, Variable b) - { - return a - new VarWrapper(b); - } - - public static LinearExpr operator-(Variable a, Variable b) - { - return new VarWrapper(a) - new VarWrapper(b); - } - - public static LinearExpr operator-(Variable a) - { - return - new VarWrapper(a); - } - - public static LinearExpr operator*(Variable a, double v) - { - return new VarWrapper(a) * v; - } - - public static LinearExpr operator/(Variable a, double v) - { - return new VarWrapper(a) / v; - } - - public static LinearExpr operator*(double v, Variable a) - { - return v * new VarWrapper(a); - } - - public static RangeConstraint operator==(Variable a, double v) - { - return new VarWrapper(a) == v; - } - - public static RangeConstraint operator==(double v, Variable a) - { - return v == new VarWrapper(a); - } - - public static RangeConstraint operator!=(Variable a, double v) - { - return new VarWrapper(a) != v; - } - - public static RangeConstraint operator!=(double v, Variable a) - { - return new VarWrapper(a) != v; - } - - public static Equality operator==(Variable a, LinearExpr b) - { - return new VarWrapper(a) == b; - } - - public static Equality operator==(LinearExpr a, Variable b) - { - return a == new VarWrapper(b); - } - - public static VarEquality operator==(Variable a, Variable b) - { - return new VarEquality(a, b, true); - } - - public static Equality operator!=(Variable a, LinearExpr b) - { - return new VarWrapper(a) != b; - } - - public static Equality operator!=(LinearExpr a, Variable b) - { - return a != new VarWrapper(b); - } - - public static VarEquality operator!=(Variable a, Variable b) - { - return new VarEquality(a, b, false); - } - - public static RangeConstraint operator<=(Variable a, double v) - { - return new VarWrapper(a) <= v; - } - - public static RangeConstraint operator>=(Variable a, double v) - { - return new VarWrapper(a) >= v; - } - - public static RangeConstraint operator<=(double v, Variable a) - { - return new VarWrapper(a) >= v; - } - - public static RangeConstraint operator>=(double v, Variable a) - { - return new VarWrapper(a) <= v; - } - - public static RangeConstraint operator<=(Variable a, LinearExpr b) - { - return new VarWrapper(a) <= b; - } - - public static RangeConstraint operator>=(Variable a, LinearExpr b) - { - return new VarWrapper(a) >= b; - } - - public static RangeConstraint operator<=(Variable a, Variable b) - { - return new VarWrapper(a) <= new VarWrapper(b); - } - - public static RangeConstraint operator>=(Variable a, Variable b) - { - return new VarWrapper(a) >= new VarWrapper(b); - } - - public static RangeConstraint operator<=(LinearExpr a, Variable b) - { - return a <= new VarWrapper(b); - } - - public static RangeConstraint operator>=(LinearExpr a, Variable b) - { - return a >= new VarWrapper(b); - } -} - -// TODO(user): Try to move this code back to the .swig with @define macros. -public partial class MPVariableVector: IDisposable, System.Collections.IEnumerable -#if !SWIG_DOTNET_1 - , System.Collections.Generic.IList -#endif -{ - // cast from C# MPVariable array - public static implicit operator MPVariableVector(Variable[] inVal) { - var outVal= new MPVariableVector(); - foreach (Variable element in inVal) { - outVal.Add(element); + // Patch the MPVariable class to support the natural language API. + public partial class Variable { + public static LinearExpr operator +(Variable a, double v) { + return new VarWrapper(a) + v; + } + + public static LinearExpr operator +(double v, Variable a) { return a + v; } + + public static LinearExpr operator +(Variable a, LinearExpr b) { + return new VarWrapper(a) + b; + } + + public static LinearExpr operator +(Variable a, Variable b) { + return new VarWrapper(a) + new VarWrapper(b); + } + + public static LinearExpr operator +(LinearExpr a, Variable b) { + return a + new VarWrapper(b); + } + + public static LinearExpr operator -(Variable a, double v) { + return new VarWrapper(a) - v; + } + + public static LinearExpr operator -(double v, Variable a) { + return v - new VarWrapper(a); + } + + public static LinearExpr operator -(Variable a, LinearExpr b) { + return new VarWrapper(a) - b; + } + + public static LinearExpr operator -(LinearExpr a, Variable b) { + return a - new VarWrapper(b); + } + + public static LinearExpr operator -(Variable a, Variable b) { + return new VarWrapper(a) - new VarWrapper(b); + } + + public static LinearExpr operator -(Variable a) { + return -new VarWrapper(a); + } + + public static LinearExpr operator*(Variable a, double v) { + return new VarWrapper(a) * v; + } + + public static LinearExpr operator /(Variable a, double v) { + return new VarWrapper(a) / v; + } + + public static LinearExpr operator*(double v, Variable a) { + return v * new VarWrapper(a); + } + + public static RangeConstraint operator ==(Variable a, double v) { + return new VarWrapper(a) == v; + } + + public static RangeConstraint operator ==(double v, Variable a) { + return v == new VarWrapper(a); + } + + public static RangeConstraint operator !=(Variable a, double v) { + return new VarWrapper(a) != v; + } + + public static RangeConstraint operator !=(double v, Variable a) { + return new VarWrapper(a) != v; + } + + public static Equality operator ==(Variable a, LinearExpr b) { + return new VarWrapper(a) == b; + } + + public static Equality operator ==(LinearExpr a, Variable b) { + return a == new VarWrapper(b); + } + + public static VarEquality operator ==(Variable a, Variable b) { + return new VarEquality(a, b, true); + } + + public static Equality operator !=(Variable a, LinearExpr b) { + return new VarWrapper(a) != b; + } + + public static Equality operator !=(LinearExpr a, Variable b) { + return a != new VarWrapper(b); + } + + public static VarEquality operator !=(Variable a, Variable b) { + return new VarEquality(a, b, false); + } + + public static RangeConstraint operator <=(Variable a, double v) { + return new VarWrapper(a) <= v; + } + + public static RangeConstraint operator >=(Variable a, double v) { + return new VarWrapper(a) >= v; + } + + public static RangeConstraint operator <=(double v, Variable a) { + return new VarWrapper(a) >= v; + } + + public static RangeConstraint operator >=(double v, Variable a) { + return new VarWrapper(a) <= v; + } + + public static RangeConstraint operator <=(Variable a, LinearExpr b) { + return new VarWrapper(a) <= b; + } + + public static RangeConstraint operator >=(Variable a, LinearExpr b) { + return new VarWrapper(a) >= b; + } + + public static RangeConstraint operator <=(Variable a, Variable b) { + return new VarWrapper(a) <= new VarWrapper(b); + } + + public static RangeConstraint operator >=(Variable a, Variable b) { + return new VarWrapper(a) >= new VarWrapper(b); + } + + public static RangeConstraint operator <=(LinearExpr a, Variable b) { + return a <= new VarWrapper(b); + } + + public static RangeConstraint operator >=(LinearExpr a, Variable b) { + return a >= new VarWrapper(b); } - return outVal; } - // cast to C# MPVariable array - public static implicit operator Variable[](MPVariableVector inVal) { - var outVal= new Variable[inVal.Count]; - inVal.CopyTo(outVal); - return outVal; + // TODO(user): Try to move this code back to the .swig with @define macros. + public partial class MPVariableVector + : IDisposable, + System.Collections.IEnumerable +#if !SWIG_DOTNET_1 + , + System.Collections.Generic.IList +#endif + { + // cast from C# MPVariable array + public static implicit operator MPVariableVector(Variable[] inVal) { + var outVal = new MPVariableVector(); + foreach (Variable element in inVal) { + outVal.Add(element); + } + return outVal; + } + + // cast to C# MPVariable array + public static implicit operator Variable[](MPVariableVector inVal) { + var outVal = new Variable[inVal.Count]; + inVal.CopyTo(outVal); + return outVal; + } } -} } // namespace Google.OrTools.LinearSolver diff --git a/ortools/linear_solver/samples/AssignmentMip.cs b/ortools/linear_solver/samples/AssignmentMip.cs index 777d2fe684..4be661eb9c 100644 --- a/ortools/linear_solver/samples/AssignmentMip.cs +++ b/ortools/linear_solver/samples/AssignmentMip.cs @@ -17,18 +17,13 @@ using System; using Google.OrTools.LinearSolver; // [END import] -public class AssignmentMip -{ - static void Main() - { +public class AssignmentMip { + static void Main() { // Data. // [START data_model] - int[,] costs = { - {90, 80, 75, 70}, - {35, 85, 55, 65}, - {125, 95, 90, 95}, - {45, 110, 95, 115}, - {50, 100, 90, 100}, + int[, ] costs = { + {90, 80, 75, 70}, {35, 85, 55, 65}, {125, 95, 90, 95}, + {45, 110, 95, 115}, {50, 100, 90, 100}, }; int numWorkers = costs.GetLength(0); int numTasks = costs.GetLength(1); @@ -43,11 +38,9 @@ public class AssignmentMip // [START variables] // x[i, j] is an array of 0-1 variables, which will be 1 // if worker i is assigned to task j. - Variable[,] x = new Variable[numWorkers, numTasks]; - for (int i = 0; i < numWorkers; ++i) - { - for (int j = 0; j < numTasks; ++j) - { + Variable[, ] x = new Variable[numWorkers, numTasks]; + for (int i = 0; i < numWorkers; ++i) { + for (int j = 0; j < numTasks; ++j) { x[i, j] = solver.MakeIntVar(0, 1, $"worker_{i}_task_{j}"); } } @@ -56,20 +49,16 @@ public class AssignmentMip // Constraints // [START constraints] // Each worker is assigned to at most one task. - for (int i = 0; i < numWorkers; ++i) - { + for (int i = 0; i < numWorkers; ++i) { Constraint constraint = solver.MakeConstraint(0, 1, ""); - for (int j = 0; j < numTasks; ++j) - { + for (int j = 0; j < numTasks; ++j) { constraint.SetCoefficient(x[i, j], 1); } } // Each task is assigned to exactly one worker. - for (int j = 0; j < numTasks; ++j) - { + for (int j = 0; j < numTasks; ++j) { Constraint constraint = solver.MakeConstraint(1, 1, ""); - for (int i = 0; i < numWorkers; ++i) - { + for (int i = 0; i < numWorkers; ++i) { constraint.SetCoefficient(x[i, j], 1); } } @@ -78,10 +67,8 @@ public class AssignmentMip // Objective // [START objective] Objective objective = solver.Objective(); - for (int i = 0; i < numWorkers; ++i) - { - for (int j = 0; j < numTasks; ++j) - { + for (int i = 0; i < numWorkers; ++i) { + for (int j = 0; j < numTasks; ++j) { objective.SetCoefficient(x[i, j], 1); } } @@ -96,18 +83,17 @@ public class AssignmentMip // Print solution. // [START print_solution] // Check that the problem has a feasible solution. - if (resultStatus == Solver.ResultStatus.OPTIMAL || resultStatus == Solver.ResultStatus.FEASIBLE) - { + if (resultStatus == Solver.ResultStatus.OPTIMAL || + resultStatus == Solver.ResultStatus.FEASIBLE) { Console.WriteLine($"Total cost: {solver.Objective().Value()}\n"); - for (int i = 0; i < numWorkers; ++i) - { - for (int j = 0; j < numTasks; ++j) - { + for (int i = 0; i < numWorkers; ++i) { + for (int j = 0; j < numTasks; ++j) { // Test if x[i, j] is 0 or 1 (with tolerance for floating point // arithmetic). - if (x[i, j].SolutionValue() > 0.5) - { - Console.WriteLine($"Worker {i} assigned to task {j}. Cost: {costs[i, j]}"); + if (x [i, j] + .SolutionValue() > 0.5) { + Console.WriteLine( + $"Worker {i} assigned to task {j}. Cost: {costs[i, j]}"); } } } diff --git a/ortools/linear_solver/samples/BinPackingMip.cs b/ortools/linear_solver/samples/BinPackingMip.cs index 073926d776..016a7c8bd9 100644 --- a/ortools/linear_solver/samples/BinPackingMip.cs +++ b/ortools/linear_solver/samples/BinPackingMip.cs @@ -18,19 +18,17 @@ using Google.OrTools.LinearSolver; // [END import] // [START program_part1] -public class BinPackingMip -{ +public class BinPackingMip { // [START data_model] - class DataModel - { - public static double[] Weights = {48, 30, 19, 36, 36, 27, 42, 42, 36, 24, 30}; + class DataModel { + public static double[] Weights = {48, 30, 19, 36, 36, 27, + 42, 42, 36, 24, 30}; public int NumItems = Weights.Length; public int NumBins = Weights.Length; public double BinCapacity = 100.0; } // [END data_model] - public static void Main() - { + public static void Main() { // [START data] DataModel data = new DataModel(); // [END data] @@ -43,19 +41,16 @@ public class BinPackingMip // [START program_part2] // [START variables] - Variable[,] x = new Variable[data.NumItems, data.NumBins]; - for (int i = 0; i < data.NumItems; i++) - { - for (int j = 0; j < data.NumBins; j++) - { + Variable[, ] x = new Variable[data.NumItems, data.NumBins]; + for (int i = 0; i < data.NumItems; i++) { + for (int j = 0; j < data.NumBins; j++) { x[i, j] = solver.MakeIntVar(0, 1, $"x_{i}_{j}"); } } Variable[] y = new Variable[data.NumBins]; - for (int j = 0; j < data.NumBins; j++) - { - y[j] = solver.MakeIntVar(0, 1, $"y_{j}"); - } + for (int j = 0; j < data.NumBins; j++) { + y[j] = solver.MakeIntVar(0, 1, $"y_{j}"); + } // [END variables] // [START constraints] @@ -66,12 +61,11 @@ public class BinPackingMip } } - for (int j = 0; j < data.NumBins; ++j) - { - Constraint constraint = solver.MakeConstraint(0, Double.PositiveInfinity, ""); + for (int j = 0; j < data.NumBins; ++j) { + Constraint constraint = + solver.MakeConstraint(0, Double.PositiveInfinity, ""); constraint.SetCoefficient(y[j], data.BinCapacity); - for (int i = 0; i < data.NumItems; ++i) - { + for (int i = 0; i < data.NumItems; ++i) { constraint.SetCoefficient(x[i, j], -DataModel.Weights[i]); } } @@ -79,8 +73,7 @@ public class BinPackingMip // [START objective] Objective objective = solver.Objective(); - for (int j = 0; j < data.NumBins; ++j) - { + for (int j = 0; j < data.NumBins; ++j) { objective.SetCoefficient(y[j], 1); } objective.SetMinimization(); @@ -92,23 +85,20 @@ public class BinPackingMip // [START print_solution] // Check that the problem has an optimal solution. - if (resultStatus != Solver.ResultStatus.OPTIMAL) - { + if (resultStatus != Solver.ResultStatus.OPTIMAL) { Console.WriteLine("The problem does not have an optimal solution!"); return; } Console.WriteLine($"Number of bins used: {solver.Objective().Value()}"); double TotalWeight = 0.0; - for (int j = 0; j < data.NumBins; ++j) - { + for (int j = 0; j < data.NumBins; ++j) { double BinWeight = 0.0; - if (y[j].SolutionValue() == 1) - { + if (y [j] + .SolutionValue() == 1) { Console.WriteLine($"Bin {j}"); - for (int i = 0; i < data.NumItems; ++i) - { - if (x[i, j].SolutionValue() == 1) - { + for (int i = 0; i < data.NumItems; ++i) { + if (x [i, j] + .SolutionValue() == 1) { Console.WriteLine($"Item {i} weight: {DataModel.Weights[i]}"); BinWeight += DataModel.Weights[i]; } diff --git a/ortools/linear_solver/samples/LinearProgrammingExample.cs b/ortools/linear_solver/samples/LinearProgrammingExample.cs index 9b84ea3647..3ce2b9e4c8 100644 --- a/ortools/linear_solver/samples/LinearProgrammingExample.cs +++ b/ortools/linear_solver/samples/LinearProgrammingExample.cs @@ -15,59 +15,57 @@ using System; using Google.OrTools.LinearSolver; -public class LinearProgrammingExample -{ - static void Main() - { - // [START solver] - Solver solver = Solver.CreateSolver("GLOP"); - // [END solver] - // x and y are continuous non-negative variables. - // [START variables] - Variable x = solver.MakeNumVar(0.0, double.PositiveInfinity, "x"); - Variable y = solver.MakeNumVar(0.0, double.PositiveInfinity, "y"); - // [END variables] +public class LinearProgrammingExample { + static void Main() { + // [START solver] + Solver solver = Solver.CreateSolver("GLOP"); + // [END solver] + // x and y are continuous non-negative variables. + // [START variables] + Variable x = solver.MakeNumVar(0.0, double.PositiveInfinity, "x"); + Variable y = solver.MakeNumVar(0.0, double.PositiveInfinity, "y"); + // [END variables] - // [START constraints] - // x + 2y <= 14. - Constraint c0 = solver.MakeConstraint(double.NegativeInfinity, 14.0); - c0.SetCoefficient(x, 1); - c0.SetCoefficient(y, 2); + // [START constraints] + // x + 2y <= 14. + Constraint c0 = solver.MakeConstraint(double.NegativeInfinity, 14.0); + c0.SetCoefficient(x, 1); + c0.SetCoefficient(y, 2); - // 3x - y >= 0. - Constraint c1 = solver.MakeConstraint(0.0, double.PositiveInfinity); - c1.SetCoefficient(x, 3); - c1.SetCoefficient(y, -1); + // 3x - y >= 0. + Constraint c1 = solver.MakeConstraint(0.0, double.PositiveInfinity); + c1.SetCoefficient(x, 3); + c1.SetCoefficient(y, -1); - // x - y <= 2. - Constraint c2 = solver.MakeConstraint(double.NegativeInfinity, 2.0); - c2.SetCoefficient(x, 1); - c2.SetCoefficient(y, -1); - // [END constraints] + // x - y <= 2. + Constraint c2 = solver.MakeConstraint(double.NegativeInfinity, 2.0); + c2.SetCoefficient(x, 1); + c2.SetCoefficient(y, -1); + // [END constraints] - // [START objective] - // Objective function: 3x + 4y. - Objective objective = solver.Objective(); - objective.SetCoefficient(x, 3); - objective.SetCoefficient(y, 4); - objective.SetMaximization(); - // [END objective] + // [START objective] + // Objective function: 3x + 4y. + Objective objective = solver.Objective(); + objective.SetCoefficient(x, 3); + objective.SetCoefficient(y, 4); + objective.SetMaximization(); + // [END objective] - // [START solve] - solver.Solve(); - // [END solve] + // [START solve] + solver.Solve(); + // [END solve] - // [START print_solution] - Console.WriteLine("Number of variables = " + solver.NumVariables()); - Console.WriteLine("Number of constraints = " + solver.NumConstraints()); - // The value of each variable in the solution. - Console.WriteLine("Solution:"); - Console.WriteLine("x = " + x.SolutionValue()); - Console.WriteLine("y = " + y.SolutionValue()); - // The objective value of the solution. - Console.WriteLine("Optimal objective value = " + + // [START print_solution] + Console.WriteLine("Number of variables = " + solver.NumVariables()); + Console.WriteLine("Number of constraints = " + solver.NumConstraints()); + // The value of each variable in the solution. + Console.WriteLine("Solution:"); + Console.WriteLine("x = " + x.SolutionValue()); + Console.WriteLine("y = " + y.SolutionValue()); + // The objective value of the solution. + Console.WriteLine("Optimal objective value = " + solver.Objective().Value()); - // [END print_solution] - } + // [END print_solution] + } } // [END program] diff --git a/ortools/linear_solver/samples/MipVarArray.cs b/ortools/linear_solver/samples/MipVarArray.cs index c854c2c3c9..96bb4e3ec2 100644 --- a/ortools/linear_solver/samples/MipVarArray.cs +++ b/ortools/linear_solver/samples/MipVarArray.cs @@ -18,25 +18,22 @@ using Google.OrTools.LinearSolver; // [END import] // [START program_part1] -public class MipVarArray -{ +public class MipVarArray { // [START data_model] - class DataModel - { - public double[,] ConstraintCoeffs = { - {5, 7, 9, 2, 1}, - {18, 4, -9, 10, 12}, - {4, 7, 3, 8, 5}, - {5, 13, 16, 3, -7}, + class DataModel { + public double[, ] ConstraintCoeffs = { + {5, 7, 9, 2, 1}, + {18, 4, -9, 10, 12}, + {4, 7, 3, 8, 5}, + {5, 13, 16, 3, -7}, }; - public double[] Bounds = { 250, 285, 211, 315 }; - public double[] ObjCoeffs = { 7, 8, 2, 9, 6 }; + public double[] Bounds = {250, 285, 211, 315}; + public double[] ObjCoeffs = {7, 8, 2, 9, 6}; public int NumVars = 5; public int NumConstraints = 4; } // [END data_model] - public static void Main() - { + public static void Main() { // [START data] DataModel data = new DataModel(); // [END data] @@ -50,19 +47,16 @@ public class MipVarArray // [START program_part2] // [START variables] Variable[] x = new Variable[data.NumVars]; - for (int j = 0; j < data.NumVars; j++) - { + for (int j = 0; j < data.NumVars; j++) { x[j] = solver.MakeIntVar(0.0, double.PositiveInfinity, $"x_{j}"); } Console.WriteLine("Number of variables = " + solver.NumVariables()); // [END variables] // [START constraints] - for (int i = 0; i < data.NumConstraints; ++i) - { + for (int i = 0; i < data.NumConstraints; ++i) { Constraint constraint = solver.MakeConstraint(0, data.Bounds[i], ""); - for (int j = 0; j < data.NumVars; ++j) - { + for (int j = 0; j < data.NumVars; ++j) { constraint.SetCoefficient(x[j], data.ConstraintCoeffs[i, j]); } } @@ -71,8 +65,7 @@ public class MipVarArray // [START objective] Objective objective = solver.Objective(); - for (int j = 0; j < data.NumVars; ++j) - { + for (int j = 0; j < data.NumVars; ++j) { objective.SetCoefficient(x[j], data.ObjCoeffs[j]); } objective.SetMaximization(); @@ -84,26 +77,30 @@ public class MipVarArray // [START print_solution] // Check that the problem has an optimal solution. - if (resultStatus != Solver.ResultStatus.OPTIMAL) - { + if (resultStatus != Solver.ResultStatus.OPTIMAL) { Console.WriteLine("The problem does not have an optimal solution!"); return; } Console.WriteLine("Solution:"); - Console.WriteLine("Optimal objective value = " + solver.Objective().Value()); + Console.WriteLine("Optimal objective value = " + + solver.Objective().Value()); - for (int j = 0; j < data.NumVars; ++j) - { - Console.WriteLine("x[" + j + "] = " + x[j].SolutionValue()); + for (int j = 0; j < data.NumVars; ++j) { + Console.WriteLine("x[" + j + "] = " + + x [j] + .SolutionValue()); } // [END print_solution] // [START advanced] Console.WriteLine("\nAdvanced usage:"); - Console.WriteLine("Problem solved in " + solver.WallTime() + " milliseconds"); - Console.WriteLine("Problem solved in " + solver.Iterations() + " iterations"); - Console.WriteLine("Problem solved in " + solver.Nodes() + " branch-and-bound nodes"); + Console.WriteLine("Problem solved in " + solver.WallTime() + + " milliseconds"); + Console.WriteLine("Problem solved in " + solver.Iterations() + + " iterations"); + Console.WriteLine("Problem solved in " + solver.Nodes() + + " branch-and-bound nodes"); // [END advanced] } } diff --git a/ortools/linear_solver/samples/MultipleKnapsackMip.cs b/ortools/linear_solver/samples/MultipleKnapsackMip.cs index bbd9fe3930..5d43edfda7 100644 --- a/ortools/linear_solver/samples/MultipleKnapsackMip.cs +++ b/ortools/linear_solver/samples/MultipleKnapsackMip.cs @@ -18,22 +18,19 @@ using Google.OrTools.LinearSolver; // [END import] // [START program_part1] -public class MultipleKnapsackMip -{ +public class MultipleKnapsackMip { // [START data_model] - class DataModel - { - public static double[] Weights = - {48, 30, 42, 36, 36, 48, 42, 42, 36, 24, 30, 30, 42, 36, 36}; - public static double[] Values = - {10, 30, 25, 50, 35, 30, 15, 40, 30, 35, 45, 10, 20, 30, 25}; + class DataModel { + public static double[] Weights = {48, 30, 42, 36, 36, 48, 42, 42, + 36, 24, 30, 30, 42, 36, 36}; + public static double[] Values = {10, 30, 25, 50, 35, 30, 15, 40, + 30, 35, 45, 10, 20, 30, 25}; public double[] BinCapacities = {100, 100, 100, 100, 100}; public int NumItems = Weights.Length; public int NumBins = 5; } // [END data_model] - public static void Main() - { + public static void Main() { // [START data] DataModel data = new DataModel(); // [END data] @@ -46,11 +43,9 @@ public class MultipleKnapsackMip // [START program_part2] // [START variables] - Variable[,] x = new Variable[data.NumItems, data.NumBins]; - for (int i = 0; i < data.NumItems; i++) - { - for (int j = 0; j < data.NumBins; j++) - { + Variable[, ] x = new Variable[data.NumItems, data.NumBins]; + for (int i = 0; i < data.NumItems; i++) { + for (int j = 0; j < data.NumBins; j++) { x[i, j] = solver.MakeIntVar(0, 1, $"x_{i}_{j}"); } } @@ -64,11 +59,10 @@ public class MultipleKnapsackMip } } - for (int j = 0; j < data.NumBins; ++j) - { - Constraint constraint = solver.MakeConstraint(0, data.BinCapacities[j], ""); - for (int i = 0; i < data.NumItems; ++i) - { + for (int j = 0; j < data.NumBins; ++j) { + Constraint constraint = + solver.MakeConstraint(0, data.BinCapacities[j], ""); + for (int i = 0; i < data.NumItems; ++i) { constraint.SetCoefficient(x[i, j], DataModel.Weights[i]); } } @@ -76,10 +70,8 @@ public class MultipleKnapsackMip // [START objective] Objective objective = solver.Objective(); - for (int i = 0; i < data.NumItems; ++i) - { - for (int j = 0; j < data.NumBins; ++j) - { + for (int i = 0; i < data.NumItems; ++i) { + for (int j = 0; j < data.NumBins; ++j) { objective.SetCoefficient(x[i, j], DataModel.Values[i]); } } @@ -92,23 +84,21 @@ public class MultipleKnapsackMip // [START print_solution] // Check that the problem has an optimal solution. - if (resultStatus != Solver.ResultStatus.OPTIMAL) - { + if (resultStatus != Solver.ResultStatus.OPTIMAL) { Console.WriteLine("The problem does not have an optimal solution!"); return; } Console.WriteLine("Total packed value: " + solver.Objective().Value()); double TotalWeight = 0.0; - for (int j = 0; j < data.NumBins; ++j) - { + for (int j = 0; j < data.NumBins; ++j) { double BinWeight = 0.0; double BinValue = 0.0; Console.WriteLine("Bin " + j); - for (int i = 0; i < data.NumItems; ++i) - { - if (x[i, j].SolutionValue() == 1) - { - Console.WriteLine($"Item {i} weight: {DataModel.Weights[i]} values: {DataModel.Values[i]}"); + for (int i = 0; i < data.NumItems; ++i) { + if (x [i, j] + .SolutionValue() == 1) { + Console.WriteLine( + $"Item {i} weight: {DataModel.Weights[i]} values: {DataModel.Values[i]}"); BinWeight += DataModel.Weights[i]; BinValue += DataModel.Values[i]; } diff --git a/ortools/linear_solver/samples/SimpleLpProgram.cs b/ortools/linear_solver/samples/SimpleLpProgram.cs index 8711896a35..14c5e80cdc 100644 --- a/ortools/linear_solver/samples/SimpleLpProgram.cs +++ b/ortools/linear_solver/samples/SimpleLpProgram.cs @@ -16,10 +16,8 @@ using System; using Google.OrTools.LinearSolver; -public class SimpleLpProgram -{ - static void Main() - { +public class SimpleLpProgram { + static void Main() { // [START solver] // Create the linear solver with the GLOP backend. Solver solver = Solver.CreateSolver("GLOP"); diff --git a/ortools/linear_solver/samples/SimpleMipProgram.cs b/ortools/linear_solver/samples/SimpleMipProgram.cs index 2b3fd2d2a3..e0bff1a12e 100644 --- a/ortools/linear_solver/samples/SimpleMipProgram.cs +++ b/ortools/linear_solver/samples/SimpleMipProgram.cs @@ -17,10 +17,8 @@ using System; using Google.OrTools.LinearSolver; // [END import] -public class SimpleMipProgram -{ - static void Main() - { +public class SimpleMipProgram { + static void Main() { // [START solver] // Create the linear solver with the SCIP backend. Solver solver = Solver.CreateSolver("SCIP"); @@ -55,8 +53,7 @@ public class SimpleMipProgram // [START print_solution] // Check that the problem has an optimal solution. - if (resultStatus != Solver.ResultStatus.OPTIMAL) - { + if (resultStatus != Solver.ResultStatus.OPTIMAL) { Console.WriteLine("The problem does not have an optimal solution!"); return; } @@ -68,9 +65,12 @@ public class SimpleMipProgram // [START advanced] Console.WriteLine("\nAdvanced usage:"); - Console.WriteLine("Problem solved in " + solver.WallTime() + " milliseconds"); - Console.WriteLine("Problem solved in " + solver.Iterations() + " iterations"); - Console.WriteLine("Problem solved in " + solver.Nodes() + " branch-and-bound nodes"); + Console.WriteLine("Problem solved in " + solver.WallTime() + + " milliseconds"); + Console.WriteLine("Problem solved in " + solver.Iterations() + + " iterations"); + Console.WriteLine("Problem solved in " + solver.Nodes() + + " branch-and-bound nodes"); // [END advanced] } } diff --git a/ortools/sat/csharp/Constraints.cs b/ortools/sat/csharp/Constraints.cs index 1b93d4e69a..ae5a9d2025 100644 --- a/ortools/sat/csharp/Constraints.cs +++ b/ortools/sat/csharp/Constraints.cs @@ -11,45 +11,38 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Google.OrTools.Sat -{ -using System; -using System.Collections.Generic; +namespace Google.OrTools.Sat { + using System; + using System.Collections.Generic; -public class Constraint -{ - public Constraint(CpModelProto model) - { - index_ = model.Constraints.Count; - constraint_ = new ConstraintProto(); - model.Constraints.Add(constraint_); - } + public class Constraint { + public Constraint(CpModelProto model) { + index_ = model.Constraints.Count; + constraint_ = new ConstraintProto(); + model.Constraints.Add(constraint_); + } - public void OnlyEnforceIf(ILiteral lit) - { - constraint_.EnforcementLiteral.Add(lit.GetIndex()); - } - - public void OnlyEnforceIf(ILiteral[] lits) - { - foreach (ILiteral lit in lits) { + public void OnlyEnforceIf(ILiteral lit) { constraint_.EnforcementLiteral.Add(lit.GetIndex()); } - } - public int Index - { - get { return index_; } - } + public void OnlyEnforceIf(ILiteral[] lits) { + foreach (ILiteral lit in lits) { + constraint_.EnforcementLiteral.Add(lit.GetIndex()); + } + } - public ConstraintProto Proto - { - get { return constraint_; } - set { constraint_ = value; } - } + public int Index { + get { return index_; } + } - private int index_; - private ConstraintProto constraint_; -} + public ConstraintProto Proto { + get { return constraint_; } + set { constraint_ = value; } + } + + private int index_; + private ConstraintProto constraint_; + } } // namespace Google.OrTools.Sat diff --git a/ortools/sat/csharp/CpModel.cs b/ortools/sat/csharp/CpModel.cs index 9c1db858f4..767d3ad757 100644 --- a/ortools/sat/csharp/CpModel.cs +++ b/ortools/sat/csharp/CpModel.cs @@ -11,8 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Google.OrTools.Sat -{ +namespace Google.OrTools.Sat { using System; using System.Collections.Generic; using Google.OrTools.Util; @@ -20,80 +19,63 @@ namespace Google.OrTools.Sat /// /// Wrapper class around the cp_model proto. /// - public class CpModel - { - public CpModel() - { + public class CpModel { + public CpModel() { model_ = new CpModelProto(); constant_map_ = new Dictionary(); } // Getters. - public CpModelProto Model - { + public CpModelProto Model { get { return model_; } } - int Negated(int index) - { - return -index - 1; - } + int Negated(int index) { return -index - 1; } // Integer variables and constraints. - public IntVar NewIntVar(long lb, long ub, string name) - { + public IntVar NewIntVar(long lb, long ub, string name) { return new IntVar(model_, new Domain(lb, ub), name); } - public IntVar NewIntVarFromDomain(Domain domain, string name) - { + public IntVar NewIntVarFromDomain(Domain domain, string name) { return new IntVar(model_, domain, name); } // Constants (named or not). // TODO: Cache constant. - public IntVar NewConstant(long value) - { + public IntVar NewConstant(long value) { return new IntVar(model_, new Domain(value), String.Format("{0}", value)); } - public IntVar NewConstant(long value, string name) - { + public IntVar NewConstant(long value, string name) { return new IntVar(model_, new Domain(value), name); } - public IntVar NewBoolVar(string name) - { + public IntVar NewBoolVar(string name) { return new IntVar(model_, new Domain(0, 1), name); } public Constraint AddLinearConstraint(LinearExpr linear_expr, long lb, - long ub) - { + long ub) { return AddLinearExpressionInDomain(linear_expr, new Domain(lb, ub)); } - public Constraint AddLinearExpressionInDomain(LinearExpr linear_expr, Domain domain) - { + public Constraint AddLinearExpressionInDomain(LinearExpr linear_expr, + Domain domain) { Dictionary dict = new Dictionary(); long constant = LinearExpr.GetVarValueMap(linear_expr, 1L, dict); Constraint ct = new Constraint(model_); LinearConstraintProto linear = new LinearConstraintProto(); - foreach (KeyValuePair term in dict) - { + foreach (KeyValuePair term in dict) { linear.Vars.Add(term.Key.Index); linear.Coeffs.Add(term.Value); } - foreach (long value in domain.FlattenedIntervals()) - { - if (value == Int64.MinValue || value == Int64.MaxValue) - { + foreach (long value in domain.FlattenedIntervals()) { + if (value == Int64.MinValue || value == Int64.MaxValue) { linear.Domain.Add(value); - } - else - { + } else { linear.Domain.Add(value - constant); } } @@ -101,47 +83,40 @@ namespace Google.OrTools.Sat return ct; } - public Constraint Add(BoundedLinearExpression lin) - { - switch (lin.CtType) - { - case BoundedLinearExpression.Type.BoundExpression: - { - return AddLinearExpressionInDomain(lin.Left, new Domain(lin.Lb, lin.Ub)); - } - case BoundedLinearExpression.Type.VarEqVar: - { - return AddLinearExpressionInDomain(lin.Left - lin.Right, new Domain(0)); - } - case BoundedLinearExpression.Type.VarDiffVar: - { - return AddLinearExpressionInDomain( - lin.Left - lin.Right, - Domain.FromFlatIntervals(new long[] { Int64.MinValue, -1, 1, - Int64.MaxValue })); - } - case BoundedLinearExpression.Type.VarEqCst: - { - return AddLinearExpressionInDomain(lin.Left, - new Domain(lin.Lb, lin.Lb)); - } - case BoundedLinearExpression.Type.VarDiffCst: - { - return AddLinearExpressionInDomain( - lin.Left, - Domain.FromFlatIntervals( - new long[] { Int64.MinValue, lin.Lb - 1, lin.Lb + 1, Int64.MaxValue })); - } + public Constraint Add(BoundedLinearExpression lin) { + switch (lin.CtType) { + case BoundedLinearExpression.Type.BoundExpression: { + return AddLinearExpressionInDomain(lin.Left, + new Domain(lin.Lb, lin.Ub)); + } + case BoundedLinearExpression.Type.VarEqVar: { + return AddLinearExpressionInDomain(lin.Left - lin.Right, + new Domain(0)); + } + case BoundedLinearExpression.Type.VarDiffVar: { + return AddLinearExpressionInDomain( + lin.Left - lin.Right, + Domain.FromFlatIntervals( + new long[]{Int64.MinValue, -1, 1, Int64.MaxValue})); + } + case BoundedLinearExpression.Type.VarEqCst: { + return AddLinearExpressionInDomain(lin.Left, + new Domain(lin.Lb, lin.Lb)); + } + case BoundedLinearExpression.Type.VarDiffCst: { + return AddLinearExpressionInDomain( + lin.Left, + Domain.FromFlatIntervals(new long[]{Int64.MinValue, lin.Lb - 1, + lin.Lb + 1, Int64.MaxValue})); + } } return null; } - public Constraint AddAllDifferent(IEnumerable vars) - { + public Constraint AddAllDifferent(IEnumerable vars) { Constraint ct = new Constraint(model_); AllDifferentConstraintProto alldiff = new AllDifferentConstraintProto(); - foreach (IntVar var in vars) - { + foreach (IntVar var in vars) { alldiff.Vars.Add(var.Index); } ct.Proto.AllDiff = alldiff; @@ -149,13 +124,11 @@ namespace Google.OrTools.Sat } public Constraint AddElement(IntVar index, IEnumerable vars, - IntVar target) - { + IntVar target) { Constraint ct = new Constraint(model_); ElementConstraintProto element = new ElementConstraintProto(); element.Index = index.Index; - foreach (IntVar var in vars) - { + foreach (IntVar var in vars) { element.Vars.Add(var.Index); } element.Target = target.Index; @@ -164,13 +137,11 @@ namespace Google.OrTools.Sat } public Constraint AddElement(IntVar index, IEnumerable values, - IntVar target) - { + IntVar target) { Constraint ct = new Constraint(model_); ElementConstraintProto element = new ElementConstraintProto(); element.Index = index.Index; - foreach (long value in values) - { + foreach (long value in values) { element.Vars.Add(ConvertConstant(value)); } element.Target = target.Index; @@ -179,13 +150,11 @@ namespace Google.OrTools.Sat } public Constraint AddElement(IntVar index, IEnumerable values, - IntVar target) - { + IntVar target) { Constraint ct = new Constraint(model_); ElementConstraintProto element = new ElementConstraintProto(); element.Index = index.Index; - foreach (int value in values) - { + foreach (int value in values) { element.Vars.Add(ConvertConstant(value)); } element.Target = target.Index; @@ -193,12 +162,10 @@ namespace Google.OrTools.Sat return ct; } - public Constraint AddCircuit(IEnumerable> arcs) - { + public Constraint AddCircuit(IEnumerable> arcs) { Constraint ct = new Constraint(model_); CircuitConstraintProto circuit = new CircuitConstraintProto(); - foreach (var arc in arcs) - { + foreach (var arc in arcs) { circuit.Tails.Add(arc.Item1); circuit.Heads.Add(arc.Item2); circuit.Literals.Add(arc.Item3.GetIndex()); @@ -208,18 +175,14 @@ namespace Google.OrTools.Sat } public Constraint AddAllowedAssignments(IEnumerable vars, - long[,] tuples) - { + long[, ] tuples) { Constraint ct = new Constraint(model_); TableConstraintProto table = new TableConstraintProto(); - foreach (IntVar var in vars) - { + foreach (IntVar var in vars) { table.Vars.Add(var.Index); } - for (int i = 0; i < tuples.GetLength(0); ++i) - { - for (int j = 0; j < tuples.GetLength(1); ++j) - { + for (int i = 0; i < tuples.GetLength(0); ++i) { + for (int j = 0; j < tuples.GetLength(1); ++j) { table.Values.Add(tuples[i, j]); } } @@ -228,31 +191,25 @@ namespace Google.OrTools.Sat } public Constraint AddForbiddenAssignments(IEnumerable vars, - long[,] tuples) - { + long[, ] tuples) { Constraint ct = AddAllowedAssignments(vars, tuples); ct.Proto.Table.Negated = true; return ct; } public Constraint AddAutomaton(IEnumerable vars, - long starting_state, - long[,] transitions, - IEnumerable final_states) - { + long starting_state, long[, ] transitions, + IEnumerable final_states) { Constraint ct = new Constraint(model_); AutomatonConstraintProto aut = new AutomatonConstraintProto(); - foreach (IntVar var in vars) - { + foreach (IntVar var in vars) { aut.Vars.Add(var.Index); } aut.StartingState = starting_state; - foreach (long f in final_states) - { + foreach (long f in final_states) { aut.FinalStates.Add(f); } - for (int i = 0; i < transitions.GetLength(0); ++i) - { + for (int i = 0; i < transitions.GetLength(0); ++i) { aut.TransitionTail.Add(transitions[i, 0]); aut.TransitionLabel.Add(transitions[i, 1]); aut.TransitionHead.Add(transitions[i, 2]); @@ -263,25 +220,19 @@ namespace Google.OrTools.Sat } public Constraint AddAutomaton( - IEnumerable vars, - long starting_state, + IEnumerable vars, long starting_state, IEnumerable> transitions, - IEnumerable final_states) - { + IEnumerable final_states) { Constraint ct = new Constraint(model_); AutomatonConstraintProto aut = new AutomatonConstraintProto(); - foreach (IntVar var in vars) - { + foreach (IntVar var in vars) { aut.Vars.Add(var.Index); } aut.StartingState = starting_state; - foreach (long f in final_states) - { + foreach (long f in final_states) { aut.FinalStates.Add(f); } - foreach (Tuple transition in transitions) - { - + foreach (Tuple transition in transitions) { aut.TransitionHead.Add(transition.Item1); aut.TransitionLabel.Add(transition.Item2); aut.TransitionTail.Add(transition.Item3); @@ -292,16 +243,13 @@ namespace Google.OrTools.Sat } public Constraint AddInverse(IEnumerable direct, - IEnumerable reverse) - { + IEnumerable reverse) { Constraint ct = new Constraint(model_); InverseConstraintProto inverse = new InverseConstraintProto(); - foreach (IntVar var in direct) - { + foreach (IntVar var in direct) { inverse.FDirect.Add(var.Index); } - foreach (IntVar var in reverse) - { + foreach (IntVar var in reverse) { inverse.FInverse.Add(var.Index); } ct.Proto.Inverse = inverse; @@ -310,16 +258,14 @@ namespace Google.OrTools.Sat public Constraint AddReservoirConstraint(IEnumerable times, IEnumerable demands, - long min_level, long max_level) - { + long min_level, + long max_level) { Constraint ct = new Constraint(model_); ReservoirConstraintProto res = new ReservoirConstraintProto(); - foreach (IntVar var in times) - { + foreach (IntVar var in times) { res.Times.Add(var.Index); } - foreach (I d in demands) - { + foreach (I d in demands) { res.Demands.Add(Convert.ToInt64(d)); } @@ -331,23 +277,17 @@ namespace Google.OrTools.Sat } public Constraint AddReservoirConstraintWithActive( - IEnumerable times, - IEnumerable demands, - IEnumerable actives, - long min_level, long max_level) - { + IEnumerable times, IEnumerable demands, + IEnumerable actives, long min_level, long max_level) { Constraint ct = new Constraint(model_); ReservoirConstraintProto res = new ReservoirConstraintProto(); - foreach (IntVar var in times) - { + foreach (IntVar var in times) { res.Times.Add(var.Index); } - foreach (I d in demands) - { + foreach (I d in demands) { res.Demands.Add(Convert.ToInt64(d)); } - foreach (IntVar var in actives) - { + foreach (IntVar var in actives) { res.Actives.Add(var.Index); } res.MinLevel = min_level; @@ -357,12 +297,10 @@ namespace Google.OrTools.Sat return ct; } - public void AddMapDomain( - IntVar var, IEnumerable bool_vars, long offset = 0) - { + public void AddMapDomain(IntVar var, IEnumerable bool_vars, + long offset = 0) { int i = 0; - foreach (IntVar bool_var in bool_vars) - { + foreach (IntVar bool_var in bool_vars) { int b_index = bool_var.Index; int var_index = var.Index; @@ -392,8 +330,7 @@ namespace Google.OrTools.Sat } } - public Constraint AddImplication(ILiteral a, ILiteral b) - { + public Constraint AddImplication(ILiteral a, ILiteral b) { Constraint ct = new Constraint(model_); BoolArgumentProto or = new BoolArgumentProto(); or.Literals.Add(a.Not().GetIndex()); @@ -402,48 +339,40 @@ namespace Google.OrTools.Sat return ct; } - public Constraint AddBoolOr(IEnumerable literals) - { + public Constraint AddBoolOr(IEnumerable literals) { Constraint ct = new Constraint(model_); BoolArgumentProto bool_argument = new BoolArgumentProto(); - foreach (ILiteral lit in literals) - { + foreach (ILiteral lit in literals) { bool_argument.Literals.Add(lit.GetIndex()); } ct.Proto.BoolOr = bool_argument; return ct; } - public Constraint AddBoolAnd(IEnumerable literals) - { + public Constraint AddBoolAnd(IEnumerable literals) { Constraint ct = new Constraint(model_); BoolArgumentProto bool_argument = new BoolArgumentProto(); - foreach (ILiteral lit in literals) - { + foreach (ILiteral lit in literals) { bool_argument.Literals.Add(lit.GetIndex()); } ct.Proto.BoolAnd = bool_argument; return ct; } - public Constraint AddBoolXor(IEnumerable literals) - { + public Constraint AddBoolXor(IEnumerable literals) { Constraint ct = new Constraint(model_); BoolArgumentProto bool_argument = new BoolArgumentProto(); - foreach (ILiteral lit in literals) - { + foreach (ILiteral lit in literals) { bool_argument.Literals.Add(lit.GetIndex()); } ct.Proto.BoolXor = bool_argument; return ct; } - public Constraint AddMinEquality(IntVar target, IEnumerable vars) - { + public Constraint AddMinEquality(IntVar target, IEnumerable vars) { Constraint ct = new Constraint(model_); IntegerArgumentProto args = new IntegerArgumentProto(); - foreach (IntVar var in vars) - { + foreach (IntVar var in vars) { args.Vars.Add(var.Index); } args.Target = target.Index; @@ -451,12 +380,10 @@ namespace Google.OrTools.Sat return ct; } - public Constraint AddMaxEquality(IntVar target, IEnumerable vars) - { + public Constraint AddMaxEquality(IntVar target, IEnumerable vars) { Constraint ct = new Constraint(model_); IntegerArgumentProto args = new IntegerArgumentProto(); - foreach (IntVar var in vars) - { + foreach (IntVar var in vars) { args.Vars.Add(var.Index); } args.Target = target.Index; @@ -464,8 +391,7 @@ namespace Google.OrTools.Sat return ct; } - public Constraint AddDivisionEquality(T target, N num, D denom) - { + public Constraint AddDivisionEquality(T target, N num, D denom) { Constraint ct = new Constraint(model_); IntegerArgumentProto args = new IntegerArgumentProto(); args.Vars.Add(GetOrCreateIndex(num)); @@ -475,8 +401,7 @@ namespace Google.OrTools.Sat return ct; } - public Constraint AddAbsEquality(IntVar target, IntVar var) - { + public Constraint AddAbsEquality(IntVar target, IntVar var) { Constraint ct = new Constraint(model_); IntegerArgumentProto args = new IntegerArgumentProto(); args.Vars.Add(var.Index); @@ -486,8 +411,7 @@ namespace Google.OrTools.Sat return ct; } - public Constraint AddModuloEquality(T target, V v, M m) - { + public Constraint AddModuloEquality(T target, V v, M m) { Constraint ct = new Constraint(model_); IntegerArgumentProto args = new IntegerArgumentProto(); args.Vars.Add(GetOrCreateIndex(v)); @@ -497,13 +421,11 @@ namespace Google.OrTools.Sat return ct; } - public Constraint AddProdEquality(IntVar target, IEnumerable vars) - { + public Constraint AddProdEquality(IntVar target, IEnumerable vars) { Constraint ct = new Constraint(model_); IntegerArgumentProto args = new IntegerArgumentProto(); args.Target = target.Index; - foreach (IntVar var in vars) - { + foreach (IntVar var in vars) { args.Vars.Add(var.Index); } ct.Proto.IntProd = args; @@ -512,35 +434,27 @@ namespace Google.OrTools.Sat // Scheduling support - public IntervalVar NewIntervalVar( - S start, D duration, E end, string name) - { - return new IntervalVar(model_, - GetOrCreateIndex(start), - GetOrCreateIndex(duration), - GetOrCreateIndex(end), + public IntervalVar NewIntervalVar(S start, D duration, E end, + string name) { + return new IntervalVar(model_, GetOrCreateIndex(start), + GetOrCreateIndex(duration), GetOrCreateIndex(end), name); } - - public IntervalVar NewOptionalIntervalVar( - S start, D duration, E end, ILiteral is_present, string name) - { + public IntervalVar NewOptionalIntervalVar(S start, D duration, + E end, + ILiteral is_present, + string name) { int i = is_present.GetIndex(); - return new IntervalVar(model_, - GetOrCreateIndex(start), - GetOrCreateIndex(duration), - GetOrCreateIndex(end), - i, - name); + return new IntervalVar(model_, GetOrCreateIndex(start), + GetOrCreateIndex(duration), GetOrCreateIndex(end), + i, name); } - public Constraint AddNoOverlap(IEnumerable intervals) - { + public Constraint AddNoOverlap(IEnumerable intervals) { Constraint ct = new Constraint(model_); NoOverlapConstraintProto args = new NoOverlapConstraintProto(); - foreach (IntervalVar var in intervals) - { + foreach (IntervalVar var in intervals) { args.Intervals.Add(var.GetIndex()); } ct.Proto.NoOverlap = args; @@ -548,16 +462,13 @@ namespace Google.OrTools.Sat } public Constraint AddNoOverlap2D(IEnumerable x_intervals, - IEnumerable y_intervals) - { + IEnumerable y_intervals) { Constraint ct = new Constraint(model_); NoOverlap2DConstraintProto args = new NoOverlap2DConstraintProto(); - foreach (IntervalVar var in x_intervals) - { + foreach (IntervalVar var in x_intervals) { args.XIntervals.Add(var.GetIndex()); } - foreach (IntervalVar var in y_intervals) - { + foreach (IntervalVar var in y_intervals) { args.YIntervals.Add(var.GetIndex()); } ct.Proto.NoOverlap2D = args; @@ -565,17 +476,13 @@ namespace Google.OrTools.Sat } public Constraint AddCumulative(IEnumerable intervals, - IEnumerable demands, - C capacity) - { + IEnumerable demands, C capacity) { Constraint ct = new Constraint(model_); CumulativeConstraintProto cumul = new CumulativeConstraintProto(); - foreach (IntervalVar var in intervals) - { + foreach (IntervalVar var in intervals) { cumul.Intervals.Add(var.GetIndex()); } - foreach (D demand in demands) - { + foreach (D demand in demands) { cumul.Demands.Add(GetOrCreateIndex(demand)); } cumul.Capacity = GetOrCreateIndex(capacity); @@ -583,56 +490,38 @@ namespace Google.OrTools.Sat return ct; } - // Objective. - public void Minimize(LinearExpr obj) - { - SetObjective(obj, true); - } + public void Minimize(LinearExpr obj) { SetObjective(obj, true); } - public void Maximize(LinearExpr obj) - { - SetObjective(obj, false); - } + public void Maximize(LinearExpr obj) { SetObjective(obj, false); } - public void Minimize() - { - SetObjective(null, true); - } + public void Minimize() { SetObjective(null, true); } - public void Maximize() - { - SetObjective(null, false); - } + public void Maximize() { SetObjective(null, false); } - public void AddVarToObjective(IntVar var) - { - if ((Object)var == null) return; + public void AddVarToObjective(IntVar var) { + if ((Object) var == null) return; model_.Objective.Vars.Add(var.Index); model_.Objective.Coeffs.Add(model_.Objective.ScalingFactor > 0 ? 1 : -1); } - public void AddTermToObjective(IntVar var, long coeff) - { - if (coeff == 0 || (Object)var == null) return; + public void AddTermToObjective(IntVar var, long coeff) { + if (coeff == 0 || (Object) var == null) return; model_.Objective.Vars.Add(var.Index); - model_.Objective.Coeffs.Add(model_.Objective.ScalingFactor > 0 ? coeff : -coeff); + model_.Objective.Coeffs.Add(model_.Objective.ScalingFactor > 0 ? coeff + : -coeff); } - bool HasObjective() - { - return model_.Objective == null; - } + bool HasObjective() { return model_.Objective == null; } // Search Decision. - public void AddDecisionStrategy(IEnumerable vars, - DecisionStrategyProto.Types.VariableSelectionStrategy var_str, - DecisionStrategyProto.Types.DomainReductionStrategy dom_str) - { + public void AddDecisionStrategy( + IEnumerable vars, + DecisionStrategyProto.Types.VariableSelectionStrategy var_str, + DecisionStrategyProto.Types.DomainReductionStrategy dom_str) { DecisionStrategyProto ds = new DecisionStrategyProto(); - foreach (IntVar var in vars) - { + foreach (IntVar var in vars) { ds.Variables.Add(var.Index); } ds.VariableSelectionStrategy = var_str; @@ -640,10 +529,9 @@ namespace Google.OrTools.Sat model_.SearchStrategy.Add(ds); } - public void AddHint(IntVar var, long value) - { + public void AddHint(IntVar var, long value) { if (model_.SolutionHint == null) { - model_.SolutionHint = new PartialVariableAssignment(); + model_.SolutionHint = new PartialVariableAssignment(); } model_.SolutionHint.Vars.Add(var.GetIndex()); model_.SolutionHint.Values.Add(value); @@ -651,45 +539,32 @@ namespace Google.OrTools.Sat // Internal methods. - void SetObjective(LinearExpr obj, bool minimize) - { + void SetObjective(LinearExpr obj, bool minimize) { CpObjectiveProto objective = new CpObjectiveProto(); - if (obj == null) - { + if (obj == null) { objective.Offset = 0L; objective.ScalingFactor = minimize ? 1L : -1; - } - else if (obj is IntVar) - { + } else if (obj is IntVar) { objective.Offset = 0L; objective.Vars.Add(obj.Index); - if (minimize) - { + if (minimize) { objective.Coeffs.Add(1L); objective.ScalingFactor = 1L; - } - else - { + } else { objective.Coeffs.Add(-1L); objective.ScalingFactor = -1L; } - } - else - { + } else { Dictionary dict = new Dictionary(); long constant = LinearExpr.GetVarValueMap(obj, 1L, dict); - if (minimize) - { + if (minimize) { objective.ScalingFactor = 1L; objective.Offset = constant; - } - else - { + } else { objective.ScalingFactor = -1L; objective.Offset = -constant; } - foreach (KeyValuePair it in dict) - { + foreach (KeyValuePair it in dict) { objective.Vars.Add(it.Key.Index); objective.Coeffs.Add(minimize ? it.Value : -it.Value); } @@ -697,28 +572,18 @@ namespace Google.OrTools.Sat model_.Objective = objective; } - public String ModelStats() - { - return SatHelper.ModelStats(model_); - } + public String ModelStats() { return SatHelper.ModelStats(model_); } public Boolean ExportToFile(String filename) { return SatHelper.WriteModelToFile(model_, filename); } - public String Validate() - { - return SatHelper.ValidateModel(model_); - } + public String Validate() { return SatHelper.ValidateModel(model_); } - private int ConvertConstant(long value) - { - if (constant_map_.ContainsKey(value)) - { + private int ConvertConstant(long value) { + if (constant_map_.ContainsKey(value)) { return constant_map_[value]; - } - else - { + } else { int index = model_.Variables.Count; IntegerVariableProto var = new IntegerVariableProto(); var.Domain.Add(value); @@ -729,15 +594,12 @@ namespace Google.OrTools.Sat } } - private int GetOrCreateIndex(X x) - { - if (typeof(X) == typeof(IntVar)) - { - IntVar vx = (IntVar)(Object)x; + private int GetOrCreateIndex(X x) { + if (typeof(X) == typeof(IntVar)) { + IntVar vx = (IntVar)(Object) x; return vx.Index; } - if (typeof(X) == typeof(long) || typeof(X) == typeof(int)) - { + if (typeof(X) == typeof(long) || typeof(X) == typeof(int)) { return ConvertConstant(Convert.ToInt64(x)); } throw new ArgumentException("Cannot extract index from argument"); diff --git a/ortools/sat/csharp/CpSolver.cs b/ortools/sat/csharp/CpSolver.cs index 14adf94025..d323cba189 100644 --- a/ortools/sat/csharp/CpSolver.cs +++ b/ortools/sat/csharp/CpSolver.cs @@ -14,52 +14,37 @@ using System; using System.Collections.Generic; -namespace Google.OrTools.Sat -{ - public class CpSolver - { - - public CpSolverStatus Solve(CpModel model) - { - if (string_parameters_ != null) - { +namespace Google.OrTools.Sat { + public class CpSolver { + public CpSolverStatus Solve(CpModel model) { + if (string_parameters_ != null) { response_ = SatHelper.SolveWithStringParameters(model.Model, string_parameters_); - } - else - { + } else { response_ = SatHelper.Solve(model.Model); } return response_.Status; } public CpSolverStatus SolveWithSolutionCallback(CpModel model, - SolutionCallback cb) - { - if (string_parameters_ != null) - { + SolutionCallback cb) { + if (string_parameters_ != null) { response_ = SatHelper.SolveWithStringParametersAndSolutionCallback( model.Model, string_parameters_, cb); - } - else - { + } else { response_ = SatHelper.SolveWithStringParametersAndSolutionCallback( model.Model, "", cb); } return response_.Status; } - public CpSolverStatus SearchAllSolutions(CpModel model, SolutionCallback cb) - { - if (string_parameters_ != null) - { + public CpSolverStatus SearchAllSolutions(CpModel model, + SolutionCallback cb) { + if (string_parameters_ != null) { string extra_parameters = " enumerate_all_solutions:true"; - response_ = - SatHelper.SolveWithStringParametersAndSolutionCallback( - model.Model, string_parameters_ + extra_parameters, cb); - } - else - { + response_ = SatHelper.SolveWithStringParametersAndSolutionCallback( + model.Model, string_parameters_ + extra_parameters, cb); + } else { string parameters = "enumerate_all_solutions:true"; response_ = SatHelper.SolveWithStringParametersAndSolutionCallback( model.Model, parameters, cb); @@ -67,81 +52,63 @@ namespace Google.OrTools.Sat return response_.Status; } - public String ResponseStats() - { + public String ResponseStats() { return SatHelper.SolverResponseStats(response_); } - public double ObjectiveValue - { + public double ObjectiveValue { get { return response_.ObjectiveValue; } } - public double BestObjectiveBound - { + public double BestObjectiveBound { get { return response_.BestObjectiveBound; } } - public string StringParameters - { + public string StringParameters { get { return string_parameters_; } set { string_parameters_ = value; } } - public CpSolverResponse Response - { + public CpSolverResponse Response { get { return response_; } } - public long Value(LinearExpr e) - { + public long Value(LinearExpr e) { List exprs = new List(); List coeffs = new List(); exprs.Add(e); coeffs.Add(1L); long constant = 0; - while (exprs.Count > 0) - { + while (exprs.Count > 0) { LinearExpr expr = exprs[0]; exprs.RemoveAt(0); long coeff = coeffs[0]; coeffs.RemoveAt(0); if (coeff == 0) continue; - if (expr is ProductCst) - { - ProductCst p = (ProductCst)expr; - if (p.Coeff != 0) - { + if (expr is ProductCst) { + ProductCst p = (ProductCst) expr; + if (p.Coeff != 0) { exprs.Add(p.Expr); coeffs.Add(p.Coeff * coeff); } - } - else if (expr is SumArray) - { - SumArray a = (SumArray)expr; + } else if (expr is SumArray) { + SumArray a = (SumArray) expr; constant += coeff * a.Constant; - foreach (LinearExpr sub in a.Expressions) - { + foreach (LinearExpr sub in a.Expressions) { exprs.Add(sub); coeffs.Add(coeff); } - } - else if (expr is IntVar) - { + } else if (expr is IntVar) { int index = expr.Index; long value = index >= 0 ? response_.Solution[index] : -response_.Solution[-index - 1]; constant += coeff * value; - } - else if (expr is NotBooleanVariable) - { + } else if (expr is NotBooleanVariable) { throw new ArgumentException( "Cannot evaluate a literal in an integer expression."); - } - else - { + } else { throw new ArgumentException("Cannot evaluate '" + expr.ToString() + "' in an integer expression"); } @@ -149,42 +116,25 @@ namespace Google.OrTools.Sat return constant; } - public Boolean BooleanValue(ILiteral literal) - { - if (literal is IntVar || literal is NotBooleanVariable) - { + public Boolean BooleanValue(ILiteral literal) { + if (literal is IntVar || literal is NotBooleanVariable) { int index = literal.GetIndex(); - if (index >= 0) - { + if (index >= 0) { return response_.Solution[index] != 0; - } - else - { + } else { return response_.Solution[-index - 1] == 0; } - } - else - { + } else { throw new ArgumentException("Cannot evaluate '" + literal.ToString() + "' as a boolean literal"); } } - public long NumBranches() - { - return response_.NumBranches; - } + public long NumBranches() { return response_.NumBranches; } - public long NumConflicts() - { - return response_.NumConflicts; - } - - public double WallTime() - { - return response_.WallTime; - } + public long NumConflicts() { return response_.NumConflicts; } + public double WallTime() { return response_.WallTime; } private CpModelProto model_; private CpSolverResponse response_; diff --git a/ortools/sat/csharp/IntegerExpressions.cs b/ortools/sat/csharp/IntegerExpressions.cs index 004e5f6539..1fabd2134e 100644 --- a/ortools/sat/csharp/IntegerExpressions.cs +++ b/ortools/sat/csharp/IntegerExpressions.cs @@ -11,8 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Google.OrTools.Sat -{ +namespace Google.OrTools.Sat { using System; using System.Collections.Generic; using Google.OrTools.Util; @@ -20,314 +19,241 @@ namespace Google.OrTools.Sat // Helpers. // IntVar[] helper class. - public static class IntVarArrayHelper - { - [Obsolete("This Sum method is deprecated, please use LinearExpr.Sum() instead.")] - public static LinearExpr Sum(this IntVar[] vars) - { + public static class IntVarArrayHelper { + [Obsolete( + "This Sum method is deprecated, please use LinearExpr.Sum() instead.")] + public static LinearExpr Sum(this IntVar[] vars) { return LinearExpr.Sum(vars); } - [Obsolete("This ScalProd method is deprecated, please use LinearExpr.ScalProd() instead.")] - public static LinearExpr ScalProd(this IntVar[] vars, int[] coeffs) - { + [Obsolete( + "This ScalProd method is deprecated, please use LinearExpr.ScalProd() instead.")] + public static LinearExpr ScalProd(this IntVar[] vars, int[] coeffs) { return LinearExpr.ScalProd(vars, coeffs); } - [Obsolete("This ScalProd method is deprecated, please use LinearExpr.ScalProd() instead.")] - public static LinearExpr ScalProd(this IntVar[] vars, long[] coeffs) - { + [Obsolete( + "This ScalProd method is deprecated, please use LinearExpr.ScalProd() instead.")] + public static LinearExpr ScalProd(this IntVar[] vars, long[] coeffs) { return LinearExpr.ScalProd(vars, coeffs); } } - public interface ILiteral - { + public interface ILiteral { ILiteral Not(); int GetIndex(); } // Holds a linear expression. - public class LinearExpr - { - - public static LinearExpr Sum(IEnumerable vars) - { + public class LinearExpr { + public static LinearExpr Sum(IEnumerable vars) { return new SumArray(vars); } - public static LinearExpr Sum(IEnumerable exprs) - { + public static LinearExpr Sum(IEnumerable exprs) { return new SumArray(exprs); } - public static LinearExpr ScalProd(IEnumerable vars, IEnumerable coeffs) - { + public static LinearExpr ScalProd(IEnumerable vars, + IEnumerable coeffs) { return new SumArray(vars, coeffs); } - public static LinearExpr ScalProd(IEnumerable vars, IEnumerable coeffs) - { + public static LinearExpr ScalProd(IEnumerable vars, + IEnumerable coeffs) { return new SumArray(vars, coeffs); } - public static LinearExpr Term(IntVar var, long coeff) - { + public static LinearExpr Term(IntVar var, long coeff) { return Prod(var, coeff); } - public int Index - { + public int Index { get { return GetIndex(); } } - public virtual int GetIndex() - { - throw new NotImplementedException(); - } + public virtual int GetIndex() { throw new NotImplementedException(); } - public virtual string ShortString() - { - return ToString(); - } + public virtual string ShortString() { return ToString(); } - public static LinearExpr operator +(LinearExpr a, LinearExpr b) - { + public static LinearExpr operator +(LinearExpr a, LinearExpr b) { return new SumArray(a, b); } - public static LinearExpr operator +(LinearExpr a, long v) - { + public static LinearExpr operator +(LinearExpr a, long v) { return new SumArray(a, v); } - public static LinearExpr operator +(long v, LinearExpr a) - { + public static LinearExpr operator +(long v, LinearExpr a) { return new SumArray(a, v); } - public static LinearExpr operator -(LinearExpr a, LinearExpr b) - { + public static LinearExpr operator -(LinearExpr a, LinearExpr b) { return new SumArray(a, Prod(b, -1)); } - public static LinearExpr operator -(LinearExpr a, long v) - { + public static LinearExpr operator -(LinearExpr a, long v) { return new SumArray(a, -v); } - public static LinearExpr operator -(long v, LinearExpr a) - { + public static LinearExpr operator -(long v, LinearExpr a) { return new SumArray(Prod(a, -1), v); } - public static LinearExpr operator *(LinearExpr a, long v) - { + public static LinearExpr operator*(LinearExpr a, long v) { return Prod(a, v); } - public static LinearExpr operator *(long v, LinearExpr a) - { + public static LinearExpr operator*(long v, LinearExpr a) { return Prod(a, v); } - public static LinearExpr operator -(LinearExpr a) - { - return Prod(a, -1); - } + public static LinearExpr operator -(LinearExpr a) { return Prod(a, -1); } - public static BoundedLinearExpression operator ==(LinearExpr a, LinearExpr b) - { + public static BoundedLinearExpression operator ==(LinearExpr a, + LinearExpr b) { return new BoundedLinearExpression(a, b, true); } - public static BoundedLinearExpression operator !=(LinearExpr a, LinearExpr b) - { + public static BoundedLinearExpression operator !=(LinearExpr a, + LinearExpr b) { return new BoundedLinearExpression(a, b, false); } - public static BoundedLinearExpression operator ==(LinearExpr a, long v) - { + public static BoundedLinearExpression operator ==(LinearExpr a, long v) { return new BoundedLinearExpression(a, v, true); } - public static BoundedLinearExpression operator !=(LinearExpr a, long v) - { + public static BoundedLinearExpression operator !=(LinearExpr a, long v) { return new BoundedLinearExpression(a, v, false); } - public static BoundedLinearExpression operator >=(LinearExpr a, long v) - { + public static BoundedLinearExpression operator >=(LinearExpr a, long v) { return new BoundedLinearExpression(v, a, Int64.MaxValue); } - public static BoundedLinearExpression operator >=(long v, LinearExpr a) - { + public static BoundedLinearExpression operator >=(long v, LinearExpr a) { return a <= v; } - public static BoundedLinearExpression operator >(LinearExpr a, long v) - { + public static BoundedLinearExpression operator>(LinearExpr a, long v) { return new BoundedLinearExpression(v + 1, a, Int64.MaxValue); } - public static BoundedLinearExpression operator >(long v, LinearExpr a) - { + public static BoundedLinearExpression operator>(long v, LinearExpr a) { return a < v; } - public static BoundedLinearExpression operator <=(LinearExpr a, long v) - { + public static BoundedLinearExpression operator <=(LinearExpr a, long v) { return new BoundedLinearExpression(Int64.MinValue, a, v); } - public static BoundedLinearExpression operator <=(long v, LinearExpr a) - { + public static BoundedLinearExpression operator <=(long v, LinearExpr a) { return a >= v; } - public static BoundedLinearExpression operator <(LinearExpr a, long v) - { + public static BoundedLinearExpression operator<(LinearExpr a, long v) { return new BoundedLinearExpression(Int64.MinValue, a, v - 1); } - public static BoundedLinearExpression operator <(long v, LinearExpr a) - { + public static BoundedLinearExpression operator<(long v, LinearExpr a) { return a > v; } - public static BoundedLinearExpression operator >=(LinearExpr a, LinearExpr b) - { + public static BoundedLinearExpression operator >=(LinearExpr a, + LinearExpr b) { return new BoundedLinearExpression(0, a - b, Int64.MaxValue); } - public static BoundedLinearExpression operator >(LinearExpr a, LinearExpr b) - { + public static BoundedLinearExpression operator>(LinearExpr a, + LinearExpr b) { return new BoundedLinearExpression(1, a - b, Int64.MaxValue); } - public static BoundedLinearExpression operator <=(LinearExpr a, LinearExpr b) - { + public static BoundedLinearExpression operator <=(LinearExpr a, + LinearExpr b) { return new BoundedLinearExpression(Int64.MinValue, a - b, 0); } - public static BoundedLinearExpression operator <(LinearExpr a, LinearExpr b) - { + public static BoundedLinearExpression operator<(LinearExpr a, + LinearExpr b) { return new BoundedLinearExpression(Int64.MinValue, a - b, -1); } - public static LinearExpr Prod(LinearExpr e, long v) - { - if (v == 1) - { + public static LinearExpr Prod(LinearExpr e, long v) { + if (v == 1) { return e; - } - else if (e is ProductCst) - { - ProductCst p = (ProductCst)e; + } else if (e is ProductCst) { + ProductCst p = (ProductCst) e; return new ProductCst(p.Expr, p.Coeff * v); - } - else - { + } else { return new ProductCst(e, v); } } - public static long GetVarValueMap(LinearExpr e, - long initial_coeff, - Dictionary dict) - { + public static long GetVarValueMap(LinearExpr e, long initial_coeff, + Dictionary dict) { List exprs = new List(); List coeffs = new List(); - if ((Object)e != null) - { + if ((Object) e != null) { exprs.Add(e); coeffs.Add(initial_coeff); } long constant = 0; - while (exprs.Count > 0) - { + while (exprs.Count > 0) { LinearExpr expr = exprs[0]; exprs.RemoveAt(0); long coeff = coeffs[0]; coeffs.RemoveAt(0); - if (coeff == 0 || (Object)expr == null) continue; + if (coeff == 0 || (Object) expr == null) continue; - if (expr is ProductCst) - { - ProductCst p = (ProductCst)expr; - if (p.Coeff != 0) - { + if (expr is ProductCst) { + ProductCst p = (ProductCst) expr; + if (p.Coeff != 0) { exprs.Add(p.Expr); coeffs.Add(p.Coeff * coeff); } - } - else if (expr is SumArray) - { - SumArray a = (SumArray)expr; + } else if (expr is SumArray) { + SumArray a = (SumArray) expr; constant += coeff * a.Constant; - foreach (LinearExpr sub in a.Expressions) - { - if (sub is IntVar) - { - IntVar i = (IntVar)sub; - if (dict.ContainsKey(i)) - { + foreach (LinearExpr sub in a.Expressions) { + if (sub is IntVar) { + IntVar i = (IntVar) sub; + if (dict.ContainsKey(i)) { dict[i] += coeff; - } - else - { + } else { dict.Add(i, coeff); } - } - else if (sub is ProductCst && ((ProductCst)sub).Expr is IntVar) - { - ProductCst sub_prod = (ProductCst)sub; - IntVar i = (IntVar)sub_prod.Expr; + } else if (sub is ProductCst && ((ProductCst) sub).Expr is IntVar) { + ProductCst sub_prod = (ProductCst) sub; + IntVar i = (IntVar) sub_prod.Expr; long sub_coeff = sub_prod.Coeff; - if (dict.ContainsKey(i)) - { + if (dict.ContainsKey(i)) { dict[i] += coeff * sub_coeff; - } - else - { + } else { dict.Add(i, coeff * sub_coeff); } - } - else - { + } else { exprs.Add(sub); coeffs.Add(coeff); } } - } - else if (expr is IntVar) - { - IntVar i = (IntVar)expr; - if (dict.ContainsKey(i)) - { + } else if (expr is IntVar) { + IntVar i = (IntVar) expr; + if (dict.ContainsKey(i)) { dict[i] += coeff; - } - else - { + } else { dict.Add(i, coeff); } - } - else if (expr is NotBooleanVariable) - { - IntVar i = ((NotBooleanVariable)expr).NotVar(); - if (dict.ContainsKey(i)) - { + } else if (expr is NotBooleanVariable) { + IntVar i = ((NotBooleanVariable) expr).NotVar(); + if (dict.ContainsKey(i)) { dict[i] -= coeff; - } - else - { + } else { dict.Add(i, -coeff); } constant += coeff; - } - else - { + } else { throw new ArgumentException("Cannot interpret '" + expr.ToString() + "' in an integer expression"); } @@ -336,152 +262,122 @@ namespace Google.OrTools.Sat } } - public class ProductCst : LinearExpr - { - public ProductCst(LinearExpr e, long v) - { + public class ProductCst : LinearExpr { + public ProductCst(LinearExpr e, long v) { expr_ = e; coeff_ = v; } - public LinearExpr Expr - { + public LinearExpr Expr { get { return expr_; } } - public long Coeff - { + public long Coeff { get { return coeff_; } } private LinearExpr expr_; private long coeff_; - } - public class SumArray : LinearExpr - { - public SumArray(LinearExpr a, LinearExpr b) - { + public class SumArray : LinearExpr { + public SumArray(LinearExpr a, LinearExpr b) { expressions_ = new List(); AddExpr(a); AddExpr(b); constant_ = 0L; } - public SumArray(LinearExpr a, long b) - { + public SumArray(LinearExpr a, long b) { expressions_ = new List(); AddExpr(a); constant_ = b; } - public SumArray(IEnumerable exprs) - { + public SumArray(IEnumerable exprs) { expressions_ = new List(exprs); constant_ = 0L; } - public SumArray(IEnumerable vars) - { + public SumArray(IEnumerable vars) { expressions_ = new List(vars); constant_ = 0L; } - public SumArray(IntVar[] vars, long[] coeffs) - { + public SumArray(IntVar[] vars, long[] coeffs) { expressions_ = new List(vars.Length); - for (int i = 0; i < vars.Length; ++i) - { + for (int i = 0; i < vars.Length; ++i) { AddExpr(Prod(vars[i], coeffs[i])); } constant_ = 0L; } - public SumArray(IEnumerable vars, IEnumerable coeffs) - { + public SumArray(IEnumerable vars, IEnumerable coeffs) { List tmp_vars = new List(); - foreach (IntVar v in vars) - { + foreach (IntVar v in vars) { tmp_vars.Add(v); } List tmp_coeffs = new List(); - foreach (long c in coeffs) - { + foreach (long c in coeffs) { tmp_coeffs.Add(c); } - if (tmp_vars.Count != tmp_coeffs.Count) - { + if (tmp_vars.Count != tmp_coeffs.Count) { throw new ArgumentException( - "in SumArray(vars, coeffs), the two lists do not have the same length"); + "in SumArray(vars, coeffs), the two lists do not have the same length"); } IntVar[] flat_vars = tmp_vars.ToArray(); long[] flat_coeffs = tmp_coeffs.ToArray(); expressions_ = new List(flat_vars.Length); - for (int i = 0; i < flat_vars.Length; ++i) - { + for (int i = 0; i < flat_vars.Length; ++i) { expressions_.Add(Prod(flat_vars[i], flat_coeffs[i])); } constant_ = 0L; } - public SumArray(IEnumerable vars, IEnumerable coeffs) - { + public SumArray(IEnumerable vars, IEnumerable coeffs) { List tmp_vars = new List(); - foreach (IntVar v in vars) - { + foreach (IntVar v in vars) { tmp_vars.Add(v); } List tmp_coeffs = new List(); - foreach (int c in coeffs) - { + foreach (int c in coeffs) { tmp_coeffs.Add(c); } - if (tmp_vars.Count != tmp_coeffs.Count) - { + if (tmp_vars.Count != tmp_coeffs.Count) { throw new ArgumentException( - "in SumArray(vars, coeffs), the two lists do not have the same length"); + "in SumArray(vars, coeffs), the two lists do not have the same length"); } IntVar[] flat_vars = tmp_vars.ToArray(); long[] flat_coeffs = tmp_coeffs.ToArray(); expressions_ = new List(flat_vars.Length); - for (int i = 0; i < flat_vars.Length; ++i) - { + for (int i = 0; i < flat_vars.Length; ++i) { expressions_.Add(Prod(flat_vars[i], flat_coeffs[i])); } constant_ = 0L; } - public void AddExpr(LinearExpr expr) - { - if ((Object)expr != null) - { + public void AddExpr(LinearExpr expr) { + if ((Object) expr != null) { expressions_.Add(expr); } } - public List Expressions - { + public List Expressions { get { return expressions_; } } - public long Constant - { + public long Constant { get { return constant_; } } - public override string ShortString() - { + public override string ShortString() { return String.Format("({0})", ToString()); } - public override string ToString() - { + public override string ToString() { string result = ""; - foreach (LinearExpr expr in expressions_) - { - if ((Object)expr == null) continue; - if (!String.IsNullOrEmpty(result)) - { + foreach (LinearExpr expr in expressions_) { + if ((Object) expr == null) continue; + if (!String.IsNullOrEmpty(result)) { result += String.Format(" + "); } @@ -494,10 +390,8 @@ namespace Google.OrTools.Sat private long constant_; } - public class IntVar : LinearExpr, ILiteral - { - public IntVar(CpModelProto model, Domain domain, string name) - { + public class IntVar : LinearExpr, ILiteral { + public IntVar(CpModelProto model, Domain domain, string name) { model_ = model; index_ = model.Variables.Count; var_ = new IntegerVariableProto(); @@ -507,61 +401,41 @@ namespace Google.OrTools.Sat negation_ = null; } - public int Index - { + public int Index { get { return index_; } } - public override int GetIndex() - { - return index_; - } + public override int GetIndex() { return index_; } - public IntegerVariableProto Proto - { + public IntegerVariableProto Proto { get { return var_; } set { var_ = value; } } - public Domain Domain - { + public Domain Domain { get { return SatHelper.VariableDomain(var_); } } - public override string ToString() - { - return var_.ToString(); - } + public override string ToString() { return var_.ToString(); } - public override string ShortString() - { - if (var_.Name != null) - { + public override string ShortString() { + if (var_.Name != null) { return var_.Name; - } - else - { + } else { return var_.ToString(); } } - public string Name() - { - return var_.Name; - } + public string Name() { return var_.Name; } - public ILiteral Not() - { - foreach (long b in var_.Domain) - { - if (b < 0 || b > 1) - { + public ILiteral Not() { + foreach (long b in var_.Domain) { + if (b < 0 || b > 1) { throw new ArgumentException( "Cannot call Not() on a non boolean variable"); } } - if (negation_ == null) - { + if (negation_ == null) { negation_ = new NotBooleanVariable(this); } return negation_; @@ -574,40 +448,24 @@ namespace Google.OrTools.Sat private NotBooleanVariable negation_; } - public class NotBooleanVariable : LinearExpr, ILiteral - { - public NotBooleanVariable(IntVar boolvar) - { - boolvar_ = boolvar; - } + public class NotBooleanVariable : LinearExpr, ILiteral { + public NotBooleanVariable(IntVar boolvar) { boolvar_ = boolvar; } - public override int GetIndex() - { - return -boolvar_.Index - 1; - } + public override int GetIndex() { return -boolvar_.Index - 1; } - public ILiteral Not() - { - return boolvar_; - } + public ILiteral Not() { return boolvar_; } - public IntVar NotVar() - { - return boolvar_; - } + public IntVar NotVar() { return boolvar_; } - public override string ShortString() - { + public override string ShortString() { return String.Format("Not({0})", boolvar_.ShortString()); } private IntVar boolvar_; } - public class BoundedLinearExpression - { - public enum Type - { + public class BoundedLinearExpression { + public enum Type { BoundExpression, VarEqVar, VarDiffVar, @@ -615,8 +473,7 @@ namespace Google.OrTools.Sat VarDiffCst, } - public BoundedLinearExpression(long lb, LinearExpr expr, long ub) - { + public BoundedLinearExpression(long lb, LinearExpr expr, long ub) { left_ = expr; right_ = null; lb_ = lb; @@ -625,8 +482,7 @@ namespace Google.OrTools.Sat } public BoundedLinearExpression(LinearExpr left, LinearExpr right, - bool equality) - { + bool equality) { left_ = left; right_ = right; lb_ = 0; @@ -634,8 +490,7 @@ namespace Google.OrTools.Sat type_ = equality ? Type.VarEqVar : Type.VarDiffVar; } - public BoundedLinearExpression(LinearExpr left, long v, bool equality) - { + public BoundedLinearExpression(LinearExpr left, long v, bool equality) { left_ = left; right_ = null; lb_ = v; @@ -643,33 +498,25 @@ namespace Google.OrTools.Sat type_ = equality ? Type.VarEqCst : Type.VarDiffCst; } - bool IsTrue() - { - if (type_ == Type.VarEqVar) - { - return (object)left_ == (object)right_; - } - else if (type_ == Type.VarDiffVar) - { - return (object)left_ != (object)right_; + bool IsTrue() { + if (type_ == Type.VarEqVar) { + return (object) left_ == (object) right_; + } else if (type_ == Type.VarDiffVar) { + return (object) left_ != (object) right_; } return false; } - public static bool operator true(BoundedLinearExpression bie) - { + public static bool operator true(BoundedLinearExpression bie) { return bie.IsTrue(); } - public static bool operator false(BoundedLinearExpression bie) - { + public static bool operator false(BoundedLinearExpression bie) { return !bie.IsTrue(); } - public override string ToString() - { - switch (type_) - { + public override string ToString() { + switch (type_) { case Type.BoundExpression: return String.Format("{0} <= {1} <= {2}", lb_, left_, ub_); case Type.VarEqVar: @@ -686,21 +533,17 @@ namespace Google.OrTools.Sat } public static BoundedLinearExpression operator <=(BoundedLinearExpression a, - long v) - { - if (a.CtType != Type.BoundExpression || a.Ub != Int64.MaxValue) - { + long v) { + if (a.CtType != Type.BoundExpression || a.Ub != Int64.MaxValue) { throw new ArgumentException( "Operator <= not supported for this BoundedLinearExpression"); } return new BoundedLinearExpression(a.Lb, a.Left, v); } - public static BoundedLinearExpression operator <(BoundedLinearExpression a, - long v) - { - if (a.CtType != Type.BoundExpression || a.Ub != Int64.MaxValue) - { + public static BoundedLinearExpression operator<(BoundedLinearExpression a, + long v) { + if (a.CtType != Type.BoundExpression || a.Ub != Int64.MaxValue) { throw new ArgumentException( "Operator < not supported for this BoundedLinearExpression"); } @@ -708,49 +551,40 @@ namespace Google.OrTools.Sat } public static BoundedLinearExpression operator >=(BoundedLinearExpression a, - long v) - { - if (a.CtType != Type.BoundExpression || a.Lb != Int64.MinValue) - { + long v) { + if (a.CtType != Type.BoundExpression || a.Lb != Int64.MinValue) { throw new ArgumentException( "Operator >= not supported for this BoundedLinearExpression"); } return new BoundedLinearExpression(v, a.Left, a.Ub); } - public static BoundedLinearExpression operator >(BoundedLinearExpression a, - long v) - { - if (a.CtType != Type.BoundExpression || a.Lb != Int64.MinValue) - { + public static BoundedLinearExpression operator>(BoundedLinearExpression a, + long v) { + if (a.CtType != Type.BoundExpression || a.Lb != Int64.MinValue) { throw new ArgumentException( "Operator < not supported for this BoundedLinearExpression"); } return new BoundedLinearExpression(v + 1, a.Left, a.Ub); } - public LinearExpr Left - { + public LinearExpr Left { get { return left_; } } - public LinearExpr Right - { + public LinearExpr Right { get { return right_; } } - public long Lb - { + public long Lb { get { return lb_; } } - public long Ub - { + public long Ub { get { return ub_; } } - public Type CtType - { + public Type CtType { get { return type_; } } diff --git a/ortools/sat/csharp/IntervalVariables.cs b/ortools/sat/csharp/IntervalVariables.cs index 68190d5374..a8cd251109 100644 --- a/ortools/sat/csharp/IntervalVariables.cs +++ b/ortools/sat/csharp/IntervalVariables.cs @@ -11,69 +11,60 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Google.OrTools.Sat -{ -using System; -using System.Collections.Generic; +namespace Google.OrTools.Sat { + using System; + using System.Collections.Generic; -public class IntervalVar -{ - public IntervalVar(CpModelProto model, - int start_index, int size_index, int end_index, - int is_present_index, string name) { - model_ = model; - index_ = model.Constraints.Count; - interval_ = new IntervalConstraintProto(); - interval_.Start = start_index; - interval_.Size = size_index; - interval_.End = end_index; + public class IntervalVar { + public IntervalVar(CpModelProto model, int start_index, int size_index, + int end_index, int is_present_index, string name) { + model_ = model; + index_ = model.Constraints.Count; + interval_ = new IntervalConstraintProto(); + interval_.Start = start_index; + interval_.Size = size_index; + interval_.End = end_index; - ConstraintProto ct = new ConstraintProto(); - ct.Interval = interval_; - ct.Name = name; - ct.EnforcementLiteral.Add(is_present_index); - model.Constraints.Add(ct); + ConstraintProto ct = new ConstraintProto(); + ct.Interval = interval_; + ct.Name = name; + ct.EnforcementLiteral.Add(is_present_index); + model.Constraints.Add(ct); + } + + public IntervalVar(CpModelProto model, int start_index, int size_index, + int end_index, string name) { + model_ = model; + index_ = model.Constraints.Count; + interval_ = new IntervalConstraintProto(); + interval_.Start = start_index; + interval_.Size = size_index; + interval_.End = end_index; + + ConstraintProto ct = new ConstraintProto(); + ct.Interval = interval_; + ct.Name = name; + model_.Constraints.Add(ct); + } + + public int GetIndex() { return index_; } + + public IntervalConstraintProto Proto { + get { return interval_; } + set { interval_ = value; } + } + + public override string ToString() { + return model_ + .Constraints [index_] + .ToString(); + } + + public string Name() { return model_.Constraints[index_].Name; } + + private CpModelProto model_; + private int index_; + private IntervalConstraintProto interval_; } - public IntervalVar(CpModelProto model, - int start_index, int size_index, int end_index, - string name) { - model_ = model; - index_ = model.Constraints.Count; - interval_ = new IntervalConstraintProto(); - interval_.Start = start_index; - interval_.Size = size_index; - interval_.End = end_index; - - ConstraintProto ct = new ConstraintProto(); - ct.Interval = interval_; - ct.Name = name; - model_.Constraints.Add(ct); - } - - public int GetIndex() - { - return index_; - } - - public IntervalConstraintProto Proto { - get { return interval_; } - set { interval_ = value; } - } - - public override string ToString() - { - return model_.Constraints[index_].ToString(); - } - - public string Name() - { - return model_.Constraints[index_].Name; - } - - private CpModelProto model_; - private int index_; - private IntervalConstraintProto interval_; -} - } // namespace Google.OrTools.Sat diff --git a/ortools/sat/csharp/SearchHelpers.cs b/ortools/sat/csharp/SearchHelpers.cs index 8741bfb716..7fd0db6039 100644 --- a/ortools/sat/csharp/SearchHelpers.cs +++ b/ortools/sat/csharp/SearchHelpers.cs @@ -14,59 +14,44 @@ using System; using System.Collections.Generic; -namespace Google.OrTools.Sat -{ +namespace Google.OrTools.Sat { - public class CpSolverSolutionCallback : SolutionCallback - { - public long Value(LinearExpr e) - { + public class CpSolverSolutionCallback : SolutionCallback { + public long Value(LinearExpr e) { List exprs = new List(); List coeffs = new List(); exprs.Add(e); coeffs.Add(1L); long constant = 0; - while (exprs.Count > 0) - { + while (exprs.Count > 0) { LinearExpr expr = exprs[0]; exprs.RemoveAt(0); long coeff = coeffs[0]; coeffs.RemoveAt(0); if (coeff == 0) continue; - if (expr is ProductCst) - { - ProductCst p = (ProductCst)expr; - if (p.Coeff != 0) - { + if (expr is ProductCst) { + ProductCst p = (ProductCst) expr; + if (p.Coeff != 0) { exprs.Add(p.Expr); coeffs.Add(p.Coeff * coeff); } - } - else if (expr is SumArray) - { - SumArray a = (SumArray)expr; + } else if (expr is SumArray) { + SumArray a = (SumArray) expr; constant += coeff * a.Constant; - foreach (LinearExpr sub in a.Expressions) - { + foreach (LinearExpr sub in a.Expressions) { exprs.Add(sub); coeffs.Add(coeff); } - } - else if (expr is IntVar) - { + } else if (expr is IntVar) { int index = expr.Index; long value = SolutionIntegerValue(index); constant += coeff * value; - } - else if (expr is NotBooleanVariable) - { + } else if (expr is NotBooleanVariable) { throw new ArgumentException( "Cannot evaluate a literal in an integer expression."); - } - else - { + } else { throw new ArgumentException("Cannot evaluate '" + expr.ToString() + "' in an integer expression"); } @@ -74,33 +59,24 @@ namespace Google.OrTools.Sat return constant; } - public Boolean BooleanValue(ILiteral literal) - { - if (literal is IntVar || literal is NotBooleanVariable) - { + public Boolean BooleanValue(ILiteral literal) { + if (literal is IntVar || literal is NotBooleanVariable) { int index = literal.GetIndex(); return SolutionBooleanValue(index); - } - else - { + } else { throw new ArgumentException("Cannot evaluate '" + literal.ToString() + "' as a boolean literal"); } } } - public class ObjectiveSolutionPrinter : CpSolverSolutionCallback - { + public class ObjectiveSolutionPrinter : CpSolverSolutionCallback { private DateTime _startTime; private int _solutionCount; - public ObjectiveSolutionPrinter() - { - _startTime = DateTime.Now; - } + public ObjectiveSolutionPrinter() { _startTime = DateTime.Now; } - public override void OnSolutionCallback() - { + public override void OnSolutionCallback() { var currentTime = DateTime.Now; var objective = ObjectiveValue(); var objectiveBound = BestObjectiveBound(); @@ -108,7 +84,9 @@ namespace Google.OrTools.Sat var objUb = Math.Max(objective, objectiveBound); var time = currentTime - _startTime; - Console.WriteLine(value: $"Solution {_solutionCount}, time = {time.TotalSeconds} s, objective = [{objLb}, {objUb}]"); + Console.WriteLine( + value + : $"Solution {_solutionCount}, time = {time.TotalSeconds} s, objective = [{objLb}, {objUb}]"); _solutionCount++; } diff --git a/ortools/sat/samples/AssignmentSat.cs b/ortools/sat/samples/AssignmentSat.cs index a102f788d0..6c5d51f11d 100644 --- a/ortools/sat/samples/AssignmentSat.cs +++ b/ortools/sat/samples/AssignmentSat.cs @@ -17,18 +17,13 @@ using System; using Google.OrTools.Sat; // [END import] -public class AssignmentSat -{ - static void Main() - { +public class AssignmentSat { + static void Main() { // Data. // [START data_model] - int[,] costs = { - {90, 80, 75, 70}, - {35, 85, 55, 65}, - {125, 95, 90, 95}, - {45, 110, 95, 115}, - {50, 100, 90, 100}, + int[, ] costs = { + {90, 80, 75, 70}, {35, 85, 55, 65}, {125, 95, 90, 95}, + {45, 110, 95, 115}, {50, 100, 90, 100}, }; int numWorkers = costs.GetLength(0); int numTasks = costs.GetLength(1); @@ -41,14 +36,12 @@ public class AssignmentSat // Variables. // [START variables] - IntVar[,] x = new IntVar[numWorkers, numTasks]; + IntVar[, ] x = new IntVar[numWorkers, numTasks]; // Variables in a 1-dim array. IntVar[] xFlat = new IntVar[numWorkers * numTasks]; int[] costsFlat = new int[numWorkers * numTasks]; - for (int i = 0; i < numWorkers; ++i) - { - for (int j = 0; j < numTasks; ++j) - { + for (int i = 0; i < numWorkers; ++i) { + for (int j = 0; j < numTasks; ++j) { x[i, j] = model.NewIntVar(0, 1, $"worker_{i}_task_{j}"); int k = i * numTasks + j; xFlat[k] = x[i, j]; @@ -60,22 +53,18 @@ public class AssignmentSat // Constraints // [START constraints] // Each worker is assigned to at most one task. - for (int i = 0; i < numWorkers; ++i) - { + for (int i = 0; i < numWorkers; ++i) { IntVar[] vars = new IntVar[numTasks]; - for (int j = 0; j < numTasks; ++j) - { + for (int j = 0; j < numTasks; ++j) { vars[j] = x[i, j]; } model.Add(LinearExpr.Sum(vars) <= 1); } // Each task is assigned to exactly one worker. - for (int j = 0; j < numTasks; ++j) - { + for (int j = 0; j < numTasks; ++j) { IntVar[] vars = new IntVar[numWorkers]; - for (int i = 0; i < numWorkers; ++i) - { + for (int i = 0; i < numWorkers; ++i) { vars[i] = x[i, j]; } model.Add(LinearExpr.Sum(vars) == 1); @@ -99,13 +88,11 @@ public class AssignmentSat // Check that the problem has a feasible solution. if (status == CpSolverStatus.Optimal || status == CpSolverStatus.Feasible) { Console.WriteLine($"Total cost: {solver.ObjectiveValue}\n"); - for (int i = 0; i < numWorkers; ++i) - { - for (int j = 0; j < numTasks; ++j) - { - if (solver.Value(x[i, j]) > 0.5) - { - Console.WriteLine($"Worker {i} assigned to task {j}. Cost: {costs[i, j]}"); + for (int i = 0; i < numWorkers; ++i) { + for (int j = 0; j < numTasks; ++j) { + if (solver.Value(x[i, j]) > 0.5) { + Console.WriteLine( + $"Worker {i} assigned to task {j}. Cost: {costs[i, j]}"); } } } diff --git a/ortools/sat/samples/BinPackingProblemSat.cs b/ortools/sat/samples/BinPackingProblemSat.cs index 95d01a41d9..3d5f39eb2a 100644 --- a/ortools/sat/samples/BinPackingProblemSat.cs +++ b/ortools/sat/samples/BinPackingProblemSat.cs @@ -14,68 +14,58 @@ using System; using Google.OrTools.Sat; -public class BinPackingProblemSat -{ - static void Main() - { +public class BinPackingProblemSat { + static void Main() { // Data. int bin_capacity = 100; int slack_capacity = 20; int num_bins = 5; - int[,] items = new int[,] { { 20, 6 }, { 15, 6 }, { 30, 4 }, { 45, 3 } }; + int[, ] items = new int[, ]{{20, 6}, {15, 6}, {30, 4}, {45, 3}}; int num_items = items.GetLength(0); // Model. CpModel model = new CpModel(); // Main variables. - IntVar[,] x = new IntVar[num_items, num_bins]; - for (int i = 0; i < num_items; ++i) - { + IntVar[, ] x = new IntVar[num_items, num_bins]; + for (int i = 0; i < num_items; ++i) { int num_copies = items[i, 1]; - for (int b = 0; b < num_bins; ++b) - { - x[i, b] = model.NewIntVar(0, num_copies, String.Format("x_{0}_{1}", i, b)); + for (int b = 0; b < num_bins; ++b) { + x[i, b] = + model.NewIntVar(0, num_copies, String.Format("x_{0}_{1}", i, b)); } } // Load variables. IntVar[] load = new IntVar[num_bins]; - for (int b = 0; b < num_bins; ++b) - { + for (int b = 0; b < num_bins; ++b) { load[b] = model.NewIntVar(0, bin_capacity, String.Format("load_{0}", b)); } // Slack variables. IntVar[] slacks = new IntVar[num_bins]; - for (int b = 0; b < num_bins; ++b) - { + for (int b = 0; b < num_bins; ++b) { slacks[b] = model.NewBoolVar(String.Format("slack_{0}", b)); } // Links load and x. int[] sizes = new int[num_items]; - for (int i = 0; i < num_items; ++i) - { + for (int i = 0; i < num_items; ++i) { sizes[i] = items[i, 0]; } - for (int b = 0; b < num_bins; ++b) - { + for (int b = 0; b < num_bins; ++b) { IntVar[] tmp = new IntVar[num_items]; - for (int i = 0; i < num_items; ++i) - { + for (int i = 0; i < num_items; ++i) { tmp[i] = x[i, b]; } model.Add(load[b] == LinearExpr.ScalProd(tmp, sizes)); } // Place all items. - for (int i = 0; i < num_items; ++i) - { + for (int i = 0; i < num_items; ++i) { IntVar[] tmp = new IntVar[num_bins]; - for (int b = 0; b < num_bins; ++b) - { + for (int b = 0; b < num_bins; ++b) { tmp[b] = x[i, b]; } model.Add(LinearExpr.Sum(tmp) == items[i, 1]); @@ -83,12 +73,13 @@ public class BinPackingProblemSat // Links load and slack. int safe_capacity = bin_capacity - slack_capacity; - for (int b = 0; b < num_bins; ++b) - { + for (int b = 0; b < num_bins; ++b) { // slack[b] => load[b] <= safe_capacity. model.Add(load[b] <= safe_capacity).OnlyEnforceIf(slacks[b]); // not(slack[b]) => load[b] > safe_capacity. - model.Add(load[b] > safe_capacity).OnlyEnforceIf(slacks[b].Not()); + model.Add(load[b] > safe_capacity) + .OnlyEnforceIf(slacks [b] + .Not()); } // Maximize sum of slacks. @@ -99,25 +90,23 @@ public class BinPackingProblemSat CpSolverStatus status = solver.Solve(model); Console.WriteLine(String.Format("Solve status: {0}", status)); if (status == CpSolverStatus.Optimal) { - Console.WriteLine(String.Format("Optimal objective value: {0}", - solver.ObjectiveValue)); - for (int b = 0; b < num_bins; ++b) - { - Console.WriteLine(String.Format("load_{0} = {1}", - b, solver.Value(load[b]))); - for (int i = 0; i < num_items; ++i) - { - Console.WriteLine(string.Format(" item_{0}_{1} = {2}", - i, b, solver.Value(x[i, b]))); + Console.WriteLine( + String.Format("Optimal objective value: {0}", solver.ObjectiveValue)); + for (int b = 0; b < num_bins; ++b) { + Console.WriteLine( + String.Format("load_{0} = {1}", b, solver.Value(load[b]))); + for (int i = 0; i < num_items; ++i) { + Console.WriteLine(string.Format(" item_{0}_{1} = {2}", i, b, + solver.Value(x[i, b]))); } } } Console.WriteLine("Statistics"); - Console.WriteLine(String.Format(" - conflicts : {0}", - solver.NumConflicts())); - Console.WriteLine(String.Format(" - branches : {0}", - solver.NumBranches())); - Console.WriteLine(String.Format(" - wall time : {0} s", - solver.WallTime())); + Console.WriteLine( + String.Format(" - conflicts : {0}", solver.NumConflicts())); + Console.WriteLine( + String.Format(" - branches : {0}", solver.NumBranches())); + Console.WriteLine( + String.Format(" - wall time : {0} s", solver.WallTime())); } } diff --git a/ortools/sat/samples/BoolOrSampleSat.cs b/ortools/sat/samples/BoolOrSampleSat.cs index 27a2db0feb..3b1948620d 100644 --- a/ortools/sat/samples/BoolOrSampleSat.cs +++ b/ortools/sat/samples/BoolOrSampleSat.cs @@ -14,15 +14,13 @@ using System; using Google.OrTools.Sat; -public class BoolOrSampleSat -{ - static void Main() - { +public class BoolOrSampleSat { + static void Main() { CpModel model = new CpModel(); IntVar x = model.NewBoolVar("x"); IntVar y = model.NewBoolVar("y"); - model.AddBoolOr(new ILiteral[] { x, y.Not() }); + model.AddBoolOr(new ILiteral[]{x, y.Not()}); } } diff --git a/ortools/sat/samples/ChannelingSampleSat.cs b/ortools/sat/samples/ChannelingSampleSat.cs index 288741fa20..46cc96e9e0 100644 --- a/ortools/sat/samples/ChannelingSampleSat.cs +++ b/ortools/sat/samples/ChannelingSampleSat.cs @@ -15,18 +15,12 @@ using System; using Google.OrTools.Sat; using Google.OrTools.Util; -public class VarArraySolutionPrinter : CpSolverSolutionCallback -{ - public VarArraySolutionPrinter(IntVar[] variables) - { - variables_ = variables; - } +public class VarArraySolutionPrinter : CpSolverSolutionCallback { + public VarArraySolutionPrinter(IntVar[] variables) { variables_ = variables; } - public override void OnSolutionCallback() - { + public override void OnSolutionCallback() { { - foreach (IntVar v in variables_) - { + foreach (IntVar v in variables_) { Console.Write(String.Format("{0}={1} ", v.ShortString(), Value(v))); } Console.WriteLine(); @@ -36,10 +30,8 @@ public class VarArraySolutionPrinter : CpSolverSolutionCallback private IntVar[] variables_; } -public class ChannelingSampleSat -{ - static void Main() - { +public class ChannelingSampleSat { + static void Main() { // Create the CP-SAT model. CpModel model = new CpModel(); @@ -62,7 +54,7 @@ public class ChannelingSampleSat // Search for x values in increasing order. model.AddDecisionStrategy( - new IntVar[] {x}, + new IntVar[]{x}, DecisionStrategyProto.Types.VariableSelectionStrategy.ChooseFirst, DecisionStrategyProto.Types.DomainReductionStrategy.SelectMinValue); @@ -73,7 +65,7 @@ public class ChannelingSampleSat solver.StringParameters = "search_branching:FIXED_SEARCH"; VarArraySolutionPrinter cb = - new VarArraySolutionPrinter(new IntVar[] {x, y, b}); + new VarArraySolutionPrinter(new IntVar[]{x, y, b}); solver.SearchAllSolutions(model, cb); } } diff --git a/ortools/sat/samples/CpIsFunSat.cs b/ortools/sat/samples/CpIsFunSat.cs index e905c1e478..54b2d9f63e 100644 --- a/ortools/sat/samples/CpIsFunSat.cs +++ b/ortools/sat/samples/CpIsFunSat.cs @@ -11,47 +11,34 @@ // See the License for the specific language governing permissions and // limitations under the License. - // [START program] using System; using Google.OrTools.Sat; // [START solution_printing] -public class VarArraySolutionPrinter : CpSolverSolutionCallback -{ - public VarArraySolutionPrinter(IntVar[] variables) - { - variables_ = variables; - } +public class VarArraySolutionPrinter : CpSolverSolutionCallback { + public VarArraySolutionPrinter(IntVar[] variables) { variables_ = variables; } - public override void OnSolutionCallback() - { + public override void OnSolutionCallback() { { - foreach (IntVar v in variables_) - { - Console.Write( - String.Format(" {0}={1}", v.ShortString(), Value(v))); + foreach (IntVar v in variables_) { + Console.Write(String.Format(" {0}={1}", v.ShortString(), Value(v))); } Console.WriteLine(); solution_count_++; } } - public int SolutionCount() - { - return solution_count_; - } + public int SolutionCount() { return solution_count_; } private int solution_count_; private IntVar[] variables_; } // [END solution_printing] -public class CpIsFunSat -{ +public class CpIsFunSat { // Solve the CP+IS+FUN==TRUE cryptarithm. - static void Main() - { + static void Main() { // Constraint programming engine CpModel model = new CpModel(); @@ -70,7 +57,7 @@ public class CpIsFunSat IntVar e = model.NewIntVar(0, kBase - 1, "E"); // We need to group variables in a list to use the constraint AllDifferent. - IntVar[] letters = new IntVar[] {c, p, i, s, f, u, n, t, r, e}; + IntVar[] letters = new IntVar[]{c, p, i, s, f, u, n, t, r, e}; // [END variables] // [START constraints] @@ -78,7 +65,8 @@ public class CpIsFunSat model.AddAllDifferent(letters); // CP + IS + FUN = TRUE - model.Add(c * kBase + p + i * kBase + s + f * kBase * kBase + u * kBase + n == + model.Add(c * kBase + p + i * kBase + s + f * kBase * kBase + u * kBase + + n == t * kBase * kBase * kBase + r * kBase * kBase + u * kBase + e); // [END constraints] diff --git a/ortools/sat/samples/EarlinessTardinessCostSampleSat.cs b/ortools/sat/samples/EarlinessTardinessCostSampleSat.cs index 4aee3a6492..2b5f14f56b 100644 --- a/ortools/sat/samples/EarlinessTardinessCostSampleSat.cs +++ b/ortools/sat/samples/EarlinessTardinessCostSampleSat.cs @@ -15,18 +15,12 @@ using System; using Google.OrTools.Sat; using Google.OrTools.Util; -public class VarArraySolutionPrinter : CpSolverSolutionCallback -{ - public VarArraySolutionPrinter(IntVar[] variables) - { - variables_ = variables; - } +public class VarArraySolutionPrinter : CpSolverSolutionCallback { + public VarArraySolutionPrinter(IntVar[] variables) { variables_ = variables; } - public override void OnSolutionCallback() - { + public override void OnSolutionCallback() { { - foreach (IntVar v in variables_) - { + foreach (IntVar v in variables_) { Console.Write(String.Format("{0}={1} ", v.ShortString(), Value(v))); } Console.WriteLine(); @@ -36,10 +30,8 @@ public class VarArraySolutionPrinter : CpSolverSolutionCallback private IntVar[] variables_; } -public class EarlinessTardinessCostSampleSat -{ - static void Main() - { +public class EarlinessTardinessCostSampleSat { + static void Main() { long earliness_date = 5; long earliness_cost = 8; long lateness_date = 15; @@ -73,11 +65,11 @@ public class EarlinessTardinessCostSampleSat model.Add(s3 == lateness_cost * (x - lateness_date)); // Link together expr and x through s1, s2, and s3. - model.AddMaxEquality(expr, new IntVar[] {s1, s2, s3}); + model.AddMaxEquality(expr, new IntVar[]{s1, s2, s3}); // Search for x values in increasing order. model.AddDecisionStrategy( - new IntVar[] {x}, + new IntVar[]{x}, DecisionStrategyProto.Types.VariableSelectionStrategy.ChooseFirst, DecisionStrategyProto.Types.DomainReductionStrategy.SelectMinValue); @@ -88,7 +80,7 @@ public class EarlinessTardinessCostSampleSat solver.StringParameters = "search_branching:FIXED_SEARCH"; VarArraySolutionPrinter cb = - new VarArraySolutionPrinter(new IntVar[] {x, expr}); + new VarArraySolutionPrinter(new IntVar[]{x, expr}); solver.SearchAllSolutions(model, cb); } } diff --git a/ortools/sat/samples/IntervalSampleSat.cs b/ortools/sat/samples/IntervalSampleSat.cs index a61533e1ca..f57156fda7 100644 --- a/ortools/sat/samples/IntervalSampleSat.cs +++ b/ortools/sat/samples/IntervalSampleSat.cs @@ -14,10 +14,8 @@ using System; using Google.OrTools.Sat; -public class IntervalSampleSat -{ - static void Main() - { +public class IntervalSampleSat { + static void Main() { CpModel model = new CpModel(); int horizon = 100; IntVar start_var = model.NewIntVar(0, horizon, "start"); diff --git a/ortools/sat/samples/LiteralSampleSat.cs b/ortools/sat/samples/LiteralSampleSat.cs index d6828989b2..a05297be82 100644 --- a/ortools/sat/samples/LiteralSampleSat.cs +++ b/ortools/sat/samples/LiteralSampleSat.cs @@ -14,10 +14,8 @@ using System; using Google.OrTools.Sat; -public class LiteralSampleSat -{ - static void Main() - { +public class LiteralSampleSat { + static void Main() { CpModel model = new CpModel(); IntVar x = model.NewBoolVar("x"); ILiteral not_x = x.Not(); diff --git a/ortools/sat/samples/NoOverlapSampleSat.cs b/ortools/sat/samples/NoOverlapSampleSat.cs index abaecc3f50..d048fa7767 100644 --- a/ortools/sat/samples/NoOverlapSampleSat.cs +++ b/ortools/sat/samples/NoOverlapSampleSat.cs @@ -14,10 +14,8 @@ using System; using Google.OrTools.Sat; -public class NoOverlapSampleSat -{ - static void Main() - { +public class NoOverlapSampleSat { + static void Main() { CpModel model = new CpModel(); // Three weeks. int horizon = 21; @@ -49,20 +47,19 @@ public class NoOverlapSampleSat IntervalVar weekend_2 = model.NewIntervalVar(19, 2, 21, "weekend_2"); // No Overlap constraint. - model.AddNoOverlap(new IntervalVar[] {task_0, task_1, task_2, weekend_0, - weekend_1, weekend_2}); + model.AddNoOverlap(new IntervalVar[]{task_0, task_1, task_2, weekend_0, + weekend_1, weekend_2}); // Makespan objective. IntVar obj = model.NewIntVar(0, horizon, "makespan"); - model.AddMaxEquality(obj, new IntVar[] {end_0, end_1, end_2}); + model.AddMaxEquality(obj, new IntVar[]{end_0, end_1, end_2}); model.Minimize(obj); // Creates a solver and solves the model. CpSolver solver = new CpSolver(); CpSolverStatus status = solver.Solve(model); - if (status == CpSolverStatus.Optimal) - { + if (status == CpSolverStatus.Optimal) { Console.WriteLine("Optimal Schedule Length: " + solver.ObjectiveValue); Console.WriteLine("Task 0 starts at " + solver.Value(start_0)); Console.WriteLine("Task 1 starts at " + solver.Value(start_1)); diff --git a/ortools/sat/samples/OptionalIntervalSampleSat.cs b/ortools/sat/samples/OptionalIntervalSampleSat.cs index af32991bdf..63cd8bf8ec 100644 --- a/ortools/sat/samples/OptionalIntervalSampleSat.cs +++ b/ortools/sat/samples/OptionalIntervalSampleSat.cs @@ -14,10 +14,8 @@ using System; using Google.OrTools.Sat; -public class OptionalIntervalSampleSat -{ - static void Main() - { +public class OptionalIntervalSampleSat { + static void Main() { CpModel model = new CpModel(); int horizon = 100; IntVar start_var = model.NewIntVar(0, horizon, "start"); diff --git a/ortools/sat/samples/RabbitsAndPheasantsSat.cs b/ortools/sat/samples/RabbitsAndPheasantsSat.cs index 23120c0f5d..2b6f4c521a 100644 --- a/ortools/sat/samples/RabbitsAndPheasantsSat.cs +++ b/ortools/sat/samples/RabbitsAndPheasantsSat.cs @@ -14,10 +14,8 @@ using System; using Google.OrTools.Sat; -public class RabbitsAndPheasantsSat -{ - static void Main() - { +public class RabbitsAndPheasantsSat { + static void Main() { // Creates the model. CpModel model = new CpModel(); // Creates the variables. @@ -32,10 +30,9 @@ public class RabbitsAndPheasantsSat CpSolver solver = new CpSolver(); CpSolverStatus status = solver.Solve(model); - if (status == CpSolverStatus.Optimal) - { - Console.WriteLine(solver.Value(r) + " rabbits, and " + - solver.Value(p) + " pheasants"); + if (status == CpSolverStatus.Optimal) { + Console.WriteLine(solver.Value(r) + " rabbits, and " + solver.Value(p) + + " pheasants"); } } } diff --git a/ortools/sat/samples/RankingSampleSat.cs b/ortools/sat/samples/RankingSampleSat.cs index 246af0ce91..422d91bdfc 100644 --- a/ortools/sat/samples/RankingSampleSat.cs +++ b/ortools/sat/samples/RankingSampleSat.cs @@ -15,16 +15,13 @@ using System; using System.Collections.Generic; using Google.OrTools.Sat; -public class RankingSampleSat -{ - static void RankTasks(CpModel model, - IntVar[] starts, - ILiteral[] presences, +public class RankingSampleSat { + static void RankTasks(CpModel model, IntVar[] starts, ILiteral[] presences, IntVar[] ranks) { int num_tasks = starts.Length; // Creates precedence variables between pairs of intervals. - ILiteral[,] precedences = new ILiteral[num_tasks, num_tasks]; + ILiteral[, ] precedences = new ILiteral[num_tasks, num_tasks]; for (int i = 0; i < num_tasks; ++i) { for (int j = 0; j < num_tasks; ++j) { if (i == j) { @@ -43,22 +40,38 @@ public class RankingSampleSat List tmp_array = new List(); tmp_array.Add(precedences[i, j]); tmp_array.Add(precedences[j, i]); - tmp_array.Add(presences[i].Not()); + tmp_array.Add(presences [i] + .Not()); // Makes sure that if i is not performed, all precedences are false. - model.AddImplication(presences[i].Not(), precedences[i, j].Not()); - model.AddImplication(presences[i].Not(), precedences[j, i].Not()); - tmp_array.Add(presences[j].Not()); + model.AddImplication(presences [i] + .Not(), + precedences [i, j] + .Not()); + model.AddImplication(presences [i] + .Not(), + precedences [j, i] + .Not()); + tmp_array.Add(presences [j] + .Not()); // Makes sure that if j is not performed, all precedences are false. - model.AddImplication(presences[j].Not(), precedences[i, j].Not()); - model.AddImplication(presences[j].Not(), precedences[j, i].Not()); + model.AddImplication(presences [j] + .Not(), + precedences [i, j] + .Not()); + model.AddImplication(presences [j] + .Not(), + precedences [j, i] + .Not()); // The following bool_or will enforce that for any two intervals: // i precedes j or j precedes i or at least one interval is not // performed. model.AddBoolOr(tmp_array); // Redundant constraint: it propagates early that at most one precedence // is true. - model.AddImplication(precedences[i, j], precedences[j, i].Not()); - model.AddImplication(precedences[j, i], precedences[i, j].Not()); + model.AddImplication(precedences[i, j], precedences [j, i] + .Not()); + model.AddImplication(precedences[j, i], precedences [i, j] + .Not()); } } @@ -66,14 +79,13 @@ public class RankingSampleSat for (int i = 0; i < num_tasks; ++i) { IntVar[] tmp_array = new IntVar[num_tasks]; for (int j = 0; j < num_tasks; ++j) { - tmp_array[j] = (IntVar)precedences[j, i]; + tmp_array[j] = (IntVar) precedences[j, i]; } model.Add(ranks[i] == LinearExpr.Sum(tmp_array) - 1); } } - static void Main() - { + static void Main() { CpModel model = new CpModel(); // Three weeks. int horizon = 100; @@ -127,7 +139,7 @@ public class RankingSampleSat // the solver will not perform the last interval. IntVar[] presences_as_int_vars = new IntVar[num_tasks]; for (int t = 0; t < num_tasks; ++t) { - presences_as_int_vars[t] = (IntVar)presences[t]; + presences_as_int_vars[t] = (IntVar) presences[t]; } model.Minimize(2 * makespan - 7 * LinearExpr.Sum(presences_as_int_vars)); @@ -136,18 +148,18 @@ public class RankingSampleSat CpSolverStatus status = solver.Solve(model); if (status == CpSolverStatus.Optimal) { - Console.WriteLine(String.Format("Optimal cost: {0}", - solver.ObjectiveValue)); + Console.WriteLine( + String.Format("Optimal cost: {0}", solver.ObjectiveValue)); Console.WriteLine(String.Format("Makespan: {0}", solver.Value(makespan))); for (int t = 0; t < num_tasks; ++t) { if (solver.BooleanValue(presences[t])) { - Console.WriteLine(String.Format( - "Task {0} starts at {1} with rank {2}", - t, solver.Value(starts[t]), solver.Value(ranks[t]))); + Console.WriteLine( + String.Format("Task {0} starts at {1} with rank {2}", t, + solver.Value(starts[t]), solver.Value(ranks[t]))); } else { - Console.WriteLine(String.Format( - "Task {0} in not performed and ranked at {1}", t, - solver.Value(ranks[t]))); + Console.WriteLine( + String.Format("Task {0} in not performed and ranked at {1}", t, + solver.Value(ranks[t]))); } } } else { diff --git a/ortools/sat/samples/ReifiedSampleSat.cs b/ortools/sat/samples/ReifiedSampleSat.cs index 1307557e75..9b69147f34 100644 --- a/ortools/sat/samples/ReifiedSampleSat.cs +++ b/ortools/sat/samples/ReifiedSampleSat.cs @@ -14,10 +14,8 @@ using System; using Google.OrTools.Sat; -public class ReifiedSampleSat -{ - static void Main() - { +public class ReifiedSampleSat { + static void Main() { CpModel model = new CpModel(); IntVar x = model.NewBoolVar("x"); @@ -25,14 +23,14 @@ public class ReifiedSampleSat IntVar b = model.NewBoolVar("b"); // First version using a half-reified bool and. - model.AddBoolAnd(new ILiteral[] {x, y.Not()}).OnlyEnforceIf(b); + model.AddBoolAnd(new ILiteral[]{x, y.Not()}).OnlyEnforceIf(b); // Second version using implications. model.AddImplication(b, x); model.AddImplication(b, y.Not()); // Third version using bool or. - model.AddBoolOr(new ILiteral[] {b.Not(), x}); - model.AddBoolOr(new ILiteral[] {b.Not(), y.Not()}); + model.AddBoolOr(new ILiteral[]{b.Not(), x}); + model.AddBoolOr(new ILiteral[]{b.Not(), y.Not()}); } } diff --git a/ortools/sat/samples/SearchForAllSolutionsSampleSat.cs b/ortools/sat/samples/SearchForAllSolutionsSampleSat.cs index 3d0b5b6275..773c0efc47 100644 --- a/ortools/sat/samples/SearchForAllSolutionsSampleSat.cs +++ b/ortools/sat/samples/SearchForAllSolutionsSampleSat.cs @@ -16,20 +16,14 @@ using System; using Google.OrTools.Sat; // [START print_solution] -public class VarArraySolutionPrinter : CpSolverSolutionCallback -{ - public VarArraySolutionPrinter(IntVar[] variables) - { - variables_ = variables; - } +public class VarArraySolutionPrinter : CpSolverSolutionCallback { + public VarArraySolutionPrinter(IntVar[] variables) { variables_ = variables; } - public override void OnSolutionCallback() - { + public override void OnSolutionCallback() { { Console.WriteLine(String.Format("Solution #{0}: time = {1:F2} s", solution_count_, WallTime())); - foreach (IntVar v in variables_) - { + foreach (IntVar v in variables_) { Console.WriteLine( String.Format(" {0} = {1}", v.ShortString(), Value(v))); } @@ -37,20 +31,15 @@ public class VarArraySolutionPrinter : CpSolverSolutionCallback } } - public int SolutionCount() - { - return solution_count_; - } + public int SolutionCount() { return solution_count_; } private int solution_count_; private IntVar[] variables_; } // [END print_solution] -public class SearchForAllSolutionsSampleSat -{ - static void Main() - { +public class SearchForAllSolutionsSampleSat { + static void Main() { // Creates the model. // [START model] CpModel model = new CpModel(); @@ -74,12 +63,12 @@ public class SearchForAllSolutionsSampleSat // [START solve] CpSolver solver = new CpSolver(); VarArraySolutionPrinter cb = - new VarArraySolutionPrinter(new IntVar[] { x, y, z }); + new VarArraySolutionPrinter(new IntVar[]{x, y, z}); solver.SearchAllSolutions(model, cb); // [END solve] - Console.WriteLine(String.Format("Number of solutions found: {0}", - cb.SolutionCount())); + Console.WriteLine( + String.Format("Number of solutions found: {0}", cb.SolutionCount())); } } // [END program] diff --git a/ortools/sat/samples/SimpleSatProgram.cs b/ortools/sat/samples/SimpleSatProgram.cs index 09fec6397c..ab484ef043 100644 --- a/ortools/sat/samples/SimpleSatProgram.cs +++ b/ortools/sat/samples/SimpleSatProgram.cs @@ -15,10 +15,8 @@ using System; using Google.OrTools.Sat; -public class SimpleSatProgram -{ - static void Main() - { +public class SimpleSatProgram { + static void Main() { // Creates the model. // [START model] CpModel model = new CpModel(); @@ -44,8 +42,7 @@ public class SimpleSatProgram CpSolverStatus status = solver.Solve(model); // [END solve] - if (status == CpSolverStatus.Optimal) - { + if (status == CpSolverStatus.Optimal) { Console.WriteLine("x = " + solver.Value(x)); Console.WriteLine("y = " + solver.Value(y)); Console.WriteLine("z = " + solver.Value(z)); diff --git a/ortools/sat/samples/SolutionHintingSampleSat.cs b/ortools/sat/samples/SolutionHintingSampleSat.cs index 78d29c5604..d8948d3d12 100644 --- a/ortools/sat/samples/SolutionHintingSampleSat.cs +++ b/ortools/sat/samples/SolutionHintingSampleSat.cs @@ -16,20 +16,14 @@ using System; using Google.OrTools.Sat; // [START print_solution] -public class VarArraySolutionPrinter : CpSolverSolutionCallback -{ - public VarArraySolutionPrinter(IntVar[] variables) - { - variables_ = variables; - } +public class VarArraySolutionPrinter : CpSolverSolutionCallback { + public VarArraySolutionPrinter(IntVar[] variables) { variables_ = variables; } - public override void OnSolutionCallback() - { + public override void OnSolutionCallback() { { Console.WriteLine(String.Format("Solution #{0}: time = {1:F2} s", solution_count_, WallTime())); - foreach (IntVar v in variables_) - { + foreach (IntVar v in variables_) { Console.WriteLine( String.Format(" {0} = {1}", v.ShortString(), Value(v))); } @@ -37,20 +31,15 @@ public class VarArraySolutionPrinter : CpSolverSolutionCallback } } - public int SolutionCount() - { - return solution_count_; - } + public int SolutionCount() { return solution_count_; } private int solution_count_; private IntVar[] variables_; } // [END print_solution] -public class SolutionHintingSampleSat -{ - static void Main() - { +public class SolutionHintingSampleSat { + static void Main() { // Creates the model. // [START model] CpModel model = new CpModel(); @@ -75,17 +64,17 @@ public class SolutionHintingSampleSat model.AddHint(y, 2); // [START objective] - model.Maximize(LinearExpr.ScalProd(new IntVar[] {x, y, z}, new int[] {1, 2, 3})); + model.Maximize( + LinearExpr.ScalProd(new IntVar[]{x, y, z}, new int[]{1, 2, 3})); // [END objective] // Creates a solver and solves the model. // [START solve] CpSolver solver = new CpSolver(); VarArraySolutionPrinter cb = - new VarArraySolutionPrinter(new IntVar[] { x, y, z }); + new VarArraySolutionPrinter(new IntVar[]{x, y, z}); CpSolverStatus status = solver.SolveWithSolutionCallback(model, cb); // [END solve] - } } // [END program] diff --git a/ortools/sat/samples/SolveAndPrintIntermediateSolutionsSampleSat.cs b/ortools/sat/samples/SolveAndPrintIntermediateSolutionsSampleSat.cs index d9eb1c8d96..c03c9921e6 100644 --- a/ortools/sat/samples/SolveAndPrintIntermediateSolutionsSampleSat.cs +++ b/ortools/sat/samples/SolveAndPrintIntermediateSolutionsSampleSat.cs @@ -16,41 +16,32 @@ using System; using Google.OrTools.Sat; // [START print_solution] -public class VarArraySolutionPrinterWithObjective : CpSolverSolutionCallback -{ - public VarArraySolutionPrinterWithObjective(IntVar[] variables) - { +public class VarArraySolutionPrinterWithObjective : CpSolverSolutionCallback { + public VarArraySolutionPrinterWithObjective(IntVar[] variables) { variables_ = variables; } - public override void OnSolutionCallback() - { + public override void OnSolutionCallback() { Console.WriteLine(String.Format("Solution #{0}: time = {1:F2} s", - solution_count_, WallTime())); + solution_count_, WallTime())); Console.WriteLine( String.Format(" objective value = {0}", ObjectiveValue())); - foreach (IntVar v in variables_) - { + foreach (IntVar v in variables_) { Console.WriteLine( String.Format(" {0} = {1}", v.ShortString(), Value(v))); } solution_count_++; } - public int SolutionCount() - { - return solution_count_; - } + public int SolutionCount() { return solution_count_; } private int solution_count_; private IntVar[] variables_; } // [END print_solution] -public class SolveAndPrintIntermediateSolutionsSampleSat -{ - static void Main() - { +public class SolveAndPrintIntermediateSolutionsSampleSat { + static void Main() { // Creates the model. // [START model] CpModel model = new CpModel(); @@ -79,12 +70,12 @@ public class SolveAndPrintIntermediateSolutionsSampleSat // [START solve] CpSolver solver = new CpSolver(); VarArraySolutionPrinterWithObjective cb = - new VarArraySolutionPrinterWithObjective(new IntVar[] { x, y, z }); + new VarArraySolutionPrinterWithObjective(new IntVar[]{x, y, z}); solver.SolveWithSolutionCallback(model, cb); // [END solve] - Console.WriteLine(String.Format("Number of solutions found: {0}", - cb.SolutionCount())); + Console.WriteLine( + String.Format("Number of solutions found: {0}", cb.SolutionCount())); } } // [END program] diff --git a/ortools/sat/samples/SolveWithTimeLimitSampleSat.cs b/ortools/sat/samples/SolveWithTimeLimitSampleSat.cs index 21d576d0b8..c0d75a6ed1 100644 --- a/ortools/sat/samples/SolveWithTimeLimitSampleSat.cs +++ b/ortools/sat/samples/SolveWithTimeLimitSampleSat.cs @@ -14,10 +14,8 @@ using System; using Google.OrTools.Sat; -public class SolveWithTimeLimitSampleSat -{ - static void Main() - { +public class SolveWithTimeLimitSampleSat { + static void Main() { // Creates the model. CpModel model = new CpModel(); // Creates the variables. @@ -37,8 +35,7 @@ public class SolveWithTimeLimitSampleSat CpSolverStatus status = solver.Solve(model); - if (status == CpSolverStatus.Optimal) - { + if (status == CpSolverStatus.Optimal) { Console.WriteLine("x = " + solver.Value(x)); Console.WriteLine("y = " + solver.Value(y)); Console.WriteLine("z = " + solver.Value(z)); diff --git a/ortools/sat/samples/StepFunctionSampleSat.cs b/ortools/sat/samples/StepFunctionSampleSat.cs index 5879a9965c..521f38f7d9 100644 --- a/ortools/sat/samples/StepFunctionSampleSat.cs +++ b/ortools/sat/samples/StepFunctionSampleSat.cs @@ -15,18 +15,12 @@ using System; using Google.OrTools.Sat; using Google.OrTools.Util; -public class VarArraySolutionPrinter : CpSolverSolutionCallback -{ - public VarArraySolutionPrinter(IntVar[] variables) - { - variables_ = variables; - } +public class VarArraySolutionPrinter : CpSolverSolutionCallback { + public VarArraySolutionPrinter(IntVar[] variables) { variables_ = variables; } - public override void OnSolutionCallback() - { + public override void OnSolutionCallback() { { - foreach (IntVar v in variables_) - { + foreach (IntVar v in variables_) { Console.Write(String.Format("{0}={1} ", v.ShortString(), Value(v))); } Console.WriteLine(); @@ -36,10 +30,8 @@ public class VarArraySolutionPrinter : CpSolverSolutionCallback private IntVar[] variables_; } -public class StepFunctionSampleSat -{ - static void Main() - { +public class StepFunctionSampleSat { + static void Main() { // Create the CP-SAT model. CpModel model = new CpModel(); @@ -59,19 +51,19 @@ public class StepFunctionSampleSat // expr == 0 on [5, 6] U [8, 10] ILiteral b0 = model.NewBoolVar("b0"); - model.AddLinearExpressionInDomain( - x, - Domain.FromValues(new long[] { 5, 6, 8, 9, 10 })).OnlyEnforceIf(b0); + model + .AddLinearExpressionInDomain( + x, Domain.FromValues(new long[]{5, 6, 8, 9, 10})) + .OnlyEnforceIf(b0); model.Add(expr == 0).OnlyEnforceIf(b0); // expr == 2 on [0, 1] U [3, 4] U [11, 20] ILiteral b2 = model.NewBoolVar("b2"); - model.AddLinearExpressionInDomain( - x, - Domain.FromIntervals( - new long[][] {new long[] {0, 1}, - new long[] {3, 4}, - new long[] {11, 20}})).OnlyEnforceIf(b2); + model + .AddLinearExpressionInDomain( + x, Domain.FromIntervals(new long[][]{ + new long[]{0, 1}, new long[]{3, 4}, new long[]{11, 20}})) + .OnlyEnforceIf(b2); model.Add(expr == 2).OnlyEnforceIf(b2); // expr == 3 when x == 7 @@ -80,11 +72,11 @@ public class StepFunctionSampleSat model.Add(expr == 3).OnlyEnforceIf(b3); // At least one bi is true. (we could use a sum == 1). - model.AddBoolOr(new ILiteral[] { b0, b2, b3 }); + model.AddBoolOr(new ILiteral[]{b0, b2, b3}); // Search for x values in increasing order. model.AddDecisionStrategy( - new IntVar[] { x }, + new IntVar[]{x}, DecisionStrategyProto.Types.VariableSelectionStrategy.ChooseFirst, DecisionStrategyProto.Types.DomainReductionStrategy.SelectMinValue); @@ -95,7 +87,7 @@ public class StepFunctionSampleSat solver.StringParameters = "search_branching:FIXED_SEARCH"; VarArraySolutionPrinter cb = - new VarArraySolutionPrinter(new IntVar[] { x, expr }); + new VarArraySolutionPrinter(new IntVar[]{x, expr}); solver.SearchAllSolutions(model, cb); } } diff --git a/ortools/sat/samples/StopAfterNSolutionsSampleSat.cs b/ortools/sat/samples/StopAfterNSolutionsSampleSat.cs index 5ba1d8b58e..e6b5413033 100644 --- a/ortools/sat/samples/StopAfterNSolutionsSampleSat.cs +++ b/ortools/sat/samples/StopAfterNSolutionsSampleSat.cs @@ -11,52 +11,40 @@ // See the License for the specific language governing permissions and // limitations under the License. - using System; using Google.OrTools.Sat; -public class VarArraySolutionPrinterWithLimit : CpSolverSolutionCallback -{ +public class VarArraySolutionPrinterWithLimit : CpSolverSolutionCallback { public VarArraySolutionPrinterWithLimit(IntVar[] variables, - int solution_limit) - { + int solution_limit) { variables_ = variables; solution_limit_ = solution_limit; } - public override void OnSolutionCallback() - { + public override void OnSolutionCallback() { Console.WriteLine(String.Format("Solution #{0}: time = {1:F2} s", - solution_count_, WallTime())); - foreach (IntVar v in variables_) - { + solution_count_, WallTime())); + foreach (IntVar v in variables_) { Console.WriteLine( String.Format(" {0} = {1}", v.ShortString(), Value(v))); } solution_count_++; - if (solution_count_ >= solution_limit_) - { - Console.WriteLine( - String.Format("Stopping search after {0} solutions", - solution_limit_)); + if (solution_count_ >= solution_limit_) { + Console.WriteLine(String.Format("Stopping search after {0} solutions", + solution_limit_)); StopSearch(); } } - public int SolutionCount() - { - return solution_count_; - } + public int SolutionCount() { return solution_count_; } private int solution_count_; private IntVar[] variables_; private int solution_limit_; } -public class StopAfterNSolutionsSampleSat -{ - static void Main() - { +public class StopAfterNSolutionsSampleSat { + static void Main() { // Creates the model. CpModel model = new CpModel(); // Creates the variables. @@ -69,9 +57,9 @@ public class StopAfterNSolutionsSampleSat // Creates a solver and solves the model. CpSolver solver = new CpSolver(); VarArraySolutionPrinterWithLimit cb = - new VarArraySolutionPrinterWithLimit(new IntVar[] { x, y, z }, 5); + new VarArraySolutionPrinterWithLimit(new IntVar[]{x, y, z}, 5); solver.SearchAllSolutions(model, cb); - Console.WriteLine(String.Format("Number of solutions found: {0}", - cb.SolutionCount())); + Console.WriteLine( + String.Format("Number of solutions found: {0}", cb.SolutionCount())); } } diff --git a/ortools/util/csharp/NestedArrayHelper.cs b/ortools/util/csharp/NestedArrayHelper.cs index c7c874d360..a0a30f7578 100644 --- a/ortools/util/csharp/NestedArrayHelper.cs +++ b/ortools/util/csharp/NestedArrayHelper.cs @@ -13,54 +13,49 @@ namespace Google.OrTools { -using System; -using System.Collections.Generic; + using System; + using System.Collections.Generic; -public static class NestedArrayHelper -{ - public static T[] GetFlatArray(T[][] arr) - { - int flatLength = 0; - for (var i = 0; i < arr.GetLength(0); i++) - flatLength += arr[i].GetLength(0); + public static class NestedArrayHelper { + public static T[] GetFlatArray(T[][] arr) { + int flatLength = 0; + for (var i = 0; i < arr.GetLength(0); i++) + flatLength += arr [i] + .GetLength(0); - int idx = 0; - T[] flat = new T[flatLength]; + int idx = 0; + T[] flat = new T[flatLength]; - for (int i = 0; i < arr.GetLength(0); i++) - { - for (int j = 0; j < arr[i].GetLength(0); j++) - flat[idx++] = arr[i][j]; + for (int i = 0; i < arr.GetLength(0); i++) { + for (int j = 0; j < arr [i] + .GetLength(0); + j++) + flat[idx++] = arr [i] + [j]; + } + + return flat; } - return flat; - } + public static T[] GetFlatArrayFromMatrix(T[, ] arr) { + int flatLength = arr.GetLength(0) * arr.GetLength(1); - public static T[] GetFlatArrayFromMatrix(T[,] arr) - { - int flatLength = arr.GetLength(0) * arr.GetLength(1); + int idx = 0; + T[] flat = new T[flatLength]; - int idx = 0; - T[] flat = new T[flatLength]; + for (int i = 0; i < arr.GetLength(0); i++) { + for (int j = 0; j < arr.GetLength(1); j++) flat[idx++] = arr[i, j]; + } - for (int i = 0; i < arr.GetLength(0); i++) - { - for (int j = 0; j < arr.GetLength(1); j++) - flat[idx++] = arr[i, j]; + return flat; } - return flat; - } - - public static int[] GetArraySecondSize(T[][]arr) - { - var result = new int[arr.GetLength(0)]; - for (var i=0; i(T[][] arr) { + var result = new int[arr.GetLength(0)]; + for (var i = 0; i < arr.GetLength(0); i++) { + if (arr[i] != null) result[i] = arr[i].Length; + } + return result; } - return result; } -} } // namespace Google.OrTools diff --git a/ortools/util/csharp/ProtoHelper.cs b/ortools/util/csharp/ProtoHelper.cs index 3ece956f31..01ce495fd9 100644 --- a/ortools/util/csharp/ProtoHelper.cs +++ b/ortools/util/csharp/ProtoHelper.cs @@ -13,18 +13,16 @@ namespace Google.OrTools { -using System; -using Google.Protobuf; + using System; + using Google.Protobuf; -public static class ProtoHelper -{ - public static byte[] ProtoToByteArray(IMessage message) - { - int size = message.CalculateSize(); - byte[] buffer = new byte[size]; - CodedOutputStream output = new CodedOutputStream(buffer); - message.WriteTo(output); - return buffer; + public static class ProtoHelper { + public static byte[] ProtoToByteArray(IMessage message) { + int size = message.CalculateSize(); + byte[] buffer = new byte[size]; + CodedOutputStream output = new CodedOutputStream(buffer); + message.WriteTo(output); + return buffer; + } } -} } // namespace Google.OrTools