# Efficient modelling via Gurobi

I would like to model the following constraint set in gurobi-java.

$$$$t^n_{ij} \geq t^n_{(i-1)j}+S_{(i-1)j} - (1 - \sum_{\substack{m \in \mathcal{M} \\ G_{ijm} = 1}}\sum_{k \in \mathcal{K}} x^n_{ijmk}) \times \Omega \hspace{1cm} \forall j \in \mathcal{J}; i \in \mathcal{I}_j/1; n \in \mathcal{N}_j$$$$

where $$t^n_{ij} \in \mathbb{R}_{\geq0}$$ and $$x^n_{ijmk} \in \{0,1\}$$ are decision variables. I have modeled this constraint set in gurobi-java as follows:

GRBVar[][][][][] x = new GRBVar[i_idx][j_idx][n_idx][m_idx][k_idx];
for (int j : j_set) {
for (int i : i_set[j]) {
for (int n : n_set[j]) {
for (int m : m_set) {
if (G[i][j][m] == true) {
for (int k : k_set) {
x[i][j][n][m][k] = model.addVar(0, 1, 1, GRB.BINARY,
i + "_" + j + "_" + n + "_" + m + "_" + k);
}
}
}
}
}
}

GRBVar[][][] t = new GRBVar[i_idx][j_idx][n_idx];
for (int j : j_set) {
for (int i : i_set[j]) {
for (int n : n_set[j]) {
t[i][j][n] = model.addVar(0, GRB.INFINITY, 0, GRB.CONTINUOUS,
i + "_" + j + "_" + n);
}
}
}

GRBVar[][][] auxvar1 = new GRBVar[i_idx][j_idx][n_idx];
for (int j : j_set) {
for (int i : i_set[j]) {
for (int n : n_set[j]) {
auxvar1[i][j][n] = model.addVar(0, 1, 1, GRB.BINARY,
i + "_" + j + "_" + n);

GRBLinExpr lhs = new GRBLinExpr();
GRBLinExpr rhs = new GRBLinExpr();

lhs.addTerm(1, auxvar1[i][j][n]);
rhs.addConstant(1);
for (int m : m_set) {
if (G[i][j][m] == true) {
for (int k : k_set) {
rhs.addTerm(-1, x[i][j][n][m][k]);
}
}
}

model.addConstr(lhs, GRB.EQUAL, rhs, "auxiliary_" + i + "_" + j + "_" + n);
}
}
}

for (int j : j_set) {
for (int i = 1; i < i_set[j].length; i++) {
for (int n : n_set[j]) {
GRBLinExpr lhs = new GRBLinExpr();
GRBLinExpr rhs = new GRBLinExpr();

lhs.addTerm(1, t[i][j][n]);

rhs.addTerm(1, t[i-1][j][n]);
rhs.addConstant(S[j][i-1]);
rhs.addTerm(-Omega, auxvar1[i][j][n]);

model.addConstr(lhs, GRB.GREATER_EQUAL, rhs, "time_flow_" + i + "_" + j + "_" + n);
}
}
}


In comparison to docplex-python, it is much less readable and requires much more lines of code.

mdl.add_constraints(t[i, j ,n] >= t[i-1, j, n] + S[i-1, j] - (1 - mdl.sum(x[i, j, n, m, k] for m in m_set if G[i, j, m] == 1 for k in k_set) * Omega for j in j_set for i in i_set[j] if i > 0 for n in n_set[j]))


I am new to gurobi-java. Are there any better ways to model this constraint set.

• Gurobi also has Model.addVars and Model.addConstrs that are used to create variables and constraints in a batch
– EhsanK
Commented Nov 7, 2022 at 4:26
• Those you pointed out are for Python. Similar functions are available for Java, however, I think they do not allow for the inline construction of variables and constraints. For example, one should determine arrays of lhsExprs, senses, rhss and names (you need the multiple loops in multiple lines). Commented Nov 7, 2022 at 14:27
• Java links: GRBModel.addVars(), GRBModel.addConstrs(). Full list of Java Examples, particularly, no example uses addConstrs as Java doesn't have nice list-comprehensions like Python. A few use addVars: e.g. GCPWL.java. Commented Nov 7, 2022 at 16:45
• Without the intention of triggering a language war now, I believe it's worth mentioning that Java doesn't support operator overloading, so the readability of math-related java code is limited by nature.
– joni
Commented Nov 8, 2022 at 9:39

## 1 Answer

Probably not the answer you want, but Gurobi has a very nice Python interface. I'd be surprised if there was anything you liked from docplex that you wouldn't find to be at least as good or better in gurobipy.

When porting Python code to Java code, as a rule, there will probably a loss in readability/brevity. That's why Python is far more popular for data science, and now, for even general purpose programming.

• Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
– Community Bot
Commented Nov 7, 2022 at 12:32