move contrib examples to a dedicated contrib directory

This commit is contained in:
Laurent Perron
2018-11-07 20:49:03 +01:00
parent 5a6e658475
commit 475ccd99e3
415 changed files with 0 additions and 3 deletions

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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");
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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");
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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");
}
}

View File

@@ -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);
}
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}