系列长度计算

时间:2013-12-22 06:14:39

标签: python python-2.7 recursion

我想计算以下算法给出的系列中的术语数:

if n=1 STOP:    
    if n is odd then n=3n+1 
    else n=n/2

例如,如果n为22,则系列如下所示,系列的长度为16:

22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1

我在python中想出了下面的递归函数:

class CycleSizeCalculator(object):
    '''
    Class to calculate the cycle count of a number. Contains the following
    members:
    counter - holds the cycle count
    number  - input number value
    calculate_cycle_size() - calculates the cycle count of the number given
    get_cycle_length()     - returns the cycle count
    '''
    def calculate_cycle_size(self,number):
        """
        Calculates the cycle count for a number passed
        """
        self.counter+=1# count increments for each recursion
        if number!=1:
            if number%2==0:
                self.calculate_cycle_size((number/2))
            else:
                self.calculate_cycle_size((3*number)+1)

    def __init__(self,number):
        '''
        variable initialization
        '''
        self.counter = 0
        self.number = number
        self.calculate_cycle_size(number)

    def get_cycle_length(self):
        """
        Returns the current counter value
        """
        return self.counter

if __name__=='__main__':
    c = CycleSizeCalculator(22);
    print c.get_cycle_length()

这在大多数情况下都有效,但是在某些n值达到了最大递归深度的消息时失败了。有替代方法吗?

3 个答案:

答案 0 :(得分:5)

那是Collatz Conjecture,最后我听说它仍然未经证实它对于所有正整数起点收敛到1。除非你能证明收敛,否则很难确定序列长度是多少。

答案 1 :(得分:3)

对于某些数字,此序列可以任意大。因此,递归方法可能还不够。您可以简单地尝试迭代方法:

def calculate_cycle_size(self,number):
    self.counter = 1
    while number != 1:
        if number%2 == 0:
            number = number / 2
        else:
            number = 3 * number + 1
        self.counter += 1

答案 2 :(得分:1)

如果您想以递归方式执行此操作,则可以:

def get_count(n):
    return 1 if n == 1 else 1 + get_count(3*n+1 if n%2 else n/2)

一个迭代版本:

def get_count(n):
    i = 1
    while n != 1:
        (n, i) = (3*n+1 if n%2 else n/2, i + 1)
    return i