组合优化0和1

时间:2014-03-29 22:10:15

标签: javascript algorithm combinatorics

我正致力于解决此问题的方法: 给定0和1的量,生成包含0和1的所有可能组合的列表。

示例:如果我们有一个1和两个0,算法将返回

 001
 010
 100

问题是经典组合算法没有针对此目的进行优化。 这是非优化组合算法返回的结果:

001
001
010
010
100
100

如您所见,所有组合都重复两次,因为0被解释为不同的元素。

如何使用算法生成输入0和1数的可能组合列表,而不重复组合?

PS:这将在Javascript中使用

编辑:解决了!使用@Batch方法。

function combin(o, i)
{
    if (o == 0 && i > 0) 
    {
        for (var j = 0, s = ''; j < i; j++)
        {
            s += '1';
        }
        return [s];
    } 
    else if (i == 0 && o > 0)
    {
        for (var j = 0, s = ''; j < o; j++)
        {
            s += '0';
        }
        return [s];
    } 
    else if (i == 0 && 0 == o)
    {
        return [''];
    } 
    else if (i > 0 && o > 0)
    {
        var l = combin(o - 1, i);
        for (var j in l)
        {
            l[j] = '0' + l[j];
        }
        var k = combin(o, i-1);
        for (var j in k)
        {
            k[j] = '1' + k[j];
        }
        return l.concat(k);
    }
}

2 个答案:

答案 0 :(得分:1)

这是一种方法:从字符串开始,将所有0放在前面。现在将最右边的0移动到最后。然后,将第二个最右边的0个位置向右移动,将最后一个0放在它旁边。再次,将最右边的0移动到最后。将第二个最右边的0向右移动,将最右边的0再次放在它旁边,换班移。一旦你移动了这两个最右边的0对,开始向右移动最右边的0 ....你得到了图片。

示例:三个0,三个1:

000111
001011
001101
001110
010011
010101
010110
011001
011010
011100
100011
100101
100110
101001
101010
101100
110001
110010
110100
111000

不确定如何为此编写一个好的循环,但是一旦你掌握了这个想法,你就可以四处玩耍,如果你愿意,可以尝试找出一个。也许你可以找到一个漂亮的递归,虽然现在不能想到这个方法。


更优雅的方法如下;请注意,使用n 0和m 1生成所有字符串的方法是:

使用0开始字符串,附加n-1 0s和m 1s生成字符串的所有组合,或者使用1开始字符串并附加{{1}生成字符串的所有组合} 0s和n 1s。生成的字符串集是不相交的,因此可以进行简单的递归,而不必担心多次生成字符串。如果您愿意,也可以迭代地进行迭代(迭代生成的字符串的长度,对于迭代i,保持设置为不使用0,使用0,使用i,等等)< / p>

总而言之,递归似乎是找我的方式。基本情况很简单:如果n = 0,你可以获得的唯一字符串是1 ^ m,如果m = 0,你可以获得的唯一字符串是0 ^ n(其中^表示重复)。


如果您想要实现该递归以及测试它(在某种程度上)的方法,请注意您可以生成的字符串数量是m-1选择n + m = {{1}选择n,所以计算你得到的字符串数量会给你一个提示,告诉你你所做的是否按预期工作。不确定javascript是否可以轻松访问二项式系数。

答案 1 :(得分:1)

我认为你想快速做到这一点。如果将0/1模式表示为整数的位,则最小的一个是&#34; 0 ... 01..1&#34;例如0001111如果你有3个0位和4个1位 - 最大的整数是&#34; 1..10..0&#34;。 (例如1111000)。

然后,您的问题是产生按字典顺序的下一位置换(即具有相同数量的1位的下一个整数)的已知问题。

使用http://graphics.stanford.edu/~seander/bithacks.html#NextBitPermutation代码的简单实现如下(伪代码):

v = '0..01..1'b  // Initialize t as smallest integer of the pattern
while ( t <= '1..10..0'b ):
    t = (v | (v - 1)) + 1
    v = t | ((((t & -t) / (v & -v)) >> 1) - 1)
    print v

请参阅http://www.geeksforgeeks.org/next-higher-number-with-same-number-of-set-bits/及其中的参考资料,以获得有关算法如何运作的更详细说明。