Muhammad Haryadi Futra
Muhammad Haryadi Futra

Reputation: 263

How to shuffling the 2D array in java correctly?

I want to shuffle my 2D array in java, the datas of this array:

2.5 2.6 
2.0 3.0 
3.0 3.0 

And this is my shuffle method:

public void shuffleData(){
        Random rnd = new Random();
        double temp[][] = new double[this.NBaris][NKolom];
        this.dataShuffle = new double[this.NBaris][NKolom];;

        for(int i = this.NBaris-1; i >= 0; i--){
            int index = rnd.nextInt(i + 1);
            for(int j = 0; j < this.NKolom; j++){
                temp[0][j] = this.data[index][j];
                this.dataShuffle[index][j] = this.dataShuffle[i][j];
                this.dataShuffle[i][j] = temp[0][j];
            }
        }

    }

But the result is become like this when i print:

2.5 2.6 
2.5 2.6 
2.0 3.0

whats wrong with my method?, can you help me guys. thanks.

Upvotes: 0

Views: 1977

Answers (1)

SubOptimal
SubOptimal

Reputation: 22983

There different problems

  1. You don't shuffle your data. You take a random value from array data this.data[index][j] (which might be multiple times the same value) and store it in array dataShuffle. This lead into unexpected duplicated rows, as you discover.
  2. On a randomly selected row (value index) you swap the column values in the colums two times. As you have only two columns at the end the order is the same as before.

If you only want to shuffle the order of the rows and leave the values always in the same column you could to it like this.

double[][] data = {{1.1, 1.2}, {2.1, 2.2}, {3.1, 3.2}};
List<double[]> asList = Arrays.asList(data);
Collections.shuffle(asList);
data = asList.toArray(new double[0][0]);
System.out.println("toArray = " + Arrays.deepToString(data));

sample output

toArray = [[1.1, 1.2], [3.1, 3.2], [2.1, 2.2]]

If you not want to shuffle only the rows but also the values between the columns you could use this snippet

double[][] data = {{1.1, 1.2}, {2.1, 2.2}, {3.1, 3.2}};
Random random = new Random();
int numberOfValues = data.length * data[0].length;
for (int i = numberOfValues - 1; i > 0; i--) {
    int index = random.nextInt(i);
    int row = i / data[0].length;
    int column = i - row * data[0].length;
    int randomRow = index / data[0].length;
    int randomColumn = index - randomRow * data[0].length;
    double temp = data[row][column];
    data[row][column] = data[randomRow][randomColumn];
    data[randomRow][randomColumn] = temp;
}
System.out.println("toArray = " + Arrays.deepToString(data));

sample output

toArray = [[2.1, 3.2], [2.2, 1.2], [1.1, 3.1]]

The idea is to treat all entries as a flat array [2.1, 3.2, 2.2, 1.2, 1.1, 3.1] and to start from the last index back to the second.

  1. take a random index 0 <= index < 5 and swap the values on data[index] and data[5]
  2. take a random index 0 <= index < 4 and swap the values on data[index] and data[4]
  3. and so on ...

Upvotes: 2

Related Questions