简体   繁体   中英

How to change this recursive function (return a list of paths for a 3X3 matrix) into iterative function in Python 2.7?

the recursive function below helps to find all the paths for a 3X3 matrix, from top left to bottom right, moving either down or right. But i want to change it into an iterative function so that I can edit the function to just find a specific completed path (just 1, from top left to bottom right, by moving right or down) which sums up( sum of the values at each point equate to a set number) to a desired number eg. 12. This is especially important for a bigger matrix eg. a 9 X 1000 matrix. How do I do it?

Note for Danoran:
The values are always positive. If you look at my 3X3 matrix a, you see values of 1s, 2s and 3s. So for example, moving from 1 to 1 to 1 to 2 to 3 (goal) is a completed path and the sum is 8.

This finds all the paths only.

a = []
for i in range(3):
    r = []
    for j in range(3):
        r.append(i+1)
    a.append(r)

a = matrix

1 1 1

2 2 2

3 3 3

all_paths = []

def printall(currentRow, currentColumn, nums):
    if (currentRow == len(a) - 1):
        for i in range(currentColumn, len(a[0])):
            nums.append(a[currentRow][i])
        all_paths.append(nums)
        return all_paths

    if (currentColumn == len(a[0]) - 1):
        for i in range(currentRow, len(a)):
            nums.append(a[i][currentColumn])
        all_paths.append(nums)
        return all_paths

    nums.append(a[currentRow][currentColumn])
    printall(currentRow+1, currentColumn, nums[:])
    printall(currentRow, currentColumn+1, nums[:])

printall(0,0,[])

print all_paths

If there are R rows and C columns, you have to make R-1 down-jumps and C-1 right-jumps. That's invariant. The only variation is in the order of the jumps. If we say dj=R-1 and rj=C-1, then the total number of paths is (dj+rj)!/(dj!rj!).

So, we can simply iterate through all the unique permutations. Note that itertools.permutations() will generate all permutations, not just the unique ones, so we have to filter out the repeats. Of course, this also means the run time will be proportional to (dj+rj)!, the number of non-unique permutations. I won't go into how to efficiently generate unique permutations; see, for example, Question 22431637 .

In the code below, I've increased the number of rows to 4, to help distinguish rows from columns.

from itertools import permutations

a = []
for i in range(4):
    r = []
    for j in range(3):
        r.append(i+1)
    a.append(r)

#print a   # Uncomment to trace execution

all_paths = []

def gen_all_paths(matrix):
    rows = len(matrix)
    cols = len(matrix[0])
    dj = rows - 1   # down-jumps
    rj = cols - 1   # right-jumps
    pathmix = 'd' * dj + 'r' * rj

    prev = ()
    for path in permutations(pathmix):
        if path <= prev:   # filter out repeats
            continue
        prev = path

        r, c = 0, 0
        cells = [matrix[0][0]]
        for i in path:
            if i == 'd':
                r += 1
            else:
                c += 1
            cells.append(matrix[r][c])
        #print ''.join(path), cells   # Uncomment to trace execution
        all_paths.append(cells)

gen_all_paths(a)

print all_paths

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM