I'm trying to write a code in Java with CPLEX but I have a problem. I'm new to CPLEX and Java as well.
I've studied for a few days and I could understand very simple CPLEX examples but I have to deal with something much more difficult now.
I was trying to write expressions like 1000*(k-Sigma y^k(k from 1)) but I couldn't make it work so I googled for this topic but I couldn't find a way to figure this out.
What I understood so far is I need an array like this
IloNumVar[] y = cplex.numVarArray(?, ?, Double.MAX_VALUE?);
I read the manual from the IBM website but I still don't understand what variables I should put inside brackets.
And I need a for loop for the summation so I wrote like
for(int k = 1; k <= bus; k++) {
objective.addTerm(1000, k-y[k]);
}
Of course it's not working. I guess something's wrong with 'k' but have no idea how to fix this.
Please take a look at the following page:
CPLEX Java API
You can see the following method header:
IloNumVar[] numVarArray(int n, double lb, double ub)
where the params are:
n - number of variables
lb - lower bound
ub - upper bound
If you use it like this:
IloNumVar[] y = cplex.numVarArray(5, 0, Double.MAX_VALUE);
you are going to create an array of 5 elements (variables). Each of them has to be a non-negative number.
Please specify more clearly the 2nd part of your question.
Related
I'm trying to study about neural networks, following a great guide:
http://neuralnetworksanddeeplearning.com/chap1.html
Currently I've reached this code snippet which I'm trying to understand and write in Java:
class Network(object):
def __init__(self, sizes):
self.num_layers = len(sizes)
self.sizes = sizes
self.biases = [np.random.randn(y, 1) for y in sizes[1:]]
self.weights = [np.random.randn(y, x)
for x, y in zip(sizes[:-1], sizes[1:])]
I managed to figure out what everything means except for the last line:
[np.random.randn(y, x) for x, y in zip(sizes[:-1], sizes[1:])]
As far as I can understand: create a matrix with y rows and x columns, for each pair x,y which can be found in the matrix zip which is created by the merging of the two "sizes" arrays. I understand that sizes[1:] means taking all elements from sizes starting from index 1, but sizes[:-1] makes no sense to me.
I read online that s[::-1] means getting the reverse of the array, but in the above case we only have one colon, while in the formula for the reverse array there seems to be two colons.
Sadly, I have no idea how Python works and I got pretty far along with the online book to give it up now (I also truly like it), so can someone say if I'm right until now, correct me if needed, or straight out explaining that final line?
sizes[:-1] is a list slice which returns a copy of the sizes list but without the last item.
I am sure that this post silly, while I need still some practical ideas. I have 20 double[] arrays named like colVal1, colVal2,... Now I have 5 variables say que1, que2, que3, que4, que5 which contain integers from 1 to 20. I want to use arrays depending on the value contained in quei. Means if que1 contains 3 then I like to use colval3 in calculation. Manual use is avoidable due permutations of 20 numbers in 5 variables. Google hints that Java, in principle avoid replacement of variable name by another variable. I am lost at using HashMap. I could not use Reflection APIs correctly due to my limited knowledge base. Any handle is welcome.
Thanks and Regards
You know how to use an array I assume, so use an array of arrays.
double[][] colVal = new double[21][];
for (int i = 1; i <= 20; i++) {
double[] row = colVal[i];
System.out.println(Arrays.toString(row));
}
Note: this might be simpler if you started at 0 for the first row, instead of 1. i.e. you wouldn't need the unused row at the start.
I've got the following objective function:
minimize sum (trueck[k] - time[k]) for all k (1..n).
I tried to set it up like this:
IloLinearNumExpr obj = cplex.linearNumExpr();
for(int k=0; k<grossK.length; k++){
obj.addTerm(1.0, cplex.sum(trueck[k], cplex.negative(time[k])));
}
cplex.addMinimize(obj);
The eclipse error message for the 4th line is:
"The method addTerm(double, IloNumVar) in the type IloLinearNumExpr is not applicable for the arguments (double, IloNumExpr)"
I guess the method "addTerm" is wrong but I can't find a solution.
Thanks in advance.
Don't use cplex.sum inside addTerm. You just need to separate out the two terms in your Objective function, since they both are summed over k.
Minimize sum (trueck[k] - time[k]) for all k (1..n)
Is the same as Min *sum_over_k* (trueck[k]) - *sum_over_k* (time[k])
This way, addTerm can handle it. (The code below is untested, but it gives you the idea of what you should try.)
IloLinearNumExpr obj = cplex.linearNumExpr();
for(int k=0; k<grossK.length; k++){
obj.addTerm(1.0, trueck[k]);
obj.addTerm(-1.0, time[k]);
}
cplex.addMinimize(obj);
Hope that helps.
The addTerm method is expecting a coefficient and a variable. It is not expecting a complex expression (e.g. A sum) or a specific numeric value as that second argument. It may be that you have a logic issue with what you are trying to pass in, so you may want to consider updating your question with more detail about what you want to accomplish if this doesn't clear things up for you. In other words, the term you are trying to enter is not compatible with the linear expression that you are using.
I just ported my code from MATLAB to Java, and I need the eigen decomposition of a matrix, specifically I only need the first k values not the full decomposition.
However in JAMA, the eigen-decomposition class computes the full eigen decomposition. I tried to modify it, but it throws some errors. Is there another similar library?
In MATLAB, the function in question is eigs(k,A)
So it's just returning the array of all the eigenvalues. You want to return an array with just the first k values of the array. There are many ways to do this in Java. One is to convert the array to an ArrayList, get a subList of that list, and convert back to an array.
double[] mySubArray = new double[k];
for (int i=0; i < k; i++) {
subArray[i] = myFullArray[i];
}
By the way, this is the library he is referring to: http://math.nist.gov/javanumerics/jama/doc/
In the case you cannot find any existing codes, I guess you should refer to this thesis or maybe this paper.
Maybe you can try another package named EigenDecomposition in http://commons.apache.org/proper/commons-math/javadocs/api-3.6/org/apache/commons/math3/linear/EigenDecomposition.html, there are some methods like getImagEigenvalue(int i), you can get the i-th eigenvalue by this.
I'm not sure if I'm using the right nomenclature, so I'll try to make my question as specific as possible. That said, I imagine this problem comes up all the time, and there are probably several different ways to deal with it.
Let's say I have an array (vector) called main of 1000 random years between 1980 and 2000 and that I want to make 20 separate arrays (vectors) out of it. These arrays would be named array1980, array1981, etc., would also have length 1000 but would contain 1s where the index in the name was equal to the corresponding element in main and 0s elsewhere. In other words:
for(int i=0; i<1000; i++){
if(main[i]==1980){
array1980[i]=1;
} else {
array1980[i]=0;
}
Of course, I don't want to have to write twenty of these, so it'd be good if I could create new variable names inside a loop. The problem is that you can't generally assign variable names to expressions with operators, e.g.,
String("array"+ j)=... # returns an error
I'm currently using Matlab the most, but I can also do a little in Java, c++ and python, and I'm trying to get an idea for how people go about solving this problem in general. Ideally, I'd like to be able to manipulate the individual variables (or sub-arrays) in some way that the year remains in the variable name (or array index) to reduce the chance for error and to make things easier to deal with in general.
I'd appreciate any help.
boolean main[][] = new boolean[1000][20];
for (int i=0; i < 1000; i++) {
array[i][main[i]-1980] = true;
}
In many cases a map will be a good solution, but here you could use a 2-dim array of booleans, since the size is known before (0-20) and continuous, and numerable.
Some languages will initialize an array of booleans to false for every element, so you would just need to set the values to true, to which main[i] points.
since main[i] returns numbers from 1980 to 2000, 1980-main[i] will return 1980-1980=0 to 2000-1980=20. To find your values, you have to add 1980 to the second index, of course.
The general solution to this is to not create variables with dynamic names, but to instead create a map. Exactly how that's done will vary by language.
For Java, it's worth looking at the map section of the Sun collections tutorial for a start.
Don Roby's answer is correct, but i would like to complete it.
You can use maps for this purpose, and it would look something like this:
Map<Integer,ArrayList<Integer>> yearMap = new HashMap<Integer,ArrayList<Integer>>();
yearMap.put(1980,new ArrayList<Integer>());
for (int i = 0; i < 1000; i++){
yearMap.get(1980).add(0);
}
yearMap.get(1980).set(999,1);
System.out.println(yearMap.get(1980).get(999));
But there is probably a better way to solve the problem that you have. You should not ask how to use X to solve Y, but how to solve Y.
So, what is it, that you are trying to solve?