Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 安排数目_Algorithm_Math - Fatal编程技术网

Algorithm 安排数目

Algorithm 安排数目,algorithm,math,Algorithm,Math,假设我们有n个元素,a1,a2,…,an,排列成一个圆圈。也就是说,a2在a1和a3之间,a3在a2和a4之间,an在an-1和a1之间,依此类推 每个元素的值可以为1或0。如果存在值不同的相应ai,则两种安排是不同的。例如,当n=3时,(1,0,0)和(0,1,0)是不同的排列,即使它们在旋转或反射下可能是同构的 因为有n个元素,每个元素可以取两个值,所以排列的总数是2n 问题是: 有多少种排列是可能的,以至于没有两个相邻的元素都具有值1?如果有帮助,只考虑n>3的情况。 我提出这个问题有几个

假设我们有n个元素,a1,a2,…,an,排列成一个圆圈。也就是说,a2在a1和a3之间,a3在a2和a4之间,an在an-1和a1之间,依此类推

每个元素的值可以为1或0。如果存在值不同的相应ai,则两种安排是不同的。例如,当n=3时,(1,0,0)和(0,1,0)是不同的排列,即使它们在旋转或反射下可能是同构的

因为有n个元素,每个元素可以取两个值,所以排列的总数是2n

问题是:

有多少种排列是可能的,以至于没有两个相邻的元素都具有值1?如果有帮助,只考虑n>3的情况。 我提出这个问题有几个原因:

  • 这是在我解决编程问题时出现的
  • 听起来这个问题可能得益于布尔逻辑/位算术
  • 也许没有封闭的解决方案

  • 让我们首先问一个问题“有多少长度为n的0-1序列没有两个连续的1?”让答案为A(n)。我们有A(0)=1(空序列),A(1)=2(“0”和“1”),和A(2)=3(“00”,“01”和“10”,但不是“11”)

    为了便于编写递归,我们将a(n)计算为两个数字的和:
    B(n),以0结尾的此类序列的数量,和
    C(n),以1结尾的序列数

    然后B(n)=A(n-1)(取任意长度为n-1的序列,并附加一个0)
    C(n)=B(n-1)(因为如果在位置n处有一个1,那么在位置n-1处必须有一个0。)
    这就给出了A(n)=B(n)+C(n)=A(n-1)+B(n-1)=A(n-1)+A(n-2)。 现在应该很熟悉了:-)

    A(n)是简单的斐波那契数Fn+2,其中斐波那契序列由F0=0、F1=1和Fn+2=Fn+1+Fn定义≥ 0.

    现在回答你的问题。我们将分别计算a1=0和a1=1的排列数。对于前者,a2…an可以是任何序列(没有连续的1),因此数字是A(n-1)=Fn+1。对于后者,我们必须有a2=0,然后a3…an是没有以0结尾的连续1s的任何序列,即B(n-2)=a(n-3)=Fn-1

    所以答案是Fn+1+Fn-1。

    事实上,我们可以走得更远。请注意,如果您将答案称为
    G(n)=Fn+1+Fn-1,则
    G(n+1)=Fn+2+Fn和
    G(n+2)=Fn+3+Fn+1,所以即使是G(n)也满足与斐波那契序列相同的递归性![事实上,任何类似斐波那契序列的线性组合都会满足相同的递归,所以这并不奇怪。]因此,计算答案的另一种方法是:
    G(2)=3
    G(3)=4
    对于n,G(n)=G(n-1)+G(n-2)≥四,

    现在还可以使用Fn=(αn-βn)/(α-β)(其中α和β为(1±)√5) /2,x2-x-1的根=0),以获得
    G(n)=(1+√5) /2)n+((1)-√5) /2)n.
    [您可以忽略第二项,因为对于大n,它非常接近0,事实上G(n)是最接近((1)的整数+√5) /2)n适用于所有n≥2.]

    我决定编写一个小脚本来试用:

    #!/usr/bin/python
    import sys
    
    # thx google 
    bstr_pos = lambda n: n>0 and bstr_pos(n>>1)+str(n&1) or ""
    
    def arrangements(n):
        count = 0
        for v in range(0, pow(2,n)-1):
            bin = bstr_pos(v).rjust(n, '0')
            if not ( bin.find("11")!=-1 or ( bin[0]=='1' and bin[-1]=='1' ) ):
                count += 1
                print bin
        print "Total = " + str(count)
    
    arrangements(int(sys.argv[1]))
    
    运行了5次,给了我11种可能性,100000, 00001, 00010, 00100, 00101, 01000, 01001, 01010, 10000, 10010, 10100


    请原谅上面代码中的not()。

    将我的天真脚本加入其中。缓存部分结果的机会很多,但对于小n来说,它的运行速度足够快,所以我不必费心

    def arcCombinations(n, lastDigitMustBeZero):
        """Takes the length of the remaining arc of the circle, and computes
           the number of legal combinations.
           The last digit may be restricted to 0 (because the first digit is a 1)"""
    
        if n == 1: 
            if lastDigitMustBeZero:
                return 1 # only legal answer is 0
            else:
                return 2 # could be 1 or 0.
        elif n == 2:
            if lastDigitMustBeZero:
                return 2 # could be 00 or 10
            else:
                return 3 # could be 10, 01 or 00
        else:
            # Could be a 1, in which case next item is a zero.
            return (
                arcCombinations(n-2, lastDigitMustBeZero) # If it starts 10
                + arcCombinations(n-1, lastDigitMustBeZero) # If it starts 0
                )
    
    def circleCombinations(n):
        """Computes the number of legal combinations for a given circle size."""
    
        # Handle case where it starts with 0 or with 1.
        total = (
                arcCombinations(n-1,True) # Number of combinations where first digit is a 1.
                +
                arcCombinations(n-1,False) # Number of combinations where first digit is a 0.
            )
        return total
    
    
    print circleCombinations(13)
    

    这个问题很类似于。由于循环约束,我找不到一个明显的方法来应用Zeckendorf定理,但Fibonacci数在这个问题中显然非常普遍。

    只是澄清一下,圆圈进入定义相邻的含义——元素n与元素1相邻,但不考虑相同位模式的旋转是相同的。是吗?用手检查2,3,4。我认为关于构造B(n)和C(n)的论点通过从长度为1的两种情况中进行推导来强制证明端点的正确性。参见“对于后者,我们必须有a2=0,然后a3…an是没有以0结尾的连续1的任何序列”这就是我认为序列不能在1开始和结束的地方。对“理论”(另一个答案)的很强的确认,因为f(6)=8和f(4)=3,所以G(5)=f(6)+f(4)确实是11:-)