【问题标题】:How to make an ordered list of boolean array permutations with a given number of trues如何制作具有给定数量的真值的布尔数组排列的有序列表
【发布时间】:2022-11-11 01:22:03
【问题描述】:

是否有一种有效的方法来生成具有给定数量的“真”值的所有可能的布尔数组?

现在我正在增加一个数字并检查它的二进制表示是否具有给定数量的 1(如果是,则添加该数组)。但是对于较大的给定,这变得非常缓慢。

这是我正在寻找的输入输出类型:

(length: 4, trues: 2) -> [[1,1,0,0],[1,0,1,0],[0,1,1,0],[1,0,0,1],[0,1,0,1],[0,0,1,1]]

问题是在小于 O(2^N) 的时间内完成,因此它们按照小端二进制表示的顺序排列。

如果它有帮助,长度将是编译时的固定数字(目前是 64)。我把它写成输入是因为我可能不得不将它增加到 128,但它在运行时不会改变。

【问题讨论】:

  • 如果在运行时可以配置真值的数量,则需要生成向量,而不是数组。
  • @user4815162342 谢谢,我知道该函数会生成一个 Vec<[bool]> (当前是一个 Vec<[bool;64]>),但为了简单起见,没有在伪代码中指定。我编辑了问题以澄清哪些输入在运行时会发生变化。
  • 您是否尝试过 itertools crate 中的 permutations()combinations()?我试过something like this,但它返回的排列比你的例子多得多。

标签: optimization rust combinations


【解决方案1】:

您可以定义此问题的递归解决方案。

fn solution(length: u32, trues: u32) -> Vec<Vec<bool>>;

我们如何递归地制定这个函数?让我们考虑一下输出数组的最后一个元素。如果最后一个元素是false,那么0..length-1 元素中true 元素的数量必须是trues。如果最后一个元素是true,那么0..length-1 元素中true 元素的数量必须是trues-1

所以我们可以只回答(length-1, trues)的问题,然后将它们全部扩展为false,并回答(length-1, trues-1)的问题并将它们全部扩展为true,然后我们可以组合结果(结束- with-true 小端排序的第一个案例)。添加一些基本情况,我们得到以下代码:

fn solution(length: u32, trues: u32) -> Vec<Vec<bool>> {
    if trues > length {
        // no candidate arrays exist
        return vec![];
    }
    if length == 0 {
        // one array exists: the empty array
        return vec![vec![]];
    }
    if trues == 0 {
        // one array exists: the all-false array
        return vec![vec![false; length as usize]];
    }

    let mut result = Vec::new();
    for mut ones in solution(length-1, trues-1) {
        ones.push(true);
        result.push(ones);
    }
    for mut zeroes in solution(length-1, trues) {
        zeroes.push(false);
        result.push(zeroes);
    }
    result
}

如果solution(L, T)的时间复杂度是O(S(L,T)),那么solution(L,T)的时间复杂度可以递归表示为O(S(L-1,T-1) + S(L-1,T)),基本情况S(0,0) = 1S(L,L+1)=1S(L,0) = L。这是可实现的最佳时间复杂度,因为S(L,T) = S(L-1,T-1) + S(L-1,T) 也是存在多少长度为 L 和真实计数 T 的数组的递归公式。这也是与binomial recurrence equation 相同的递归公式,但基本情况不同。我将把计算时间复杂度作为练习留给读者,并且可以对上述代码进行一些简单的优化,以进一步降低计算时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-27
    • 2012-09-27
    • 2017-02-13
    • 1970-01-01
    • 1970-01-01
    • 2020-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多