I'm trying to formulate a VRPTW model in Java, same one in OPL works just fine, but I keep getting problem with one constrain:
a[i][k]+t[i][j]- a[j][k] + M * x[i][j][k] = M
I get error mesagge: The method addTerm(double, IloNumVar) in the type IloLinearNumExpr is not applicable for the arguments (double).
It seams that it is a problem only with t[i][j] which is double and calculated based on two other doubles: t[i][j] = d[i][j]+ s[i];
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
for(int k = 0; k < v; k++) {
if(i != j) {
IloLinearNumExpr expr8 = cplex.linearNumExpr();
expr8.addTerm(1.0, a[i][k]);
expr8.addTerm(t[i][j]);
expr8.addTerm(-1.0, a[j][k]);
expr8.addTerm(M, x[i][j][k]);
cplex.addLe(expr8, M);
Any ideas are welcome.
Thank you!
You should use setConstant:
expr8.setConstant(t[i][j]);
Related
I need to blend two objective functions f1 and f2 (see image here) where c is a continuous variable, C_{ug} is a binary variable and a,d and f are parameters. I'm using Cplex Studio IDE 22.1.0 Java in eclipse.
// create the objetive function f1
IloLinearNumExpr firstPart = cplex.linearNumExpr();
int aSum = 0;
for (int k = 0; k < inst.n + inst.m; k++) {
firstPart.addTerm(1, c[k]);
aSum += -inst.a[k];
}
firstPart.setConstant(aSum);
IloLinearNumExpr secondPart = cplex.linearNumExpr();
for (int k = 0; k < inst.n + inst.m; k++) {
// This is the equivalent to z[k] = max(c[k] - d[k], 0)
cplex.addEq(z[k], cplex.max(0, cplex.sum(c[k], -inst.d[k])));
secondPart.addTerm(inst.f[k], z[k]);
}
IloLinearNumExpr objective = cplex.linearNumExpr();
objective.add(firstPart);
objective.add(secondPart);
// create the objetive function f2
IloLinearNumExpr secobj = cplex.linearNumExpr();
for (int tt = 0; tt < inst.T; tt++) {
for (int k = 0; k < inst.q; k++) {
for (int j = 0; j < inst.B; j++) {
secobj.addTerm(1, C[j][k]);
}}}
IloCplex.staticLex(objective, secobj );
I'm getting the following error: the method staticLex(IloNumExpr, String) in the type IloCplex is not applicable for the arguments (IloLinearNumExpr, IloLinearNumExpr).
Does anyone know how I can solve this problem? Many thanks.
I am trying to minimize the function a quadratic function sum(sum (w*a)-v)^2
being "a" square array and "w" and "v" two vectors. "a" and "v" are known, "w" is unknown. I am using CPLEX in Java
double [][] input = {{1,2},{3,4}};
double[] result = {3,2};
//define new model
IloCplex cplex = new IloCplex();
// variables
IloNumVar[] w = new IloNumVar[input[0].length];
for (int i = 0; i < w.length; i++) {
w[i] = cplex.numVar(0.0, 1.0, IloNumVarType.Float);
}
IloNumExpr value = cplex.numExpr();
IloNumExpr objective = cplex.numExpr();
for (int i = 0; i < result.length; i++) {
for (int j = 0; j < result.length; j++) {
value = cplex.sum(value, cplex.prod(input[i][j], w[i]));
}
value = cplex.diff(value, result[i]);
value = cplex.square(value);
objective = cplex.sum(objective, value);
}
but I got this exception which I do not understand:
Exception in thread "main" java.lang.UnsupportedOperationException: CpxObjective for general expressions
at ilog.cplex.CpxObjective.setExpr(CpxObjective.java:102)
at ilog.cplex.CpxObjective.<init>(CpxObjective.java:357)
at ilog.cplex.IloCplexModeler.objective(IloCplexModeler.java:796)
at ilog.cplex.IloCplexModeler.minimize(IloCplexModeler.java:714)
at ilog.cplex.IloCplexModeler.minimize(IloCplexModeler.java:810)
at Tont.main(Tont.java:55)
Thanks for helping.
As far as I can tell, your first iteration of the outer loop creates terms like w[i]^2. The second iteration of the outer loops then takes this expression and squares it. Thus creating terms like w[i]^2. This is not supported. Only exponents of 1 and 2 are supported (linear and quadratic objectives).
From what you wrote, I think you are not creating your objective right. It should look something like this (note the initialization of value moved into the loop):
for (int i = 0; i < result.length; i++) {
IloNumExpr value = cplex.numExpr();
for (int j = 0; j < result.length; j++) {
value = cplex.sum(value, cplex.prod(input[i][j], w[i]));
}
value = cplex.diff(value, result[i]);
value = cplex.square(value);
objective = cplex.sum(objective, value);
}
This is the complete code, but it is infeasible. is it because Cplex cannot solve this kind of problems?
double [][] input = {{1,2},{3,4}};
double[] result = {3,2};
// define new model
IloCplex cplex = new IloCplex();
//cplex.setParam(IloCplex.Param.RootAlgorithm, IloCplex.Algorithm.Auto);
// variables
IloNumVar[] w = cplex.numVarArray(input[0].length, 0, Float.MAX_VALUE);// new IloNumVar[input[0].length];
for (int i = 0; i < w.length; i++) {
w[i] = cplex.numVar(0.0, 1.0, IloNumVarType.Float);
}
//IloNumExpr value = cplex.numExpr();
IloNumExpr objective = cplex.numExpr();
for (int i = 0; i < result.length; i++) {
IloNumExpr value = cplex.numExpr();
for (int j = 0; j < result.length; j++) {
value = cplex.sum(value, cplex.prod(input[i][j], w[i]));
}
value = cplex.diff(value, result[i]);
value = cplex.square(value);
objective = cplex.sum(objective, value);
}
cplex.minimize(objective);
//constraints
IloLinearNumExpr weightsAdded = cplex.linearNumExpr();
for (int j = 0; j < w.length; j++) {
weightsAdded.addTerm(1, w[j]);
}
cplex.addEq(weightsAdded, 1);
for (int i = 0; i < w.length; i++) {
cplex.addGe(0, w[i]);
}
// solve model
if (cplex.solve()) {
System.out.println("obj = "+cplex.getObjValue());
}
else {
System.out.println("problem not solved");
Thank you
Actually the following code is doing the gaussian elimination for a matrix. And my job is to try some java concurrency technique to let it be a parallel program.
However, the problem is that each external loop has the data dependency which comes from the previous loop. And I have try that it is too costly to use the parallel technique inside the external loop. Can someone help me with it? How to let the following code run by parallel? Is there any technique in java concurrency technique can handle with this condition?
for (int i = 0; i <1; i++) {
int max = i;
for (int j = i + 1; j < N; j++) {
if (Math.abs(matrix[j][i]) > Math.abs(matrix[max][i])) {
max = j;
}
}
double[] temp = matrix[i];
matrix[i] = matrix[max];
matrix[max] = temp;
for (int k = i + 1; k < N; k++)
{
double alpha = matrix[k][i] / matrix[i][i];
for (int j = i; j < N; j++)
{
matrix[k][j] -= alpha * matrix[i][j];
}
}
}
The work done by the k loop can be made parallel, since the modified data is non-overlapping.
Simply delegate the work done by the body of the loop to a thread.
Easiest way is to use a Java 8 parallel stream, i.e. replace the k loop with:
final int ii = i; // since 'i' is not effectively-final
IntStream.range(ii + 1, N).parallel().forEach(k -> {
double alpha = matrix[k][ii] / matrix[ii][ii];
for (int j = ii; j < N; j++) {
matrix[k][j] -= alpha * matrix[ii][j];
}
});
This code is supposed to multiply two matrices which it does. This was for a homework assignment that I got 100 on it because my buddy helped me out.
But I'm trying to actually understand how it works and I keep getting confused for some reason. I don't really understand what the third for loop is doing.
int mA = matrix1.length;
int nA = matrix1[0].length;
int mB = matrix2.length;
int nB = matrix2[0].length;
if (nA != mB){
return null;
double[][] C = new double[mA][nB];
for (int i = 0; i < mA; i++)
for (int j = 0; j < nB; j++)
for (int k = 0; k < nA; k++)
C[i][j] += matrix1[i][k] * matrix2[k][j];
return C;
You are implementing matrix multiplication.
You can find a good explanation on Java With Us
I have three arrays of equal lengths that I combine (as I will sort them on column c later):
double abc[][] = {
Arrays.copyOf(a, a.length),
Arrays.copyOf(b, a.length),
Arrays.copyOf(c, a.length)
};
When I call
System.out.println(Arrays.deepToString(abc));
I receieve:
[[4.0, 2.0, 1.3333333333333333, 5.0, 2.5, 1.6666666666666667 ....
However, I would prefer something like:
[[1.0, 1.0, 4.0], [2.0, 2.0, 5.0], [3.0, 3.0, 7.0]]
This is possible using double singlets
double test[][] = {{1,1,4},{2,2,5},{3,3,7}};
How can I populate/initialize three columns using three double[ ]?
EDIT:
Solution based on vojta's answer:
double abcT[][] = new double[abc[0].length][abc.length];
for (int i = 0; i < abc.length; i++) {
for (int j = 0; j < abc[0].length; j++) {
abcT[j][i] = abc[i][j];
}
}
System.out.println(Arrays.deepToString(abcT));
I think there is no one-line solution of your problem, unfortunately. You will have to use some homemade code:
static <T> T[][] createMatrix(T[]... columns) {
if (columns== null || columns.length == 0)
return new T[0][0];
int wid = columns.length;
int ht = columns[0].length;
T[][] result = new T[ht][wid];
for (int x = 0; x < wid; x++) {
for (int y = 0; y < ht; y++) {
result[y][x] = columns[x][y];
}
}
return result;
}
I hope it was useful.
I finally reached this more elegant solution:
for (int i = 0; i < a.length; i++){
abc[0][i] = a[i];
abc[1][i] = b[i];
abc[2][i] = c[i];
}
Although it is not a general solution for n[], this avoids the need to make intermediate copies of the original arrays. And then I just swap the for-loops for row and column:
for (int j = 0; j < abc[0].length; j++) {
for (int i = 0; i < abc.length; i++) {
System.out.print(abc[i][j] + " ");
}
System.out.print("\n");
}
Note: This solution does not store in the intended R:C format, but retrieves in C:R.