Skip to content

Commit

Permalink
Memory mapping to speed up calls, ByReference pooling in JSCIP, numer…
Browse files Browse the repository at this point in the history
…ical accuracy calls
  • Loading branch information
Timeroot committed Jul 6, 2022
1 parent 5a3132d commit 1696f02
Show file tree
Hide file tree
Showing 9 changed files with 650 additions and 157 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ need `libscip.so` where JNA can find it. Your working directory should work,
but you can also set the system property `jna.library.path`, or [a few other
options listed here](https://java-native-access.github.io/jna/4.2.1/com/sun/jna/NativeLibrary.html#library_search_paths).

## Examples

JNA\_SCIP currently has 5 example programs:
* Simple\_MILP, which solves a two-variable MILP.
* Queens, a translation of SCIP's n-Queens problem.
* Queens_C is a 1-to-1 translation of the C.
* Queens_Obj is showing how to refer to variable names in a somewhat more Java way.
* Heuristic, which shows how to implement a SCIP_HEUR callback.
* Conshdlr, which shows how to implement a constraint handler callback.
* Conshdlr_Manual gives the callbacks to SCIP directly.
* Conshdlr_Obj uses JNA\_SCIP's helper classes (ConstraintHandler) to make the management easier.
* LOP, a translation of SCIP's Linear Ordering Problem solver. It includes a constraint
handler and a problem reader, and uses JNA\_SCIP's ConstraintHandler structures.

## How to find a function

Alright, you have a SCIP function with a certain name, and you want to know
Expand Down
76 changes: 62 additions & 14 deletions src/JNA_SCIP/Examples/LOP/Cons_LOP.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ public class Cons_LOP extends ConstraintData<Cons_LOP, Conshdlr_LOP> {
/* Member methods and data for per-constraint data. */
SCIP_VAR[][] vars;
Cons_LOP(SCIP_VAR[][] _vars, boolean copy) {
int n = _vars.length;
if(!copy) {
this.vars = _vars;
return;
}
//deep copy
int n = _vars.length;
vars = new SCIP_VAR[n][];
for(int i=0; i<n; i++) {
vars[i] = Arrays.copyOf(_vars[i], n);
} else {
//deep copy
vars = new SCIP_VAR[n][];
for(int i=0; i<n; i++) {
vars[i] = Arrays.copyOf(_vars[i], n);
}
}
}

Expand All @@ -27,14 +28,15 @@ SCIP_RESULT LOPseparate(SCIP scip, SCIP_SOL sol) {
int nGen = 0;
boolean cutoff = false;

int n = vars.length;
int n = vars.length;
double[][] vals = scip.getSolVals(sol, vars);

for(int i=0; i<n; i++) {
for(int j=i+1; j<n; j++) {
double valIJ = scip.getSolVal(sol, vars[i][j]);
double valJI = scip.getSolVal(sol, vars[j][i]);
double valIJ = vals[i][j];;
double valJI = vals[j][i];

if ( Math.abs(valIJ + valJI - 1.0) > 1e-7 ) {
if ( !scip.isFeasEQ(scip, valIJ + valJI, 1.0) ) {
String name = "sym#"+i+"#"+j;
SCIP_ROW row = scip.createEmptyRowConshdlr(getScipHdlr(), name, 1.0, 1.0, false, false, true);
scip.cacheRowExtensions(row);
Expand All @@ -58,11 +60,11 @@ SCIP_RESULT LOPseparate(SCIP scip, SCIP_SOL sol) {
if(k==j)
continue;

double valJK = scip.getSolVal(sol, vars[j][k]);
double valKI = scip.getSolVal(sol, vars[k][i]);
double valJK = vals[j][k];
double valKI = vals[k][i];
double sum = valIJ + valJK + valKI;

if ( sum > 2.0 ) {
if ( scip.isEfficacious(sum - 2.0) ) {
//build row
String name = "triangle#"+i+"#"+j+"#"+k;
SCIP_ROW row = scip.createEmptyRowConshdlr(getScipHdlr(), name, -scip.infinity(), 2.0, false, false, true);
Expand Down Expand Up @@ -93,6 +95,52 @@ SCIP_RESULT LOPseparate(SCIP scip, SCIP_SOL sol) {
} else
return SCIP_RESULT.SCIP_DIDNOTFIND;
}

boolean isFeasible_Integral(SCIP scip, SCIP_SOL sol, boolean printreason) {
int n = vars.length;
double[][] vals = scip.getSolVals(sol, vars);

/* check triangle inequalities and symmetry equations */
for(int i=0; i<n; i++) {
for(int j=i+1; j<n; j++) {
boolean oneIJ = vals[i][j] > 0.5;
boolean oneJI = vals[j][i] > 0.5;

if ( oneIJ == oneJI ) {
scip.debugMsg("constraint <"+getName()+"> infeasible (violated equation).\n");
if( printreason ) {
scip.infoMessage(null,
"violation: symmetry equation violated <%s> = %.15g and <%s> = %.15g\n",
vars[i][j].getName(), scip.getSolVal(sol, vars[i][j]),
vars[j][i].getName(), scip.getSolVal(sol, vars[j][i]));
}
return false;
}

for(int k=i+1; k<n; k++) {
if(k==j)
continue;

boolean oneJK = vals[j][k] > 0.5;
boolean oneKI = vals[k][i] > 0.5;

if (oneIJ && oneJK && oneKI) {
scip.debugMsg("constraint <"+getName()+"> infeasible (violated triangle ineq.).\n");
if( printreason ) {
scip.infoMessage(null,
"violation: triangle inequality violated <%s> = %.15g, <%s> = %.15g, <%s> = %.15g\n",
vars[i][j].getName(), scip.getSolVal(sol, vars[i][j]),
vars[j][k].getName(), scip.getSolVal(sol, vars[j][k]),
vars[k][i].getName(), scip.getSolVal(sol, vars[k][i]));
}
return false;
}
}
}
}

return true;
}

@Override
public Cons_LOP copy(SCIP sourcescip, SCIP targetscip,
Expand Down
114 changes: 24 additions & 90 deletions src/JNA_SCIP/Examples/LOP/Conshdlr_LOP.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,20 @@ public class Conshdlr_LOP extends ConstraintHandler<Cons_LOP,Conshdlr_LOP> {
//Uncomment block below for the equivalent of #define SCIP_DEBUG.
//But it will hold for all Java code, not just this class.

// static{ SCIP.DEBUG = true; }
//static{ SCIP.DEBUG = true; }

/* Constants to define behavior and timing */
static final String CONSHDLR_NAME = "lop";
static final String CONSHDLR_DESC = "linear ordering constraint handler";
static final int CONSHDLR_SEPAPRIORITY = 100;
static final int CONSHDLR_ENFOPRIORITY = -100;
static final int CONSHDLR_CHECKPRIORITY = -100;
static final int CONSHDLR_SEPAFREQ = 1;
static final int CONSHDLR_PROPFREQ = 1;
static final int CONSHDLR_EAGERFREQ = 100;
static final boolean CONSHDLR_DELAYSEPA = false;
static final boolean CONSHDLR_DELAYPROP = false;
static final boolean CONSHDLR_NEEDSCONS = true;
static final String CONSHDLR_NAME = "lop";
static final String CONSHDLR_DESC = "linear ordering constraint handler";
static final int CONSHDLR_SEPAPRIORITY = 100;
static final int CONSHDLR_ENFOPRIORITY = -100;
static final int CONSHDLR_CHECKPRIORITY = -100;
static final int CONSHDLR_SEPAFREQ = 1;
static final int CONSHDLR_PROPFREQ = 1;
static final int CONSHDLR_EAGERFREQ = 100;
static final boolean CONSHDLR_DELAYSEPA = false;
static final boolean CONSHDLR_DELAYPROP = false;
static final boolean CONSHDLR_NEEDSCONS = true;
static final SCIP_PROPTIMING CONSHDLR_PROP_TIMING = SCIP_PROPTIMING.BEFORELP;

/* Static methods for including the handler into SCIP or creating constraints. */
Expand Down Expand Up @@ -68,49 +68,9 @@ public SCIP_RESULT conscheck(SCIP scip, Cons_LOP[] conss, SCIP_SOL sol, boolean
boolean checklprows, boolean printreason, boolean completely) {
for(Cons_LOP cons : conss) {
scip.debugMsg("checking linear ordering constraint <"+cons.getName()+">.\n");
SCIP_VAR[][] vars = cons.vars;
int n = vars.length;

/* check triangle inequalities and symmetry equations */
for(int i=0; i<n; i++) {
for(int j=i+1; j<n; j++) {
boolean oneIJ = scip.getSolVal(sol, vars[i][j]) > 0.5;
boolean oneJI = scip.getSolVal(sol, vars[j][i]) > 0.5;

if ( oneIJ == oneJI ) {
scip.debugMsg("constraint <"+cons.getName()+"> infeasible (violated equation).\n");
scip.debugMsg("%s == %f, %s == %f\n", vars[i][j].getName(), scip.getSolVal(sol, vars[i][j]),
vars[j][i].getName(), scip.getSolVal(sol, vars[j][i]));
if( printreason ) {
scip.infoMessage(null,
"violation: symmetry equation violated <%s> = %.15g and <%s> = %.15g\n",
vars[i][j].getName(), scip.getSolVal(sol, vars[i][j]),
vars[j][i].getName(), scip.getSolVal(sol, vars[j][i]));
}
return SCIP_INFEASIBLE;
}

for(int k=i+1; k<n; k++) {
if(k==j)
continue;

boolean oneJK = scip.getSolVal(sol, vars[j][k]) > 0.5;
boolean oneKI = scip.getSolVal(sol, vars[k][i]) > 0.5;

if (oneIJ && oneJK && oneKI) {
scip.debugMsg("constraint <"+cons.getName()+"> infeasible (violated triangle ineq.).\n");
if( printreason ) {
scip.infoMessage(null,
"violation: triangle inequality violated <%s> = %.15g, <%s> = %.15g, <%s> = %.15g\n",
vars[i][j].getName(), scip.getSolVal(sol, vars[i][j]),
vars[j][k].getName(), scip.getSolVal(sol, vars[j][k]),
vars[k][i].getName(), scip.getSolVal(sol, vars[k][i]));
}
return SCIP_INFEASIBLE;
}
}
}
}

if(!cons.isFeasible_Integral(scip, sol, printreason))
return SCIP_INFEASIBLE;
}
scip.debugMsg("all linear ordering constraints are feasible.\n");
return SCIP_FEASIBLE;
Expand Down Expand Up @@ -139,39 +99,13 @@ public SCIP_RETCODE conslock(SCIP scip, Cons_LOP cons, SCIP_LOCKTYPE locktype, i
public SCIP_RESULT consenfops(SCIP scip, Cons_LOP[] conss, int nusefulconss, boolean solinfeasible,
boolean objinfeasible) {
for(Cons_LOP cons : conss) {
scip.debugMsg("enforcing pseudo solution for linear ordering constraint <"+cons.getName()+">.\n");

SCIP_VAR[][] vars = cons.vars;
int n = vars.length;

/* check triangle inequalities and symmetry equations */
for(int i=0; i<n; i++) {
for(int j=i+1; j<n; j++) {
boolean oneIJ = scip.getSolVal(null, vars[i][j]) > 0.5;
boolean oneJI = scip.getSolVal(null, vars[j][i]) > 0.5;

if ( oneIJ == oneJI ) {
scip.debugMsg("constraint <"+cons.getName()+"> infeasible (violated equation).\n");
return SCIP_INFEASIBLE;
}

for(int k=i+1; k<n; k++) {
if(k==j)
continue;

boolean oneJK = scip.getSolVal(null, vars[j][k]) > 0.5;
boolean oneKI = scip.getSolVal(null, vars[k][i]) > 0.5;

if (oneIJ && oneJK && oneKI) {
scip.debugMsg("constraint <"+cons.getName()+"> infeasible (violated triangle ineq.).\n");
return SCIP_INFEASIBLE;
}
}
}
}
}
scip.debugMsg("all linear ordering constraints are feasible.\n");
return SCIP_FEASIBLE;

scip.debugMsg("enforcing pseudo solution for linear ordering constraint <"+cons.getName()+">.\n");
if(!cons.isFeasible_Integral(scip, null, false))
return SCIP_INFEASIBLE;
}
scip.debugMsg("all linear ordering constraints are feasible.\n");
return SCIP_FEASIBLE;
}

@Override
Expand All @@ -181,8 +115,8 @@ public SCIP_RESULT consenfolp(SCIP scip, Cons_LOP[] conss, int nusefulconss, boo
return SCIP_DIDNOTRUN;

for(Cons_LOP cons : conss) {
scip.debugMsg("enforcing lp solution for linear ordering constraint <"+cons.getName()+">.\n");

scip.debugMsg("enforcing lp solution for linear ordering constraint <"+cons.getName()+">.\n");
SCIP_RESULT separation_res = cons.LOPseparate(scip, null);

//CUTOFF or SEPARATED
Expand Down Expand Up @@ -444,4 +378,4 @@ public SCIP_RESULT consresprop(SCIP scip, Cons_LOP cons, SCIP_VAR infervar, int

return SCIP_DIDNOTFIND;
}
}
}
Loading

0 comments on commit 1696f02

Please sign in to comment.