use of gurobi.GRBLinExpr in project chordatlas by twak.
the class GurobiSkelSolver method buildColouringProblem.
private void buildColouringProblem() throws GRBException {
Random randy = new Random();
for (int f = 0; f < mesh.faces.size(); f++) {
// create face colors
SuperFace sf = (SuperFace) mesh.faces.get(f);
// f2i.put( sf, f );
// int startCol = 0;
//
// for (HalfFace n : sf.getNeighbours()) {
// Integer ni;
// if ( (ni = f2i.get( (SuperFace) n ) ) != null ) {
//
// int nc = -1;
// for ( int c = 0; c < colors; c++ )
// if ( setVars.get( xfc[ni][c] ) == 1)
// nc = c;
//
// if (nc == startCol)
// startCol++;
//
// }
// }
// if (startCol == colors)
int startCol = randy.nextInt(colors);
FaceVars fv;
faceInfo.put(sf, fv = new FaceVars());
fv.color = new GRBVar[colors];
for (int c = 0; c < colors; c++) {
fv.color[c] = model.addVar(0.0, 1.0, 0.0, GRB.BINARY, FACE_COLOR);
set(fv.color[c], c == startCol ? 1 : 0);
}
}
for (HalfFace f : mesh) {
FaceVars fv = faceInfo.get(f);
GRBLinExpr expr = new GRBLinExpr();
for (int c = 0; c < colors; c++) expr.addTerm(1, fv.color[c]);
model.addConstr(expr, GRB.EQUAL, 1, "overlap_" + f);
}
}
use of gurobi.GRBLinExpr in project chordatlas by twak.
the class GurobiSkelSolver method buildIsEdge.
private void buildIsEdge() throws GRBException {
for (int e = 0; e < edges.size(); e++) {
SuperEdge se = (SuperEdge) edges.get(e);
edgeInfo.put(se, new EdgeVars(model.addVar(0.0, 1.0, 0, GRB.BINARY, IS_EDGE), model.addVar(0.0, 1.0, 0, GRB.BINARY, IS_NOT_EDGE), se.profLine != null || (se.over != null && ((SuperEdge) se.over).profLine != null) ? 1 : 0, model.addVar(0.0, 1.0, 0, GRB.BINARY, EDGE_NO_PROFILE), model.addVar(0.0, 1.0, 0, GRB.BINARY, PROFILE_NO_EDGE)));
GRBLinExpr notEdge = new GRBLinExpr();
notEdge.addConstant(1);
notEdge.addTerm(-1, edgeInfo.get(se).isEdge);
model.addConstr(notEdge, GRB.EQUAL, notEdge, "is not isEdge");
}
for (int e = 0; e < edges.size(); e++) {
SuperEdge se = (SuperEdge) edges.get(e);
EdgeVars ei = edgeInfo.get(se);
if (se.over == null) {
model.addConstr(ei.isEdge, GRB.EQUAL, 1, "is outside edge");
continue;
}
buildIsDifferentColor(ei.isEdge, faceInfo.get((SuperFace) se.face).color, faceInfo.get((SuperFace) se.over.face).color, "face colouring");
GRBLinExpr expr;
{
// edge no profile from isEdge, hasProfile
expr = new GRBLinExpr();
expr.addTerm(1, ei.isEdge);
expr.addConstant(ei.hasProfile);
model.addConstr(ei.edgeNoProfile, GRB.LESS_EQUAL, expr, null);
expr = new GRBLinExpr();
expr.addTerm(1, ei.edgeNoProfile);
expr.addConstant(ei.hasProfile);
model.addConstr(expr, GRB.LESS_EQUAL, 1, null);
expr = new GRBLinExpr();
expr.addTerm(1, ei.isEdge);
expr.addConstant(-ei.hasProfile);
model.addConstr(ei.edgeNoProfile, GRB.GREATER_EQUAL, expr, null);
}
{
// profile no edge from isEdge, hasProfile
expr = new GRBLinExpr();
expr.addTerm(1, ei.isEdge);
expr.addConstant(ei.hasProfile);
model.addConstr(ei.profileNoEdge, GRB.LESS_EQUAL, expr, null);
expr = new GRBLinExpr();
expr.addTerm(1, ei.profileNoEdge);
expr.addTerm(1, ei.isEdge);
model.addConstr(expr, GRB.LESS_EQUAL, 1, null);
expr = new GRBLinExpr();
expr.addTerm(-1, ei.isEdge);
expr.addConstant(ei.hasProfile);
model.addConstr(ei.profileNoEdge, GRB.GREATER_EQUAL, expr, null);
}
}
}
use of gurobi.GRBLinExpr in project chordatlas by twak.
the class GurobiSkelSolver method scale.
private GRBLinExpr scale(double scale, GRBLinExpr is) throws GRBException {
if (scale == 1)
return is;
GRBLinExpr out = new GRBLinExpr();
for (int i = 0; i < is.size(); i++) {
out.addTerm(is.getCoeff(i) * scale, is.getVar(i));
}
out.addConstant(is.getConstant() * scale);
return out;
}
use of gurobi.GRBLinExpr in project chordatlas by twak.
the class GurobiSkelSolver method buildMini.
private void buildMini() throws GRBException {
Cache<HalfEdge, GRBLinExpr> isMiniExpr = new Cach<HalfMesh2.HalfEdge, GRBLinExpr>(he -> new GRBLinExpr());
if (minis == null)
return;
for (MegaFeatures mf : minis.keySet()) {
List<MiniPtCluster> clusterVars = new ArrayList<>();
mega2clusters.put(mf, clusterVars);
double mLen = mf.megafacade.length();
DumbCluster1D<MFPoint> clusters = clusterMinis(mf, minis);
for (DumbCluster1D.Cluster<MFPoint> d : clusters) {
// for each cluster, we pick a single MFPoint as the boundary
MiniPtCluster miniPtVar = new MiniPtCluster();
Cache<HalfEdge, GRBLinExpr> isEdgeBind = new Cach<HalfMesh2.HalfEdge, GRBLinExpr>(he -> new GRBLinExpr());
GRBLinExpr selectHE = new GRBLinExpr();
boolean one = false;
for (MFPoint pt : d.things) {
MiniSelectEdge miniSelectEdge = new MiniSelectEdge();
miniPtVar.put(pt, miniSelectEdge);
List<HalfEdge> nearCorners = findNear(mf.megafacade, pt, mesh);
try {
for (HalfEdge he : nearCorners) {
GRBVar heVar = model.addVar(0.0, 1.0, 0, GRB.BINARY, MINI_TO_EDGE);
miniSelectEdge.edge.put(he, heVar);
selectHE.addTerm(1, heVar);
double cost = he.end.distance(pt);
if (he.over != null) {
if (pt.right != null)
cost += Math.abs(pt.right.height - ((SuperFace) he.face).height);
if (pt.left != null)
cost += Math.abs(pt.left.height - ((SuperFace) he.over.face).height);
isEdgeBind.get(he).addTerm(1, heVar);
} else
// bonus for being on a corner;
cost -= totalEdgeLength * 0.1;
target.addTerm(cost, heVar);
isMiniExpr.get(he).addTerm(1, heVar);
one = true;
}
} catch (Throwable th) {
th.printStackTrace();
}
}
if (one) {
clusterVars.add(miniPtVar);
model.addConstr(selectHE, GRB.EQUAL, 1, "pick one near " + d.things.iterator().next());
} else
print("warning skipping minifacade loction " + d.things.size());
for (HalfEdge he : isEdgeBind.cache.keySet()) model.addConstr(isEdgeBind.get(he), GRB.EQUAL, edgeInfo.get(he).isEdge, "minifacade boundary must terminate on edge " + he);
miniPtVar.mean = mf.megafacade.fromPPram(d.mean / mLen);
}
}
double penalty = totalEdgeLength * 0.1;
for (HalfEdge he : edges) {
if (he.over != null && he.next.over == null) {
// edge comes to boundary without minifacade --> penalty
OptionalDouble miniDist = minis.keySet().stream().map(mf -> mf.megafacade).mapToDouble(line -> line.distance(he.end, true)).min();
if (!miniDist.isPresent() || miniDist.getAsDouble() > 4)
continue;
EdgeVars ei = edgeInfo.get(he);
ei.edgeNoMini = model.addVar(0.0, 1.0, 0, GRB.BINARY, EDGE_NO_MINI);
if (isMiniExpr.cache.containsKey(he)) {
ei.isMini = model.addVar(0.0, 1.0, 0, GRB.BINARY, IS_MINI);
GRBLinExpr is = isMiniExpr.get(he);
/* ei.isMini might take 0 or positive integer... assume it's below 10 (0.1 = 1/10) */
model.addConstr(ei.isMini, GRB.LESS_EQUAL, is, "is minifacade on edge " + he);
model.addConstr(scale(0.1, is), GRB.LESS_EQUAL, ei.isMini, "is minifacade on edge " + he);
GRBLinExpr expr = new GRBLinExpr();
expr.addTerm(1, ei.isEdge);
expr.addTerm(1, ei.isMini);
model.addConstr(ei.edgeNoMini, GRB.LESS_EQUAL, expr, null);
expr = new GRBLinExpr();
expr.addTerm(1, ei.edgeNoMini);
expr.addTerm(1, ei.isMini);
model.addConstr(expr, GRB.LESS_EQUAL, 1, null);
expr = new GRBLinExpr();
expr.addTerm(1, ei.isEdge);
expr.addTerm(-1, ei.isMini);
model.addConstr(ei.edgeNoMini, GRB.GREATER_EQUAL, expr, null);
} else {
// no mini, but easier debug
model.addConstr(ei.edgeNoMini, GRB.EQUAL, ei.isEdge, null);
}
target.addTerm(penalty, ei.edgeNoMini);
}
}
}
use of gurobi.GRBLinExpr in project chordatlas by twak.
the class SliceSolver method sliceOptimize.
public static int[] sliceOptimize(int numSlices, double[][] data, double[][] alignment) {
try {
GRBEnv env = new GRBEnv("mip1.log");
GRBModel model = new GRBModel(env);
GRBVar[][] xij = new GRBVar[numSlices][numSlices];
for (int i = 0; i < numSlices; i++) for (int j = 0; j < numSlices; j++) xij[i][j] = model.addVar(0.0, 1.0, 1.0, GRB.BINARY, "x" + i + "_" + j);
// overlap term n^2 terms
for (int i = 0; i < numSlices; i++) {
GRBLinExpr expr = new GRBLinExpr();
for (int j = 0; j < numSlices; j++) expr.addTerm(1, xij[i][j]);
model.addConstr(expr, GRB.EQUAL, 1, "overlap_" + i);
}
// for ( int i = 0; i < numSlices-1; i++ ) {
// for ( int j = 0; j < numSlices; j++ ) {
// GRBLinExpr expr = new GRBLinExpr();
// expr.addTerm( 1, xij[ i ] [ j ] );
// expr.addTerm( -1, xij[ i+1 ] [ j ] );
// model.addConstr( expr, GRB.EQUAL, 0, "super_adjacency" + j );
// }
// }
// data fitting term n^2 terms
GRBQuadExpr target = new GRBQuadExpr();
for (int i = 0; i < numSlices; i++) {
for (int j = 0; j < numSlices; j++) {
if (data[i][j] != Double.MAX_VALUE)
target.addTerm(data[i][j] * 30, xij[i][j]);
else
target.addTerm(1e3, xij[i][j]);
}
}
// neighbour alignment n^3 quadratic terms
for (int i = 0; i < numSlices - 1; i++) for (int ja = 0; ja < numSlices; ja++) for (int jb = 0; jb < numSlices; jb++) target.addTerm(alignment[ja][jb] == Double.MAX_VALUE ? 1e2 : alignment[ja][jb], xij[i][ja], xij[i + 1][jb]);
model.setObjective(target, GRB.MINIMIZE);
model.getEnv().set(GRB.DoubleParam.TimeLimit, 10.0);
model.optimize();
// xij[0][0].set( DoubleAttr.X, 1 );
// target.getValue();
System.out.println("Obj: " + model.get(GRB.DoubleAttr.ObjVal));
int[] out = new int[numSlices];
for (int i = 0; i < numSlices; i++) {
System.out.print("i: " + i + " ");
for (int j = 0; j < numSlices; j++) {
System.out.print(xij[i][j].get(GRB.DoubleAttr.X) + " ");
if (xij[i][j].get(GRB.DoubleAttr.X) == 1)
out[i] = j;
}
System.out.println();
}
// Dispose of model and environment
model.dispose();
env.dispose();
return out;
} catch (GRBException e) {
System.out.println("Error code: " + e.getErrorCode() + ". " + e.getMessage());
e.printStackTrace();
}
return null;
}
Aggregations