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.
Related
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
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]);
The following code:
// Adds game button container
Object[][] gameButtons = new Object[3][3];
// Adds game buttons to game button container
Arrays.fill(gameButtons, new JButton[3][3]);
for (int i = 0; i < gameButtons.length; i++) {
for (int j = 0; j < gameButtons[i].length; j++) {
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 3; l++) {
gameButtons[i][j][k][l] = new JButton();******
}
}
}
}
is throwing me an error:
The type of the expression must be an array type but it resolved to Object. How do I initialize the JButtons?
EDIT: I forgot to clarify. The error was thrown at the line ******
Note that the ****** was not in my code.
EDIT 2: I tried Logan's fix, but it still didn't work:
for (Object[] row : gameButtons)
Arrays.fill(row, new JButton[3][3]);
for (int i = 0; i < gameButtons.length; i++) {
for (int j = 0; j < gameButtons[i].length; j++) {
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 3; l++) {
gameButtons[i][j][k][l] = new JButton();
}
}
}
}
Same error, same place.
gameButtons[i][j] is of type Object, which cannot be indexed as an array. You must first cast it to a JButton[][] type:
for (int i = 0; i < gameButtons.length; i++) {
for (int j = 0; j < gameButtons[i].length; j++) {
// cast it to an array type before accessing
JButton[][] subArray = (JButton[][])(gameButtons[i][j]);
for (int k = 0; k < 3; k++)
for (int l = 0; l < 3; l++)
subArray[k][l] = new JButton();
}
}
I believe you don't need a for loop. If I understand your problem correctly, you can do like this:
//create a sub array
Object[][] subArray = new Object[3][3];
// create game button container
Object[][] gameButtons = new Object[3][3];
// Adds buttons to sub array
Arrays.fill(subArray, new JButton[3][3]);
// Adds sub array to game button container
Arrays.fill(gameButtons, subArray);
The docs helped me a lot with this.
You could also use a GUI maker such as the one in NetBeans IDE it's much simpler than writing the code yourself.
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.
how do I populate a matrix in java with a array without using libs?
I have this method
public static String[][] transformArray(String msg, int slice) {
String matrix[][] = new String[slice][msg.length() / slice];
String[] msgArray= mensagem.split("");
for (int j = 0; j < matrix.length; j++) {
for (int h = 0; h < matrix[j].length; h++) {
for (int i = 0; i < matrix.length(); i++ ) {
matrix[j][h] = msgArray[i];
}
}
}
return matrix;
}
And when I call:
String anotherMatrix = transformArray("Java is cool", 2);
My return is this (i have a method to print a matrix):
l l l l l l
l l l l l l
What I'm doing wrong?
I assume you want this
int i = 0;
for (int j = 0; j < matrix.length; j++) {
for (int h = 0; h < matrix[j].length; h++) {
matrix[j][h] = msgArray[i++];
}
}
You should not use 3 loops. What is happening with your code is that for each j and h, the matrix entry is being replaced with every character in turn, so every entry is ending up with the l from cool. There should not be a loop for each entry as you only want one character.
In order to access every element within your 2D-array you would have to iterate like so:
for(int i=0 ; i<n ; i++) {
for(int j=0; j<n ; j++) {
myArray[i][j] = inc;
inc++;
}
}
You instead are using three for-loops which is incorrect. Try adjusting your code to follow this set up, it's really easy. Edit: pbabcdefp has already done that for you!