2013-07-10 3 views
0

Я столкнулся с ошибкой памяти в одной из моих рекурсивных функций.Ошибка памяти в рекурсивной функции (Python 2.7.3)

def allPaths(self, adjMat, start, stop, flag=[0], walks=[]): 
    walks = walks + [start] 
    if start == stop: 
     return [walks] 
    loc = 0 
    flag=flag*len(adjMat) 
    output = [] 
    for value in adjMat[start]: 
     if value > 0.0: 
      if flag[loc] < 3: 
       flag[loc]+=1 
       paths = self.allPaths(adjMat, loc, stop, flag, walks) 
       for k in paths: 
        output.append(k) 
     loc += 1 
    return output 

Один пример ввода в порядке, но я получаю ошибку памяти с разной матрицей.

>>>print test.allPaths([[0.0, 0.9, 0.0, 0.0, 0.0, 0.0, 0.1, 0.0], 
      [0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
      [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0], 
      [0.0, 0.0, 0.0, 0.8, .15, .05, 0.0, 0.0], 
      [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0], 
      [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0], 
      [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0], 
      [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]],0,7) 
[[0, 1, 2, 3, 3, 3, 4, 7], [0, 1, 2, 3, 3, 3, 5, 7], [0, 1, 2, 3, 3, 4, 7], [0, 1, 2, 3, 3, 5, 7], [0, 1, 2, 3, 4, 7], [0, 1, 2, 3, 5, 7], [0, 6, 7]] 

>>>print test.allPaths([[0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
      [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0], 
      [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0], 
      [0.8, 0.0, 0.0, 0.0, .05, .15, 0.0, 0.0], 
      [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0], 
      [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0], 
      [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
      [0.9, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0]],0,7) 

Ошибка, похоже, встречается на линии «flag = flag * len (adjMat)». Какие-либо предложения?

+0

Я не уверен, что это проблема, но одна вещь, которую вы, вероятно, должны избегать, - это использовать переменные по умолчанию, такие как '[0]' и '[]', поскольку они оцениваются только один раз по определению функции каждый раз, когда вы вызываете функцию, как вы могли бы ожидать). См. Объяснение и обсуждение [здесь] (http://stackoverflow.com/questions/1132941/least-astonishment-in-python-the-mutable-default-argument). – andersschuller

ответ

1

Каждый рекурсивный вызов увеличивает размер списка flag в len(adjMat).

Первый вызов функции использует список флагов с элементами len(adjMat) и передает его на рекурсивный вызов. Там список будет умножен на len(adjMat), что приведет к len(adjMat) * len(adjMat) элементам. С несколькими рекурсивными вызовами это может быстро выйти из-под контроля, и вы, вероятно, исчерпали память, чтобы сохранить этот чрезмерно большой список flag.