use of gurobi.GRBLinExpr in project chordatlas by twak.
the class GurobiSkelSolver method buildProfiles.
private void buildProfiles() throws GRBException {
for (HalfEdge e : edges) {
if (// when a profile ends, we assume it can't start again...
((SuperEdge) e).profLine == null)
continue;
EdgeVars ev = edgeInfo.get(e);
ev.profile = new GRBVar[globalProfs.size()];
for (int p = 0; p < globalProfs.size(); p++) {
ev.profile[p] = model.addVar(0.0, 1.0, 0, GRB.BINARY, PROFILE_SELECT);
set(ev.profile[p], p == 0 ? 1 : 0);
}
}
Cache2<HalfEdge, HalfEdge, GRBVar> isProfileDifferent = new Cache2<HalfMesh2.HalfEdge, HalfMesh2.HalfEdge, GRBVar>() {
@Override
public GRBVar create(HalfEdge e1, HalfEdge e2) {
try {
GRBVar s = model.addVar(0.0, 1.0, 0.0, GRB.BINARY, PROFILE_DIFFERENT);
buildIsDifferentColor(s, edgeInfo.get(e1).profile, edgeInfo.get(e2).profile, "profile");
s.set(DoubleAttr.Start, 0);
return s;
} catch (GRBException e) {
e.printStackTrace();
}
return null;
}
};
for (HalfEdge e1 : edges) {
// if (e1.over != null)
// continue;
EdgeVars ev = edgeInfo.get(e1);
if (ev.profile == null)
continue;
double[] fit = profFit.get(e1);
GRBLinExpr pickOneProfile = new GRBLinExpr();
for (int p = 0; p < globalProfs.size(); p++) {
GRBVar a = ev.profile[p];
pickOneProfile.addTerm(1, a);
target.addTerm(.001 * fit[p] * e1.length(), a);
}
model.addConstr(pickOneProfile, GRB.EQUAL, 1, /*ev.isEdge*/
"pick only one profile for " + e1);
List<HalfEdge> atEnd = e1.collectAroundEnd();
for (HalfEdge e2 : atEnd) {
if (e1 != e2 && edgeInfo.get(e2).profile != null && // only constrain if ~parallel
e1.line().absAngle(e2.line()) < 0.1) {
GRBVar s = isProfileDifferent.get(e1, e2);
// ev.debug = s;
// Point2d dbg = new Point2d(e1.end);
// dbg.add(new Point2d(Math.random() * 0.1, Math.random() * 0.1));
GRBLinExpr perpIsEdge = new GRBLinExpr();
for (HalfEdge e3 : atEnd) {
if (e3 == e1 || e3 == e2 || e3 == e1.over || e3 == e2.over || (e3.over != null && (e3.over == e1.over || e3.over == e2.over)))
continue;
if (!e1.line().isOnLeft(e1.end.distanceSquared(e3.start) > e1.end.distanceSquared(e3.end) ? e3.start : e3.end))
continue;
perpIsEdge.addTerm(1, edgeInfo.get(e3).isEdge);
// PaintThing.debug.put(e2, dbg);
// Point2d d2 = new Point2d(e3.line().dir());
// d2.scale (0.1/new Vector2d(d2).length());
// d2.add(dbg);
// PaintThing.debug.put(e2, new Line (dbg, d2));
// model.addConstr( s, GRB.LESS_EQUAL, edgeInfo.get(e3).isEdge, "only change profile if no adjacent edge "+e1 );
}
model.addConstr(s, GRB.LESS_EQUAL, perpIsEdge, "dont' change profile over " + e1);
// PaintThing.debug.put(e2, dbg);
// Point2d d2 = new Point2d(e2.line().dir());
// d2.scale (0.2/new Vector2d(d2).length());
// d2.add(dbg);
// PaintThing.debug.put(e2, new Line (dbg, d2));
}
}
}
countNearbyProfiles = 0;
if (false)
for (int i = 0; i < edges.size(); i++) {
HalfEdge e1 = edges.get(i);
if (edgeInfo.get(e1).profile == null)
continue;
print("building edge locality term " + i + " / " + edges.size());
for (HalfEdge e2 : edges) if (lt(e1, e2) && edgeInfo.get(e2).profile != null) {
if (e1.line().distance(e2.line()) < 2) {
GRBVar s = isProfileDifferent.get(e1, e2);
target.addTerm(0.1 * (e1.length() + e2.length()), s);
countNearbyProfiles++;
}
}
}
}
use of gurobi.GRBLinExpr in project chordatlas by twak.
the class GurobiSkelSolver method notBoth.
private void notBoth(HalfEdge e1, HalfEdge e2, boolean isContraint, double badThingsAreBad) throws GRBException {
GRBLinExpr no = new GRBLinExpr();
no.addTerm(1, edgeInfo.get(e1).isEdge);
no.addTerm(1, edgeInfo.get(e2).isEdge);
if (isContraint) {
model.addConstr(no, GRB.LESS_EQUAL, 1, "bad geom < 1");
} else {
GRBVar bothSelected = model.addVar(0.0, 1.0, 0, GRB.BINARY, BAD_GEOM);
no.addTerm(-2, bothSelected);
model.addConstr(no, GRB.LESS_EQUAL, 1, "bad geom <");
model.addConstr(no, GRB.GREATER_EQUAL, -0.5, "bad geom >");
target.addTerm(badThingsAreBad, bothSelected);
{
Line l1 = e1.line(), l2 = e2.line();
l1.start = new Point2d(l1.start);
l1.end = new Point2d(l1.end);
l2.start = new Point2d(l2.start);
l2.end = new Point2d(l2.end);
l1.moveLeft(-0.1);
l2.moveLeft(-0.1);
PaintThing.debug(new Color(255, 170, 0), 2, l1);
PaintThing.debug(new Color(170, 0, 255), 2, l2);
edgeInfo.get(e1).debug = bothSelected;
}
}
}
use of gurobi.GRBLinExpr in project chordatlas by twak.
the class GurobiSkelSolver method buildIsDifferentColor.
private void buildIsDifferentColor(GRBVar isDifferent, GRBVar[] ac, GRBVar[] bc, String desc) throws GRBException {
GRBLinExpr isEdgeEx = new GRBLinExpr();
GRBLinExpr expr;
for (int c = 0; c < ac.length; c++) {
GRBVar a = ac[c], b = bc[c], xor = model.addVar(0.0, 1.0, 0, GRB.BINARY, XOR + " " + desc);
// if (setVars.containsKey( a ) && setVars.containsKey( b ))
// xor.set( DoubleAttr.Start, (setVars.get(a) == 1) ^ ( setVars.get(b) == 1 ) ? 1 : 0 );
expr = new GRBLinExpr();
expr.addTerm(1, a);
expr.addTerm(1, b);
model.addConstr(xor, GRB.LESS_EQUAL, expr, "same color " + c);
expr = new GRBLinExpr();
expr.addTerm(1, a);
expr.addTerm(-1, b);
model.addConstr(xor, GRB.GREATER_EQUAL, expr, "same color " + c);
expr = new GRBLinExpr();
expr.addTerm(-1, a);
expr.addTerm(1, b);
model.addConstr(xor, GRB.GREATER_EQUAL, expr, "same color " + c);
expr = new GRBLinExpr();
expr.addTerm(1, a);
expr.addTerm(1, b);
expr.addTerm(1, xor);
model.addConstr(expr, GRB.LESS_EQUAL, 2, "same color " + c);
isEdgeEx.addTerm(1, xor);
}
isEdgeEx.addTerm(-2, isDifferent);
model.addConstr(isEdgeEx, GRB.LESS_EQUAL, 0.5, "is different " + desc);
model.addConstr(isEdgeEx, GRB.GREATER_EQUAL, -1.5, "is different " + desc);
}
Aggregations