【问题标题】:Randomly select index of matrix exactly once随机选择矩阵的索引恰好一次
【发布时间】:2017-01-10 18:05:05
【问题描述】:

我有一个 1 的矩阵(只是一个 2D 整数向量),我正在尝试随机选择一个索引,以便我可以将该 1 变为 0。我的目标是只选择矩阵的每个索引一次所以在以与索引完全相同的迭代次数运行 for 循环后,矩阵将填充 0(实际上 0 并不重要,替换 1 的数字和 1 本身是任意的)。

我目前的方法很慢。一直在运行一个 while 循环,检查每个通过,看看是否还剩下任何 1。这显然是非常低效的,但我不确定如何为每个索引只执行一次并确保没有重复,以便我可以更改为 for 循环。任何建议都会非常有帮助!

【问题讨论】:

  • 创建一个用矩阵的每个索引填充的数组,打乱该数组,遍历数组,将矩阵中的每个索引更改为 0。
  • 做费雪-耶茨洗牌...

标签: arrays algorithm matrix vector random


【解决方案1】:

只需像评论中提到的@Jonny 那样生成矩阵索引的随机序列。然后遍历这个序列的每个元素。以下是我刚刚编写的 Java 实现,以防万一:

import java.util.Random;

public class Test {

    public static void randomSelectMatrixIndex(int[][] matrix) {
        int rows = matrix.length;
        int cols = matrix[0].length;
        int[] indices = new int[rows*cols];
        System.out.println("Index array before shuffle: ");
        for (int i=0; i<indices.length; i++) {
            indices[i] = i;
            System.out.print(i+" ");            
        }
        System.out.println();
        System.out.println();

        shuffle(indices);

        System.out.println("Index array after shuffle: ");
        for (int j=0; j<indices.length; j++) {
            System.out.print(indices[j]+" ");
            matrix[indices[j]/cols][indices[j]%cols] = 0;
        }
        System.out.println();
        System.out.println();
    }

    private static void shuffle(int[] indices) {
        Random ran = new Random();
        for (int i=indices.length; i>0; i--) {
            int randomIndex = ran.nextInt(i);
            int temp = indices[i-1];
            indices[i-1] = indices[randomIndex];
            indices[randomIndex] = temp;
        }
    }

    private static void printMatrix(int[][] matrix) {
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                System.out.print(matrix[i][j] + " ");
            }
            System.out.println();
        }
    }

    public static void main(String[] args) throws Exception {

        int[][] matrix = {{1,1,1,1,1}, {1,1,1,1,1}, {1,1,1,1,1}, {1,1,1,1,1}};

        System.out.println("Matrix before random select: ");
        printMatrix(matrix);
        System.out.println();

        randomSelectMatrixIndex(matrix);

        System.out.println("Matrix after random select: ");
        printMatrix(matrix);
    }

}

【讨论】:

    【解决方案2】:

    你使用这个算法,它效率更高一些,尽管经过多次迭代后仍然不是很有效(请注意,为获得最佳结果,请使用均匀分布的随机数生成器):

    select random index -> check if 1
      |                    |        |
      |      repeat        |False   |True
      |--------------------|        |--Change value at index to 0
                                               |
                                               |
                                            the end
    

    我想知道是否可以进行一些更改以提高效率...

    【讨论】:

      【解决方案3】:

      简单。使用嵌套循环创建一个指针向量,以便有一个指向矩阵中每个元素的指针。随机选择一个指针。将值更改为 0。从向量中删除指针。重复直到向量为空。矩阵现在是空的。

      【讨论】:

      • 要从向量中删除指针,您可以简单地将其与向量末尾的指针交换,然后调整向量的大小;这比从中间擦除要快。但是此时你几乎已经实现了 shuffle,而且 shuffle 更简单。
      猜你喜欢
      • 2012-01-01
      • 2019-09-18
      • 1970-01-01
      • 2011-12-30
      • 1970-01-01
      • 2019-05-10
      • 1970-01-01
      • 1970-01-01
      • 2011-03-17
      相关资源
      最近更新 更多