Printing A class with 3D Array field - java

I have a class which is :
public class CCTest {
public double f;
public double[][][] x;
public double counter;
};
and i have assigned random number to x,
CCTest[] cls = new CCTest[5];
for (int i = 0; i < cls.length; i++) {
cls[i] = new CCTest();
}
for (int i = 0; i < (Size = 5); i++) {
cls[i].x = new double[this.c][this.D][this.Size];
for (int j = 0; j < this.D; j++) {
cls[i].x = getRandomX(this.c, this.D, this.Size);
}
}
then I tried to display the result using :
public static void display(double[][][] array) {
int rows = array.length;
int columns = array[0].length;
int depth = array[0][0].length;
for (int d = 0; d < depth; d++) {
for (int r = 0; r < rows; r++) {
for (int c = 0; c < columns; c++) {
System.out.print(array[r][c][d] + " ");
}
System.out.println();
}
System.out.println();
}
}
The Random Generation method is :
public static double[][][] getRandomX(int x, int y, int z) {
double[][][] result = new double[x][y][z];
Random r = new Random();
for (int i = 0; i < z; i++) {
for (int j = 0; j < y; j++) {
for (int k = 0; k < x; k++) {
result[k][j][i] = r.nextDouble();
}
}
}
return result;
}
but the output is empty [] , any idea please

The inner loop : for (int j = 0; j < this.D; j++) {...} is useless so you can remove this.The display and getRandomX() functions are fine. Try this in main , works in my environment:
CCTest[] cls = new CCTest[5];
for (int i = 0; i < cls.length; i++) {
cls[i] = new CCTest();
}
for (int i = 0; i < (Size = 5); i++) {
cls[i].x = new double[c][D][S];
cls[i].x = getRandomX(c, D, S);
}
for (int i = 0; i < (Size = 5); i++) {
display(cls[0].x);
}

Your display method should rather look like:
public static void display(double[][][] array) {
for (int x = 0; x < array.length; x++) {
for (int y = 0; y < array[x].length; y++) {
for (int z = 0; z < array[x][y].length; z++) {
System.out.println(array[x][y][z]);
}
}
}
}
There is another question which comes to my mind. What is getRandomX? You haven't shown us. I'd use the following:
public static double[][][] getRandom3DArray(double[][][] array) {
Random r = new Random();
for (int x = 0; x < array.length; x++) {
for (int y = 0; y < array[x].length; y++) {
for (int z = 0; z < array[x][y].length; z++) {
array[x][y][z] = r.nextDouble();
}
}
}
return array;
}
You're mistaking rows with depth in your display.

Related

How to implement Lazy Constraint Callbacks in CPLEX (java API)

currently I am trying to implement a CPLEX exact solution for the Asymmetric Capacitated Vehicle Routing Problem with the MTZ sub-tour elimination constraints.
My problems occurs when I try to implement Lazy Constraint Callbacks. More specifically I get a null pointer exception. There are almost no tutorials for implementing callbacks, so your help will be deeply appreciated.
This is my code:
CVRP class
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import ilog.concert.*;
import ilog.cplex.*;
public class ACVRP {
// euclidean distance method
public static double distance(int x1, int y1, int x2, int y2) {
return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}
public static void solveModel() {
int n = 32; // number of customers
int k = 5; // number of vehicles
int c = 100; // capacity of vehicles
int datacoords[][] = new int[n][2];
double[][] node = new double[n][n]; // dissimilarity matrix
int[] demand = new int[n]; // demand of every customer
try {
// load matrixes
FileReader frd = new FileReader("demands.txt");
FileReader frcoords = new FileReader("coords.txt");
BufferedReader brd = new BufferedReader(frd);
BufferedReader brcoords = new BufferedReader(frcoords);
String str;
int counter = 0;
while ((str = brd.readLine()) != null) {
String[] splitStr = str.trim().split("\\s+");
demand[counter] = Integer.parseInt(splitStr[1]);
counter++;
}
counter = 0;
while ((str = brcoords.readLine()) != null) {
String[] splitStr = str.trim().split("\\s+");
datacoords[counter][0] = Integer.parseInt(splitStr[1]);
datacoords[counter][1] = Integer.parseInt(splitStr[2]);
counter++;
}
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
node[i][j] = distance(datacoords[i][0],datacoords[i][1],datacoords[j][0],datacoords[j][1]);
// if (i == j ){
// node[i][j] = 99999999;
// }
}
}
brd.close();
brcoords.close();
IloCplex cplex = new IloCplex();
// variables
IloIntVar[][] x = new IloIntVar[n][];
for (int i = 0; i < n; i++) {
x[i] = cplex.boolVarArray(n);
for (int j = 0; j < n; j++) {
x[i][j].setName("x." + i + "." + j );
}
}
// mtz variables
IloNumVar[] u = cplex.numVarArray(n, 0, Double.MAX_VALUE);
for (int j = 0; j < n; j++) {
u[j].setName("u." + j);
}
//objective
IloLinearNumExpr conObj = cplex.linearNumExpr();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if ( i != j ){
conObj.addTerm(node[i][j], x[i][j]) ;
}
}
}
cplex.addMinimize(conObj);
// constraints
for (int i = 1; i < n; i++) {
IloLinearNumExpr equation1 = cplex.linearNumExpr();
for (int j = 0; j < n; j++) {
if (i!=j) {
equation1.addTerm(1.0, x[i][j]);
}
}
cplex.addEq(equation1, 1.0);
}
for (int j = 1; j < n; j++) {
IloLinearNumExpr equation2 = cplex.linearNumExpr();
for (int i = 0; i < n; i++) {
if (i!=j) {
equation2.addTerm(1.0, x[i][j]);
}
}
cplex.addEq(equation2, 1.0);
}
IloLinearNumExpr equation3 = cplex.linearNumExpr();
for (int i = 1; i < n; i++) {
equation3.addTerm(1.0, x[i][0]);
}
cplex.addEq(equation3, k);
IloLinearNumExpr equation4 = cplex.linearNumExpr();
for (int j = 1; j < n; j++) {
equation4.addTerm(1.0, x[0][j]);
}
cplex.addEq(equation4, k);
cplex.use(new LazyContstraintMTZ(n, c, demand, x, u, cplex));
//parameters
//cplex.setParam(IloCplex.Param.TimeLimit,50);
//cplex.setParam(IloCplex.Param.Preprocessing.Reduce, 0);
// cplex.setParam(IloCplex.Param.RootAlgorithm, IloCplex.Algorithm.Primal);
// solve model
cplex.solve();
cplex.exportModel("model.lp");
System.out.println(cplex.getBestObjValue());
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i != j) {
if (cplex.getValue(x[i][j]) != 0) {
System.out.println("name: " + x[i][j].getName() + " value: " + cplex.getValue(x[i][j]));
}
}
}
}
// end
cplex.end();
} catch (IloException | NumberFormatException | IOException exc) {
exc.printStackTrace();
}
}
}
class for lazy constraint :
import ilog.concert.*;
import ilog.cplex.*;
public class LazyContstraintMTZ extends IloCplex.LazyConstraintCallback {
int n; // number of customers
int c; // capacity of vehicles
int[] demand; // demand of every customer
IloIntVar[][] x;
IloNumVar[] u;
IloCplex cplex;
IloRange[] rng;
//constructor
LazyContstraintMTZ(int n, int c, int[] demand, IloIntVar[][] x, IloNumVar[] u, IloCplex cplex){
this.n = n;
this.c = c;
this.demand = demand;
this.x = x;
this.u = u;
this.cplex = cplex;
}
protected void main() throws IloException {
// Get the current x solution
// double[][] sol = new double[n][n];
// for (int i = 0; i < n; i++) {
// for (int j = 0; j < n; j++) {
// sol[i][j] = cplex.getValue(x[i][j]);
// }
// }
for (int i = 1; i < n; i++) {
for (int j = 1; j < n; j++) {
if (i!=j && demand[i]+demand[j]<=c){
IloLinearNumExpr equation5 = cplex.linearNumExpr();
equation5.addTerm(1.0, u[i]);
equation5.addTerm(-1.0, u[j]);
equation5.addTerm(c, x[i][j]);
rng[i].setExpr(equation5);
rng[i].setBounds(Double.MIN_VALUE, c-demand[j]);
cplex.addLazyConstraint(rng[i]);
}
}
}
for (int i = 1; i < n; i++) {
IloLinearNumExpr equation6 = cplex.linearNumExpr();
equation6.addTerm(1.0, u[i]);
rng[i].setExpr(equation6);
rng[i].setBounds(demand[i], c);
cplex.addLazyConstraint(rng[i]);
}
}
}
As far as I can tell, rng is never initialized in your callback class. So it is always null and as soon as you attempt to set an element in it, you will get that NullPointerException.
Note that you don't even need that array. Instead of
rng[i].setExpr(equation5);
rng[i].setBounds(Double.MIN_VALUE, c-demand[j]);
cplex.addLazyConstraint(rng[i]);
you can just write
IloRange rng = cplex.range(Double.MIN_VALUE, equation5, c - demand[j]);
cplex.addLazyConstraint(rng);
(and similarly for equation6).
Also note that Double.MIN_VALUE is likely not what you want. This gives the smallest representable number larger than 0. I guess what you want is Double.NEGATIVE_INFINITY to specify a range without lower bound. In that case you could also just write
IloRange rng = cplex.le(equation5, c - demand[j]);

Java - Sorting a 2D Array by Row Sum

Trying to write a method that swaps the rows of a 2D array in order of increasing row sum.
For example, if I have the following 2d array:
int [][] array = {4,5,6},{3,4,5},{2,3,4};
I would want it to output an array as so:
{2 3 4}, {3 4 5}, {4 5 6}
Methodology:
a.) take the sums of each row and make a 1D array of the sums
b.) do a bubble sort on rowSum array
c.) swap the rows of the original array based on the bubble sort swaps made
d.) then print the newly row sorted array.
Here's my code so far:
public void sortedArrayByRowTot() {
int [][] tempArray2 = new int [salaryArray.length [salaryArray[0].length];
for (int i = 0; i < tempArray2.length; i++) {
for (int j = 0; j < tempArray2[i].length; j++) {
tempArray2[i][j] = salaryArray[i][j];
}
}
int [] rowSums = new int [tempArray2.length];
int sum = 0;
for (int i = 0; i < tempArray2.length; i++) {
for (int j = 0; j < tempArray2[i].length; j++) {
sum += tempArray2[i][j];
}
rowSums[i] = sum;
sum = 0;
}
int temp;
int i = -1;
for(int j = rowSums.length; j > 0; j--){
boolean isSwap = false;
for (i = 1; i < j; i++) {
if(rowSums[i-1] > rowSums[i]) {
temp = rowSums[i-1];
rowSums[i-1] = rowSums[i];
rowSums[i] = temp;
isSwap = true;
}
}
if(!isSwap){
break;
}
}
for (int k = 0; k < tempArray2.length; k++) {
temp = tempArray2[i-1][k];
tempArray2[i-1][k] = tempArray2[i][k];
tempArray2[i][k] = temp;
}
for (int b = 0; b < tempArray2.length; b++) {
for (int c = 0; c < tempArray2[b].length; c++) {
System.out.print(tempArray2[b][c] + " ");
}
}
}
}
Not sure if I am doing part c of my methodology correctly?
It keeps saying "Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2"
As #shmosel said, you can do it like this:
public static void sortedArrayByRowTot() {
int [][] array = {{4,5,6},{3,4,5},{2,3,4}};
Arrays.sort(array, Comparator.comparingInt(a -> IntStream.of(a).sum()));
}
I was able to solve my question. Thanks.
public void sortedArrayByRowTot() {
//Creates tempArray2 to copy salaryArray into
int [][] tempArray2 = new int [salaryArray.length][salaryArray[0].length];
//Copies salaryArray into tempArray2
for (int i = 0; i < salaryArray.length; i++) {
for (int j = 0; j < salaryArray[i].length; j++) {
tempArray2[i][j] = salaryArray[i][j];
}
}
//Creates rowSum array to store sum of each row
int [] rowSums = new int [tempArray2.length];
for (int i = 0; i < tempArray2.length; i++) {
for (int j = 0; j < tempArray2[0].length; j++) {
rowSums[i] += tempArray2[i][j];
}
}
//Modified Bubble Sort of rowSum array (highest to lowest values)
int temp;
int i = 0;
for(int j = rowSums.length; j > 0; j--){
boolean isSwap = false;
for (i = 1; i < j; i++) {
if(rowSums[i-1] < rowSums[i]) {
temp = rowSums[i-1];
rowSums[i-1] = rowSums[i];
rowSums[i] = temp;
isSwap = true;
//swaps rows in corresponding tempArray2
int [] temp2 = tempArray2[i-1];
tempArray2[i-1] = tempArray2[i];
tempArray2[i] = temp2;
}
}
if(!isSwap){
break;
}
}
//Prints sorted array
System.out.println("Sorted array: ");
for (i = 0; i < tempArray2.length; i++) {
for (int j = 0; j < tempArray2[i].length; j++) {
System.out.print("$"+ tempArray2[i][j] + " ");
}
System.out.println();
}
}
You may try this way. That I have solved.
public class Solution{
public static void sortedArrayByRowTot() {
int [][] salaryArray = { {4,5,6},{3,4,5},{2,3,4} };
int [][] tempArray2 = new int [salaryArray.length][salaryArray[0].length];
for (int i = 0; i < salaryArray.length; i++) {
for (int j = 0; j < salaryArray[i].length; j++) {
tempArray2[i][j] = salaryArray[i][j];
}
}
// Buble Sort to store rowSums
int [] rowSums = new int [tempArray2.length];
for (int i = 0; i < tempArray2.length; i++) {
for (int j = 0; j < tempArray2[0].length; j++) {
rowSums[i] += tempArray2[i][j];
}
}
//Buble Sort by Rows Sum (Lowest Value to Highest)
int temp;
int i = 0;
for(int j = rowSums.length; j > 0; j--){
boolean isSwap = false;
for (i = 1; i < j; i++) {
if(rowSums[i-1] > rowSums[i]) {
temp = rowSums[i-1];
rowSums[i-1] = rowSums[i];
rowSums[i] = temp;
isSwap = true;
//swaps rows in corresponding tempArray2
int [] temp2 = tempArray2[i-1];
tempArray2[i-1] = tempArray2[i];
tempArray2[i] = temp2;
}
}
if(!isSwap){
break;
}
}
/** No Need.
for (int k = 0; k < tempArray2.length; k++) {
temp = tempArray2[i-1][k];
tempArray2[i-1][k] = tempArray2[i][k];
tempArray2[i][k] = temp;
}
*/
for (int b = 0; b < tempArray2.length; b++) {
for (int c = 0; c < tempArray2[b].length; c++) {
System.out.print(tempArray2[b][c] + " ");
}
}
}
public static void main(String[] args) {
sortedArrayByRowTot();
}
}

Why can't i generate this 10x10 2D array?

I am trying to generate this 2D Array maze 10 by 10 with numbers 0-9 in each row for 10 rows, but I keep getting array out of bounds exception. I double checked my indexes and the loop format and everything looks standard.
public class MazeDemo {
public static void main(String[] args) {
Maze maze = new Maze(10, 10);
maze.generate();
}
}
class Maze {
int N, M;
int[][] cell = new int[N][M];
public Maze(int N, int M) {
this.N = N;
this.M = M;
}
public void generate() {
for (int i = 0; i < N; i++) {
int counter = 0;
for (int j = 0; i < M; j++) {
cell[i][j] = counter;
counter++;
}
}
display(cell, 10, 10);
}
public static void display(int a[][], int N, int M) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
System.out.print(a[i][j]);
}
}
}
}
What is going on here? Why am I getting the out of bounds exception?
When you declare cell, N and M are 0. Change it to something like
int N, M;
int[][] cell;
public Maze(int N, int M) {
this.N = N;
this.M = M;
this.cell = new int[N][M]; // <-- add this.
}
And in generate, this
for (int j = 0; i < M; j++) {
should be
for (int j = 0; j < M; j++) {
The problem is in the generate method in:
for (int j = 0; i < M; j++)
^
it should be:
for (int j = 0; j < M; j++)

Matrix Transpose in Java

I have a method transpose in class Matice. When i apply this method on my m2.matice i can see during debugging that my matrix is being transposed, but when i print m2 i get the same matrix as before.
public class Main {
public static void main(String[] args) {
Matice m1 = new Matice(5);
m1.matrixFill(0, 5);
m1.matrixPrint();
Matice m2 = new Matice(3);
m2.matrixFill(-5, 10);
m2.matrixPrint();
m2.transpose();
m2.matrixPrint();
}
}
package matice;
/**
*
* #author Adam Rychter
*/
public class Matice {
int[][] matice;
private int n;
public Matice(int n) {
this.n = n;
if(n > 0) {
matice = new int[n][n];
}
}
public void matrixPrint(){
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
System.out.format("%5d", matice[i][j]);
}
System.out.println("");
}
System.out.println("");
}
public void matrixFill(int a, int b){
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
matice[i][j] = (int) (Math.random() * (a + b + 1) - a);
}
}
}
public void transpose(){
int tmp;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
tmp = matice[i][j];
matice[i][j] = matice[j][i];
matice[j][i] = tmp;
}
}
}
}
Your problem is that you're transposing each element twice ! once when i=row, j=col, and once when i=col, j=row, with the net effect of leaving the matrix as it was. The easiest way I see to fix it is do the swap only if i>j (and then test to make sure :) this is a suggestion, not working code :)
Note that j goes from i to n, not 1 to n; also note need for two tmp variables.
public void transpose(){
int tmp1, tmp2;
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
tmp1 = matice[i][j];
tmp2 = matice[j][i];
matice[i][j] = tmp2;
matice[j][i] = tmp1;
}
}
Like this, maybe:
public void transpose(){
Matice mL = new Matice(n);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
mL.matice[i][j] = matice[j][i];
}
}
matice = mL.matice;
}
See alternate, more efficient answer above.
public void transpose(){
int tmp;
for (int i = 0; i < n; i++) {
for (int j = i+1; j < n; j++) {
tmp = matice[i][j];
matice[i][j] = matice[j][i];
matice[j][i] = tmp;
}
}
}

Filling a ragged array with a loop in java

I was wondering how it was possible to fill a ragged array with a loop in Java.
In my example I want to put Pascals Triangle in the Array. When I try to do it ragged, (
// int [][] hako = new int [n][]; -> as I understand it; it gives a java.lang.NullPointerException.
Thanks
int n = 12, r = 1;
int [][] hako = new int [n][];
for(int i = 0; i < n; i++){
for(int j = 0; j < r; j++){
hako[i][j] = newton(i, j);
}
r++;
}
static int factorial(int n){
int k = 1;
if(n == 0)
return 1;
while(n>1){
k*=n;
n--;
}
return k;
}
static int newton(int i, int j){
return factorial(i)/((factorial(j))*(factorial(i-j)));
}
You need to initialize hako[i] as an array before you can assign a variable to an index within it i.e. hako[i][j].
int n = 12, r = 1;
int [][] hako = new int [n][];
for(int i = 0; i < n; i++){
for(int j = 0; j < r; j++){
// need to initialize hako[i]
hako[i] = new int[r];
hako[i][j] = newton(i, j);
}
r++;
}
your hako, is a matrix, but you initialize only one dimension thus your NullPointerException
to fix it try
for(int i = 0; i < n; i++){
hako[i] = new int[r];
for(int j = 0; j < r; j++){
hako[i][j] = newton(i, j);
}
r++;
}
public static void main(String[] args) {
int y[][] = new int[4][];
int four =4;
for (int row = 0; row < y.length; row++) {
y[row] = new int[four--];
}
RaggedArray(y);
for (int row = 0; row < y.length; row++) {
for (int column = 0; column < y[row].length; column++) {
System.out.print(y[row][column] + " ");
}
System.out.println();
}
}
public static void RaggedArray(int x[][]) {
int j;
for (int i = 0; i < x.length; i++) {
int k=1;
for (j = 0;j<x[i].length ; j++) {
x[i][j] = k++;
}
}
}}
You can change the size and fill it with any data. I wish it will be useful for u and anyone see this code.

Categories