diff --git a/inference/lib/libjscip-0.1.darwin.x86_64.gnu.opt.spx.dylib b/inference/lib/libjscip-0.1.darwin.x86_64.gnu.opt.spx.dylib new file mode 100755 index 000000000..c70cd6226 Binary files /dev/null and b/inference/lib/libjscip-0.1.darwin.x86_64.gnu.opt.spx.dylib differ diff --git a/inference/lib/libjscip-0.1.linux.x86_64.gnu.opt.spx.dylib b/inference/lib/libjscip-0.1.linux.x86_64.gnu.opt.spx.dylib new file mode 120000 index 000000000..a57506013 --- /dev/null +++ b/inference/lib/libjscip-0.1.linux.x86_64.gnu.opt.spx.dylib @@ -0,0 +1 @@ +libjscip-0.1.darwin.x86_64.gnu.opt.spx.dylib \ No newline at end of file diff --git a/inference/lib/libjscip-0.1.linux.x86_64.gnu.opt.spx.so b/inference/lib/libjscip-0.1.linux.x86_64.gnu.opt.spx.so new file mode 100755 index 000000000..4ac79cf40 Binary files /dev/null and b/inference/lib/libjscip-0.1.linux.x86_64.gnu.opt.spx.so differ diff --git a/inference/lib/liblpispx-3.1.1.darwin.x86_64.gnu.opt.so b/inference/lib/liblpispx-3.1.1.darwin.x86_64.gnu.opt.so new file mode 100644 index 000000000..caa62c772 Binary files /dev/null and b/inference/lib/liblpispx-3.1.1.darwin.x86_64.gnu.opt.so differ diff --git a/inference/lib/liblpispx.linux.x86_64.gnu.opt.so b/inference/lib/liblpispx.linux.x86_64.gnu.opt.so new file mode 100644 index 000000000..ad4933d83 Binary files /dev/null and b/inference/lib/liblpispx.linux.x86_64.gnu.opt.so differ diff --git a/inference/lib/libnlpi.cppad-3.1.1.darwin.x86_64.gnu.opt.so b/inference/lib/libnlpi.cppad-3.1.1.darwin.x86_64.gnu.opt.so new file mode 100644 index 000000000..2f9257542 Binary files /dev/null and b/inference/lib/libnlpi.cppad-3.1.1.darwin.x86_64.gnu.opt.so differ diff --git a/inference/lib/libnlpi.cppad.linux.x86_64.gnu.opt.so b/inference/lib/libnlpi.cppad.linux.x86_64.gnu.opt.so new file mode 100644 index 000000000..e325f381b Binary files /dev/null and b/inference/lib/libnlpi.cppad.linux.x86_64.gnu.opt.so differ diff --git a/inference/lib/libscip-3.1.1.darwin.x86_64.gnu.opt.so b/inference/lib/libscip-3.1.1.darwin.x86_64.gnu.opt.so new file mode 100644 index 000000000..ef1c8277c Binary files /dev/null and b/inference/lib/libscip-3.1.1.darwin.x86_64.gnu.opt.so differ diff --git a/inference/lib/libscip.linux.x86_64.gnu.opt.so b/inference/lib/libscip.linux.x86_64.gnu.opt.so new file mode 100644 index 000000000..b5a5a6d7d Binary files /dev/null and b/inference/lib/libscip.linux.x86_64.gnu.opt.so differ diff --git a/inference/lib/libsoplex-2.0.1.darwin.x86_64.gnu.opt.so b/inference/lib/libsoplex-2.0.1.darwin.x86_64.gnu.opt.so new file mode 100644 index 000000000..8f4c21d0f Binary files /dev/null and b/inference/lib/libsoplex-2.0.1.darwin.x86_64.gnu.opt.so differ diff --git a/inference/lib/libsoplex.linux.x86_64.gnu.opt.so b/inference/lib/libsoplex.linux.x86_64.gnu.opt.so new file mode 100644 index 000000000..d66a7e4ae Binary files /dev/null and b/inference/lib/libsoplex.linux.x86_64.gnu.opt.so differ diff --git a/inference/lib/scip.jar b/inference/lib/scip.jar new file mode 100644 index 000000000..1a2f897d0 Binary files /dev/null and b/inference/lib/scip.jar differ diff --git a/inference/pom.xml b/inference/pom.xml index 2a3abfd55..8a340d695 100644 --- a/inference/pom.xml +++ b/inference/pom.xml @@ -62,6 +62,30 @@ 1.7.12 true + + de.zib.jscip.nativ + scip + 1.0 + system + ${basedir}/lib/scip.jar + + + + + maven-surefire-plugin + 2.19.1 + + + true + + ${basedir}/lib/ + ${basedir}/lib/ + + + + + + diff --git a/inference/src/main/java/edu/illinois/cs/cogcomp/infer/ilp/GurobiHook.java b/inference/src/main/java/edu/illinois/cs/cogcomp/infer/ilp/GurobiHook.java index f44561900..160cabbbf 100644 --- a/inference/src/main/java/edu/illinois/cs/cogcomp/infer/ilp/GurobiHook.java +++ b/inference/src/main/java/edu/illinois/cs/cogcomp/infer/ilp/GurobiHook.java @@ -430,6 +430,7 @@ public boolean isSolved() { * @param index The index of the variable whose value is requested. * @return The value of the variable. **/ + @Override public boolean getBooleanValue(int index) { if (!isSolved) return false; diff --git a/inference/src/main/java/edu/illinois/cs/cogcomp/infer/ilp/ScipHook.java b/inference/src/main/java/edu/illinois/cs/cogcomp/infer/ilp/ScipHook.java new file mode 100644 index 000000000..ec2fe29d7 --- /dev/null +++ b/inference/src/main/java/edu/illinois/cs/cogcomp/infer/ilp/ScipHook.java @@ -0,0 +1,334 @@ +/** + * This software is released under the University of Illinois/Research and Academic Use License. See + * the LICENSE file in the root folder for details. Copyright (c) 2016 + * + * Developed by: The Cognitive Computation Group University of Illinois at Urbana-Champaign + * http://cogcomp.cs.illinois.edu/ + */ +package edu.illinois.cs.cogcomp.infer.ilp; + +import de.zib.jscip.nativ.NativeScipException; +import de.zib.jscip.nativ.jni.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * This is a generic interface to the SCIP ILP solver providing a number of common initialization + * steps and access to the SCIP environment. This class is NOT guaranteed to be thread-safe! + */ +public class ScipHook implements ILPSolver { + + // default parameters + static double timeLimit = 180d; + static int threads = 1; + static String logFile = "scip.log"; + static boolean messagehdlrQuiet = false; + static int printVersion = 0; + + // Min and max values to use when defining the model + // TODO(ashish33) check how to access SCIP's built-in SCIP_REAL_MAX, etc. + private double scipMin = -1e+20; + private double scipMax = 1e+20; + + private final static Logger logger = LoggerFactory.getLogger(ScipHook.class); + + // the SCIP environment + private JniScip env; + + // the SCIP variable environment + private JniScipVar envVar; + + // SCIP set packing constraint environment + private JniScipConsSetppc envConsSetppc; + + // the SCIP linear constraint environment + private JniScipConsLinear envConsLinear; + + // a SCIP instance + private Long scip; + + Map intToLongIndex; + Map longToIntIndex; + + public ScipHook(String probName, double timeLimit, int threads, String logFile, + boolean messagehdlrQuiet, int printVersion) { + + intToLongIndex = new HashMap<>(); + longToIntIndex = new HashMap<>(); + + // initialization: load JNI library + logger.debug("Java library path = " + System.getProperty("java.library.path")); + JniScipLibraryLoader.loadLibrary(); + + // initialization: create various handlers in the SCIP environment + // create the SCIP environment + env = new JniScip(); + + // create the SCIP variable environment + envVar = new JniScipVar(); + + // create SCIP set packing constraint environment + envConsSetppc = new JniScipConsSetppc(); + + // create the SCIP linear constraint environment + envConsLinear = new JniScipConsLinear(); + + // initialization: create a SCIP instance + try { + scip = env.create(); + } catch (NativeScipException e) { + e.printStackTrace(); + } + + // initialization: set various parameters + try { + env.setMessagehdlrQuiet(scip, messagehdlrQuiet); + if (logFile.length() > 0) { + env.setMessagehdlrLogfile(scip, logFile); + } + env.includeDefaultPlugins(scip); // include default plugins of SCIP + env.setRealParam(scip, "limits/time", timeLimit); // set SCIP's overall time limit + env.setIntParam(scip, "lp/threads", threads); // number of threads used for LP + + // initialization: create empty problem tied to the given problem name + env.createProbBasic(scip, probName); + } catch (NativeScipException e) { + e.printStackTrace(); + } + } + + public ScipHook(String probName) { + this(probName, timeLimit, threads, logFile, messagehdlrQuiet, printVersion); + } + + @Override + public void setMaximize(boolean d) { + try { + if (d) + env.setObjsense(scip, JniScipObjsense.SCIP_OBJSENSE_MAXIMIZE); + else + env.setObjsense(scip, JniScipObjsense.SCIP_OBJSENSE_MINIMIZE); + } catch (NativeScipException e) { + e.printStackTrace(); + } + } + + @Override + public int addBooleanVariable(double c) { + long variableId = -1; + try { + variableId = env.createVarBasic(scip, "", 0, 1, c, JniScipVartype.SCIP_VARTYPE_BINARY); + env.addVar(scip, variableId); + } catch (NativeScipException e) { + e.printStackTrace(); + } + int newIntIdx = intToLongIndex.size(); + intToLongIndex.put(newIntIdx, variableId); + longToIntIndex.put(variableId, newIntIdx); + + + return newIntIdx; + } + + @Override + public int addRealVariable(double c) { + long variableId = -1; + try { + variableId = + env.createVarBasic(scip, "", -Double.MAX_VALUE, Double.MAX_VALUE, c, + JniScipVartype.SCIP_VARTYPE_CONTINUOUS); + env.addVar(scip, variableId); + } catch (NativeScipException e) { + e.printStackTrace(); + } + + int newIntIdx = intToLongIndex.size(); + intToLongIndex.put(newIntIdx, variableId); + longToIntIndex.put(variableId, newIntIdx); + + return newIntIdx; + } + + @Override + public int addIntegerVariable(double c) { + long variableId = -1; + try { + variableId = + env.createVarBasic(scip, "", -Double.MAX_VALUE, Double.MAX_VALUE, c, + JniScipVartype.SCIP_VARTYPE_INTEGER); + env.addVar(scip, variableId); + } catch (NativeScipException e) { + e.printStackTrace(); + } + + int newIntIdx = intToLongIndex.size(); + intToLongIndex.put(newIntIdx, variableId); + longToIntIndex.put(variableId, newIntIdx); + + return newIntIdx; + } + + @Override + public int[] addDiscreteVariable(double[] c) { + int[] indices = new int[c.length]; + for (int idx = 0; idx < c.length; idx++) { + indices[idx] = addBooleanVariable(c[idx]); + } + double[] allOnesCoeffs = new double[c.length]; + Arrays.fill(allOnesCoeffs, 1.0); + addLessThanConstraint(indices, allOnesCoeffs, 1); + return indices; + } + + @Override + public void addEqualityConstraint(int[] i, double[] a, double b) { + addReleaseCons(createConsBasicLinear("", i, a, b, b)); + } + + @Override + public void addGreaterThanConstraint(int[] i, double[] a, double b) { + addReleaseCons(createConsBasicLinear("", i, a, b, null)); + } + + @Override + public void addLessThanConstraint(int[] i, double[] a, double b) { + addReleaseCons(createConsBasicLinear("", i, a, null, b)); + } + + /** Adds a constraint to SCIP and "release" it */ + private void addReleaseCons(long cons) { + try { + env.addCons(scip, cons); + env.releaseCons(scip, cons); + } catch (NativeScipException e) { + e.printStackTrace(); + } + } + + /** + * Creates and captures a linear constraint in its most basic version; all constraint flags are + * set to their basic value as explained for the method SCIPcreateConsLinear(); all flags can be + * set via SCIPsetConsFLAGNAME methods in scip.h + * + * @param name name of constraint + * @param vars seq with variables of constraint entries + * @param coeffs seq with coefficients of constraint entries + * @param lhs left hand side of constraint, optional + * @param rhs right hand side of constraint, optional + */ + private long createConsBasicLinear(String name, int[] vars, double[] coeffs, Double lhs, + Double rhs) { + long constraintPt = Long.MIN_VALUE; + try { + Double lhsCorrected = (lhs == null) ? scipMin : lhs; + Double rhsCorrected = (rhs == null) ? scipMax : rhs; + long[] longIndices = new long[vars.length]; + for (int i = 0; i < vars.length; i++) { + longIndices[i] = intToLongIndex.get(vars[i]); + } + + constraintPt = + envConsLinear.createConsBasicLinear(scip, name, vars.length, longIndices, + coeffs, lhsCorrected, rhsCorrected); + } catch (NativeScipException e) { + e.printStackTrace(); + } + return constraintPt; + } + + @Override + public boolean solve() throws Exception { + // although solve() could have been directly called here, first call presolve() so that + // simplified problem stats can be stored for future reference + env.presolve(scip); + + // now do branch-and-bound search using solve() + env.solve(scip); + + logger.info("Solution status: " + env.getStatus(scip)); + logger.info("Objective value: " + env.getPrimalbound(scip)); + + return env.getStatus(scip) == JniScipStatus.SCIP_STATUS_OPTIMAL; + } + + @Override + public boolean isSolved() { + try { + return env.getStatus(scip) >= JniScipStatus.SCIP_STATUS_BESTSOLLIMIT; + } catch (NativeScipException e) { + e.printStackTrace(); + } + return false; + } + + @Override + public boolean getBooleanValue(int index) { + double x = getRealValue(index); + return x > 0.5; + } + + @Override + public int getIntegerValue(int index) { + double x = getRealValue(index); + return (int) Math.round(x); + } + + @Override + public double getRealValue(int index) { + try { + return env.getSolVal(scip, getBestSol(), intToLongIndex.get(index)); + } catch (NativeScipException e) { + e.printStackTrace(); + } + return -1; + } + + /** get pointer to the best solution found */ + private Long getBestSol() throws NativeScipException { + return env.getBestSol(scip); + } + + @Override + public double objectiveValue() { + try { + return env.getPrimalbound(scip); + } catch (NativeScipException e) { + e.printStackTrace(); + } + return -1; + } + + @Override + public double objectiveCoeff(int index) { + try { + return envVar.varGetObj(index); + } catch (NativeScipException e) { + e.printStackTrace(); + } + return -1; + } + + @Override + public void reset() { + long origScipStage = 0; + long newScipStage = 0; + // reset SCIP to pre-presolve stage + try { + origScipStage = env.getStage(scip); + env.freeTransform(scip); + newScipStage = env.getStage(scip); + } catch (NativeScipException e) { + e.printStackTrace(); + } + logger.debug("SCIP solver stage changed from " + origScipStage + " to " + newScipStage); + } + + @Override + public void write(StringBuffer buffer) { + + } +} diff --git a/inference/src/test/java/edu/illinois/cs/cogcomp/infer/ilp/GurobiHookTest.java b/inference/src/test/java/edu/illinois/cs/cogcomp/infer/ilp/GurobiHookTest.java index e219f07a4..3d095b2a7 100644 --- a/inference/src/test/java/edu/illinois/cs/cogcomp/infer/ilp/GurobiHookTest.java +++ b/inference/src/test/java/edu/illinois/cs/cogcomp/infer/ilp/GurobiHookTest.java @@ -14,7 +14,8 @@ public class GurobiHookTest { @Test public void testAll() throws Exception { - // if we are running the test on Semaphore, ignore this test, since Gurobi is not provided on Semaphore. + // if we are running the test on Semaphore, ignore this test, since Gurobi is not provided + // on Semaphore. if (System.getenv().containsKey("CI") && System.getenv().get("CI").equals("true") && System.getenv().containsKey("SEMAPHORE") && System.getenv().get("SEMAPHORE").equals("true")) { diff --git a/inference/src/test/java/edu/illinois/cs/cogcomp/infer/ilp/GurobiTest.java b/inference/src/test/java/edu/illinois/cs/cogcomp/infer/ilp/GurobiTest.java index a622fe54b..9e37bd64d 100644 --- a/inference/src/test/java/edu/illinois/cs/cogcomp/infer/ilp/GurobiTest.java +++ b/inference/src/test/java/edu/illinois/cs/cogcomp/infer/ilp/GurobiTest.java @@ -17,12 +17,11 @@ public class GurobiTest { @Test public void testGurobi() throws GRBException { - if(System.getenv().containsKey("CI") && System.getenv().get("CI").equals("true") && - System.getenv().containsKey("SEMAPHORE") && System.getenv().get("SEMAPHORE").equals("true") - && System.getenv().containsKey("CIRCLECI") && System.getenv().get("CIRCLECI").equals("true")) { + if (System.getenv().containsKey("CI") && System.getenv().get("CI").equals("true") + && System.getenv().containsKey("SEMAPHORE") + && System.getenv().get("SEMAPHORE").equals("true")) { System.out.println("Running the test on Semaphore. Skipping this test . . . "); - } - else { + } else { try { GRBEnv env = new GRBEnv(); GRBModel model = new GRBModel(env); diff --git a/inference/src/test/java/edu/illinois/cs/cogcomp/infer/ilp/ScipHookTest.java b/inference/src/test/java/edu/illinois/cs/cogcomp/infer/ilp/ScipHookTest.java new file mode 100644 index 000000000..59f062fe9 --- /dev/null +++ b/inference/src/test/java/edu/illinois/cs/cogcomp/infer/ilp/ScipHookTest.java @@ -0,0 +1,303 @@ +/** + * This software is released under the University of Illinois/Research and Academic Use License. See + * the LICENSE file in the root folder for details. Copyright (c) 2016 + * + * Developed by: The Cognitive Computation Group University of Illinois at Urbana-Champaign + * http://cogcomp.cs.illinois.edu/ + */ +package edu.illinois.cs.cogcomp.infer.ilp; + +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +public class ScipHookTest { + @Test + public void testProgram1() throws Exception { + ScipHook scipHook = new ScipHook(""); + int[] varInds = new int[2]; + + int i = 0; + while (i < 2) { + int x = scipHook.addBooleanVariable(-1.0); + varInds[i] = x; + i++; + } + + double[] coeffs = {1, 2}; + scipHook.addGreaterThanConstraint(varInds, coeffs, -3); + scipHook.addLessThanConstraint(varInds, coeffs, 4); + + scipHook.setMaximize(false); + + try { + scipHook.solve(); + } catch (Exception e) { + e.printStackTrace(); + } + + assertTrue(scipHook.objectiveValue() == -2.0); + assertTrue(scipHook.getBooleanValue(0)); + assertTrue(scipHook.getBooleanValue(1)); + } + + @Test + public void testProgram2() throws Exception { + ScipHook scipHook = new ScipHook(""); + int[] varInds = new int[2]; + + int i = 0; + while (i < 2) { + int x = scipHook.addBooleanVariable(-1.0); + varInds[i] = x; + i++; + } + + double[] coeffs = {1, 2}; + scipHook.addGreaterThanConstraint(varInds, coeffs, -3); + scipHook.addLessThanConstraint(varInds, coeffs, 4); + + scipHook.setMaximize(true); + + try { + scipHook.solve(); + } catch (Exception e) { + e.printStackTrace(); + } + + assertTrue(scipHook.objectiveValue() == 0); + assertTrue(!scipHook.getBooleanValue(0)); + assertTrue(!scipHook.getBooleanValue(1)); + } + + @Test + public void testProgram3() throws Exception { + ScipHook scipHook = new ScipHook(""); + int[] varInds = new int[2]; + + int i = 0; + while (i < 2) { + int x = scipHook.addBooleanVariable(1.5); + varInds[i] = x; + i++; + } + + double[] coeffs = {1, 2}; + scipHook.addGreaterThanConstraint(varInds, coeffs, -3); + scipHook.addLessThanConstraint(varInds, coeffs, 4); + + scipHook.setMaximize(true); + + try { + scipHook.solve(); + } catch (Exception e) { + e.printStackTrace(); + } + + + assertTrue(scipHook.objectiveValue() == 3); + assertTrue(scipHook.getBooleanValue(0)); + assertTrue(scipHook.getBooleanValue(1)); + } + + @Test + public void testProgram4() throws Exception { + ScipHook scipHook = new ScipHook(""); + int[] varInds = new int[2]; + + int i = 0; + while (i < 2) { + int x = scipHook.addBooleanVariable(1.5); + varInds[i] = x; + i++; + } + + double[] coeffs = {1, 2}; + scipHook.addGreaterThanConstraint(varInds, coeffs, -3); + scipHook.addLessThanConstraint(varInds, coeffs, 4); + + scipHook.setMaximize(false); + + try { + scipHook.solve(); + } catch (Exception e) { + e.printStackTrace(); + } + + assertTrue(scipHook.objectiveValue() == 0); + assertTrue(!scipHook.getBooleanValue(0)); + assertTrue(!scipHook.getBooleanValue(1)); + } + + @Test + public void testProgram5() throws Exception { + ScipHook scipHook = new ScipHook(""); + int[] varInds = new int[2]; + + double[] objcoeffs = {1.5, 2.5}; + int i = 0; + while (i < 2) { + int x = scipHook.addBooleanVariable(objcoeffs[i]); + varInds[i] = x; + i++; + } + + double[] coeffs = {1, 2}; + scipHook.addGreaterThanConstraint(varInds, coeffs, 1); + scipHook.addLessThanConstraint(varInds, coeffs, 4); + + scipHook.setMaximize(true); + + try { + scipHook.solve(); + } catch (Exception e) { + e.printStackTrace(); + } + + assertTrue(scipHook.objectiveValue() == 4); + assertTrue(scipHook.getBooleanValue(0)); + assertTrue(scipHook.getBooleanValue(1)); + } + + @Test + public void testProgram6() throws Exception { + ScipHook scipHook = new ScipHook(""); + int[] varInds = new int[2]; + + double[] objcoeffs = {1.5, 2.5}; + int i = 0; + while (i < 2) { + int x = scipHook.addBooleanVariable(objcoeffs[i]); + varInds[i] = x; + i++; + } + + double[] coeffs = {1, 2}; + scipHook.addGreaterThanConstraint(varInds, coeffs, 1); + scipHook.addLessThanConstraint(varInds, coeffs, 2); + + scipHook.setMaximize(false); + + try { + scipHook.solve(); + } catch (Exception e) { + e.printStackTrace(); + } + + assertTrue(scipHook.objectiveValue() == 1.5); + assertTrue(scipHook.getBooleanValue(0)); + assertTrue(!scipHook.getBooleanValue(1)); + } + + @Test + public void testProgram7() throws Exception { + ScipHook scipHook = new ScipHook(""); + int[] varInds = new int[2]; + + double[] objcoeffs = {1.5, 2.5}; + int i = 0; + while (i < 2) { + int x = scipHook.addBooleanVariable(objcoeffs[i]); + varInds[i] = x; + i++; + } + + double[] coeffs = {1, 2}; + scipHook.addGreaterThanConstraint(varInds, coeffs, 1); + scipHook.addLessThanConstraint(varInds, coeffs, 2); + + scipHook.setMaximize(true); + + try { + scipHook.solve(); + } catch (Exception e) { + e.printStackTrace(); + } + + assertTrue(scipHook.objectiveValue() == 2.5); + assertTrue(!scipHook.getBooleanValue(0)); + assertTrue(scipHook.getBooleanValue(1)); + } + + @Test + public void testProgram8() throws Exception { + ScipHook scipHook = new ScipHook(""); + int[] varInds = new int[3]; + + double[] objcoeffs = {-1, -1, -1}; + int i = 0; + while (i < 3) { + int x = scipHook.addBooleanVariable(objcoeffs[i]); + varInds[i] = x; + i++; + } + + double[] coeffs = {1, 1, 1}; + scipHook.addEqualityConstraint(varInds, coeffs, 3); + scipHook.setMaximize(true); + + try { + scipHook.solve(); + } catch (Exception e) { + e.printStackTrace(); + } + + assertTrue(scipHook.objectiveValue() == -3); + assertTrue(scipHook.getBooleanValue(0)); + assertTrue(scipHook.getBooleanValue(1)); + assertTrue(scipHook.getBooleanValue(2)); + } + + @Test + public void testProgram9() throws Exception { + ScipHook scipHook = new ScipHook(""); + + double[] objcoeffs = {0, -1}; + scipHook.addDiscreteVariable(objcoeffs); + scipHook.addDiscreteVariable(objcoeffs); + scipHook.addDiscreteVariable(objcoeffs); + + double[] coeffs = {1, 1, 1}; + int[] varInds = {1, 3, 5}; + scipHook.addEqualityConstraint(varInds, coeffs, 3); + scipHook.setMaximize(true); + + try { + scipHook.solve(); + } catch (Exception e) { + e.printStackTrace(); + } + + assertTrue(scipHook.objectiveValue() == -3); + assertTrue(!scipHook.getBooleanValue(0)); + assertTrue(scipHook.getBooleanValue(1)); + assertTrue(!scipHook.getBooleanValue(2)); + assertTrue(scipHook.getBooleanValue(3)); + assertTrue(!scipHook.getBooleanValue(4)); + assertTrue(scipHook.getBooleanValue(5)); + } + + @Test + public void testProgram10() throws Exception { + ScipHook scipHook = new ScipHook(""); + + double[] objcoeffs = {0, 1, 2}; + int[] indices = scipHook.addDiscreteVariable(objcoeffs); + + + scipHook.setMaximize(true); + + try { + scipHook.solve(); + } catch (Exception e) { + e.printStackTrace(); + } + + System.out.println(indices[0] + "/ " + indices[1] + " / " + indices[2]); + + assertTrue(scipHook.objectiveValue() == 2); + assertTrue(scipHook.getBooleanValue(indices[2])); + assertTrue(!scipHook.getBooleanValue(indices[1])); + assertTrue(!scipHook.getBooleanValue(indices[0])); + } +}