move contrib examples to a dedicated contrib directory
This commit is contained in:
@@ -1,118 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
|
||||
public class AllDifferentExcept0 {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
//
|
||||
// alldifferent_except_0(solver, x)
|
||||
//
|
||||
// A decomposition of the global constraint
|
||||
// alldifferent_except_0, i.e. all values
|
||||
// must be either distinct, or 0.
|
||||
//
|
||||
public static void alldifferent_except_0(Solver solver, IntVar[] a) {
|
||||
|
||||
int n = a.length;
|
||||
for(int i = 0; i < n; i++) {
|
||||
for(int j = 0; j < i; j++) {
|
||||
IntVar bi = solver.makeIsDifferentCstVar(a[i], 0);
|
||||
IntVar bj = solver.makeIsDifferentCstVar(a[j], 0);
|
||||
IntVar bij = solver.makeIsDifferentCstVar(a[i], a[j]);
|
||||
solver.addConstraint(
|
||||
solver.makeLessOrEqual(
|
||||
solver.makeProd(bi, bj).var(), bij));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Implements a (decomposition) of global constraint
|
||||
* alldifferent_except_0.
|
||||
* See http://www.hakank.org/google_or_tools/circuit.py
|
||||
*
|
||||
*/
|
||||
private static void solve() {
|
||||
|
||||
Solver solver = new Solver("AllDifferentExcept0");
|
||||
|
||||
//
|
||||
// data
|
||||
//
|
||||
int n = 5;
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
IntVar[] x = solver.makeIntVarArray(n, 0, n - 1, "x");
|
||||
|
||||
//
|
||||
// constraints
|
||||
//
|
||||
alldifferent_except_0(solver, x);
|
||||
|
||||
// we also require at least 2 0's
|
||||
IntVar[] z_tmp = solver.makeBoolVarArray(n, "z_tmp");
|
||||
for(int i = 0; i < n; i++) {
|
||||
solver.addConstraint(
|
||||
solver.makeIsEqualCstCt(x[i], 0, z_tmp[i]));
|
||||
}
|
||||
|
||||
IntVar z = solver.makeSum(z_tmp).var();
|
||||
solver.addConstraint(solver.makeEquality(z, 2));
|
||||
|
||||
//
|
||||
// search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(x,
|
||||
solver.INT_VAR_DEFAULT,
|
||||
solver.INT_VALUE_DEFAULT);
|
||||
solver.newSearch(db);
|
||||
|
||||
//
|
||||
// output
|
||||
//
|
||||
while (solver.nextSolution()) {
|
||||
System.out.print("x: ");
|
||||
for(int i = 0; i < n; i++) {
|
||||
System.out.print(x[i].value() + " ");
|
||||
}
|
||||
System.out.println(" z: " + z.value());
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
AllDifferentExcept0.solve();
|
||||
}
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
|
||||
public class AllInterval {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Implements the all interval problem.
|
||||
* See http://www.hakank.org/google_or_tools/all_interval.py
|
||||
*
|
||||
*/
|
||||
private static void solve(int n) {
|
||||
|
||||
Solver solver = new Solver("AllInterval");
|
||||
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
IntVar[] x = solver.makeIntVarArray(n, 0, n - 1, "x");
|
||||
IntVar[] diffs = solver.makeIntVarArray(n - 1, 1, n - 1, "diffs");
|
||||
|
||||
//
|
||||
// constraints
|
||||
//
|
||||
solver.addConstraint(solver.makeAllDifferent(x));
|
||||
solver.addConstraint(solver.makeAllDifferent(diffs));
|
||||
|
||||
for(int k = 0; k < n - 1; k++) {
|
||||
solver.addConstraint(
|
||||
solver.makeEquality(diffs[k],
|
||||
solver.makeAbs(solver.makeDifference(x[k + 1], x[k])).var()));
|
||||
}
|
||||
|
||||
|
||||
// symmetry breaking
|
||||
solver.addConstraint(solver.makeLess(x[0], x[n - 1]));
|
||||
solver.addConstraint(solver.makeLess(diffs[0], diffs[1]));
|
||||
|
||||
|
||||
//
|
||||
// search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(x,
|
||||
solver.CHOOSE_FIRST_UNBOUND,
|
||||
solver.ASSIGN_MIN_VALUE);
|
||||
|
||||
solver.newSearch(db);
|
||||
|
||||
//
|
||||
// output
|
||||
//
|
||||
while (solver.nextSolution()) {
|
||||
System.out.print("x : ");
|
||||
for(int i = 0; i < n; i++) {
|
||||
System.out.print(x[i].value() + " ");
|
||||
}
|
||||
System.out.print("\ndiffs: ");
|
||||
|
||||
for(int i = 0; i < n-1; i++) {
|
||||
System.out.print(diffs[i].value() + " ");
|
||||
}
|
||||
System.out.println("\n");
|
||||
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
int n = 12;
|
||||
if (args.length > 0) {
|
||||
n = Integer.parseInt(args[0]);
|
||||
}
|
||||
|
||||
AllInterval.solve(n);
|
||||
}
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
|
||||
public class Circuit {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
/**
|
||||
* circuit(solver, x)
|
||||
*
|
||||
* A decomposition of the global constraint circuit, based
|
||||
* on some observation of the orbits in an array.
|
||||
*
|
||||
* Note: The domain of x must be 0..n-1 (not 1..n)
|
||||
* since Java is 0-based.
|
||||
*/
|
||||
public static void circuit(Solver solver, IntVar[] x) {
|
||||
|
||||
int n = x.length;
|
||||
IntVar[] z = solver.makeIntVarArray(n, 0, n - 1, "z");
|
||||
|
||||
solver.addConstraint(solver.makeAllDifferent(x));
|
||||
solver.addConstraint(solver.makeAllDifferent(z));
|
||||
|
||||
// put the orbit of x[0] in z[0..n-1]
|
||||
solver.addConstraint(solver.makeEquality(z[0], x[0]));
|
||||
for(int i = 1; i < n-1; i++) {
|
||||
solver.addConstraint(
|
||||
solver.makeEquality(z[i],
|
||||
solver.makeElement(x, z[i-1]).var()));
|
||||
}
|
||||
|
||||
// z may not be 0 for i < n-1
|
||||
for(int i = 1; i < n - 1; i++) {
|
||||
solver.addConstraint(solver.makeNonEquality(z[i], 0));
|
||||
}
|
||||
|
||||
// when i = n-1 it must be 0
|
||||
solver.addConstraint(solver.makeEquality(z[n - 1], 0));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Implements a (decomposition) of the global constraint circuit.
|
||||
* See http://www.hakank.org/google_or_tools/circuit.py
|
||||
*
|
||||
*/
|
||||
private static void solve(int n) {
|
||||
|
||||
Solver solver = new Solver("Circuit");
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
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);
|
||||
solver.newSearch(db);
|
||||
|
||||
//
|
||||
// output
|
||||
//
|
||||
while (solver.nextSolution()) {
|
||||
for(int i = 0; i < n; i++) {
|
||||
System.out.print(x[i].value() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
int n = 5;
|
||||
if (args.length > 0) {
|
||||
n = Integer.parseInt(args[0]);
|
||||
}
|
||||
Circuit.solve(n);
|
||||
}
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
import com.google.ortools.constraintsolver.OptimizeVar;
|
||||
|
||||
|
||||
public class CoinsGrid {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Solves the Coins Grid problem.
|
||||
* See http://www.hakank.org/google_or_tools/coins_grid.py
|
||||
*
|
||||
*/
|
||||
private static void solve() {
|
||||
Solver solver = new Solver("CoinsGrid");
|
||||
|
||||
//
|
||||
// data
|
||||
//
|
||||
int n = 31;
|
||||
int c = 14;
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
IntVar[][] x = new IntVar[n][n];
|
||||
IntVar[] x_flat = new IntVar[n * n];
|
||||
|
||||
for(int i = 0; i < n; i++) {
|
||||
for(int j = 0; j < n; j++) {
|
||||
x[i][j] = solver.makeIntVar(0, 1, "x[" + i + "," + j + "]");
|
||||
x_flat[i * n + j] = x[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// constraints
|
||||
//
|
||||
|
||||
// sum row/columns == c
|
||||
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];
|
||||
}
|
||||
solver.addConstraint(solver.makeSumEquality(row, c));
|
||||
solver.addConstraint(solver.makeSumEquality(col, c));
|
||||
}
|
||||
|
||||
// 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] =
|
||||
solver.makeProd(x[i][j],(i - j) * (i - j)).var();
|
||||
}
|
||||
}
|
||||
IntVar obj_var = solver.makeSum(obj_tmp).var();
|
||||
|
||||
//
|
||||
// objective
|
||||
//
|
||||
OptimizeVar obj = solver.makeMinimize(obj_var, 1);
|
||||
|
||||
//
|
||||
// search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(x_flat,
|
||||
solver.CHOOSE_FIRST_UNBOUND,
|
||||
solver.ASSIGN_MAX_VALUE);
|
||||
|
||||
solver.newSearch(db, obj);
|
||||
|
||||
//
|
||||
// output
|
||||
//
|
||||
while (solver.nextSolution()) {
|
||||
System.out.println("obj_var: " + obj_var.value());
|
||||
for(int i = 0; i < n; i++) {
|
||||
for(int j = 0; j < n; j++) {
|
||||
System.out.print(x[i][j].value() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
CoinsGrid.solve();
|
||||
}
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017 Darian Sastre darian.sastre@minimaxlabs.com
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ************************************************************************
|
||||
*
|
||||
* Coins grid problem in Google CP Solver.
|
||||
*
|
||||
* Problem from
|
||||
* Tony Hurlimann: "A coin puzzle - SVOR-contest 2007"
|
||||
* http://www.svor.ch/competitions/competition2007/AsroContestSolution.pdf
|
||||
* "
|
||||
* In a quadratic grid (or a larger chessboard) with 31x31 cells, one should
|
||||
* place coins in such a way that the following conditions are fulfilled:
|
||||
* 1. In each row exactly 14 coins must be placed.
|
||||
* 2. In each column exactly 14 coins must be placed.
|
||||
* 3. The sum of the quadratic horizontal distance from the main diagonal
|
||||
* of all cells containing a coin must be as small as possible.
|
||||
* 4. In each cell at most one coin can be placed.
|
||||
* The description says to place 14x31 = 434 coins on the chessboard each row
|
||||
* containing 14 coins and each column also containing 14 coins.
|
||||
* "
|
||||
*
|
||||
* This is a Java MIP version of
|
||||
* http://www.hakank.org/google_or_tools/coins_grid_mip.py
|
||||
*
|
||||
* which is the MIP version of
|
||||
* http://www.hakank.org/google_or_tools/coins_grid.py
|
||||
*
|
||||
* by Hakan Kjellerstrand (hakank@gmail.com).
|
||||
*
|
||||
* Java version by Darian Sastre (darian.sastre@minimaxlabs.com)
|
||||
*/
|
||||
|
||||
import com.google.ortools.linearsolver.*;
|
||||
|
||||
public class CoinsGridMIP {
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
private static MPSolver createSolver (String solverType) {
|
||||
return new MPSolver("MIPDiet",
|
||||
MPSolver.OptimizationProblemType.valueOf(solverType));
|
||||
}
|
||||
|
||||
private static void solve(String solverType) {
|
||||
MPSolver solver = createSolver(solverType);
|
||||
|
||||
/** invariants */
|
||||
int n = 31;
|
||||
int c = 14;
|
||||
|
||||
/** variables */
|
||||
MPVariable[][] x = new MPVariable[n][n];
|
||||
for (int i = 0; i < n; i ++) {
|
||||
x[i] = solver.makeBoolVarArray(n);
|
||||
}
|
||||
|
||||
/** constraints & objective */
|
||||
MPConstraint[] constraints = new MPConstraint[2 * n];
|
||||
MPObjective obj = solver.objective();
|
||||
|
||||
for (int i = 0; i < n; i ++) {
|
||||
constraints[2*i] = solver.makeConstraint(c, c);
|
||||
constraints[2*i + 1] = solver.makeConstraint(c, c);
|
||||
|
||||
for (int j = 0; j < n; j ++) {
|
||||
constraints[2*i].setCoefficient(x[i][j], 1);
|
||||
constraints[2*i + 1].setCoefficient(x[j][i], 1);
|
||||
|
||||
obj.setCoefficient(x[i][j], (i-j) * (j-i));
|
||||
}
|
||||
}
|
||||
|
||||
solver.solve();
|
||||
|
||||
for (int i = 0; i < n; i ++) {
|
||||
for (int j = 0; j < n; j ++) {
|
||||
System.out.print((int) x[i][j].solutionValue() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
System.out.println("---- Integer programming example with SCIP (recommended) ----");
|
||||
solve("SCIP_MIXED_INTEGER_PROGRAMMING");
|
||||
} catch (java.lang.IllegalArgumentException e) {
|
||||
System.err.println("Bad solver type: " + e);
|
||||
}
|
||||
try {
|
||||
System.out.println("---- Integer programming example with CBC ----");
|
||||
solve("CBC_MIXED_INTEGER_PROGRAMMING");
|
||||
} catch (java.lang.IllegalArgumentException e) {
|
||||
System.err.println("Bad solver type: " + e);
|
||||
}
|
||||
try {
|
||||
System.out.println("---- Integer programming example with GLPK ----");
|
||||
solve("GLPK_MIXED_INTEGER_PROGRAMMING");
|
||||
} catch (java.lang.IllegalArgumentException e) {
|
||||
System.err.println("Bad solver type: " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017 Darian Sastre darian.sastre@minimaxlabs.com
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ************************************************************************
|
||||
*
|
||||
* This model was created by Hakan Kjellerstrand (hakank@gmail.com)
|
||||
*
|
||||
* Java version by Darian Sastre (darian.sastre@minimaxlabs.com)
|
||||
*/
|
||||
import com.google.ortools.linearsolver.MPConstraint;
|
||||
import com.google.ortools.linearsolver.MPObjective;
|
||||
import com.google.ortools.linearsolver.MPSolver;
|
||||
import com.google.ortools.linearsolver.MPVariable;
|
||||
|
||||
public class ColoringMIP {
|
||||
public static class Edge {
|
||||
public int a, b;
|
||||
|
||||
public Edge(int a, int b) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
private static MPSolver createSolver (String solverType) {
|
||||
return new MPSolver("MIPDiet",
|
||||
MPSolver.OptimizationProblemType.valueOf(solverType));
|
||||
}
|
||||
|
||||
private static void solve(String solverType) {
|
||||
MPSolver solver = createSolver(solverType);
|
||||
double infinity = MPSolver.infinity();
|
||||
|
||||
/** invariants */
|
||||
int noCols = 5; // variables number
|
||||
int noNodes = 11; // constraints number
|
||||
|
||||
Edge[] edges = {
|
||||
new Edge(1,2),
|
||||
new Edge(1,4),
|
||||
new Edge(1,7),
|
||||
new Edge(1,9),
|
||||
new Edge(2,3),
|
||||
new Edge(2,6),
|
||||
new Edge(2,8),
|
||||
new Edge(3,5),
|
||||
new Edge(3,7),
|
||||
new Edge(3,10),
|
||||
new Edge(4,5),
|
||||
new Edge(4,6),
|
||||
new Edge(4,10),
|
||||
new Edge(5,8),
|
||||
new Edge(5,9),
|
||||
new Edge(6,11),
|
||||
new Edge(7,11),
|
||||
new Edge(8,11),
|
||||
new Edge(9,11),
|
||||
new Edge(10,11)
|
||||
};
|
||||
|
||||
/** variables */
|
||||
MPVariable[][] x = new MPVariable[noNodes][noCols];
|
||||
for (Integer i = 0; i < noNodes; i ++) {
|
||||
x[i] = solver.makeBoolVarArray(noCols);
|
||||
}
|
||||
|
||||
MPVariable[] colUsed = solver.makeBoolVarArray(noCols);
|
||||
|
||||
MPObjective obj = solver.objective();
|
||||
for (MPVariable objVar : colUsed) {
|
||||
obj.setCoefficient(objVar, 1);
|
||||
}
|
||||
|
||||
/** Bound each vertex to only one color */
|
||||
MPConstraint[] constraints = new MPConstraint[noNodes];
|
||||
for (int i = 0; i < noNodes; i ++) {
|
||||
constraints[i] = solver.makeConstraint(1,1);
|
||||
for (int j = 0; j < noCols; j ++) {
|
||||
constraints[i].setCoefficient(x[i][j], 1);
|
||||
}
|
||||
}
|
||||
|
||||
/** Set adjacent nodes to have different colors */
|
||||
MPConstraint[][] adjacencies = new MPConstraint[edges.length][noCols];
|
||||
for (int i = 0; i < edges.length; i ++) {
|
||||
for (int j = 0; j < noCols; j ++) {
|
||||
adjacencies[i][j] = solver.makeConstraint(-infinity, 0);
|
||||
adjacencies[i][j].setCoefficient(x[edges[i].a - 1][j], 1);
|
||||
adjacencies[i][j].setCoefficient(x[edges[i].b - 1][j], 1);
|
||||
adjacencies[i][j].setCoefficient(colUsed[j], -1);
|
||||
}
|
||||
}
|
||||
|
||||
/** Minimize by default */
|
||||
final MPSolver.ResultStatus resultStatus = solver.solve();
|
||||
|
||||
/** printing */
|
||||
if (resultStatus != MPSolver.ResultStatus.OPTIMAL) {
|
||||
System.err.println("The problem does not have an optimal solution!");
|
||||
return;
|
||||
} else {
|
||||
System.out.print("Colors used: ");
|
||||
for (MPVariable var : colUsed) {
|
||||
System.out.print((int) var.solutionValue() + " ");
|
||||
}
|
||||
System.out.println("\n");
|
||||
|
||||
for (int i = 0; i < noNodes; i ++) {
|
||||
System.out.print("Col of vertex " + i + " : ");
|
||||
for (int j = 0; j < noCols; j ++) {
|
||||
if (x[i][j].solutionValue() > 0) {
|
||||
System.out.println(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
System.out.println("---- Integer programming example with SCIP (recommended) ----");
|
||||
solve("SCIP_MIXED_INTEGER_PROGRAMMING");
|
||||
} catch (java.lang.IllegalArgumentException e) {
|
||||
System.err.println("Bad solver type: " + e);
|
||||
}
|
||||
try {
|
||||
System.out.println("---- Integer programming example with CBC ----");
|
||||
solve("CBC_MIXED_INTEGER_PROGRAMMING");
|
||||
} catch (java.lang.IllegalArgumentException e) {
|
||||
System.err.println("Bad solver type: " + e);
|
||||
}
|
||||
try {
|
||||
System.out.println("---- Integer programming example with GLPK ----");
|
||||
solve("GLPK_MIXED_INTEGER_PROGRAMMING");
|
||||
} catch (java.lang.IllegalArgumentException e) {
|
||||
System.err.println("Bad solver type: " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
import com.google.ortools.constraintsolver.OptimizeVar;
|
||||
|
||||
public class CoveringOpl {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Solves a set covering problem.
|
||||
* See http://www.hakank.org/google_or_tools/covering_opl.py
|
||||
*
|
||||
*/
|
||||
private static void solve() {
|
||||
|
||||
Solver solver = new Solver("CoveringOpl");
|
||||
|
||||
//
|
||||
// data
|
||||
//
|
||||
int num_workers = 32;
|
||||
int num_tasks = 15;
|
||||
|
||||
// Which worker is qualified for each task.
|
||||
// Note: This is 1-based and will be made 0-base below.
|
||||
int[][] qualified = {{ 1, 9, 19, 22, 25, 28, 31 },
|
||||
{ 2, 12, 15, 19, 21, 23, 27, 29, 30, 31, 32 },
|
||||
{ 3, 10, 19, 24, 26, 30, 32 },
|
||||
{ 4, 21, 25, 28, 32 },
|
||||
{ 5, 11, 16, 22, 23, 27, 31 },
|
||||
{ 6, 20, 24, 26, 30, 32 },
|
||||
{ 7, 12, 17, 25, 30, 31 } ,
|
||||
{ 8, 17, 20, 22, 23 },
|
||||
{ 9, 13, 14, 26, 29, 30, 31 },
|
||||
{ 10, 21, 25, 31, 32 },
|
||||
{ 14, 15, 18, 23, 24, 27, 30, 32 },
|
||||
{ 18, 19, 22, 24, 26, 29, 31 },
|
||||
{ 11, 20, 25, 28, 30, 32 },
|
||||
{ 16, 19, 23, 31 },
|
||||
{ 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};
|
||||
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
IntVar[] hire = solver.makeIntVarArray(num_workers, 0, 1, "workers");
|
||||
IntVar total_cost = solver.makeScalProd(hire, cost).var();
|
||||
|
||||
//
|
||||
// constraints
|
||||
//
|
||||
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];
|
||||
}
|
||||
IntVar b = solver.makeSum(tmp).var();
|
||||
solver.addConstraint(solver.makeGreaterOrEqual(b, 1));
|
||||
}
|
||||
|
||||
|
||||
// Objective: Minimize total cost
|
||||
OptimizeVar objective = solver.makeMinimize(total_cost, 1);
|
||||
|
||||
//
|
||||
// search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(hire,
|
||||
solver.CHOOSE_FIRST_UNBOUND,
|
||||
solver.ASSIGN_MIN_VALUE);
|
||||
|
||||
solver.newSearch(db, objective);
|
||||
|
||||
//
|
||||
// output
|
||||
//
|
||||
while (solver.nextSolution()) {
|
||||
System.out.println("Cost: " + total_cost.value());
|
||||
System.out.print("Hire: ");
|
||||
for(int i = 0; i < num_workers; i++) {
|
||||
if (hire[i].value() == 1) {
|
||||
System.out.print(i + " ");
|
||||
}
|
||||
}
|
||||
System.out.println("\n");
|
||||
|
||||
}
|
||||
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
CoveringOpl.solve();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,182 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
|
||||
public class Crossword {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Solving a simple crossword.
|
||||
* See http://www.hakank.org/google_or_tools/crossword2.py
|
||||
*
|
||||
*/
|
||||
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"};
|
||||
|
||||
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 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 num_overlapping = 12;
|
||||
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
|
||||
|
||||
{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
|
||||
|
||||
int N = 8;
|
||||
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
IntVar[][] A = new IntVar[num_words][word_len];
|
||||
IntVar[] A_flat = new IntVar[num_words * word_len];
|
||||
// for labeling on A and E
|
||||
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++) {
|
||||
A[I][J] = solver.makeIntVar(0, 26, "A[" + I + "," + J + "]");
|
||||
A_flat[I * word_len + J] = A[I][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++) {
|
||||
all[num_words * word_len + I] = E[I];
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// constraints
|
||||
//
|
||||
solver.addConstraint(solver.makeAllDifferent(E));
|
||||
|
||||
for(int I = 0; I < num_words; I++) {
|
||||
for(int J = 0; J < word_len; J++) {
|
||||
solver.addConstraint(solver.makeEquality(A[I][J], AA[I][J]));
|
||||
}
|
||||
}
|
||||
|
||||
for(int I = 0; I < num_overlapping; I++) {
|
||||
solver.addConstraint(
|
||||
solver.makeEquality(
|
||||
solver.makeElement(A_flat,
|
||||
solver.makeSum(
|
||||
solver.makeProd(
|
||||
E[overlapping[I][0]], word_len).var(),
|
||||
overlapping[I][1]).var()).var(),
|
||||
solver.makeElement(A_flat,
|
||||
solver.makeSum(
|
||||
solver.makeProd(
|
||||
E[overlapping[I][2]], word_len).var(),
|
||||
overlapping[I][3]).var()).var() ));
|
||||
}
|
||||
|
||||
//
|
||||
// search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(all,
|
||||
solver.INT_VAR_DEFAULT,
|
||||
solver.INT_VALUE_DEFAULT);
|
||||
|
||||
solver.newSearch(db);
|
||||
|
||||
//
|
||||
// output
|
||||
//
|
||||
while (solver.nextSolution()) {
|
||||
System.out.println("E:");
|
||||
for(int ee = 0; ee < N; ee++) {
|
||||
int e_val = (int)E[ee].value();
|
||||
System.out.print(ee + ": (" + e_val + ") ");
|
||||
for(int ii = 0; ii < word_len; ii++) {
|
||||
System.out.print(alpha[(int)A[ee][ii].value()]);
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
System.out.println();
|
||||
|
||||
}
|
||||
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
Crossword.solve();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,228 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
|
||||
public class DeBruijn {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* toNum(solver, a, num, base)
|
||||
*
|
||||
* channelling between the array a and the number num
|
||||
*
|
||||
*/
|
||||
private static void toNum(Solver solver, IntVar[] a, IntVar num, int base) {
|
||||
int len = a.length;
|
||||
|
||||
IntVar[] tmp = new IntVar[len];
|
||||
for(int i = 0; i < len; i++) {
|
||||
tmp[i] = solver.makeProd(a[i], (int)Math.pow(base,(len-i-1))).var();
|
||||
}
|
||||
solver.addConstraint(
|
||||
solver.makeEquality(solver.makeSum(tmp).var(), num));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Implements "arbitrary" de Bruijn sequences.
|
||||
* See http://www.hakank.org/google_or_tools/debruijn_binary.py
|
||||
*
|
||||
*/
|
||||
private static void solve(int base, int n, int m) {
|
||||
|
||||
Solver solver = new Solver("DeBruijn");
|
||||
|
||||
System.out.println("base: " + base + " n: " + n + " m: " + m);
|
||||
|
||||
// Ensure that the number of each digit in bin_code is
|
||||
// the same. Nice feature, but it can slow things down...
|
||||
boolean check_same_gcc = false; // true;
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
IntVar[] x =
|
||||
solver.makeIntVarArray(m, 0, (int)Math.pow(base, n) - 1, "x");
|
||||
|
||||
IntVar[][] binary = new IntVar[m][n];
|
||||
for(int i = 0; i < m; i++) {
|
||||
for(int j = 0; j < n; j++) {
|
||||
binary[i][j] =
|
||||
solver.makeIntVar(0, base - 1, "binary[" + i + "," + j + "]");
|
||||
}
|
||||
}
|
||||
|
||||
// this is the de Bruijn sequence
|
||||
IntVar[] bin_code =
|
||||
solver.makeIntVarArray(m, 0, base - 1, "bin_code");
|
||||
|
||||
// occurences of each number in bin_code
|
||||
IntVar[] gcc = solver.makeIntVarArray(base, 0, m, "gcc");
|
||||
|
||||
// for the branching
|
||||
IntVar[] all = new IntVar[2 * m + base];
|
||||
for(int i = 0; i < m; i++) {
|
||||
all[i] = x[i];
|
||||
all[m + i] = bin_code[i];
|
||||
}
|
||||
for(int i = 0; i < base; i++) {
|
||||
all[2 * m + i] = gcc[i];
|
||||
}
|
||||
|
||||
//
|
||||
// constraints
|
||||
//
|
||||
solver.addConstraint(solver.makeAllDifferent(x));
|
||||
|
||||
// converts x <-> binary
|
||||
for(int i = 0; i < m; i++) {
|
||||
IntVar[] t = new IntVar[n];
|
||||
for(int j = 0; j < n; j++) {
|
||||
t[j] = binary[i][j];
|
||||
}
|
||||
toNum(solver, t, x[i], base);
|
||||
}
|
||||
|
||||
// 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.addConstraint(
|
||||
solver.makeEquality(binary[i - 1][j], binary[i][j - 1]));
|
||||
}
|
||||
}
|
||||
|
||||
// ... and around the corner
|
||||
for(int j = 1; j < n; j++) {
|
||||
solver.addConstraint(
|
||||
solver.makeEquality(binary[m - 1][j], binary[0][j - 1]));
|
||||
}
|
||||
|
||||
// converts binary -> bin_code (de Bruijn sequence)
|
||||
for(int i = 0; i < m; i++) {
|
||||
solver.addConstraint(solver.makeEquality(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.addConstraint(solver.makeDistribute(bin_code, gcc));
|
||||
if (check_same_gcc && m % base == 0) {
|
||||
for(int i = 1; i < base; i++) {
|
||||
solver.addConstraint(solver.makeEquality(gcc[i], gcc[i - 1]));
|
||||
}
|
||||
}
|
||||
|
||||
// symmetry breaking:
|
||||
// the minimum value of x should be first
|
||||
solver.addConstraint(solver.makeEquality(x[0], solver.makeMin(x).var()));
|
||||
|
||||
|
||||
//
|
||||
// search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(all,
|
||||
solver.CHOOSE_MIN_SIZE_LOWEST_MAX,
|
||||
solver.ASSIGN_MIN_VALUE);
|
||||
|
||||
solver.newSearch(db);
|
||||
|
||||
//
|
||||
// output
|
||||
//
|
||||
while (solver.nextSolution()) {
|
||||
System.out.print("x: ");
|
||||
for(int i = 0; i < m; i++) {
|
||||
System.out.print(x[i].value() + " ");
|
||||
}
|
||||
|
||||
System.out.print("\nde Bruijn sequence:");
|
||||
for(int i = 0; i < m; i++) {
|
||||
System.out.print(bin_code[i].value() + " ");
|
||||
}
|
||||
|
||||
System.out.print("\ngcc: ");
|
||||
for(int i = 0; i < base; i++) {
|
||||
System.out.print(gcc[i].value() + " ");
|
||||
}
|
||||
System.out.println("\n");
|
||||
|
||||
|
||||
// for debugging etc: show the full binary table
|
||||
/*
|
||||
System.out.println("binary:");
|
||||
for(int i = 0; i < m; i++) {
|
||||
for(int j = 0; j < n; j++) {
|
||||
System.out.print(binary[i][j].value() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
System.out.println();
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
int base = 2;
|
||||
int n = 3;
|
||||
int m = 8;
|
||||
|
||||
if (args.length > 0) {
|
||||
base = Integer.parseInt(args[0]);
|
||||
}
|
||||
|
||||
if (args.length > 1) {
|
||||
n = Integer.parseInt(args[1]);
|
||||
m = (int)Math.pow(base, n);
|
||||
}
|
||||
|
||||
if (args.length > 2) {
|
||||
int m_max = (int) Math.pow(base, n);
|
||||
m = Integer.parseInt(args[2]);
|
||||
if (m > m_max) {
|
||||
System.out.println("m(" + m + ") is too large. Set m to " +
|
||||
m_max + ".");
|
||||
m = m_max;
|
||||
}
|
||||
}
|
||||
|
||||
DeBruijn.solve(base, n, m);
|
||||
}
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
import com.google.ortools.constraintsolver.*;
|
||||
|
||||
public class Diet {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Solves the Diet problem.
|
||||
* See http://www.hakank.org/google_or_tools/diet1.py
|
||||
*
|
||||
*/
|
||||
private static void solve() {
|
||||
|
||||
Solver solver = new Solver("Diet");
|
||||
|
||||
int n = 4;
|
||||
int[] price = { 50, 20, 30, 80}; // in cents
|
||||
|
||||
// requirements for each nutrition type
|
||||
int[] limits = {500, 6, 10, 8};
|
||||
|
||||
// nutritions for each product
|
||||
int[] calories = {400, 200, 150, 500};
|
||||
int[] chocolate = {3, 2, 0, 0};
|
||||
int[] sugar = {2, 2, 4, 4};
|
||||
int[] fat = {2, 4, 1, 5};
|
||||
|
||||
|
||||
//
|
||||
// Variables
|
||||
//
|
||||
IntVar[] x = solver.makeIntVarArray(n, 0, 100, "x");
|
||||
|
||||
IntVar cost = solver.makeScalProd(x, price).var();
|
||||
|
||||
//
|
||||
// Constraints
|
||||
//
|
||||
solver.addConstraint(
|
||||
solver.makeScalProdGreaterOrEqual(x, calories, limits[0]));
|
||||
|
||||
solver.addConstraint(
|
||||
solver.makeScalProdGreaterOrEqual(x,chocolate, limits[1]));
|
||||
|
||||
solver.addConstraint(
|
||||
solver.makeScalProdGreaterOrEqual(x, sugar, limits[2]));
|
||||
|
||||
solver.addConstraint(
|
||||
solver.makeScalProdGreaterOrEqual(x, fat, limits[3]));
|
||||
|
||||
|
||||
//
|
||||
// Objective
|
||||
//
|
||||
OptimizeVar obj = solver.makeMinimize(cost, 1);
|
||||
|
||||
//
|
||||
// Search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(x,
|
||||
solver.CHOOSE_PATH,
|
||||
solver.ASSIGN_MIN_VALUE);
|
||||
solver.newSearch(db, obj);
|
||||
while (solver.nextSolution()) {
|
||||
System.out.println("cost: " + cost.value());
|
||||
System.out.print("x: ");
|
||||
for(int i = 0; i < n; i++) {
|
||||
System.out.print(x[i].value() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Diet.solve();
|
||||
}
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
|
||||
/*
|
||||
* Copyright 2017 Darian Sastre darian.sastre@minimaxlabs.com
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ************************************************************************
|
||||
*
|
||||
* This model was created by Hakan Kjellerstrand (hakank@gmail.com)
|
||||
*/
|
||||
|
||||
import com.google.ortools.linearsolver.MPConstraint;
|
||||
import com.google.ortools.linearsolver.MPObjective;
|
||||
import com.google.ortools.linearsolver.MPSolver;
|
||||
import com.google.ortools.linearsolver.MPVariable;
|
||||
|
||||
public class DietMIP {
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
private static MPSolver createSolver(String solverType) {
|
||||
try {
|
||||
return new MPSolver("MIPDiet", MPSolver.OptimizationProblemType.valueOf(solverType));
|
||||
} catch (java.lang.IllegalArgumentException e) {
|
||||
System.err.println("Bad solver type: " + e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void solve(String solverType) {
|
||||
MPSolver solver = createSolver(solverType);
|
||||
double infinity = MPSolver.infinity();
|
||||
|
||||
int n = 4; // variables number
|
||||
int m = 4; // constraints number
|
||||
|
||||
int[] price = { 50, 20, 30, 80 };
|
||||
|
||||
int[] limits = { 500, 6, 10, 8 };
|
||||
|
||||
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[][] values = { calories, chocolate, sugar, fat };
|
||||
|
||||
MPVariable[] x = solver.makeIntVarArray(n, 0, 100, "x");
|
||||
MPObjective objective = solver.objective();
|
||||
MPConstraint[] targets = new MPConstraint[4];
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
objective.setCoefficient(x[i], price[i]);
|
||||
|
||||
// constraints
|
||||
targets[i] = solver.makeConstraint(limits[i], infinity);
|
||||
for (int j = 0; j < m; j++) {
|
||||
targets[i].setCoefficient(x[j], values[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
final MPSolver.ResultStatus resultStatus = solver.solve();
|
||||
|
||||
/** printing */
|
||||
if (resultStatus != MPSolver.ResultStatus.OPTIMAL) {
|
||||
System.err.println("The problem does not have an optimal solution!");
|
||||
return;
|
||||
} else {
|
||||
System.out.println("Optimal objective value = " + solver.objective().value());
|
||||
|
||||
System.out.print("Item quantities: ");
|
||||
System.out.print((int) x[0].solutionValue() + " ");
|
||||
System.out.print((int) x[1].solutionValue() + " ");
|
||||
System.out.print((int) x[2].solutionValue() + " ");
|
||||
System.out.print((int) x[3].solutionValue() + " ");
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
solve("CBC_MIXED_INTEGER_PROGRAMMING");
|
||||
}
|
||||
}
|
||||
@@ -1,216 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
|
||||
public class DivisibleBy9Through1 {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* A simple propagator for modulo constraint.
|
||||
*
|
||||
* This implementation is based on the ECLiPSe version
|
||||
* mentioned in "A Modulo propagator for ECLiPSE"
|
||||
* http://www.hakank.org/constraint_programming_blog/2010/05/a_modulo_propagator_for_eclips.html
|
||||
* The ECLiPSe Prolog source code:
|
||||
* http://www.hakank.org/eclipse/modulo_propagator.ecl
|
||||
*
|
||||
*/
|
||||
public static void my_mod(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);
|
||||
|
||||
IntVar d = solver.makeIntVar(min_x, max_x, "d");
|
||||
|
||||
// r >= 0
|
||||
solver.addConstraint(solver.makeGreaterOrEqual(r,0));
|
||||
|
||||
// x*r >= 0
|
||||
solver.addConstraint(
|
||||
solver.makeGreaterOrEqual(
|
||||
solver.makeProd(x,r).var(), 0));
|
||||
|
||||
// -abs(y) < r
|
||||
solver.addConstraint(
|
||||
solver.makeLess(
|
||||
solver.makeOpposite(solver.makeAbs(y).var()).var(), r));
|
||||
|
||||
// r < abs(y)
|
||||
solver.addConstraint(
|
||||
solver.makeLess(r,
|
||||
solver.makeAbs(y).var().var()));
|
||||
|
||||
// min_x <= d, i.e. d > min_x
|
||||
solver.addConstraint(solver.makeGreater(d, min_x));
|
||||
|
||||
|
||||
// d <= max_x
|
||||
solver.addConstraint(solver.makeLessOrEqual(d, max_x));
|
||||
|
||||
// x == y*d+r
|
||||
solver.addConstraint(solver.makeEquality(x,
|
||||
solver.makeSum(
|
||||
solver.makeProd(y,d).var(),r).var()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* toNum(solver, a, num, base)
|
||||
*
|
||||
* channelling between the array a and the number num
|
||||
*
|
||||
*/
|
||||
private static void toNum(Solver solver, IntVar[] a, IntVar num, int base) {
|
||||
int len = a.length;
|
||||
|
||||
IntVar[] tmp = new IntVar[len];
|
||||
for(int i = 0; i < len; i++) {
|
||||
tmp[i] = solver.makeProd(a[i], (int)Math.pow(base,(len-i-1))).var();
|
||||
}
|
||||
solver.addConstraint(
|
||||
solver.makeEquality(solver.makeSum(tmp).var(), num));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Solves the divisible by 9 through 1 problem.
|
||||
* See http://www.hakank.org/google_or_tools/divisible_by_9_through_1.py
|
||||
*
|
||||
*/
|
||||
private static void solve(int base) {
|
||||
|
||||
Solver solver = new Solver("DivisibleBy9Through1");
|
||||
|
||||
//
|
||||
// data
|
||||
//
|
||||
int m = (int)Math.pow(base,(base-1)) - 1;
|
||||
int n = base - 1;
|
||||
|
||||
String[] digits_str = {"_","0","1","2","3","4","5","6","7","8","9"};
|
||||
|
||||
System.out.println("base: " + base);
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
|
||||
// digits
|
||||
IntVar[] x = solver.makeIntVarArray(n, 1, base - 1, "x");
|
||||
|
||||
// the numbers. t[0] contains the answe
|
||||
IntVar[] t = solver.makeIntVarArray(n, 0, m, "t");
|
||||
|
||||
|
||||
//
|
||||
// constraints
|
||||
//
|
||||
solver.addConstraint(solver.makeAllDifferent(x));
|
||||
|
||||
// Ensure the divisibility of base .. 1
|
||||
IntVar zero = solver.makeIntConst(0);
|
||||
for(int i = 0; i < n; i++) {
|
||||
int mm = base - i - 1;
|
||||
IntVar[] tt = new IntVar[mm];
|
||||
for(int j = 0; j < mm; j++) {
|
||||
tt[j] = x[j];
|
||||
}
|
||||
toNum(solver, tt, t[i], base);
|
||||
IntVar mm_const = solver.makeIntConst(mm);
|
||||
my_mod(solver, t[i], mm_const, zero);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(x,
|
||||
solver.INT_VAR_DEFAULT,
|
||||
solver.INT_VALUE_DEFAULT);
|
||||
solver.newSearch(db);
|
||||
|
||||
//
|
||||
// output
|
||||
//
|
||||
while (solver.nextSolution()) {
|
||||
System.out.print("x: ");
|
||||
for(int i = 0; i < n; i++) {
|
||||
System.out.print(x[i].value() + " ");
|
||||
}
|
||||
System.out.println("\nt: ");
|
||||
for(int i = 0; i < n; i++) {
|
||||
System.out.print(t[i].value() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
if (base != 10) {
|
||||
System.out.print("Number base 10: " + t[0].value());
|
||||
System.out.print(" Base " + base + ": ");
|
||||
for(int i = 0; i < n; i++) {
|
||||
System.out.print(digits_str[(int)x[i].value() + 1]);
|
||||
}
|
||||
System.out.println("\n");
|
||||
}
|
||||
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
int base = 10;
|
||||
|
||||
if (args.length > 0) {
|
||||
int new_base = Integer.parseInt(args[0]);
|
||||
if (new_base > 10) {
|
||||
// Note: The next valid base after 10 is 14 and
|
||||
// the number 559922224824157, which is too large in this model.
|
||||
System.out.println("Sorry, max allowed base is 10. Setting base to 10.");
|
||||
} else if (new_base < 2) {
|
||||
System.out.println("Sorry, min allowed base is 2. Setting base to 2.");
|
||||
base = 2;
|
||||
} else {
|
||||
base = new_base;
|
||||
}
|
||||
}
|
||||
|
||||
DivisibleBy9Through1.solve(base);
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 1999-2011, Ecole des Mines de Nantes
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the Ecole des Mines de Nantes nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntExpr;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.OptimizeVar;
|
||||
import com.google.ortools.constraintsolver.SearchMonitor;
|
||||
import com.google.ortools.constraintsolver.SolutionCollector;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
|
||||
/**
|
||||
* Golomb ruler problem
|
||||
* <br/>
|
||||
*
|
||||
* @author Charles Prud'homme
|
||||
* @since 17/03/11
|
||||
*/
|
||||
public class GolombRuler {
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Golomb Ruler Problem.
|
||||
*/
|
||||
private static void solve(int m) {
|
||||
Solver solver = new Solver("GR " + m);
|
||||
|
||||
IntVar[] ticks =
|
||||
solver.makeIntVarArray(m,
|
||||
0,
|
||||
((m < 31) ? (1 << (m + 1)) - 1 : 9999),
|
||||
"ticks");
|
||||
|
||||
solver.addConstraint(solver.makeEquality(ticks[0], 0));
|
||||
|
||||
for (int i = 0; i < ticks.length - 1; i++) {
|
||||
solver.addConstraint(solver.makeLess(ticks[i], ticks[i + 1]));
|
||||
}
|
||||
|
||||
IntVar[] diff = new IntVar[(m * m - m) / 2];
|
||||
|
||||
for (int k = 0, i = 0; i < m - 1; i++) {
|
||||
for (int j = i + 1; j < m; j++, k++) {
|
||||
diff[k] = solver.makeDifference(ticks[j], ticks[i]).var();
|
||||
solver.addConstraint(
|
||||
solver.makeGreaterOrEqual(diff[k], (j - i) * (j - i + 1) / 2));
|
||||
}
|
||||
}
|
||||
|
||||
solver.addConstraint(solver.makeAllDifferent(diff));
|
||||
|
||||
// break symetries
|
||||
if (m > 2) {
|
||||
solver.addConstraint(solver.makeLess(diff[0], diff[diff.length - 1]));
|
||||
}
|
||||
|
||||
OptimizeVar opt = solver.makeMinimize(ticks[m - 1], 1);
|
||||
DecisionBuilder db = solver.makePhase(ticks,
|
||||
solver.CHOOSE_MIN_SIZE_LOWEST_MIN,
|
||||
solver.ASSIGN_MIN_VALUE);
|
||||
SolutionCollector collector = solver.makeLastSolutionCollector();
|
||||
collector.add(ticks);
|
||||
collector.addObjective(ticks[m - 1]);
|
||||
SearchMonitor log = solver.makeSearchLog(10000, opt);
|
||||
solver.solve(db, opt, log, collector);
|
||||
System.out.println("Optimal solution = " + collector.objectiveValue(0));
|
||||
for (int i = 0; i < m; ++i) {
|
||||
System.out.print("[" + collector.value(0, ticks[i]) + "] ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
GolombRuler.solve(8);
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
import com.google.ortools.linearsolver.MPConstraint;
|
||||
import com.google.ortools.linearsolver.MPObjective;
|
||||
import com.google.ortools.linearsolver.MPSolver;
|
||||
import com.google.ortools.linearsolver.MPVariable;
|
||||
|
||||
public class Issue173 {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
public static void breakit() {
|
||||
|
||||
for (int i = 0; i < 50000; i++) {
|
||||
solveLP();
|
||||
}
|
||||
}
|
||||
|
||||
private static void solveLP() {
|
||||
MPSolver solver = new MPSolver(
|
||||
"test",
|
||||
MPSolver.OptimizationProblemType.CBC_MIXED_INTEGER_PROGRAMMING);
|
||||
MPVariable x = solver.makeNumVar(Double.NEGATIVE_INFINITY,
|
||||
Double.POSITIVE_INFINITY, "x");
|
||||
|
||||
final MPObjective objective = solver.objective();
|
||||
objective.setMaximization();
|
||||
objective.setCoefficient(x, 1);
|
||||
|
||||
MPConstraint constraint = solver.makeConstraint(0, 5);
|
||||
constraint.setCoefficient(x, 1);
|
||||
|
||||
solver.solve();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
breakit();
|
||||
}
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017 Darian Sastre darian.sastre@minimaxlabs.com
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ************************************************************************
|
||||
*
|
||||
* Each knapsack perceives a different weight for each item. Item values are
|
||||
* the same across knapsacks. Optimizing constrains the count of each item such
|
||||
* that all knapsack capacities are respected, and their values are maximized.
|
||||
*
|
||||
* This model was created by Hakan Kjellerstrand (hakank@gmail.com)
|
||||
*/
|
||||
|
||||
import com.google.ortools.linearsolver.*;
|
||||
|
||||
public class KnapsackMIP {
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
private static MPSolver createSolver (String solverType) {
|
||||
try {
|
||||
return new MPSolver("MIPDiet",
|
||||
MPSolver.OptimizationProblemType.valueOf(solverType));
|
||||
} catch (java.lang.IllegalArgumentException e) {
|
||||
System.err.println("Bad solver type: " + e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void solve(String solverType) {
|
||||
MPSolver solver = createSolver(solverType);
|
||||
|
||||
/** variables */
|
||||
int itemCount = 12;
|
||||
int capacityCount = 7;
|
||||
|
||||
int[] capacity = {18209, 7692, 1333, 924, 26638, 61188, 13360};
|
||||
int[] value = {96, 76, 56, 11, 86, 10, 66, 86, 83, 12, 9, 81};
|
||||
int[][] weights = {
|
||||
{19, 1, 10, 1, 1, 14, 152, 11, 1, 1, 1, 1},
|
||||
{0, 4, 53, 0, 0, 80, 0, 4, 5, 0, 0, 0},
|
||||
{4, 660, 3, 0, 30, 0, 3, 0, 4, 90, 0, 0},
|
||||
{7, 0, 18, 6, 770, 330, 7, 0, 0, 6, 0, 0},
|
||||
{0, 20, 0, 4, 52, 3, 0, 0, 0, 5, 4, 0},
|
||||
{0, 0, 40, 70, 4, 63, 0, 0, 60, 0, 4, 0},
|
||||
{0, 32, 0, 0, 0, 5, 0, 3, 0, 660, 0, 9}
|
||||
};
|
||||
|
||||
int maxCapacity = -1;
|
||||
for (int c : capacity) {
|
||||
if (c > maxCapacity) {
|
||||
maxCapacity = c;
|
||||
}
|
||||
}
|
||||
|
||||
MPVariable[] taken = solver.makeIntVarArray(itemCount, 0, maxCapacity);
|
||||
|
||||
/** constraints */
|
||||
MPConstraint constraints[] = new MPConstraint[capacityCount];
|
||||
for (int i = 0; i < capacityCount; i ++) {
|
||||
constraints[i] = solver.makeConstraint(0, capacity[i]);
|
||||
for (int j = 0; j < itemCount; j ++) {
|
||||
constraints[i].setCoefficient(taken[j], weights[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
/** objective */
|
||||
MPObjective obj = solver.objective();
|
||||
obj.setMaximization();
|
||||
for (int i = 0; i < itemCount; i ++) {
|
||||
obj.setCoefficient(taken[i], value[i]);
|
||||
}
|
||||
|
||||
solver.solve();
|
||||
|
||||
/** printing */
|
||||
System.out.println("Max cost: " + obj.value());
|
||||
System.out.print("Item quantities: ");
|
||||
for (MPVariable var : taken) {
|
||||
System.out.print((int) var.solutionValue() + " ");
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
solve("CBC_MIXED_INTEGER_PROGRAMMING");
|
||||
}
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.*;
|
||||
|
||||
public class LeastDiff {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Solves the Least Diff problem.
|
||||
* See http://www.hakank.org/google_or_tools/least_diff.py
|
||||
*
|
||||
*/
|
||||
private static void solve() {
|
||||
final int base = 10;
|
||||
|
||||
Solver solver = new Solver("LeastDiff");
|
||||
|
||||
//
|
||||
// Variables
|
||||
//
|
||||
IntVar a = solver.makeIntVar(0, base - 1, "a");
|
||||
IntVar b = solver.makeIntVar(0, base - 1, "b");
|
||||
IntVar c = solver.makeIntVar(0, base - 1, "c");
|
||||
IntVar d = solver.makeIntVar(0, base - 1, "d");
|
||||
IntVar e = solver.makeIntVar(0, base - 1, "e");
|
||||
|
||||
IntVar f = solver.makeIntVar(0, base - 1, "f");
|
||||
IntVar g = solver.makeIntVar(0, base - 1, "g");
|
||||
IntVar h = solver.makeIntVar(0, base - 1, "h");
|
||||
IntVar i = solver.makeIntVar(0, base - 1, "i");
|
||||
IntVar j = solver.makeIntVar(0, base - 1, "j");
|
||||
|
||||
IntVar[] all = {a,b,c,d,e,f,g,h,i,j};
|
||||
|
||||
//
|
||||
// Constraints
|
||||
//
|
||||
int[] coeffs = {10000, 1000, 100, 10, 1};
|
||||
IntVar x = solver.makeScalProd(new IntVar[]{a,b,c,d,e}, coeffs).var();
|
||||
x.setName("x");
|
||||
IntVar y = solver.makeScalProd(new IntVar[]{f,g,h,i,j}, coeffs).var();
|
||||
y.setName("y");
|
||||
|
||||
// a > 0
|
||||
solver.addConstraint(solver.makeGreater(a, 0));
|
||||
// f > 0
|
||||
solver.addConstraint(solver.makeGreater(f, 0));
|
||||
|
||||
// diff = x - y
|
||||
IntVar diff = solver.makeDifference(x, y).var();
|
||||
diff.setName("diff");
|
||||
|
||||
solver.addConstraint(solver.makeAllDifferent(all));
|
||||
|
||||
//
|
||||
// Objective
|
||||
//
|
||||
OptimizeVar obj = solver.makeMinimize(diff, 1);
|
||||
|
||||
//
|
||||
// Search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(all,
|
||||
solver.CHOOSE_PATH,
|
||||
solver.ASSIGN_MIN_VALUE);
|
||||
solver.newSearch(db, obj);
|
||||
while (solver.nextSolution()) {
|
||||
System.out.println("" + x.value() + " - " +
|
||||
y.value() + " = " + diff.value());
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
LeastDiff.solve();
|
||||
}
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
|
||||
public class MagicSquare {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Solves the Magic Square problem.
|
||||
* See http://www.hakank.org/google_or_tools/magic_square.py
|
||||
*
|
||||
*/
|
||||
private static void solve(int n, int num) {
|
||||
|
||||
Solver solver = new Solver("MagicSquare");
|
||||
|
||||
System.out.println("n: " + n);
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
IntVar[][] x = new IntVar[n][n];
|
||||
|
||||
// for the branching
|
||||
IntVar[] x_flat = new IntVar[n*n];
|
||||
|
||||
//
|
||||
// constraints
|
||||
//
|
||||
final long s = (n * (n * n + 1)) / 2;
|
||||
System.out.println("s: " + s);
|
||||
// IntVar s = solver.makeIntVar(0, n*n*n, "s");
|
||||
|
||||
IntVar[] diag1 = new IntVar[n];
|
||||
IntVar[] diag2 = new IntVar[n];
|
||||
for(int i = 0; i < n; i++) {
|
||||
IntVar[] row = new IntVar[n];
|
||||
for(int j = 0; j < n; j++) {
|
||||
x[i][j] = solver.makeIntVar(1, n * n, "x[" + i + "," + j + "]");
|
||||
x_flat[i * n + j] = x[i][j];
|
||||
row[j] = x[i][j];
|
||||
}
|
||||
// sum row to s
|
||||
solver.addConstraint(solver.makeSumEquality(row, s));
|
||||
|
||||
diag1[i] = x[i][i];
|
||||
diag2[i] = x[i][n - i - 1];
|
||||
}
|
||||
// sum diagonals to s
|
||||
solver.addConstraint(solver.makeSumEquality(diag1, s));
|
||||
solver.addConstraint(solver.makeSumEquality(diag2, s));
|
||||
|
||||
// sum columns to s
|
||||
for(int j = 0; j < n; j++) {
|
||||
IntVar[] col = new IntVar[n];
|
||||
for(int i = 0; i < n; i++) {
|
||||
col[i] = x[i][j];
|
||||
}
|
||||
solver.addConstraint(solver.makeSumEquality(col, s));
|
||||
}
|
||||
|
||||
// all are different
|
||||
solver.addConstraint(solver.makeAllDifferent(x_flat));
|
||||
|
||||
// symmetry breaking: upper left is 1
|
||||
// solver.addConstraint(solver.makeEquality(x[0][0], 1));
|
||||
|
||||
|
||||
//
|
||||
// Solve
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(x_flat,
|
||||
solver.CHOOSE_FIRST_UNBOUND,
|
||||
solver.ASSIGN_CENTER_VALUE);
|
||||
solver.newSearch(db);
|
||||
int c = 0;
|
||||
while (solver.nextSolution()) {
|
||||
for(int i = 0; i < n; i++) {
|
||||
for(int j = 0; j < n; j++) {
|
||||
System.out.print(x[i][j].value() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
System.out.println();
|
||||
c++;
|
||||
if (num > 0 && c >= num) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
int n = 4;
|
||||
int num = 0;
|
||||
|
||||
if (args.length > 0) {
|
||||
n = Integer.parseInt(args[0]);
|
||||
}
|
||||
|
||||
if (args.length > 1) {
|
||||
num = Integer.parseInt(args[1]);
|
||||
}
|
||||
|
||||
MagicSquare.solve(n, num);
|
||||
}
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
import com.google.ortools.constraintsolver.*;
|
||||
|
||||
public class Map {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Solves a simple map coloring problem.
|
||||
* See http://www.hakank.org/google_or_tools/map.py
|
||||
*
|
||||
*/
|
||||
private static void solve() {
|
||||
|
||||
Solver solver = new Solver("Map");
|
||||
|
||||
//
|
||||
// data
|
||||
//
|
||||
int Belgium = 0;
|
||||
int Denmark = 1;
|
||||
int France = 2;
|
||||
int Germany = 3;
|
||||
int Netherlands = 4;
|
||||
int Luxembourg = 5;
|
||||
|
||||
int n = 6;
|
||||
int max_num_colors = 4;
|
||||
|
||||
//
|
||||
// Variables
|
||||
//
|
||||
IntVar[] color = solver.makeIntVarArray(n, 1, max_num_colors, "x");
|
||||
|
||||
//
|
||||
// Constraints
|
||||
//
|
||||
solver.addConstraint(solver.makeNonEquality(color[France],
|
||||
color[Belgium]));
|
||||
solver.addConstraint(solver.makeNonEquality(color[France],
|
||||
color[Luxembourg]));
|
||||
solver.addConstraint(solver.makeNonEquality(color[France],
|
||||
color[Germany]));
|
||||
solver.addConstraint(solver.makeNonEquality(color[Luxembourg],
|
||||
color[Germany]));
|
||||
solver.addConstraint(solver.makeNonEquality(color[Luxembourg],
|
||||
color[Belgium]));
|
||||
solver.addConstraint(solver.makeNonEquality(color[Belgium],
|
||||
color[Netherlands]));
|
||||
solver.addConstraint(solver.makeNonEquality(color[Belgium],
|
||||
color[Germany]));
|
||||
solver.addConstraint(solver.makeNonEquality(color[Germany],
|
||||
color[Netherlands]));
|
||||
solver.addConstraint(solver.makeNonEquality(color[Germany],
|
||||
color[Denmark]));
|
||||
|
||||
// Symmetry breaking
|
||||
solver.addConstraint(solver.makeEquality(color[Belgium], 1));
|
||||
|
||||
//
|
||||
// Search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(color,
|
||||
solver.CHOOSE_FIRST_UNBOUND,
|
||||
solver.ASSIGN_MIN_VALUE);
|
||||
solver.newSearch(db);
|
||||
|
||||
while (solver.nextSolution()) {
|
||||
System.out.print("Colors: ");
|
||||
for(int i = 0; i < n; i++) {
|
||||
System.out.print(color[i].value() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Map.solve();
|
||||
}
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
import com.google.ortools.constraintsolver.*;
|
||||
|
||||
public class Map2 {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Solves a simple map coloring problem, take II.
|
||||
* See http://www.hakank.org/google_or_tools/map.py
|
||||
*
|
||||
*/
|
||||
private static void solve() {
|
||||
|
||||
Solver solver = new Solver("Map2");
|
||||
|
||||
//
|
||||
// data
|
||||
//
|
||||
int Belgium = 0;
|
||||
int Denmark = 1;
|
||||
int France = 2;
|
||||
int Germany = 3;
|
||||
int Netherlands = 4;
|
||||
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}};
|
||||
|
||||
|
||||
//
|
||||
// Variables
|
||||
//
|
||||
IntVar[] color = solver.makeIntVarArray(n, 1, max_num_colors, "x");
|
||||
|
||||
//
|
||||
// Constraints
|
||||
//
|
||||
for(int i = 0; i < neighbours.length; i++) {
|
||||
solver.addConstraint(
|
||||
solver.makeNonEquality(color[neighbours[i][0]],
|
||||
color[neighbours[i][1]]));
|
||||
}
|
||||
|
||||
// Symmetry breaking
|
||||
solver.addConstraint(solver.makeEquality(color[Belgium], 1));
|
||||
|
||||
|
||||
//
|
||||
// Search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(color,
|
||||
solver.CHOOSE_FIRST_UNBOUND,
|
||||
solver.ASSIGN_MIN_VALUE);
|
||||
solver.newSearch(db);
|
||||
|
||||
while (solver.nextSolution()) {
|
||||
System.out.print("Colors: ");
|
||||
for(int i = 0; i < n; i++) {
|
||||
System.out.print(color[i].value() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Map2.solve();
|
||||
}
|
||||
}
|
||||
@@ -1,252 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
import com.google.ortools.constraintsolver.*;
|
||||
|
||||
public class Minesweeper {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
static int X = -1;
|
||||
|
||||
//
|
||||
// Default problem.
|
||||
// It has 4 solutions.
|
||||
//
|
||||
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}};
|
||||
|
||||
// for the actual problem
|
||||
static int r;
|
||||
static int c;
|
||||
static int[][] game;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Solves the Minesweeper problems.
|
||||
* See http://www.hakank.org/google_or_tools/minesweeper.py
|
||||
*
|
||||
*/
|
||||
private static void solve() {
|
||||
|
||||
Solver solver = new Solver("Minesweeper");
|
||||
|
||||
int[] S = {-1, 0, 1};
|
||||
|
||||
//
|
||||
// data
|
||||
//
|
||||
System.out.println("Problem:");
|
||||
for(int i = 0; i < r; i++) {
|
||||
for(int j = 0; j < c; j++) {
|
||||
if (game[i][j] > X) {
|
||||
System.out.print(game[i][j] + " ");
|
||||
} else {
|
||||
System.out.print("X ");
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
|
||||
//
|
||||
// Variables
|
||||
//
|
||||
IntVar[][] mines = new IntVar[r][c];
|
||||
IntVar[] mines_flat = new IntVar[r * c]; // for branching
|
||||
for(int i = 0; i < r; i++) {
|
||||
for(int j = 0; j < c; j++) {
|
||||
mines[i][j] = solver.makeIntVar(0, 1, "mines[" + i + ", " + j + "]");
|
||||
mines_flat[i * c + j] = mines[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Constraints
|
||||
//
|
||||
for(int i = 0; i < r; i++) {
|
||||
for(int j = 0; j < c; j++) {
|
||||
if (game[i][j] >= 0) {
|
||||
solver.addConstraint(
|
||||
solver.makeEquality(mines[i][j], 0));
|
||||
|
||||
// this cell is the sum of all its neighbours
|
||||
ArrayList<IntVar> neighbours = new ArrayList<IntVar>();
|
||||
for(int a: S) {
|
||||
for(int b: S) {
|
||||
if (i + a >= 0 &&
|
||||
j + b >= 0 &&
|
||||
i + a < r &&
|
||||
j + b < c) {
|
||||
neighbours.add(mines[i + a][j + b]);
|
||||
}
|
||||
}
|
||||
}
|
||||
solver.addConstraint(
|
||||
solver.makeSumEquality(
|
||||
neighbours.toArray(new IntVar[1]), game[i][j]));
|
||||
}
|
||||
|
||||
if (game[i][j] > X) {
|
||||
// This cell cannot be a mine since it
|
||||
// has some value assigned to it
|
||||
solver.addConstraint(
|
||||
solver.makeEquality(mines[i][j], 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(mines_flat,
|
||||
solver.INT_VAR_SIMPLE,
|
||||
solver.ASSIGN_MIN_VALUE);
|
||||
solver.newSearch(db);
|
||||
|
||||
int sol = 0;
|
||||
while (solver.nextSolution()) {
|
||||
sol++;
|
||||
System.out.println("Solution #" + sol + ":");
|
||||
for(int i = 0; i < r; i++) {
|
||||
for(int j = 0; j < c; j++) {
|
||||
System.out.print(mines[i][j].value() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Reads a minesweeper file.
|
||||
* File format:
|
||||
* # a comment which is ignored
|
||||
* % a comment which also is ignored
|
||||
* number of rows
|
||||
* number of columns
|
||||
* <
|
||||
* 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
|
||||
* 6
|
||||
* ..2.3.
|
||||
* 2.....
|
||||
* ..24.3
|
||||
* 1.34..
|
||||
* .....3
|
||||
* .3.3..
|
||||
*
|
||||
*/
|
||||
private static void readFile(String file) {
|
||||
|
||||
System.out.println("readFile(" + file + ")");
|
||||
int lineCount = 0;
|
||||
|
||||
try {
|
||||
|
||||
BufferedReader inr = new BufferedReader(new FileReader(file));
|
||||
String str;
|
||||
while ((str = inr.readLine()) != null && str.length() > 0) {
|
||||
|
||||
str = str.trim();
|
||||
|
||||
// ignore comments
|
||||
if(str.startsWith("#") || str.startsWith("%")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
System.out.println(str);
|
||||
if (lineCount == 0) {
|
||||
r = Integer.parseInt(str); // number of rows
|
||||
} else if (lineCount == 1) {
|
||||
c = Integer.parseInt(str); // number of columns
|
||||
game = new int[r][c];
|
||||
} else {
|
||||
// the problem matrix
|
||||
String row[] = str.split("");
|
||||
for(int j = 1; j <= c; j++) {
|
||||
String s = row[j];
|
||||
if (s.equals(".")) {
|
||||
game[lineCount-2][j-1] = -1;
|
||||
} else {
|
||||
game[lineCount-2][j-1] = Integer.parseInt(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lineCount++;
|
||||
|
||||
} // end while
|
||||
|
||||
inr.close();
|
||||
|
||||
} catch (IOException e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
|
||||
} // end readFile
|
||||
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
String file = "";
|
||||
if (args.length > 0) {
|
||||
file = args[0];
|
||||
Minesweeper.readFile(file);
|
||||
} else {
|
||||
game = default_game;
|
||||
r = default_r;
|
||||
c = default_c;
|
||||
}
|
||||
|
||||
Minesweeper.solve();
|
||||
}
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.google.ortools.linearsolver.MPConstraint;
|
||||
import com.google.ortools.linearsolver.MPObjective;
|
||||
import com.google.ortools.linearsolver.MPSolver;
|
||||
import com.google.ortools.linearsolver.MPSolver.OptimizationProblemType;
|
||||
import com.google.ortools.linearsolver.MPSolver.ResultStatus;
|
||||
import com.google.ortools.linearsolver.MPVariable;
|
||||
|
||||
|
||||
public class MultiThreadTest {
|
||||
|
||||
static { System.loadLibrary("jniortools"); }
|
||||
|
||||
private final static boolean verboseOutput = false; // To enable Cbc logging
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
launchProtocol(10, 8, true);
|
||||
System.out.println("Cbc multi thread test successful");
|
||||
return;
|
||||
}
|
||||
|
||||
public static void launchProtocol(int wholeLoopAttmpts, int threadPoolSize, boolean runInParallel) throws Exception {
|
||||
|
||||
for (int noAttmpt = 0; noAttmpt < wholeLoopAttmpts; noAttmpt++) {
|
||||
|
||||
System.out.println(String.format("Attempt %d", noAttmpt));
|
||||
|
||||
int maxThreads = threadPoolSize;
|
||||
|
||||
List<SolverThread> threadList = new ArrayList<SolverThread>();
|
||||
|
||||
for (int i = 0; i < maxThreads; i++) {
|
||||
SolverThread thread = new SolverThread();
|
||||
threadList.add(thread);
|
||||
}
|
||||
|
||||
ExecutorService executor = Executors.newFixedThreadPool(maxThreads);
|
||||
|
||||
if (runInParallel) {
|
||||
System.out.println("Launching thread pool");
|
||||
executor.invokeAll(threadList);
|
||||
for( SolverThread thread : threadList ) {
|
||||
System.out.println(thread.getStatusSolver().toString());
|
||||
}
|
||||
} else {
|
||||
|
||||
for (SolverThread thread : threadList) {
|
||||
System.out.println("Launching single thread");
|
||||
executor.invokeAll( Arrays.asList(thread) );
|
||||
System.out.println(thread.getStatusSolver().toString());
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Attempt finalized!");
|
||||
executor.shutdown();
|
||||
|
||||
}
|
||||
|
||||
System.out.println("Now exiting multi thread execution");
|
||||
|
||||
}
|
||||
|
||||
private static MPSolver makeProblem() {
|
||||
|
||||
MPSolver solver = new MPSolver(UUID.randomUUID().toString(), OptimizationProblemType.CBC_MIXED_INTEGER_PROGRAMMING);
|
||||
|
||||
double infinity = MPSolver.infinity();
|
||||
|
||||
// x1 and x2 are integer non-negative variables.
|
||||
MPVariable x1 = solver.makeIntVar(0.0, infinity, "x1");
|
||||
MPVariable x2 = solver.makeIntVar(0.0, infinity, "x2");
|
||||
|
||||
// Minimize x1 + 2 * x2.
|
||||
MPObjective objective = solver.objective();
|
||||
objective.setCoefficient(x1, 1);
|
||||
objective.setCoefficient(x2, 2);
|
||||
|
||||
// 2 * x2 + 3 * x1 >= 17.
|
||||
MPConstraint ct = solver.makeConstraint(17, infinity);
|
||||
ct.setCoefficient(x1, 3);
|
||||
ct.setCoefficient(x2, 2);
|
||||
|
||||
if (verboseOutput) {
|
||||
solver.enableOutput();
|
||||
}
|
||||
|
||||
return solver;
|
||||
|
||||
}
|
||||
|
||||
private final static class SolverThread implements Callable<MPSolver.ResultStatus> {
|
||||
|
||||
private MPSolver.ResultStatus statusSolver;
|
||||
|
||||
public SolverThread() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultStatus call() throws Exception {
|
||||
MPSolver solver = makeProblem();
|
||||
statusSolver = solver.solve();
|
||||
|
||||
// Check that the problem has an optimal solution.
|
||||
if ( MPSolver.ResultStatus.OPTIMAL.equals(statusSolver) ) {
|
||||
throw new RuntimeException("Non OPTIMAL status after solve.");
|
||||
}
|
||||
return statusSolver;
|
||||
|
||||
}
|
||||
|
||||
public MPSolver.ResultStatus getStatusSolver() {
|
||||
return statusSolver;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
|
||||
public class NQueens {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Solves the N Queens problem.
|
||||
* See http://www.hakank.org/google_or_tools/nqueens2.py
|
||||
*
|
||||
*/
|
||||
private static void solve(int n, int num, int print) {
|
||||
|
||||
Solver solver = new Solver("NQueens");
|
||||
|
||||
System.out.println("n: " + n);
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
IntVar[] q = solver.makeIntVarArray(n, 0, n-1, "q");
|
||||
|
||||
//
|
||||
// constraints
|
||||
//
|
||||
solver.addConstraint(solver.makeAllDifferent(q));
|
||||
|
||||
IntVar b = solver.makeIntVar(1, 1, "b");
|
||||
IntVar[] q1 = new IntVar[n];
|
||||
IntVar[] q2 = new IntVar[n];
|
||||
for(int i = 0; i < n; i++) {
|
||||
for(int j = 0; j < i; j++) {
|
||||
// // q[i]+i != q[j]+j
|
||||
solver.addConstraint(
|
||||
solver.makeNonEquality(
|
||||
solver.makeSum(q[i],i).var(),
|
||||
solver.makeSum(q[j],j).var()));
|
||||
|
||||
// q[i]-i != q[j]-j
|
||||
solver.addConstraint(
|
||||
solver.makeNonEquality(solver.makeSum(q[i],-i).var(),
|
||||
solver.makeSum(q[j],-j).var()));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Solve
|
||||
//
|
||||
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++) {
|
||||
System.out.print(q[i].value() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
c++;
|
||||
if (num > 0 && c >= num) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
int n = 8;
|
||||
int num = 0;
|
||||
int print = 1;
|
||||
|
||||
if (args.length > 0) {
|
||||
n = Integer.parseInt(args[0]);
|
||||
}
|
||||
|
||||
if (args.length > 1) {
|
||||
num = Integer.parseInt(args[1]);
|
||||
}
|
||||
|
||||
if (args.length > 2) {
|
||||
print = Integer.parseInt(args[2]);
|
||||
}
|
||||
|
||||
|
||||
NQueens.solve(n, num, print);
|
||||
}
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
|
||||
public class NQueens2 {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Solves the N Queens problem.
|
||||
* See http://www.hakank.org/google_or_tools/nqueens2.py
|
||||
*
|
||||
*/
|
||||
private static void solve(int n, int num, int print) {
|
||||
|
||||
Solver solver = new Solver("NQueens");
|
||||
|
||||
System.out.println("n: " + n);
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
IntVar[] q = solver.makeIntVarArray(n, 0, n-1, "q");
|
||||
|
||||
//
|
||||
// constraints
|
||||
//
|
||||
solver.addConstraint(solver.makeAllDifferent(q));
|
||||
|
||||
IntVar[] q1 = new IntVar[n];
|
||||
IntVar[] q2 = new IntVar[n];
|
||||
for(int i = 0; i < n; i++) {
|
||||
q1[i] = solver.makeSum(q[i], i).var();
|
||||
q2[i] = solver.makeSum(q[i], -i).var();
|
||||
}
|
||||
solver.addConstraint(solver.makeAllDifferent(q1));
|
||||
solver.addConstraint(solver.makeAllDifferent(q2));
|
||||
|
||||
//
|
||||
// Solve
|
||||
//
|
||||
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++) {
|
||||
System.out.print(q[i].value() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
c++;
|
||||
if (num > 0 && c >= num) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
int n = 8;
|
||||
int num = 0;
|
||||
int print = 1;
|
||||
|
||||
if (args.length > 0) {
|
||||
n = Integer.parseInt(args[0]);
|
||||
}
|
||||
|
||||
if (args.length > 1) {
|
||||
num = Integer.parseInt(args[1]);
|
||||
}
|
||||
|
||||
if (args.length > 2) {
|
||||
print = Integer.parseInt(args[2]);
|
||||
}
|
||||
|
||||
|
||||
NQueens2.solve(n, num, print);
|
||||
}
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 1999-2011, Ecole des Mines de Nantes
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the Ecole des Mines de Nantes nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
import com.google.ortools.constraintsolver.*;
|
||||
|
||||
/**
|
||||
* Partition n numbers into two groups, so that
|
||||
* - the sum of the first group equals the sum of the second,
|
||||
* - and the sum of the squares of the first group equals the sum of
|
||||
* the squares of the second
|
||||
* <br/>
|
||||
*
|
||||
* @author Charles Prud'homme
|
||||
* @since 18/03/11
|
||||
*/
|
||||
public class Partition {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Partition Problem.
|
||||
*/
|
||||
private static void solve(int m) {
|
||||
Solver solver = new Solver("Partition " + m);
|
||||
|
||||
IntVar[] x, y;
|
||||
x = solver.makeIntVarArray(m, 1, 2 * m, "x");
|
||||
y = solver.makeIntVarArray(m, 1, 2 * m, "y");
|
||||
|
||||
// break symmetries
|
||||
for (int i = 0; i < m - 1; i++) {
|
||||
solver.addConstraint(solver.makeLess(x[i], x[i + 1]));
|
||||
solver.addConstraint(solver.makeLess(y[i], y[i + 1]));
|
||||
}
|
||||
solver.addConstraint(solver.makeLess(x[0], y[0]));
|
||||
|
||||
IntVar[] xy = new IntVar[2 * m];
|
||||
for (int i = m - 1; i >= 0; i--) {
|
||||
xy[i] = x[i];
|
||||
xy[m + i] = y[i];
|
||||
}
|
||||
|
||||
solver.addConstraint(solver.makeAllDifferent(xy));
|
||||
|
||||
int[] coeffs = new int[2 * m];
|
||||
for (int i = m - 1; i >= 0; i--) {
|
||||
coeffs[i] = 1;
|
||||
coeffs[m + i] = -1;
|
||||
}
|
||||
solver.addConstraint(solver.makeScalProdEquality(xy, coeffs, 0));
|
||||
|
||||
IntVar[] sxy, sx, sy;
|
||||
sxy = new IntVar[2 * m];
|
||||
sx = new IntVar[m];
|
||||
sy = new IntVar[m];
|
||||
for (int i = m - 1; i >= 0; i--) {
|
||||
sx[i] = solver.makeSquare(x[i]).var();
|
||||
sxy[i] = sx[i];
|
||||
sy[i] = solver.makeSquare(y[i]).var();
|
||||
sxy[m + i] = sy[i];
|
||||
}
|
||||
solver.addConstraint(solver.makeScalProdEquality(sxy, coeffs, 0));
|
||||
|
||||
solver.addConstraint(
|
||||
solver.makeSumEquality(x, 2 * m * (2 * m + 1) / 4));
|
||||
solver.addConstraint(
|
||||
solver.makeSumEquality(y, 2 * m * (2 * m + 1) / 4));
|
||||
solver.addConstraint(
|
||||
solver.makeSumEquality(sx, 2 * m * (2 * m + 1) * (4 * m + 1) / 12));
|
||||
solver.addConstraint(
|
||||
solver.makeSumEquality(sy, 2 * m * (2 * m + 1) * (4 * m + 1) / 12));
|
||||
|
||||
DecisionBuilder db = solver.makeDefaultPhase(xy);
|
||||
SolutionCollector collector = solver.makeFirstSolutionCollector();
|
||||
collector.add(xy);
|
||||
SearchMonitor log = solver.makeSearchLog(10000);
|
||||
solver.newSearch(db, log, collector);
|
||||
solver.nextSolution();
|
||||
System.out.println("Solution solution");
|
||||
for (int i = 0; i < m; ++i) {
|
||||
System.out.print("[" + collector.value(0, xy[i]) + "] ");
|
||||
}
|
||||
System.out.printf("\n");
|
||||
for (int i = 0; i < m; ++i) {
|
||||
System.out.print("[" + collector.value(0, xy[m+i]) + "] ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Partition.solve(32);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,239 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
import com.google.ortools.constraintsolver.*;
|
||||
|
||||
public class QuasigroupCompletion {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
static int X = 0;
|
||||
|
||||
/*
|
||||
* default problem
|
||||
*
|
||||
* Example from Ruben Martins and Ines Lynce
|
||||
* Breaking Local Symmetries in Quasigroup Completion Problems, page 3
|
||||
* The solution is unique:
|
||||
*
|
||||
* 1 3 2 5 4
|
||||
* 2 5 4 1 3
|
||||
* 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}};
|
||||
|
||||
|
||||
// for the actual problem
|
||||
static int n;
|
||||
static int[][] problem;
|
||||
|
||||
|
||||
/**
|
||||
* Solves the Quasigroup Completion problem.
|
||||
* See http://www.hakank.org/google_or_tools/quasigroup_completion.py
|
||||
*/
|
||||
private static void solve() {
|
||||
|
||||
Solver solver = new Solver("QuasigroupCompletion");
|
||||
|
||||
//
|
||||
// data
|
||||
//
|
||||
System.out.println("Problem:");
|
||||
for(int i = 0; i < n; i++) {
|
||||
for(int j = 0; j < n; j++) {
|
||||
System.out.print(problem[i][j] + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
|
||||
//
|
||||
// Variables
|
||||
//
|
||||
IntVar[][] x = new IntVar[n][n];
|
||||
IntVar[] x_flat = new IntVar[n * n]; // for branching
|
||||
for(int i = 0; i < n; i++) {
|
||||
for(int j = 0; j < n; j++) {
|
||||
x[i][j] = solver.makeIntVar(1, n, "x[" + i + "," + j + "]");
|
||||
x_flat[i * n + j] = x[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Constraints
|
||||
//
|
||||
for(int i = 0; i < n; i++) {
|
||||
for(int j = 0; j < n; j++) {
|
||||
if (problem[i][j] > X) {
|
||||
solver.addConstraint(solver.makeEquality(x[i][j], problem[i][j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// rows and columns must be different
|
||||
//
|
||||
|
||||
// rows
|
||||
for(int i = 0; i < n; i++) {
|
||||
IntVar[] row = new IntVar[n];
|
||||
for(int j = 0; j < n; j++) {
|
||||
row[j] = x[i][j];
|
||||
}
|
||||
solver.addConstraint(
|
||||
solver.makeAllDifferent(row));
|
||||
|
||||
}
|
||||
|
||||
// columns
|
||||
for(int j = 0; j < n; j++) {
|
||||
IntVar[] col = new IntVar[n];
|
||||
for(int i = 0; i < n; i++) {
|
||||
col[i] = x[i][j];
|
||||
}
|
||||
solver.addConstraint(solver.makeAllDifferent(col));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(x_flat,
|
||||
solver.INT_VAR_SIMPLE,
|
||||
solver.ASSIGN_MIN_VALUE);
|
||||
solver.newSearch(db);
|
||||
|
||||
int sol = 0;
|
||||
while (solver.nextSolution()) {
|
||||
sol++;
|
||||
System.out.println("Solution #" + sol + ":");
|
||||
for(int i = 0; i < n; i++) {
|
||||
for(int j = 0; j < n; j++) {
|
||||
System.out.print(x[i][j].value() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a Quasigroup completion file.
|
||||
* File format:
|
||||
* # a comment which is ignored
|
||||
* % a comment which also is ignored
|
||||
* number of rows (n)
|
||||
* <
|
||||
* row number of space separated entries
|
||||
* >
|
||||
*
|
||||
* "." or "0" means unknown, integer 1..n means known value
|
||||
*
|
||||
* Example
|
||||
* 5
|
||||
* 1 . . . 4
|
||||
* . 5 . . .
|
||||
* 4 . . 2 .
|
||||
* . 4 . . .
|
||||
* . . 5 . 1
|
||||
*
|
||||
*/
|
||||
private static void readFile(String file) {
|
||||
|
||||
System.out.println("readFile(" + file + ")");
|
||||
int lineCount = 0;
|
||||
|
||||
try {
|
||||
|
||||
BufferedReader inr = new BufferedReader(new FileReader(file));
|
||||
String str;
|
||||
while ((str = inr.readLine()) != null && str.length() > 0) {
|
||||
|
||||
str = str.trim();
|
||||
|
||||
// ignore comments
|
||||
if(str.startsWith("#") || str.startsWith("%")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
System.out.println(str);
|
||||
if (lineCount == 0) {
|
||||
n = Integer.parseInt(str); // number of rows
|
||||
problem = new int[n][n];
|
||||
} else {
|
||||
// the problem matrix
|
||||
String row[] = str.split(" ");
|
||||
for(int i = 0; i < n; i++) {
|
||||
String s = row[i];
|
||||
if (s.equals(".")) {
|
||||
problem[lineCount - 1][i] = 0;
|
||||
} else {
|
||||
problem[lineCount - 1][i] = Integer.parseInt(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lineCount++;
|
||||
|
||||
} // end while
|
||||
|
||||
inr.close();
|
||||
|
||||
} catch (IOException e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
|
||||
} // end readFile
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
if (args.length > 0) {
|
||||
String file = "";
|
||||
file = args[0];
|
||||
QuasigroupCompletion.readFile(file);
|
||||
} else {
|
||||
problem = default_problem;
|
||||
n = default_n;
|
||||
}
|
||||
|
||||
QuasigroupCompletion.solve();
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
|
||||
public class SendMoreMoney {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Solves the SEND+MORE=MONEY problem.
|
||||
*
|
||||
*/
|
||||
private static void solve() {
|
||||
int base = 10;
|
||||
|
||||
Solver solver = new Solver("SendMoreMoney");
|
||||
IntVar s = solver.makeIntVar(0, base - 1, "s");
|
||||
IntVar e = solver.makeIntVar(0, base - 1, "e");
|
||||
IntVar n = solver.makeIntVar(0, base - 1, "n");
|
||||
IntVar d = solver.makeIntVar(0, base - 1, "d");
|
||||
IntVar m = solver.makeIntVar(0, base - 1, "m");
|
||||
IntVar o = solver.makeIntVar(0, base - 1, "o");
|
||||
IntVar r = solver.makeIntVar(0, base - 1, "r");
|
||||
IntVar y = solver.makeIntVar(0, base - 1, "y");
|
||||
|
||||
IntVar[] x = {s,e,n,d,m,o,r,y};
|
||||
|
||||
IntVar[] eq = {s,e,n,d, m,o,r,e, m,o,n,e,y};
|
||||
int[] coeffs = {1000, 100, 10, 1, // S E N D +
|
||||
1000, 100, 10, 1, // M O R E
|
||||
-10000, -1000, -100, -10, -1 // == M O N E Y
|
||||
};
|
||||
solver.addConstraint(solver.makeScalProdEquality(eq, coeffs, 0));
|
||||
|
||||
// alternative:
|
||||
solver.addConstraint(
|
||||
solver.makeScalProdEquality(new IntVar[] {s,e,n,d, m,o,r,e, m,o,n,e,y},
|
||||
coeffs, 0));
|
||||
|
||||
// s > 0
|
||||
solver.addConstraint(solver.makeGreater(s, 0));
|
||||
// m > 0
|
||||
solver.addConstraint(solver.makeGreater(m, 0));
|
||||
|
||||
solver.addConstraint(solver.makeAllDifferent(x));
|
||||
|
||||
DecisionBuilder db = solver.makePhase(x,
|
||||
solver.INT_VAR_DEFAULT,
|
||||
solver.INT_VALUE_DEFAULT);
|
||||
solver.newSearch(db);
|
||||
while (solver.nextSolution()) {
|
||||
for(int i = 0; i < 8; i++) {
|
||||
System.out.print(x[i].toString() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SendMoreMoney.solve();
|
||||
}
|
||||
}
|
||||
@@ -1,214 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.*;
|
||||
|
||||
public class SendMoreMoney2 {
|
||||
|
||||
static Solver sol;
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
//
|
||||
// Some helper methods
|
||||
//
|
||||
static IntExpr p(IntExpr a, int b, IntExpr c) {
|
||||
return sol.makeSum(sol.makeProd(a, b), c);
|
||||
}
|
||||
|
||||
static IntExpr p(IntVar a, int b) {
|
||||
return sol.makeProd(a, b);
|
||||
}
|
||||
|
||||
// a slighly more intelligent scalar product
|
||||
static IntExpr sp(IntVar[] a) {
|
||||
int len = a.length;
|
||||
int c = 1;
|
||||
int[] t = new int[len];
|
||||
for(int i = len-1; i >= 0; i--) {
|
||||
t[i] = c;
|
||||
c *= 10;
|
||||
}
|
||||
return sol.makeScalProd(a, t);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Solves the SEND+MORE=MONEY problem with different approaches.
|
||||
*
|
||||
*/
|
||||
private static void solve(int alt) {
|
||||
|
||||
sol = new Solver("SendMoreMoney");
|
||||
|
||||
int base = 10;
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
IntVar s = sol.makeIntVar(0, base - 1, "s");
|
||||
IntVar e = sol.makeIntVar(0, base - 1, "e");
|
||||
IntVar n = sol.makeIntVar(0, base - 1, "n");
|
||||
IntVar d = sol.makeIntVar(0, base - 1, "d");
|
||||
IntVar m = sol.makeIntVar(0, base - 1, "m");
|
||||
IntVar o = sol.makeIntVar(0, base - 1, "o");
|
||||
IntVar r = sol.makeIntVar(0, base - 1, "r");
|
||||
IntVar y = sol.makeIntVar(0, base - 1, "y");
|
||||
|
||||
IntVar[] x = {s, e, n, d, m, o, r, y};
|
||||
|
||||
//
|
||||
// Constraints
|
||||
//
|
||||
|
||||
/*
|
||||
*
|
||||
* Below are some alternatives encodings of the
|
||||
* same idea:
|
||||
*
|
||||
* 1000*s + 100*e + 10*n + d +
|
||||
* 1000*m + 100*o + 10*r + e ==
|
||||
* 10000*m + 1000*o + 100*n + 10*e + y
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
if (alt == 0) {
|
||||
//
|
||||
// First, a version approach which is just too noisy.
|
||||
//
|
||||
sol.addConstraint(
|
||||
sol.makeEquality(
|
||||
sol.makeSum(sol.makeSum(
|
||||
sol.makeProd(s, 1000),
|
||||
sol.makeSum(sol.makeProd(e, 100),
|
||||
sol.makeSum(sol.makeProd(n, 10),
|
||||
sol.makeProd(d, 1)))),
|
||||
sol.makeSum(
|
||||
sol.makeProd(m, 1000),
|
||||
sol.makeSum(sol.makeProd(o, 100),
|
||||
sol.makeSum(sol.makeProd(r, 10),
|
||||
sol.makeProd(e, 1))))
|
||||
).var(),
|
||||
sol.makeSum(sol.makeProd(m, 10000),
|
||||
sol.makeSum(
|
||||
sol.makeProd(o, 1000),
|
||||
sol.makeSum(
|
||||
sol.makeProd(n, 100),
|
||||
sol.makeSum(
|
||||
sol.makeProd(e, 10),
|
||||
sol.makeProd(y, 1))))).var()));
|
||||
|
||||
} else if (alt == 1) {
|
||||
|
||||
//
|
||||
// Alternative 1, using the helper methods
|
||||
//
|
||||
// p(IntExpr, int, IntExpr) and
|
||||
// p(IntVar, int)
|
||||
//
|
||||
sol.addConstraint(
|
||||
sol.makeEquality(
|
||||
sol.makeSum(p(s, 1000, p(e, 100, p(n, 10, p(d, 1)))),
|
||||
p(m, 1000, p(o, 100, p(r, 10, p(e, 1))))).var(),
|
||||
p(m, 10000, p(o, 1000, p(n, 100, p(e, 10, p(y, 1))))).var()));
|
||||
|
||||
} else if (alt == 2) {
|
||||
|
||||
//
|
||||
// Alternative 2
|
||||
//
|
||||
sol.addConstraint(
|
||||
sol.makeEquality(
|
||||
sol.makeSum(
|
||||
sol.makeScalProd(new IntVar[] {s, e, n, d},
|
||||
new int[] {1000, 100, 10, 1}),
|
||||
sol.makeScalProd(new IntVar[] {m, o, r, e},
|
||||
new int[] {1000, 100, 10, 1})).var(),
|
||||
sol.makeScalProd(new IntVar[] {m, o, n, e, y},
|
||||
new int[] {10000, 1000, 100, 10, 1}).var()));
|
||||
|
||||
} else if (alt == 3) {
|
||||
|
||||
|
||||
//
|
||||
// alternative 3: same approach as 2, with some helper methods
|
||||
//
|
||||
sol.addConstraint(
|
||||
sol.makeEquality(sol.makeSum(sp(new IntVar[] {s, e, n, d}),
|
||||
sp(new IntVar[] {m, o, r, e})).var(),
|
||||
sp(new IntVar[] {m, o, n, e, y}).var()));
|
||||
|
||||
} else if (alt == 4) {
|
||||
|
||||
//
|
||||
// Alternative 4, using explicit variables
|
||||
//
|
||||
IntExpr send = sol.makeScalProd(new IntVar[] {s, e, n, d},
|
||||
new int[] {1000, 100, 10, 1});
|
||||
IntExpr more = sol.makeScalProd(new IntVar[] {m, o, r, e},
|
||||
new int[] {1000, 100, 10, 1});
|
||||
IntExpr money = sol.makeScalProd(new IntVar[] {m, o, n, e, y},
|
||||
new int[] {10000, 1000, 100, 10, 1});
|
||||
sol.addConstraint(
|
||||
sol.makeEquality(sol.makeSum(send, more).var(), money.var()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
// s > 0
|
||||
sol.addConstraint(sol.makeGreater(s, 0));
|
||||
// m > 0
|
||||
sol.addConstraint(sol.makeGreater(m, 0));
|
||||
|
||||
sol.addConstraint(sol.makeAllDifferent(x));
|
||||
|
||||
//
|
||||
// Search
|
||||
//
|
||||
DecisionBuilder db = sol.makePhase(x,
|
||||
sol.INT_VAR_DEFAULT,
|
||||
sol.INT_VALUE_DEFAULT);
|
||||
sol.newSearch(db);
|
||||
while (sol.nextSolution()) {
|
||||
for(int i = 0; i < 8; i++) {
|
||||
System.out.print(x[i].toString() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
sol.endSearch();
|
||||
|
||||
//
|
||||
// Statistics
|
||||
//
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + sol.solutions());
|
||||
System.out.println("Failures: " + sol.failures());
|
||||
System.out.println("Branches: " + sol.branches());
|
||||
System.out.println("Wall time: " + sol.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
System.out.println("\nalternative #" + i);
|
||||
SendMoreMoney2.solve(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
import com.google.ortools.constraintsolver.*;
|
||||
|
||||
public class SendMostMoney {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Solves the SEND+MOST=MONEY problem, where
|
||||
* we maximize MONEY.
|
||||
* See http://www.hakank.org/google_or_tools/send_more_money.py
|
||||
*
|
||||
*/
|
||||
private static long solve(long MONEY) {
|
||||
|
||||
Solver solver = new Solver("SendMostMoney");
|
||||
|
||||
|
||||
//
|
||||
// data
|
||||
//
|
||||
final int base = 10;
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
IntVar s = solver.makeIntVar(0, base - 1, "s");
|
||||
IntVar e = solver.makeIntVar(0, base - 1, "e");
|
||||
IntVar n = solver.makeIntVar(0, base - 1, "n");
|
||||
IntVar d = solver.makeIntVar(0, base - 1, "d");
|
||||
IntVar m = solver.makeIntVar(0, base - 1, "m");
|
||||
IntVar o = solver.makeIntVar(0, base - 1, "o");
|
||||
IntVar t = solver.makeIntVar(0, base - 1, "t");
|
||||
IntVar y = solver.makeIntVar(0, base - 1, "y");
|
||||
|
||||
IntVar[] x = {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
|
||||
};
|
||||
solver.addConstraint(solver.makeScalProdEquality(eq, coeffs, 0));
|
||||
|
||||
IntVar money = solver.makeScalProd(new IntVar[] {m, o, n, e, y},
|
||||
new int[] {10000, 1000, 100, 10, 1}).var();
|
||||
|
||||
//
|
||||
// constraints
|
||||
//
|
||||
|
||||
// s > 0
|
||||
solver.addConstraint(solver.makeGreater(s, 0));
|
||||
// m > 0
|
||||
solver.addConstraint(solver.makeGreater(m, 0));
|
||||
|
||||
solver.addConstraint(solver.makeAllDifferent(x));
|
||||
|
||||
if (MONEY > 0) {
|
||||
// Search for all solutions.
|
||||
solver.addConstraint(solver.makeEquality(money, MONEY));
|
||||
}
|
||||
|
||||
//
|
||||
// search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(x,
|
||||
solver.CHOOSE_FIRST_UNBOUND,
|
||||
solver.ASSIGN_MAX_VALUE);
|
||||
|
||||
if (MONEY == 0) {
|
||||
// first round: get the optimal value
|
||||
OptimizeVar obj = solver.makeMaximize(money, 1);
|
||||
solver.newSearch(db, obj);
|
||||
} else {
|
||||
// search for all solutions
|
||||
solver.newSearch(db);
|
||||
}
|
||||
|
||||
long money_ret = 0;
|
||||
while (solver.nextSolution()) {
|
||||
System.out.println("money: " + money.value());
|
||||
money_ret = money.value();
|
||||
for(int i = 0; i < x.length; i++) {
|
||||
System.out.print(x[i].value() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
return money_ret;
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println("Get the max value of money:");
|
||||
long this_money = SendMostMoney.solve(0);
|
||||
System.out.println("\nThen find all solutions with this value:");
|
||||
long tmp = SendMostMoney.solve(this_money);
|
||||
}
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
|
||||
public class Seseman {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Solves the Seseman convent problem.
|
||||
* See http://www.hakank.org/google_or_tools/seseman.py
|
||||
*
|
||||
*/
|
||||
private static void solve(int n) {
|
||||
|
||||
Solver solver = new Solver("Seseman");
|
||||
|
||||
//
|
||||
// data
|
||||
//
|
||||
final int border_sum = n * n;
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
IntVar[][] x = new IntVar[n][n];
|
||||
IntVar[] x_flat = new IntVar[n * n];
|
||||
for(int i = 0; i < n; i++) {
|
||||
for(int j = 0; j < n; j++) {
|
||||
x[i][j] = solver.makeIntVar(0, n * n);
|
||||
x_flat[i * n + j] = x[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
IntVar total_sum = solver.makeSum(x_flat).var();
|
||||
|
||||
|
||||
//
|
||||
// constraints
|
||||
//
|
||||
|
||||
// zero in all middle cells
|
||||
for(int i = 1; i < n-1; i++) {
|
||||
for(int j = 1; j < n-1; j++) {
|
||||
solver.addConstraint(solver.makeEquality(x[i][j], 0));
|
||||
}
|
||||
}
|
||||
|
||||
// all borders must be >= 1
|
||||
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.addConstraint(solver.makeGreaterOrEqual(x[i][j], 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sum the four borders
|
||||
IntVar[] border1 = new IntVar[n];
|
||||
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];
|
||||
}
|
||||
solver.addConstraint(
|
||||
solver.makeSumEquality(border1, border_sum));
|
||||
|
||||
solver.addConstraint(
|
||||
solver.makeSumEquality(border2, border_sum));
|
||||
|
||||
solver.addConstraint(
|
||||
solver.makeSumEquality(border3, border_sum));
|
||||
|
||||
solver.addConstraint(
|
||||
solver.makeSumEquality(border4, border_sum));
|
||||
|
||||
|
||||
//
|
||||
// search
|
||||
//
|
||||
|
||||
DecisionBuilder db = solver.makePhase(x_flat,
|
||||
solver.INT_VAR_DEFAULT,
|
||||
solver.INT_VALUE_DEFAULT);
|
||||
solver.newSearch(db);
|
||||
|
||||
while (solver.nextSolution()) {
|
||||
System.out.println("total_sum: " + total_sum.value());
|
||||
for(int i = 0; i < n; i++) {
|
||||
for(int j = 0; j < n; j++) {
|
||||
System.out.print(x[i][j].value() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
int n = 3;
|
||||
if (args.length > 0) {
|
||||
n = Integer.parseInt(args[0]);
|
||||
}
|
||||
Seseman.solve(n);
|
||||
}
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
import com.google.ortools.constraintsolver.OptimizeVar;
|
||||
|
||||
public class SetCovering {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Solves a set covering problem.
|
||||
* See http://www.hakank.org/google_or_tools/set_covering.py
|
||||
*
|
||||
*/
|
||||
private static void solve() {
|
||||
|
||||
Solver solver = new Solver("SetCovering");
|
||||
|
||||
//
|
||||
// data
|
||||
//
|
||||
// Placing of firestations, from Winston 'Operations Research',
|
||||
// page 486.
|
||||
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}};
|
||||
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
IntVar[] x = solver.makeIntVarArray(num_cities, 0, 1, "x");
|
||||
IntVar z = solver.makeSum(x).var();
|
||||
|
||||
|
||||
//
|
||||
// constraints
|
||||
//
|
||||
|
||||
// ensure that all cities are covered
|
||||
for(int i = 0; i < num_cities; i++) {
|
||||
ArrayList<IntVar> b = new ArrayList<IntVar>();
|
||||
for(int j = 0; j < num_cities; j++) {
|
||||
if (distance[i][j] <= min_distance) {
|
||||
b.add(x[j]);
|
||||
}
|
||||
}
|
||||
solver.addConstraint(
|
||||
solver.makeSumGreaterOrEqual(b.toArray(new IntVar[1]), 1));
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// objective
|
||||
//
|
||||
OptimizeVar objective = solver.makeMinimize(z, 1);
|
||||
|
||||
|
||||
//
|
||||
// search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(x,
|
||||
solver.INT_VAR_DEFAULT,
|
||||
solver.INT_VALUE_DEFAULT);
|
||||
solver.newSearch(db, objective);
|
||||
|
||||
//
|
||||
// output
|
||||
//
|
||||
while (solver.nextSolution()) {
|
||||
System.out.println("z: " + z.value());
|
||||
System.out.print("x: ");
|
||||
for(int i = 0; i < num_cities; i++) {
|
||||
System.out.print(x[i].value() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SetCovering.solve();
|
||||
}
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
import com.google.ortools.constraintsolver.OptimizeVar;
|
||||
|
||||
public class SetCovering2 {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Solves a set covering problem.
|
||||
* See http://www.hakank.org/google_or_tools/set_covering2.py
|
||||
*
|
||||
*/
|
||||
private static void solve() {
|
||||
|
||||
Solver solver = new Solver("SetCovering2");
|
||||
|
||||
//
|
||||
// data
|
||||
//
|
||||
|
||||
// Example 9.1-2 from
|
||||
// Taha "Operations Research - An Introduction",
|
||||
// page 354ff.
|
||||
// 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
|
||||
|
||||
// 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}};
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
IntVar[] x = solver.makeIntVarArray(n, 0, 1, "x");
|
||||
|
||||
// number of telephones, to be minimize
|
||||
IntVar z = solver.makeSum(x).var();
|
||||
|
||||
//
|
||||
// constraints
|
||||
//
|
||||
|
||||
// ensure that all cities are covered
|
||||
for(int i = 0; i < num_streets; i++) {
|
||||
IntVar[] b = new IntVar[2];
|
||||
b[0] = x[corner[i][0] - 1];
|
||||
b[1] = x[corner[i][1] - 1];
|
||||
solver.addConstraint(
|
||||
solver.makeSumGreaterOrEqual(b, 1));
|
||||
}
|
||||
|
||||
//
|
||||
// objective
|
||||
//
|
||||
OptimizeVar objective = solver.makeMinimize(z, 1);
|
||||
|
||||
|
||||
//
|
||||
// search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(x,
|
||||
solver.INT_VAR_DEFAULT,
|
||||
solver.INT_VALUE_DEFAULT);
|
||||
solver.newSearch(db, objective);
|
||||
|
||||
//
|
||||
// output
|
||||
//
|
||||
while (solver.nextSolution()) {
|
||||
System.out.println("z: " + z.value());
|
||||
System.out.print("x: ");
|
||||
for(int i = 0; i < n; i++) {
|
||||
System.out.print(x[i].value() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SetCovering2.solve();
|
||||
}
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
import com.google.ortools.constraintsolver.OptimizeVar;
|
||||
|
||||
public class SetCovering3 {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Solves a set covering problem.
|
||||
* See http://www.hakank.org/google_or_tools/set_covering3.py
|
||||
*
|
||||
*/
|
||||
private static void solve() {
|
||||
|
||||
Solver solver = new Solver("SetCovering3");
|
||||
|
||||
//
|
||||
// data
|
||||
//
|
||||
|
||||
// Set covering problem from
|
||||
// Katta G. Murty: 'Optimization Models for Decision Making',
|
||||
// page 302f
|
||||
// http://ioe.engin.umich.edu/people/fac/books/murty/opti_model/junior-7.pdf
|
||||
int num_groups = 6;
|
||||
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
|
||||
{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
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
IntVar[] x = solver.makeIntVarArray(num_senators, 0, 1, "x");
|
||||
|
||||
// number of assigned senators, to be minimize
|
||||
IntVar z = solver.makeSum(x).var();
|
||||
|
||||
//
|
||||
// constraints
|
||||
//
|
||||
|
||||
|
||||
// ensure that each group is covered by at least
|
||||
// one senator
|
||||
for(int i = 0; i < num_groups; i++) {
|
||||
IntVar[] b = new IntVar[num_senators];
|
||||
for(int j = 0; j < num_senators; j++) {
|
||||
b[j] = solver.makeProd(x[j], belongs[i][j]).var();
|
||||
}
|
||||
solver.addConstraint(
|
||||
solver.makeSumGreaterOrEqual(b, 1));
|
||||
}
|
||||
|
||||
//
|
||||
// objective
|
||||
//
|
||||
OptimizeVar objective = solver.makeMinimize(z, 1);
|
||||
|
||||
|
||||
//
|
||||
// search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(x,
|
||||
solver.INT_VAR_DEFAULT,
|
||||
solver.INT_VALUE_DEFAULT);
|
||||
solver.newSearch(db, objective);
|
||||
|
||||
//
|
||||
// output
|
||||
//
|
||||
while (solver.nextSolution()) {
|
||||
System.out.println("z: " + z.value());
|
||||
System.out.print("x: ");
|
||||
for(int j = 0; j < num_senators; j++) {
|
||||
System.out.print(x[j].value() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
// More details
|
||||
for(int j = 0; j < num_senators; j++) {
|
||||
if (x[j].value() == 1) {
|
||||
System.out.print("Senator " + (1 + j) +
|
||||
" belongs to these groups: ");
|
||||
for(int i = 0; i < num_groups; i++) {
|
||||
if (belongs[i][j] == 1) {
|
||||
System.out.print((1 + i) + " ");
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SetCovering3.solve();
|
||||
}
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
import com.google.ortools.constraintsolver.OptimizeVar;
|
||||
|
||||
public class SetCovering4 {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Solves a set covering problem.
|
||||
* See http://www.hakank.org/google_or_tools/set_covering4.py
|
||||
*
|
||||
*/
|
||||
private static void solve(int set_partition) {
|
||||
|
||||
Solver solver = new Solver("SetCovering4");
|
||||
|
||||
//
|
||||
// data
|
||||
//
|
||||
|
||||
|
||||
// Set partition and set covering problem from
|
||||
// Example from the Swedish book
|
||||
// Lundgren, Roennqvist, Vaebrand
|
||||
// 'Optimeringslaera' (translation: 'Optimization theory'),
|
||||
// page 408.
|
||||
int num_alternatives = 10;
|
||||
int num_objects = 8;
|
||||
|
||||
// costs for the alternatives
|
||||
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
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
IntVar[] x = solver.makeIntVarArray(num_alternatives, 0, 1, "x");
|
||||
|
||||
// number of assigned senators, to be minimize
|
||||
IntVar z = solver.makeScalProd(x, costs).var();
|
||||
|
||||
//
|
||||
// constraints
|
||||
//
|
||||
|
||||
|
||||
for(int j = 0; j < num_objects; j++) {
|
||||
IntVar[] b = new IntVar[num_alternatives];
|
||||
for(int i = 0; i < num_alternatives; i++) {
|
||||
b[i] = solver.makeProd(x[i], a[i][j]).var();
|
||||
}
|
||||
|
||||
if (set_partition == 1) {
|
||||
solver.addConstraint(
|
||||
solver.makeSumGreaterOrEqual(b, 1));
|
||||
} else {
|
||||
solver.addConstraint(
|
||||
solver.makeSumEquality(b, 1));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// objective
|
||||
//
|
||||
OptimizeVar objective = solver.makeMinimize(z, 1);
|
||||
|
||||
|
||||
//
|
||||
// search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(x,
|
||||
solver.INT_VAR_DEFAULT,
|
||||
solver.INT_VALUE_DEFAULT);
|
||||
solver.newSearch(db, objective);
|
||||
|
||||
//
|
||||
// output
|
||||
//
|
||||
while (solver.nextSolution()) {
|
||||
System.out.println("z: " + z.value());
|
||||
System.out.print("Selected alternatives: ");
|
||||
for(int i = 0; i < num_alternatives; i++) {
|
||||
if (x[i].value() == 1) {
|
||||
System.out.print((1 + i) + " ");
|
||||
}
|
||||
}
|
||||
System.out.println("\n");
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println("Set partition:");
|
||||
SetCovering4.solve(1);
|
||||
System.out.println("\nSet covering:");
|
||||
SetCovering4.solve(0);
|
||||
}
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
import com.google.ortools.constraintsolver.OptimizeVar;
|
||||
|
||||
public class SetCoveringDeployment {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Solves a set covering deployment problem.
|
||||
* See http://www.hakank.org/google_or_tools/set_covering_deployment.py
|
||||
*
|
||||
*/
|
||||
private static void solve() {
|
||||
|
||||
Solver solver = new Solver("SetCoveringDeployment");
|
||||
|
||||
//
|
||||
// data
|
||||
//
|
||||
|
||||
// From http://mathworld.wolfram.com/SetCoveringDeployment.html
|
||||
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}};
|
||||
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
|
||||
// First army
|
||||
IntVar[] x = solver.makeIntVarArray(n, 0, 1, "x");
|
||||
|
||||
// Second (reserve) army
|
||||
IntVar[] y = solver.makeIntVarArray(n, 0, 1, "y");
|
||||
|
||||
// total number of armies
|
||||
IntVar num_armies = solver.makeSum(solver.makeSum(x),
|
||||
solver.makeSum(y)).var();
|
||||
|
||||
//
|
||||
// constraints
|
||||
//
|
||||
|
||||
//
|
||||
// Constraint 1: There is always an army in a city
|
||||
// (+ maybe a backup)
|
||||
// Or rather: Is there a backup, there
|
||||
// must be an an army
|
||||
//
|
||||
for(int i = 0; i < n; i++) {
|
||||
solver.addConstraint(solver.makeGreaterOrEqual(x[i], y[i]));
|
||||
}
|
||||
|
||||
//
|
||||
// Constraint 2: There should always be an backup
|
||||
// army near every city
|
||||
//
|
||||
for(int i = 0; i < n; i++) {
|
||||
ArrayList<IntVar> count_neighbours = new ArrayList<IntVar>();
|
||||
for(int j = 0; j < n; j++) {
|
||||
if (mat[i][j] == 1) {
|
||||
count_neighbours.add(y[j]);
|
||||
}
|
||||
}
|
||||
solver.addConstraint(
|
||||
solver.makeGreaterOrEqual(
|
||||
solver.makeSum(x[i],
|
||||
solver.makeSum(
|
||||
count_neighbours.toArray(new IntVar[1])).var()), 1));
|
||||
}
|
||||
|
||||
//
|
||||
// objective
|
||||
//
|
||||
OptimizeVar objective = solver.makeMinimize(num_armies, 1);
|
||||
|
||||
|
||||
//
|
||||
// search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(x,
|
||||
solver.INT_VAR_DEFAULT,
|
||||
solver.INT_VALUE_DEFAULT);
|
||||
solver.newSearch(db, objective);
|
||||
|
||||
//
|
||||
// output
|
||||
//
|
||||
while (solver.nextSolution()) {
|
||||
System.out.println("num_armies: " + num_armies.value());
|
||||
for(int i = 0; i < n; i++) {
|
||||
if (x[i].value() == 1) {
|
||||
System.out.print("Army: " + countries[i] + " ");
|
||||
}
|
||||
if (y[i].value() == 1) {
|
||||
System.out.println("Reserve army: " + countries[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
SetCoveringDeployment.solve();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.google.ortools.constraintsolver.Assignment;
|
||||
import com.google.ortools.constraintsolver.NodeEvaluator2;
|
||||
import com.google.ortools.constraintsolver.RoutingModel;
|
||||
import com.google.ortools.constraintsolver.FirstSolutionStrategy;
|
||||
import com.google.ortools.constraintsolver.RoutingSearchParameters;
|
||||
|
||||
public class SimpleRoutingTest {
|
||||
|
||||
//Static Add Library
|
||||
static { System.loadLibrary("jniortools"); }
|
||||
|
||||
private ArrayList<Integer> globalRes;
|
||||
private long globalResCost;
|
||||
private int[][] costMatrix;
|
||||
|
||||
public ArrayList<Integer> getGlobalRes() {return globalRes;}
|
||||
public void setGlobalRes(ArrayList<Integer> globalRes) {this.globalRes = globalRes;}
|
||||
public long getGlobalResCost() {return globalResCost;}
|
||||
public void setGlobalResCost(int globalResCost) {this.globalResCost = globalResCost;}
|
||||
public int[][] getCostMatrix() {return costMatrix;}
|
||||
public void setCostMatrix(int[][] costMatrix) {this.costMatrix = costMatrix;}
|
||||
|
||||
public SimpleRoutingTest(int[][] costMatrix) {
|
||||
super();
|
||||
this.costMatrix = costMatrix;
|
||||
globalRes = new ArrayList();
|
||||
}
|
||||
|
||||
//Node Distance Evaluation
|
||||
public static class NodeDistance extends NodeEvaluator2 {
|
||||
private int[][] costMatrix;
|
||||
|
||||
public NodeDistance(int[][] costMatrix) {
|
||||
this.costMatrix = costMatrix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long run(int firstIndex, int secondIndex) {
|
||||
return costMatrix[firstIndex][secondIndex];
|
||||
}
|
||||
}
|
||||
|
||||
//Solve Method
|
||||
public void solve() {
|
||||
RoutingModel routing = new RoutingModel(costMatrix.length, 1, 0);
|
||||
RoutingSearchParameters parameters =
|
||||
RoutingSearchParameters.newBuilder()
|
||||
.mergeFrom(RoutingModel.defaultSearchParameters())
|
||||
.setFirstSolutionStrategy(FirstSolutionStrategy.Value.PATH_CHEAPEST_ARC)
|
||||
.build();
|
||||
NodeDistance distances = new NodeDistance(costMatrix);
|
||||
routing.setArcCostEvaluatorOfAllVehicles(distances);
|
||||
|
||||
Assignment solution = routing.solve();
|
||||
if (solution != null) {
|
||||
int route_number = 0;
|
||||
for (long node = routing.start(route_number); !routing.isEnd(node); node = solution.value(routing.nextVar(node))) {
|
||||
globalRes.add((int) node);
|
||||
}
|
||||
}
|
||||
globalResCost = solution.objectiveValue();
|
||||
System.out.println("cost = " + globalResCost);
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
int[][] values = new int[4][4];
|
||||
values[0][0]=0;
|
||||
values[0][1]=5;
|
||||
values[0][2]=3;
|
||||
values[0][3]=6;
|
||||
values[1][0]=5;
|
||||
values[1][1]=0;
|
||||
values[1][2]=8;
|
||||
values[1][3]=1;
|
||||
values[2][0]=3;
|
||||
values[2][1]=8;
|
||||
values[2][2]=0;
|
||||
values[2][3]=4;
|
||||
values[3][0]=6;
|
||||
values[3][1]=1;
|
||||
values[3][2]=4;
|
||||
values[3][3]=0;
|
||||
SimpleRoutingTest model = new SimpleRoutingTest(values);
|
||||
model.solve();
|
||||
}
|
||||
}
|
||||
@@ -1,242 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
|
||||
public class StableMarriage {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Solves some stable marriage problems.
|
||||
* See http://www.hakank.org/google_or_tools/stable_marriage.py
|
||||
*
|
||||
*/
|
||||
private static void solve(long[][][] ranks, String problem_name) {
|
||||
|
||||
Solver solver = new Solver("StableMarriage");
|
||||
|
||||
//
|
||||
// data
|
||||
//
|
||||
System.out.println("\n#####################");
|
||||
System.out.println("Problem: " + problem_name);
|
||||
|
||||
|
||||
long[][] rankWomen = ranks[0];
|
||||
long[][] rankMen = ranks[1];
|
||||
|
||||
int n = rankWomen.length;
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
IntVar[] wife = solver.makeIntVarArray(n, 0, n - 1, "wife");
|
||||
IntVar[] husband = solver.makeIntVarArray(n, 0, n - 1, "husband");
|
||||
|
||||
//
|
||||
// constraints
|
||||
// (the comments are the Comet code)
|
||||
// forall(m in Men)
|
||||
// cp.post(husband[wife[m]] == m);
|
||||
for(int m = 0; m < n; m++) {
|
||||
solver.addConstraint(
|
||||
solver.makeEquality(solver.makeElement(husband, wife[m]), m));
|
||||
}
|
||||
|
||||
// forall(w in Women)
|
||||
// cp.post(wife[husband[w]] == w);
|
||||
for(int w = 0; w < n; w++) {
|
||||
solver.addConstraint(
|
||||
solver.makeEquality(solver.makeElement(wife, 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 = solver.makeIsGreaterCstVar(
|
||||
solver.makeElement(rankMen[m], wife[m]).var(),
|
||||
rankMen[m][o]);
|
||||
|
||||
IntVar b2 = solver.makeIsLessCstVar(
|
||||
solver.makeElement(rankWomen[o], husband[o]).var(),
|
||||
rankWomen[o][m]);
|
||||
solver.addConstraint(
|
||||
solver.makeLessOrEqual(
|
||||
solver.makeDifference(b1, b2), 0));
|
||||
}
|
||||
}
|
||||
|
||||
// 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 = solver.makeIsGreaterCstVar(
|
||||
solver.makeElement(rankWomen[w], husband[w]).var(),
|
||||
rankWomen[w][o]);
|
||||
IntVar b2 = solver.makeIsLessCstVar(
|
||||
solver.makeElement(rankMen[o], wife[o]).var(),
|
||||
rankMen[o][w]);
|
||||
solver.addConstraint(
|
||||
solver.makeLessOrEqual(
|
||||
solver.makeDifference(b1, b2), 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(wife,
|
||||
solver.INT_VAR_DEFAULT,
|
||||
solver.INT_VALUE_DEFAULT);
|
||||
|
||||
solver.newSearch(db);
|
||||
|
||||
//
|
||||
// output
|
||||
//
|
||||
while (solver.nextSolution()) {
|
||||
System.out.print("wife : ");
|
||||
for(int i = 0; i < n; i++) {
|
||||
System.out.print(wife[i].value() + " ");
|
||||
}
|
||||
System.out.print("\nhusband: ");
|
||||
for(int i = 0; i < n; i++) {
|
||||
System.out.print(husband[i].value() + " ");
|
||||
}
|
||||
System.out.println("\n");
|
||||
|
||||
}
|
||||
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
// System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
//
|
||||
// From Pascal Van Hentenryck's OPL book
|
||||
//
|
||||
long[][][] van_hentenryck = {
|
||||
// rankWomen
|
||||
{{1, 2, 4, 3, 5},
|
||||
{3, 5, 1, 2, 4},
|
||||
{5, 4, 2, 1, 3},
|
||||
{1, 3, 5, 4, 2},
|
||||
{4, 2, 3, 5, 1}},
|
||||
|
||||
// rankMen
|
||||
{{5, 1, 2, 4, 3},
|
||||
{4, 1, 3, 2, 5},
|
||||
{5, 3, 2, 4, 1},
|
||||
{1, 5, 4, 3, 2},
|
||||
{4, 3, 2, 1, 5}}
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Data from MathWorld
|
||||
// http://mathworld.wolfram.com/StableMarriageProblem.html
|
||||
//
|
||||
long[][][] mathworld = {
|
||||
// rankWomen
|
||||
{{3, 1, 5, 2, 8, 7, 6, 9, 4},
|
||||
{9, 4, 8, 1, 7, 6, 3, 2, 5},
|
||||
{3, 1, 8, 9, 5, 4, 2, 6, 7},
|
||||
{8, 7, 5, 3, 2, 6, 4, 9, 1},
|
||||
{6, 9, 2, 5, 1, 4, 7, 3, 8},
|
||||
{2, 4, 5, 1, 6, 8, 3, 9, 7},
|
||||
{9, 3, 8, 2, 7, 5, 4, 6, 1},
|
||||
{6, 3, 2, 1, 8, 4, 5, 9, 7},
|
||||
{8, 2, 6, 4, 9, 1, 3, 7, 5}},
|
||||
|
||||
// rankMen
|
||||
{{7, 3, 8, 9, 6, 4, 2, 1, 5},
|
||||
{5, 4, 8, 3, 1, 2, 6, 7, 9},
|
||||
{4, 8, 3, 9, 7, 5, 6, 1, 2},
|
||||
{9, 7, 4, 2, 5, 8, 3, 1, 6},
|
||||
{2, 6, 4, 9, 8, 7, 5, 1, 3},
|
||||
{2, 7, 8, 6, 5, 3, 4, 1, 9},
|
||||
{1, 6, 2, 3, 8, 5, 4, 9, 7},
|
||||
{5, 6, 9, 1, 2, 8, 4, 3, 7},
|
||||
{6, 1, 4, 7, 5, 8, 3, 9, 2}}};
|
||||
|
||||
//
|
||||
// Data from
|
||||
// http://www.csee.wvu.edu/~ksmani/courses/fa01/random/lecnotes/lecture5.pdf
|
||||
//
|
||||
long[][][] problem3 = {
|
||||
// rankWomen
|
||||
{{1,2,3,4},
|
||||
{4,3,2,1},
|
||||
{1,2,3,4},
|
||||
{3,4,1,2}},
|
||||
|
||||
// rankMen"
|
||||
{{1,2,3,4},
|
||||
{2,1,3,4},
|
||||
{1,4,3,2},
|
||||
{4,3,1,2}}};
|
||||
|
||||
|
||||
//
|
||||
// Data from
|
||||
// http://www.comp.rgu.ac.uk/staff/ha/ZCSP/additional_problems/stable_marriage/stable_marriage.pdf
|
||||
// page 4
|
||||
//
|
||||
long[][][] problem4 = {
|
||||
// rankWomen
|
||||
{{1,5,4,6,2,3},
|
||||
{4,1,5,2,6,3},
|
||||
{6,4,2,1,5,3},
|
||||
{1,5,2,4,3,6},
|
||||
{4,2,1,5,6,3},
|
||||
{2,6,3,5,1,4}},
|
||||
|
||||
// rankMen
|
||||
{{1,4,2,5,6,3},
|
||||
{3,4,6,1,5,2},
|
||||
{1,6,4,2,3,5},
|
||||
{6,5,3,4,2,1},
|
||||
{3,1,2,4,5,6},
|
||||
{2,3,1,6,5,4}}};
|
||||
|
||||
|
||||
StableMarriage.solve(van_hentenryck, "Van Hentenryck");
|
||||
StableMarriage.solve(mathworld, "MathWorld");
|
||||
StableMarriage.solve(problem3, "Problem 3");
|
||||
StableMarriage.solve(problem4, "Problem 4");
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,300 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017 Darian Sastre darian.sastre@minimaxlabs.com
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ************************************************************************
|
||||
*
|
||||
* This model was created by Hakan Kjellerstrand (hakank@gmail.com)
|
||||
*
|
||||
* Java version by Darian Sastre (darian.sastre@minimaxlabs.com)
|
||||
*/
|
||||
import java.math.RoundingMode;
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import com.google.ortools.linearsolver.MPConstraint;
|
||||
import com.google.ortools.linearsolver.MPObjective;
|
||||
import com.google.ortools.linearsolver.MPSolver;
|
||||
import com.google.ortools.linearsolver.MPVariable;
|
||||
|
||||
public class StiglerMIP {
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
private static MPSolver createSolver (String solverType) {
|
||||
return new MPSolver("MIPDiet",
|
||||
MPSolver.OptimizationProblemType.valueOf(solverType));
|
||||
}
|
||||
|
||||
private static void solve(String solverType) {
|
||||
MPSolver solver = createSolver(solverType);
|
||||
double infinity = MPSolver.infinity();
|
||||
|
||||
/** invariants */
|
||||
double days = 365.25;
|
||||
int nutrientsCount = 9;
|
||||
int commoditiesCount = 77;
|
||||
|
||||
String[] nutrients = {
|
||||
"calories", // Calories, unit = 1000
|
||||
"protein", // Protein, unit = grams
|
||||
"calcium", // Calcium, unit = grams
|
||||
"iron", // Iron, unit = milligrams
|
||||
"vitaminA", // Vitamin A, unit = 1000 International Units
|
||||
"thiamine", // Thiamine, Vit. B1, unit = milligrams
|
||||
"riboflavin", // Riboflavin, Vit. B2, unit = milligrams
|
||||
"niacin", // Niacin (Nicotinic Acid), unit = milligrams
|
||||
"ascorbicAcid" // Ascorbic Acid, Vit. C, unit = milligrams
|
||||
};
|
||||
|
||||
String[] commodities = {
|
||||
"Wheat Flour (Enriched), 10 lb.",
|
||||
"Macaroni, 1 lb.",
|
||||
"Wheat Cereal (Enriched), 28 oz.",
|
||||
"Corn Flakes, 8 oz.",
|
||||
"Corn Meal, 1 lb.",
|
||||
"Hominy Grits, 24 oz.",
|
||||
"Rice, 1 lb.",
|
||||
"Rolled Oats, 1 lb.",
|
||||
"White Bread (Enriched), 1 lb.",
|
||||
"Whole Wheat Bread, 1 lb.",
|
||||
"Rye Bread, 1 lb.",
|
||||
"Pound Cake, 1 lb.",
|
||||
"Soda Crackers, 1 lb.",
|
||||
"Milk, 1 qt.",
|
||||
"Evaporated Milk (can), 14.5 oz.",
|
||||
"Butter, 1 lb.",
|
||||
"Oleomargarine, 1 lb.",
|
||||
"Eggs, 1 doz.",
|
||||
"Cheese (Cheddar), 1 lb.",
|
||||
"Cream, 1/2 pt.",
|
||||
"Peanut Butter, 1 lb.",
|
||||
"Mayonnaise, 1/2 pt.",
|
||||
"Crisco, 1 lb.",
|
||||
"Lard, 1 lb.",
|
||||
"Sirloin Steak, 1 lb.",
|
||||
"Round Steak, 1 lb.",
|
||||
"Rib Roast, 1 lb.",
|
||||
"Chuck Roast, 1 lb.",
|
||||
"Plate, 1 lb.",
|
||||
"Liver (Beef), 1 lb.",
|
||||
"Leg of Lamb, 1 lb.",
|
||||
"Lamb Chops (Rib), 1 lb.",
|
||||
"Pork Chops, 1 lb.",
|
||||
"Pork Loin Roast, 1 lb.",
|
||||
"Bacon, 1 lb.",
|
||||
"Ham - smoked, 1 lb.",
|
||||
"Salt Pork, 1 lb.",
|
||||
"Roasting Chicken, 1 lb.",
|
||||
"Veal Cutlets, 1 lb.",
|
||||
"Salmon, Pink (can), 16 oz.",
|
||||
"Apples, 1 lb.",
|
||||
"Bananas, 1 lb.",
|
||||
"Lemons, 1 doz.",
|
||||
"Oranges, 1 doz.",
|
||||
"Green Beans, 1 lb.",
|
||||
"Cabbage, 1 lb.",
|
||||
"Carrots, 1 bunch",
|
||||
"Celery, 1 stalk",
|
||||
"Lettuce, 1 head",
|
||||
"Onions, 1 lb.",
|
||||
"Potatoes, 15 lb.",
|
||||
"Spinach, 1 lb.",
|
||||
"Sweet Potatoes, 1 lb.",
|
||||
"Peaches (can), No. 2 1/2",
|
||||
"Pears (can), No. 2 1/2,",
|
||||
"Pineapple (can), No. 2 1/2",
|
||||
"Asparagus (can), No. 2",
|
||||
"Grean Beans (can), No. 2",
|
||||
"Pork and Beans (can), 16 oz.",
|
||||
"Corn (can), No. 2",
|
||||
"Peas (can), No. 2",
|
||||
"Tomatoes (can), No. 2",
|
||||
"Tomato Soup (can), 10 1/2 oz.",
|
||||
"Peaches, Dried, 1 lb.",
|
||||
"Prunes, Dried, 1 lb.",
|
||||
"Raisins, Dried, 15 oz.",
|
||||
"Peas, Dried, 1 lb.",
|
||||
"Lima Beans, Dried, 1 lb.",
|
||||
"Navy Beans, Dried, 1 lb.",
|
||||
"Coffee, 1 lb.",
|
||||
"Tea, 1/4 lb.",
|
||||
"Cocoa, 8 oz.",
|
||||
"Chocolate, 8 oz.",
|
||||
"Sugar, 10 lb.",
|
||||
"Corn Sirup, 24 oz.",
|
||||
"Molasses, 18 oz.",
|
||||
"Strawberry Preserve, 1 lb."
|
||||
};
|
||||
|
||||
// price and weight per unit correspond to the two first columns
|
||||
double[][] data = {
|
||||
{36.0, 12600.0, 44.7, 1411.0, 2.0, 365.0, 0.0, 55.4, 33.3, 441.0, 0.0},
|
||||
{14.1, 3217.0, 11.6, 418.0, 0.7, 54.0, 0.0, 3.2, 1.9, 68.0, 0.0},
|
||||
{24.2, 3280.0, 11.8, 377.0, 14.4, 175.0, 0.0, 14.4, 8.8, 114.0, 0.0},
|
||||
{7.1, 3194.0, 11.4, 252.0, 0.1, 56.0, 0.0, 13.5, 2.3, 68.0, 0.0},
|
||||
{4.6, 9861.0, 36.0, 897.0, 1.7, 99.0, 30.9, 17.4, 7.9, 106.0, 0.0},
|
||||
{8.5, 8005.0, 28.6, 680.0, 0.8, 80.0, 0.0, 10.6, 1.6, 110.0, 0.0},
|
||||
{7.5, 6048.0, 21.2, 460.0, 0.6, 41.0, 0.0, 2.0, 4.8, 60.0, 0.0},
|
||||
{7.1, 6389.0, 25.3, 907.0, 5.1, 341.0, 0.0, 37.1, 8.9, 64.0, 0.0},
|
||||
{7.9, 5742.0, 15.6, 488.0, 2.5, 115.0, 0.0, 13.8, 8.5, 126.0, 0.0},
|
||||
{9.1, 4985.0, 12.2, 484.0, 2.7, 125.0, 0.0, 13.9, 6.4, 160.0, 0.0},
|
||||
{9.2, 4930.0, 12.4, 439.0, 1.1, 82.0, 0.0, 9.9, 3.0, 66.0, 0.0},
|
||||
{24.8, 1829.0, 8.0, 130.0, 0.4, 31.0, 18.9, 2.8, 3.0, 17.0, 0.0},
|
||||
{15.1, 3004.0, 12.5, 288.0, 0.5, 50.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{11.0, 8867.0, 6.1, 310.0, 10.5, 18.0, 16.8, 4.0, 16.0, 7.0, 177.0},
|
||||
{6.7, 6035.0, 8.4, 422.0, 15.1, 9.0, 26.0, 3.0, 23.5, 11.0, 60.0},
|
||||
{20.8, 1473.0, 10.8, 9.0, 0.2, 3.0, 44.2, 0.0, 0.2, 2.0, 0.0},
|
||||
{16.1, 2817.0, 20.6, 17.0, 0.6, 6.0, 55.8, 0.2, 0.0, 0.0, 0.0},
|
||||
{32.6, 1857.0, 2.9, 238.0, 1.0, 52.0, 18.6, 2.8, 6.5, 1.0, 0.0},
|
||||
{24.2, 1874.0, 7.4, 448.0, 16.4, 19.0, 28.1, 0.8, 10.3, 4.0, 0.0},
|
||||
{14.1, 1689.0, 3.5, 49.0, 1.7, 3.0, 16.9, 0.6, 2.5, 0.0, 17.0},
|
||||
{17.9, 2534.0, 15.7, 661.0, 1.0, 48.0, 0.0, 9.6, 8.1, 471.0, 0.0},
|
||||
{16.7, 1198.0, 8.6, 18.0, 0.2, 8.0, 2.7, 0.4, 0.5, 0.0, 0.0},
|
||||
{20.3, 2234.0, 20.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{9.8, 4628.0, 41.7, 0.0, 0.0, 0.0, 0.2, 0.0, 0.5, 5.0, 0.0},
|
||||
{39.6, 1145.0, 2.9, 166.0, 0.1, 34.0, 0.2, 2.1, 2.9, 69.0, 0.0},
|
||||
{36.4, 1246.0, 2.2, 214.0, 0.1, 32.0, 0.4, 2.5, 2.4, 87.0, 0.0},
|
||||
{29.2, 1553.0, 3.4, 213.0, 0.1, 33.0, 0.0, 0.0, 2.0, 0.0, 0.0},
|
||||
{22.6, 2007.0, 3.6, 309.0, 0.2, 46.0, 0.4, 1.0, 4.0, 120.0, 0.0},
|
||||
{14.6, 3107.0, 8.5, 404.0, 0.2, 62.0, 0.0, 0.9, 0.0, 0.0, 0.0},
|
||||
{26.8, 1692.0, 2.2, 333.0, 0.2, 139.0, 169.2, 6.4, 50.8, 316.0, 525.0},
|
||||
{27.6, 1643.0, 3.1, 245.0, 0.1, 20.0, 0.0, 2.8, 3.0, 86.0, 0.0},
|
||||
{36.6, 1239.0, 3.3, 140.0, 0.1, 15.0, 0.0, 1.7, 2.7, 54.0, 0.0},
|
||||
{30.7, 1477.0, 3.5, 196.0, 0.2, 80.0, 0.0, 17.4, 2.7, 60.0, 0.0},
|
||||
{24.2, 1874.0, 4.4, 249.0, 0.3, 37.0, 0.0, 18.2, 3.6, 79.0, 0.0},
|
||||
{25.6, 1772.0, 10.4, 152.0, 0.2, 23.0, 0.0, 1.8, 1.8, 71.0, 0.0},
|
||||
{27.4, 1655.0, 6.7, 212.0, 0.2, 31.0, 0.0, 9.9, 3.3, 50.0, 0.0},
|
||||
{16.0, 2835.0, 18.8, 164.0, 0.1, 26.0, 0.0, 1.4, 1.8, 0.0, 0.0},
|
||||
{30.3, 1497.0, 1.8, 184.0, 0.1, 30.0, 0.1, 0.9, 1.8, 68.0, 46.0},
|
||||
{42.3, 1072.0, 1.7, 156.0, 0.1, 24.0, 0.0, 1.4, 2.4, 57.0, 0.0},
|
||||
{13.0, 3489.0, 5.8, 705.0, 6.8, 45.0, 3.5, 1.0, 4.9, 209.0, 0.0},
|
||||
{4.4, 9072.0, 5.8, 27.0, 0.5, 36.0, 7.3, 3.6, 2.7, 5.0, 544.0},
|
||||
{6.1, 4982.0, 4.9, 60.0, 0.4, 30.0, 17.4, 2.5, 3.5, 28.0, 498.0},
|
||||
{26.0, 2380.0, 1.0, 21.0, 0.5, 14.0, 0.0, 0.5, 0.0, 4.0, 952.0},
|
||||
{30.9, 4439.0, 2.2, 40.0, 1.1, 18.0, 11.1, 3.6, 1.3, 10.0, 1993.0},
|
||||
{7.1, 5750.0, 2.4, 138.0, 3.7, 80.0, 69.0, 4.3, 5.8, 37.0, 862.0},
|
||||
{3.7, 8949.0, 2.6, 125.0, 4.0, 36.0, 7.2, 9.0, 4.5, 26.0, 5369.0},
|
||||
{4.7, 6080.0, 2.7, 73.0, 2.8, 43.0, 188.5, 6.1, 4.3, 89.0, 608.0},
|
||||
{7.3, 3915.0, 0.9, 51.0, 3.0, 23.0, 0.9, 1.4, 1.4, 9.0, 313.0},
|
||||
{8.2, 2247.0, 0.4, 27.0, 1.1, 22.0, 112.4, 1.8, 3.4, 11.0, 449.0},
|
||||
{3.6, 11844.0, 5.8, 166.0, 3.8, 59.0, 16.6, 4.7, 5.9, 21.0, 1184.0},
|
||||
{34.0, 16810.0, 14.3, 336.0, 1.8, 118.0, 6.7, 29.4, 7.1, 198.0, 2522.0},
|
||||
{8.1, 4592.0, 1.1, 106.0, 0.0, 138.0, 918.4, 5.7, 13.8, 33.0, 2755.0},
|
||||
{5.1, 7649.0, 9.6, 138.0, 2.7, 54.0, 290.7, 8.4, 5.4, 83.0, 1912.0},
|
||||
{16.8, 4894.0, 3.7, 20.0, 0.4, 10.0, 21.5, 0.5, 1.0, 31.0, 196.0},
|
||||
{20.4, 4030.0, 3.0, 8.0, 0.3, 8.0, 0.8, 0.8, 0.8, 5.0, 81.0},
|
||||
{21.3, 3993.0, 2.4, 16.0, 0.4, 8.0, 2.0, 2.8, 0.8, 7.0, 399.0},
|
||||
{27.7, 1945.0, 0.4, 33.0, 0.3, 12.0, 16.3, 1.4, 2.1, 17.0, 272.0},
|
||||
{10.0, 5386.0, 1.0, 54.0, 2.0, 65.0, 53.9, 1.6, 4.3, 32.0, 431.0},
|
||||
{7.1, 6389.0, 7.5, 364.0, 4.0, 134.0, 3.5, 8.3, 7.7, 56.0, 0.0},
|
||||
{10.4, 5452.0, 5.2, 136.0, 0.2, 16.0, 12.0, 1.6, 2.7, 42.0, 218.0},
|
||||
{13.8, 4109.0, 2.3, 136.0, 0.6, 45.0, 34.9, 4.9, 2.5, 37.0, 370.0},
|
||||
{8.6, 6263.0, 1.3, 63.0, 0.7, 38.0, 53.2, 3.4, 2.5, 36.0, 1253.0},
|
||||
{7.6, 3917.0, 1.6, 71.0, 0.6, 43.0, 57.9, 3.5, 2.4, 67.0, 862.0},
|
||||
{15.7, 2889.0, 8.5, 87.0, 1.7, 173.0, 86.8, 1.2, 4.3, 55.0, 57.0},
|
||||
{9.0, 4284.0, 12.8, 99.0, 2.5, 154.0, 85.7, 3.9, 4.3, 65.0, 257.0},
|
||||
{9.4, 4524.0, 13.5, 104.0, 2.5, 136.0, 4.5, 6.3, 1.4, 24.0, 136.0},
|
||||
{7.9, 5742.0, 20.0, 1367.0, 4.2, 345.0, 2.9, 28.7, 18.4, 162.0, 0.0},
|
||||
{8.9, 5097.0, 17.4, 1055.0, 3.7, 459.0, 5.1, 26.9, 38.2, 93.0, 0.0},
|
||||
{5.9, 7688.0, 26.9, 1691.0, 11.4, 792.0, 0.0, 38.4, 24.6, 217.0, 0.0},
|
||||
{22.4, 2025.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 5.1, 50.0, 0.0},
|
||||
{17.4, 652.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.3, 42.0, 0.0},
|
||||
{8.6, 2637.0, 8.7, 237.0, 3.0, 72.0, 0.0, 2.0, 11.9, 40.0, 0.0},
|
||||
{16.2, 1400.0, 8.0, 77.0, 1.3, 39.0, 0.0, 0.9, 3.4, 14.0, 0.0},
|
||||
{51.7, 8773.0, 34.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{13.7, 4996.0, 14.7, 0.0, 0.5, 74.0, 0.0, 0.0, 0.0, 5.0, 0.0},
|
||||
{13.6, 3752.0, 9.0, 0.0, 10.3, 244.0, 0.0, 1.9, 7.5, 146.0, 0.0},
|
||||
{20.5, 2213.0, 6.4, 11.0, 0.4, 7.0, 0.2, 0.2, 0.4, 3.0, 0.0}
|
||||
};
|
||||
|
||||
// recommended daily nutritional allowance
|
||||
double[] allowance = {3.0, 70.0, 0.8, 12.0, 5.0, 1.8, 2.7, 18.0, 75.0};
|
||||
|
||||
|
||||
/** variables */
|
||||
MPVariable[] x = solver.makeNumVarArray(commoditiesCount, 0, 1000);
|
||||
MPVariable[] xCost = solver.makeNumVarArray(commoditiesCount, 0, 1000);
|
||||
MPVariable[] quant = solver.makeNumVarArray(commoditiesCount, 0, 1000);
|
||||
|
||||
MPVariable totalCost = solver.makeNumVar(0, 1000, "total_cost");
|
||||
|
||||
/** constraints & objective */
|
||||
MPObjective obj = solver.objective();
|
||||
|
||||
MPConstraint[] costConstraint = new MPConstraint[2 * commoditiesCount];
|
||||
MPConstraint[] quantConstraint = new MPConstraint[2 * commoditiesCount];
|
||||
|
||||
MPConstraint totalCostConstraint = solver.makeConstraint(0, 0);
|
||||
|
||||
for (int i = 0; i < commoditiesCount; i ++) {
|
||||
totalCostConstraint.setCoefficient(x[i], days);
|
||||
|
||||
costConstraint[i] = solver.makeConstraint(0, 0);
|
||||
costConstraint[i].setCoefficient(x[i], days);
|
||||
costConstraint[i].setCoefficient(xCost[i], -1);
|
||||
|
||||
quantConstraint[i] = solver.makeConstraint(0, 0);
|
||||
quantConstraint[i].setCoefficient(x[i], days * 100 / data[i][0]);
|
||||
quantConstraint[i].setCoefficient(quant[i], -1);
|
||||
|
||||
obj.setCoefficient(x[i], 1);
|
||||
}
|
||||
totalCostConstraint.setCoefficient(totalCost, -1);
|
||||
|
||||
MPConstraint[] nutrientConstraint = new MPConstraint[nutrientsCount];
|
||||
|
||||
for (int i = 0; i < nutrientsCount; i ++) {
|
||||
nutrientConstraint[i] = solver.makeConstraint(allowance[i], infinity);
|
||||
for (int j = 0; j < commoditiesCount; j ++) {
|
||||
nutrientConstraint[i].setCoefficient(x[j], data[j][i+2]);
|
||||
}
|
||||
}
|
||||
|
||||
solver.solve();
|
||||
|
||||
/** printing */
|
||||
DecimalFormat df = new DecimalFormat("#.##");
|
||||
df.setRoundingMode(RoundingMode.CEILING);
|
||||
|
||||
System.out.println("Min cost: " + df.format(obj.value()));
|
||||
System.out.println("Total cost: " + df.format(totalCost.solutionValue()));
|
||||
|
||||
for (int i = 0; i < commoditiesCount; i ++) {
|
||||
if (x[i].solutionValue() > 0) {
|
||||
System.out.println(commodities[i] + ": " + df.format(xCost[i].solutionValue()) + " " + df.format(quant[i].solutionValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
System.out.println("---- Integer programming example with SCIP (recommended) ----");
|
||||
solve("SCIP_MIXED_INTEGER_PROGRAMMING");
|
||||
} catch (java.lang.IllegalArgumentException e) {
|
||||
System.err.println("Bad solver type: " + e);
|
||||
}
|
||||
try {
|
||||
System.out.println("---- Integer programming example with CBC ----");
|
||||
solve("CBC_MIXED_INTEGER_PROGRAMMING");
|
||||
} catch (java.lang.IllegalArgumentException e) {
|
||||
System.err.println("Bad solver type: " + e);
|
||||
}
|
||||
try {
|
||||
System.out.println("---- Integer programming example with GLPK ----");
|
||||
solve("GLPK_MIXED_INTEGER_PROGRAMMING");
|
||||
} catch (java.lang.IllegalArgumentException e) {
|
||||
System.err.println("Bad solver type: " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
|
||||
public class Strimko2 {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Solves a Strimko problem.
|
||||
* See http://www.hakank.org/google_or_tools/strimko2.py
|
||||
*
|
||||
*/
|
||||
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}};
|
||||
|
||||
// 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 n = streams.length;
|
||||
int num_placed = placed.length;
|
||||
|
||||
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
|
||||
IntVar[][] x = new IntVar[n][n];
|
||||
IntVar[] x_flat = new IntVar[n * n];
|
||||
for(int i = 0; i < n; i++) {
|
||||
for(int j = 0; j < n; j++) {
|
||||
x[i][j] = solver.makeIntVar(1, n, "x[" + i + "," + j + "]");
|
||||
x_flat[i * n + j] = x[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// constraints
|
||||
//
|
||||
|
||||
// all rows and columns must be unique, i.e. a Latin Square
|
||||
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];
|
||||
}
|
||||
|
||||
solver.addConstraint(solver.makeAllDifferent(row));
|
||||
solver.addConstraint(solver.makeAllDifferent(col));
|
||||
}
|
||||
|
||||
|
||||
// streams
|
||||
for(int s = 1; s <= n; s++) {
|
||||
ArrayList<IntVar> tmp = new ArrayList<IntVar>();
|
||||
for(int i = 0; i < n; i++) {
|
||||
for(int j = 0; j < n; j++) {
|
||||
if (streams[i][j] == s) {
|
||||
tmp.add(x[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
solver.addConstraint(
|
||||
solver.makeAllDifferent(tmp.toArray(new IntVar[1])));
|
||||
}
|
||||
|
||||
|
||||
// placed
|
||||
for(int i = 0; i < num_placed; i++) {
|
||||
// note: also adjust to 0-based
|
||||
solver.addConstraint(
|
||||
solver.makeEquality(x[placed[i][0] - 1][placed[i][1] - 1],
|
||||
placed[i][2]));
|
||||
}
|
||||
|
||||
//
|
||||
// search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(x_flat,
|
||||
solver.INT_VAR_DEFAULT,
|
||||
solver.INT_VALUE_DEFAULT);
|
||||
solver.newSearch(db);
|
||||
|
||||
//
|
||||
// output
|
||||
//
|
||||
while (solver.nextSolution()) {
|
||||
for(int i = 0; i < n; i++) {
|
||||
for(int j = 0; j < n; j++) {
|
||||
System.out.print(x[i][j].value() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
Strimko2.solve();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
|
||||
public class Sudoku {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Solves a Sudoku problem.
|
||||
*
|
||||
*/
|
||||
private static void solve() {
|
||||
|
||||
Solver solver = new Solver("Sudoku");
|
||||
|
||||
int cell_size = 3;
|
||||
int n = cell_size * cell_size;
|
||||
|
||||
// 0 marks an unknown value
|
||||
int[][] initial_grid = new int[][] {{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}};
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
IntVar[][] grid = new IntVar[n][n];
|
||||
IntVar[] grid_flat = new IntVar[n * n];
|
||||
|
||||
for(int i = 0; i < n; i++) {
|
||||
for(int j = 0; j < n; j++) {
|
||||
grid[i][j] = solver.makeIntVar(1, 9, "grid[" + i +"," + j + "]");
|
||||
grid_flat[i * n + j] = grid[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// constraints
|
||||
//
|
||||
|
||||
// init and rows
|
||||
for(int i = 0; i < n; i++) {
|
||||
IntVar[] row = new IntVar[n];
|
||||
for(int j = 0; j < n; j++) {
|
||||
if (initial_grid[i][j] > 0) {
|
||||
solver.addConstraint(
|
||||
solver.makeEquality(grid[i][j], initial_grid[i][j]));
|
||||
}
|
||||
row[j] = grid[i][j];
|
||||
}
|
||||
solver.addConstraint(solver.makeAllDifferent(row));
|
||||
}
|
||||
|
||||
// columns
|
||||
for(int j = 0; j < n; j++) {
|
||||
IntVar[] col = new IntVar[n];
|
||||
for(int i = 0; i < n; i++) {
|
||||
col[i] = grid[i][j];
|
||||
}
|
||||
solver.addConstraint(solver.makeAllDifferent(col));
|
||||
}
|
||||
|
||||
// cells
|
||||
for(int i = 0; i < cell_size; i++) {
|
||||
for(int j = 0; j < cell_size; j++) {
|
||||
IntVar[] cell = new IntVar[n];
|
||||
for(int di = 0; di < cell_size; di++) {
|
||||
for(int dj = 0; dj < cell_size; dj++) {
|
||||
cell[di * cell_size + dj] =
|
||||
grid[i * cell_size + di][j * cell_size + dj];
|
||||
}
|
||||
}
|
||||
solver.addConstraint(solver.makeAllDifferent(cell));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Search
|
||||
//
|
||||
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++) {
|
||||
System.out.print(grid[i][j].value() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Sudoku.solve();
|
||||
}
|
||||
}
|
||||
@@ -1,248 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
import com.google.ortools.constraintsolver.*;
|
||||
|
||||
public class SurvoPuzzle {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
/*
|
||||
* 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}};
|
||||
|
||||
|
||||
// for the actual problem
|
||||
static int r;
|
||||
static int c;
|
||||
static int[] rowsums;
|
||||
static int[] colsums;
|
||||
static int[][] game;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Solves the Survo puzzle problem.
|
||||
* See http://www.hakank.org/google_or_tools/survo_puzzle.py
|
||||
*
|
||||
*/
|
||||
private static void solve() {
|
||||
|
||||
Solver solver = new Solver("Survopuzzle");
|
||||
|
||||
//
|
||||
// data
|
||||
//
|
||||
System.out.println("Problem:");
|
||||
for(int i = 0; i < r; i++) {
|
||||
for(int j = 0; j < c; j++) {
|
||||
System.out.print(game[i][j] + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
|
||||
//
|
||||
// Variables
|
||||
//
|
||||
IntVar[][] x = new IntVar[r][c];
|
||||
IntVar[] x_flat = new IntVar[r * c]; // for branching
|
||||
for(int i = 0; i < r; i++) {
|
||||
for(int j = 0; j < c; j++) {
|
||||
x[i][j] = solver.makeIntVar(1, r * c, "x[" + i + "," + j + "]");
|
||||
x_flat[i * c + j] = x[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Constraints
|
||||
//
|
||||
for(int i = 0; i < r; i++) {
|
||||
for(int j = 0; j < c; j++) {
|
||||
if (game[i][j] > 0) {
|
||||
solver.addConstraint(
|
||||
solver.makeEquality(x[i][j], game[i][j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
solver.addConstraint(solver.makeAllDifferent(x_flat));
|
||||
|
||||
//
|
||||
// calculate rowsums and colsums
|
||||
//
|
||||
for(int i = 0; i < r; i++) {
|
||||
IntVar[] row = new IntVar[c];
|
||||
for(int j = 0; j < c; j++) {
|
||||
row[j] = x[i][j];
|
||||
}
|
||||
solver.addConstraint(
|
||||
solver.makeEquality(solver.makeSum(row).var(), rowsums[i]));
|
||||
}
|
||||
|
||||
for(int j = 0; j < c; j++) {
|
||||
IntVar[] col = new IntVar[r];
|
||||
for(int i = 0; i < r; i++) {
|
||||
col[i] = x[i][j];
|
||||
}
|
||||
solver.addConstraint(
|
||||
solver.makeEquality(solver.makeSum(col).var(), colsums[j]));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(x_flat,
|
||||
solver.INT_VAR_SIMPLE,
|
||||
solver.ASSIGN_MIN_VALUE);
|
||||
solver.newSearch(db);
|
||||
|
||||
int sol = 0;
|
||||
while (solver.nextSolution()) {
|
||||
sol++;
|
||||
System.out.println("Solution #" + sol + ":");
|
||||
for(int i = 0; i < r; i++) {
|
||||
for(int j = 0; j < c; j++) {
|
||||
System.out.print(x[i][j].value() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* readFile()
|
||||
*
|
||||
* Reads a Survo puzzle in the following format
|
||||
* r
|
||||
* c
|
||||
* rowsums
|
||||
* olsums
|
||||
* data
|
||||
* ...
|
||||
*
|
||||
* Example:
|
||||
* 3
|
||||
* 4
|
||||
* 30,18,30
|
||||
* 27,16,10,25
|
||||
* 0,6,0,0
|
||||
* 8,0,0,0
|
||||
* 0,0,3,0
|
||||
*
|
||||
*/
|
||||
private static void readFile(String file) {
|
||||
|
||||
System.out.println("readFile(" + file + ")");
|
||||
|
||||
try {
|
||||
|
||||
BufferedReader inr = new BufferedReader(new FileReader(file));
|
||||
|
||||
r = Integer.parseInt(inr.readLine());
|
||||
c = Integer.parseInt(inr.readLine());
|
||||
rowsums = new int[r];
|
||||
colsums = new int[c];
|
||||
System.out.println("r: " + r + " c: " + c);
|
||||
|
||||
String[] rowsums_str = inr.readLine().split(",\\s*");
|
||||
String[] colsums_str = inr.readLine().split(",\\s*");
|
||||
System.out.println("rowsums:");
|
||||
for(int i = 0; i < r; i++) {
|
||||
System.out.print(rowsums_str[i] + " ");
|
||||
rowsums[i] = Integer.parseInt(rowsums_str[i]);
|
||||
}
|
||||
System.out.println("\ncolsums:");
|
||||
for(int j = 0; j < c; j++) {
|
||||
System.out.print(colsums_str[j] + " ");
|
||||
colsums[j] = Integer.parseInt(colsums_str[j]);
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
// init the game matrix and read data from file
|
||||
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("%")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String this_row[] = str.split(",\\s*");
|
||||
for(int j = 0; j < this_row.length; j++) {
|
||||
game[line_count][j] = Integer.parseInt(this_row[j]);
|
||||
}
|
||||
|
||||
line_count++;
|
||||
|
||||
} // end while
|
||||
|
||||
inr.close();
|
||||
|
||||
} catch (IOException e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
|
||||
} // end readFile
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
if (args.length > 0) {
|
||||
String file = args[0];
|
||||
SurvoPuzzle.readFile(file);
|
||||
} else {
|
||||
r = default_r;
|
||||
c = default_c;
|
||||
game = default_game;
|
||||
rowsums = default_rowsums;
|
||||
colsums = default_colsums;
|
||||
}
|
||||
|
||||
SurvoPuzzle.solve();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
|
||||
public class ToNum {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* toNum(solver, a, num, base)
|
||||
*
|
||||
* channelling between the array a and the number num
|
||||
*
|
||||
*/
|
||||
private static void toNum(Solver solver, IntVar[] a, IntVar num, int base) {
|
||||
int len = a.length;
|
||||
|
||||
IntVar[] tmp = new IntVar[len];
|
||||
for(int i = 0; i < len; i++) {
|
||||
tmp[i] = solver.makeProd(a[i], (int)Math.pow(base,(len-i-1))).var();
|
||||
}
|
||||
solver.addConstraint(
|
||||
solver.makeEquality(solver.makeSum(tmp).var(), num));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Implements toNum: channeling between a number and an array.
|
||||
* See http://www.hakank.org/google_or_tools/toNum.py
|
||||
*
|
||||
*/
|
||||
private static void solve() {
|
||||
|
||||
Solver solver = new Solver("ToNum");
|
||||
|
||||
int n = 5;
|
||||
int base = 10;
|
||||
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
IntVar[] x = solver.makeIntVarArray(n, 0, base - 1, "x");
|
||||
IntVar num = solver.makeIntVar(0, (int)Math.pow(base, n) - 1 , "num");
|
||||
|
||||
|
||||
|
||||
//
|
||||
// constraints
|
||||
//
|
||||
solver.addConstraint(solver.makeAllDifferent(x));
|
||||
|
||||
|
||||
toNum(solver, x, num, base);
|
||||
|
||||
// extra constraint (just for fun):
|
||||
// second digit should be 7
|
||||
// solver.addConstraint(solver.makeEquality(x[1], 7));
|
||||
|
||||
|
||||
//
|
||||
// search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(x,
|
||||
solver.CHOOSE_FIRST_UNBOUND,
|
||||
solver.ASSIGN_MIN_VALUE);
|
||||
|
||||
solver.newSearch(db);
|
||||
|
||||
//
|
||||
// output
|
||||
//
|
||||
while (solver.nextSolution()) {
|
||||
System.out.print("num: " + num.value() + ": ");
|
||||
for(int i = 0; i < n; i++) {
|
||||
System.out.print(x[i].value() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
ToNum.solve();
|
||||
}
|
||||
}
|
||||
@@ -1,205 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
|
||||
public class WhoKilledAgatha {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Implements the Who killed Agatha problem.
|
||||
* See http://www.hakank.org/google_or_tools/who_killed_agatha.py
|
||||
*
|
||||
*/
|
||||
private static void solve() {
|
||||
|
||||
Solver solver = new Solver("WhoKilledAgatha");
|
||||
|
||||
//
|
||||
// data
|
||||
//
|
||||
final int n = 3;
|
||||
final int agatha = 0;
|
||||
final int butler = 1;
|
||||
final int charles = 2;
|
||||
|
||||
String[] names = {"Agatha", "Butler", "Charles"};
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
IntVar the_killer = solver.makeIntVar(0, 2, "the_killer");
|
||||
IntVar the_victim = solver.makeIntVar(0, 2, "the_victim");
|
||||
|
||||
IntVar[] all = new IntVar[2 * n * n]; // for branching
|
||||
|
||||
IntVar[][] hates = new IntVar[n][n];
|
||||
IntVar[] hates_flat = new IntVar[n * n];
|
||||
for(int i = 0; i < n; i++) {
|
||||
for(int j = 0; j < n; j++) {
|
||||
hates[i][j] = solver.makeIntVar(0, 1, "hates[" + i + "," + j + "]");
|
||||
hates_flat[i * n + j] = hates[i][j];
|
||||
all[i * n + j] = hates[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
IntVar[][] richer = new IntVar[n][n];
|
||||
IntVar[] richer_flat = new IntVar[n * n];
|
||||
for(int i = 0; i < n; i++) {
|
||||
for(int j = 0; j < n; j++) {
|
||||
richer[i][j] = solver.makeIntVar(0, 1, "richer[" + i + "," + j + "]");
|
||||
richer_flat[i * n + j] = richer[i][j];
|
||||
all[(n * n) + (i * n + j)] = richer[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// constraints
|
||||
//
|
||||
|
||||
// Agatha, the butler, and Charles live in Dreadsbury Mansion, and
|
||||
// are the only ones to live there.
|
||||
|
||||
// A killer always hates, and is no richer than his victim.
|
||||
// hates[the_killer, the_victim] == 1
|
||||
// hates_flat[the_killer * n + the_victim] == 1
|
||||
solver.addConstraint(
|
||||
solver.makeEquality(
|
||||
solver.makeElement(
|
||||
hates_flat,
|
||||
solver.makeSum(
|
||||
solver.makeProd(the_killer, n).var(),
|
||||
the_victim).var()).var(), 1));
|
||||
|
||||
// richer[the_killer, the_victim] == 0
|
||||
solver.addConstraint(
|
||||
solver.makeEquality(
|
||||
solver.makeElement(
|
||||
richer_flat,
|
||||
solver.makeSum(
|
||||
solver.makeProd(the_killer, n).var(),
|
||||
the_victim).var()).var(), 0));
|
||||
|
||||
// define the concept of richer:
|
||||
// no one is richer than him-/herself...
|
||||
for(int i = 0; i < n; i++) {
|
||||
solver.addConstraint(solver.makeEquality(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++) {
|
||||
if (i != j) {
|
||||
IntVar bi = solver.makeIsEqualCstVar(richer[i][j], 1);
|
||||
IntVar bj = solver.makeIsEqualCstVar(richer[j][i], 0);
|
||||
solver.addConstraint(solver.makeEquality(bi, bj));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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++) {
|
||||
IntVar b1a = solver.makeIsEqualCstVar(hates[agatha][i], 1);
|
||||
IntVar b1b = solver.makeIsEqualCstVar(hates[charles][i], 0);
|
||||
solver.addConstraint(
|
||||
solver.makeLessOrEqual(
|
||||
solver.makeDifference(b1a, b1b).var(), 0));
|
||||
}
|
||||
|
||||
// Agatha hates everybody except the butler.
|
||||
solver.addConstraint(solver.makeEquality(hates[agatha][charles], 1));
|
||||
solver.addConstraint(solver.makeEquality(hates[agatha][agatha], 1));
|
||||
solver.addConstraint(solver.makeEquality(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++) {
|
||||
IntVar b2a = solver.makeIsEqualCstVar(richer[i][agatha], 0);
|
||||
IntVar b2b = solver.makeIsEqualCstVar(hates[butler][i], 1);
|
||||
solver.addConstraint(
|
||||
solver.makeLessOrEqual(
|
||||
solver.makeDifference(b2a, b2b).var(), 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++) {
|
||||
IntVar b3a = solver.makeIsEqualCstVar(hates[agatha][i], 1);
|
||||
IntVar b3b = solver.makeIsEqualCstVar(hates[butler][i], 1);
|
||||
solver.addConstraint(
|
||||
solver.makeLessOrEqual(
|
||||
solver.makeDifference(b3a, b3b).var(), 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++) {
|
||||
IntVar[] tmp = new IntVar[n];
|
||||
for(int j = 0; j < n; j++) {
|
||||
tmp[j] = hates[i][j];
|
||||
}
|
||||
solver.addConstraint(
|
||||
solver.makeLessOrEqual(solver.makeSum(tmp).var(), 2));
|
||||
}
|
||||
|
||||
|
||||
// Who killed Agatha?
|
||||
solver.addConstraint(solver.makeEquality(the_victim, agatha));
|
||||
|
||||
//
|
||||
// search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(all,
|
||||
solver.CHOOSE_FIRST_UNBOUND,
|
||||
solver.ASSIGN_MIN_VALUE);
|
||||
|
||||
solver.newSearch(db);
|
||||
|
||||
//
|
||||
// output
|
||||
//
|
||||
while (solver.nextSolution()) {
|
||||
System.out.println("the_killer: " + names[(int)the_killer.value()]);
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
WhoKilledAgatha.solve();
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
import com.google.ortools.constraintsolver.*;
|
||||
|
||||
public class Xkcd {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Solves the xkcd problem.
|
||||
* See http://www.hakank.org/google_or_tools/xkcd.py
|
||||
*
|
||||
*/
|
||||
private static void solve() {
|
||||
|
||||
Solver solver = new Solver("Xkcd");
|
||||
|
||||
int n = 6;
|
||||
// for price and total: multiplied by 100 to be able to use integers
|
||||
int[]price = {215, 275, 335, 355, 420, 580};
|
||||
int total = 1505;
|
||||
|
||||
//
|
||||
// Variables
|
||||
//
|
||||
IntVar[] x = solver.makeIntVarArray(n, 0, 10, "x");
|
||||
|
||||
//
|
||||
// Constraints
|
||||
//
|
||||
solver.addConstraint(
|
||||
solver.makeEquality(solver.makeScalProd(x, price).var(), total));
|
||||
|
||||
//
|
||||
// Search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(x,
|
||||
solver.CHOOSE_FIRST_UNBOUND,
|
||||
solver.ASSIGN_MIN_VALUE);
|
||||
solver.newSearch(db);
|
||||
|
||||
while (solver.nextSolution()) {
|
||||
System.out.print("x: ");
|
||||
for(int i = 0; i < n; i++) {
|
||||
System.out.print(x[i].value() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Xkcd.solve();
|
||||
}
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
// Copyright 2011 Hakan Kjellerstrand hakank@gmail.com
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import com.google.ortools.constraintsolver.DecisionBuilder;
|
||||
import com.google.ortools.constraintsolver.IntVar;
|
||||
import com.google.ortools.constraintsolver.Solver;
|
||||
|
||||
public class YoungTableaux {
|
||||
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Implements Young tableaux and partitions.
|
||||
* See http://www.hakank.org/google_or_tools/young_tableuax.py
|
||||
*
|
||||
*/
|
||||
private static void solve(int n) {
|
||||
|
||||
Solver solver = new Solver("YoungTableaux");
|
||||
|
||||
System.out.println("n: " + n);
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
IntVar[][] x = new IntVar[n][n];
|
||||
IntVar[] x_flat = new IntVar[n * n];
|
||||
|
||||
for(int i = 0; i < n; i++) {
|
||||
for(int j = 0; j < n; j++) {
|
||||
x[i][j] = solver.makeIntVar(1, n + 1, "x[" + i + "," + j + "]");
|
||||
x_flat[i * n + j] = x[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
// partition structure
|
||||
IntVar[] p = solver.makeIntVarArray(n, 0, n + 1, "p");
|
||||
|
||||
//
|
||||
// constraints
|
||||
//
|
||||
|
||||
// 1..n is used exactly once
|
||||
for(int i = 1; i <= n; i++) {
|
||||
solver.addConstraint(solver.makeCount(x_flat, i, 1));
|
||||
}
|
||||
|
||||
solver.addConstraint(solver.makeEquality(x[0][0], 1));
|
||||
|
||||
// row wise
|
||||
for(int i = 0; i < n; i++) {
|
||||
for(int j = 1; j < n; j++) {
|
||||
solver.addConstraint(
|
||||
solver.makeGreaterOrEqual(x[i][j], x[i][j - 1]));
|
||||
}
|
||||
}
|
||||
|
||||
// column wise
|
||||
for(int j = 0; j < n; j++) {
|
||||
for(int i = 1; i < n; i++) {
|
||||
solver.addConstraint(
|
||||
solver.makeGreaterOrEqual(x[i][j], x[i - 1][j]));
|
||||
}
|
||||
}
|
||||
|
||||
// calculate the structure (i.e. the partition)
|
||||
for(int i = 0; i < n; i++) {
|
||||
IntVar[] b = new IntVar[n];
|
||||
for(int j = 0; j < n; j++) {
|
||||
b[j] = solver.makeIsLessOrEqualCstVar(x[i][j], n);
|
||||
}
|
||||
solver.addConstraint(
|
||||
solver.makeEquality(p[i], solver.makeSum(b).var()));
|
||||
}
|
||||
|
||||
solver.addConstraint(
|
||||
solver.makeEquality(solver.makeSum(p).var(), n));
|
||||
|
||||
for(int i = 1; i < n; i++) {
|
||||
solver.addConstraint(solver.makeGreaterOrEqual(p[i - 1], p[i]));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// search
|
||||
//
|
||||
DecisionBuilder db = solver.makePhase(x_flat,
|
||||
solver.CHOOSE_FIRST_UNBOUND,
|
||||
solver.ASSIGN_MIN_VALUE);
|
||||
|
||||
solver.newSearch(db);
|
||||
|
||||
//
|
||||
// output
|
||||
//
|
||||
while (solver.nextSolution()) {
|
||||
System.out.print("p: ");
|
||||
for(int i = 0; i < n; i++) {
|
||||
System.out.print(p[i].value() + " ");
|
||||
}
|
||||
|
||||
System.out.println("\nx:");
|
||||
for(int i = 0; i < n; i++) {
|
||||
for(int j = 0; j < n; j++) {
|
||||
long val = x[i][j].value();
|
||||
if (val <= n) {
|
||||
System.out.print(val + " ");
|
||||
}
|
||||
}
|
||||
if (p[i].value() > 0) {
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
}
|
||||
solver.endSearch();
|
||||
|
||||
// Statistics
|
||||
System.out.println();
|
||||
System.out.println("Solutions: " + solver.solutions());
|
||||
System.out.println("Failures: " + solver.failures());
|
||||
System.out.println("Branches: " + solver.branches());
|
||||
System.out.println("Wall time: " + solver.wallTime() + "ms");
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
int n = 5;
|
||||
if (args.length > 0) {
|
||||
n = Integer.parseInt(args[0]);
|
||||
}
|
||||
|
||||
YoungTableaux.solve(n);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user