OR-Tools  7.1
BinPackingProblemSat.java
Go to the documentation of this file.
1 // Copyright 2010-2018 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
17 import com.google.ortools.sat.IntVar;
19 
21 public class BinPackingProblemSat {
22  static {
23  System.loadLibrary("jniortools");
24  }
25 
26  public static void main(String[] args) throws Exception {
27  // Data.
28  int binCapacity = 100;
29  int slackCapacity = 20;
30  int numBins = 5;
31 
32  int[][] items = new int[][] {{20, 6}, {15, 6}, {30, 4}, {45, 3}};
33  int numItems = items.length;
34 
35  // Model.
36  CpModel model = new CpModel();
37 
38  // Main variables.
39  IntVar[][] x = new IntVar[numItems][numBins];
40  for (int i = 0; i < numItems; ++i) {
41  int numCopies = items[i][1];
42  for (int b = 0; b < numBins; ++b) {
43  x[i][b] = model.newIntVar(0, numCopies, "x_" + i + "_" + b);
44  }
45  }
46 
47  // Load variables.
48  IntVar[] load = new IntVar[numBins];
49  for (int b = 0; b < numBins; ++b) {
50  load[b] = model.newIntVar(0, binCapacity, "load_" + b);
51  }
52 
53  // Slack variables.
54  IntVar[] slacks = new IntVar[numBins];
55  for (int b = 0; b < numBins; ++b) {
56  slacks[b] = model.newBoolVar("slack_" + b);
57  }
58 
59  // Links load and x.
60  int[] sizes = new int[numItems];
61  for (int i = 0; i < numItems; ++i) {
62  sizes[i] = items[i][0];
63  }
64  for (int b = 0; b < numBins; ++b) {
65  IntVar[] vars = new IntVar[numItems];
66  for (int i = 0; i < numItems; ++i) {
67  vars[i] = x[i][b];
68  }
69  model.addEquality(LinearExpr.scalProd(vars, sizes), load[b]);
70  }
71 
72  // Place all items.
73  for (int i = 0; i < numItems; ++i) {
74  IntVar[] vars = new IntVar[numBins];
75  for (int b = 0; b < numBins; ++b) {
76  vars[b] = x[i][b];
77  }
78  model.addEquality(LinearExpr.sum(vars), items[i][1]);
79  }
80 
81  // Links load and slack.
82  int safeCapacity = binCapacity - slackCapacity;
83  for (int b = 0; b < numBins; ++b) {
84  // slack[b] => load[b] <= safeCapacity.
85  model.addLessOrEqual(load[b], safeCapacity).onlyEnforceIf(slacks[b]);
86  // not(slack[b]) => load[b] > safeCapacity.
87  model.addGreaterOrEqual(load[b], safeCapacity + 1).onlyEnforceIf(slacks[b].not());
88  }
89 
90  // Maximize sum of slacks.
91  model.maximize(LinearExpr.sum(slacks));
92 
93  // Solves and prints out the solution.
94  CpSolver solver = new CpSolver();
95  CpSolverStatus status = solver.solve(model);
96  System.out.println("Solve status: " + status);
97  if (status == CpSolverStatus.OPTIMAL) {
98  System.out.printf("Optimal objective value: %f%n", solver.objectiveValue());
99  for (int b = 0; b < numBins; ++b) {
100  System.out.printf("load_%d = %d%n", b, solver.value(load[b]));
101  for (int i = 0; i < numItems; ++i) {
102  System.out.printf(" item_%d_%d = %d%n", i, b, solver.value(x[i][b]));
103  }
104  }
105  }
106  System.out.println("Statistics");
107  System.out.println(" - conflicts : " + solver.numConflicts());
108  System.out.println(" - branches : " + solver.numBranches());
109  System.out.println(" - wall time : " + solver.wallTime() + " s");
110  }
111 }
A linear expression interface that can be parsed.
Definition: LinearExpr.java:17
void onlyEnforceIf(Literal lit)
Adds a literal to the constraint.
Constraint addEquality(LinearExpr expr, long value)
Adds.
Definition: CpModel.java:153
Wrapper around the SAT solver.
Definition: CpSolver.java:26
IntVar newIntVar(long lb, long ub, String name)
Creates an integer variable with domain [lb, ub].
Definition: CpModel.java:69
double objectiveValue()
Returns the best objective value found during search.
Definition: CpSolver.java:66
IntVar newBoolVar(String name)
Creates a Boolean variable with the given name.
Definition: CpModel.java:85
long value(IntVar var)
Returns the value of a variable in the last solution found.
Definition: CpSolver.java:79
long numConflicts()
Returns the number of conflicts created during search.
Definition: CpSolver.java:104
Constraint addGreaterOrEqual(LinearExpr expr, long value)
Adds.
Definition: CpModel.java:194
Main modeling class.
Definition: CpModel.java:40
static LinearExpr scalProd(IntVar[] variables, long[] coefficients)
Creates a scalar product.
Definition: LinearExpr.java:33
Constraint addLessOrEqual(LinearExpr expr, long value)
Adds.
Definition: CpModel.java:168
void maximize(LinearExpr expr)
Adds a maximization objective of a linear expression.
Definition: CpModel.java:967
long numBranches()
Returns the number of branches explored during search.
Definition: CpSolver.java:99
double wallTime()
Returns the wall time of the search.
Definition: CpSolver.java:109
Solves a bin packing problem with the CP-SAT solver.
static LinearExpr sum(IntVar[] variables)
Creates a sum expression.
Definition: LinearExpr.java:28
CpSolverStatus solve(CpModel model)
Solves the given module, and returns the solve status.
Definition: CpSolver.java:33
static void main(String[] args)