Search in sources :

Example 1 with GRBLinExpr

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);
    }
}
Also used : GRBLinExpr(gurobi.GRBLinExpr) Random(java.util.Random) HalfFace(org.twak.utils.geom.HalfMesh2.HalfFace) MFPoint(org.twak.tweed.gen.FeatureCache.MFPoint)

Example 2 with GRBLinExpr

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);
        }
    }
}
Also used : GRBLinExpr(gurobi.GRBLinExpr) MFPoint(org.twak.tweed.gen.FeatureCache.MFPoint)

Example 3 with GRBLinExpr

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;
}
Also used : GRBLinExpr(gurobi.GRBLinExpr) MFPoint(org.twak.tweed.gen.FeatureCache.MFPoint)

Example 4 with GRBLinExpr

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);
        }
    }
}
Also used : Color(java.awt.Color) GRBQuadExpr(gurobi.GRBQuadExpr) DumbCluster1D(org.twak.utils.DumbCluster1D) GRBException(gurobi.GRBException) Cache2(org.twak.utils.Cache2) StringAttr(gurobi.GRB.StringAttr) OptionalDouble(java.util.OptionalDouble) HalfFace(org.twak.utils.geom.HalfMesh2.HalfFace) HashMap(java.util.HashMap) Random(java.util.Random) Cach(org.twak.utils.Cach) Tweed(org.twak.tweed.Tweed) ArrayList(java.util.ArrayList) TweedSettings(org.twak.tweed.TweedSettings) HashSet(java.util.HashSet) GRBModel(gurobi.GRBModel) Map(java.util.Map) Cache(org.twak.utils.Cache) Mathz(org.twak.utils.Mathz) PaintThing(org.twak.utils.PaintThing) ProgressMonitor(javax.swing.ProgressMonitor) GRBVar(gurobi.GRBVar) Iterator(java.util.Iterator) ImageFeatures(org.twak.tweed.gen.FeatureCache.ImageFeatures) GRBLinExpr(gurobi.GRBLinExpr) MultiMap(org.twak.utils.collections.MultiMap) Line(org.twak.utils.Line) HalfEdge(org.twak.utils.geom.HalfMesh2.HalfEdge) Set(java.util.Set) HalfMesh2(org.twak.utils.geom.HalfMesh2) DoubleAttr(gurobi.GRB.DoubleAttr) MegaFeatures(org.twak.tweed.gen.FeatureCache.MegaFeatures) LinearForm(org.twak.utils.geom.LinearForm) Collectors(java.util.stream.Collectors) File(java.io.File) MFPoint(org.twak.tweed.gen.FeatureCache.MFPoint) Point2d(javax.vecmath.Point2d) List(java.util.List) Collections(java.util.Collections) GRBEnv(gurobi.GRBEnv) GRB(gurobi.GRB) GRBLinExpr(gurobi.GRBLinExpr) MegaFeatures(org.twak.tweed.gen.FeatureCache.MegaFeatures) ArrayList(java.util.ArrayList) HalfEdge(org.twak.utils.geom.HalfMesh2.HalfEdge) DumbCluster1D(org.twak.utils.DumbCluster1D) OptionalDouble(java.util.OptionalDouble) MFPoint(org.twak.tweed.gen.FeatureCache.MFPoint) GRBVar(gurobi.GRBVar) Cach(org.twak.utils.Cach) HalfMesh2(org.twak.utils.geom.HalfMesh2)

Example 5 with GRBLinExpr

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;
}
Also used : GRBModel(gurobi.GRBModel) GRBLinExpr(gurobi.GRBLinExpr) GRBVar(gurobi.GRBVar) GRBQuadExpr(gurobi.GRBQuadExpr) GRBEnv(gurobi.GRBEnv) GRBException(gurobi.GRBException)

Aggregations

GRBLinExpr (gurobi.GRBLinExpr)8 MFPoint (org.twak.tweed.gen.FeatureCache.MFPoint)6 GRBVar (gurobi.GRBVar)5 GRBException (gurobi.GRBException)3 GRBEnv (gurobi.GRBEnv)2 GRBModel (gurobi.GRBModel)2 GRBQuadExpr (gurobi.GRBQuadExpr)2 Color (java.awt.Color)2 Random (java.util.Random)2 Point2d (javax.vecmath.Point2d)2 Cache2 (org.twak.utils.Cache2)2 Line (org.twak.utils.Line)2 HalfMesh2 (org.twak.utils.geom.HalfMesh2)2 HalfEdge (org.twak.utils.geom.HalfMesh2.HalfEdge)2 HalfFace (org.twak.utils.geom.HalfMesh2.HalfFace)2 GRB (gurobi.GRB)1 DoubleAttr (gurobi.GRB.DoubleAttr)1 StringAttr (gurobi.GRB.StringAttr)1 File (java.io.File)1 ArrayList (java.util.ArrayList)1