# Recursive backtracking function: how to clear variables on new function call?

I've been trying to write a simple function to make lists of all the Young diagrams/partitions between a starting partition ('top') and an ending partition ('bot'), with each step in the list a covering relation (exactly one box difference in each step).

For instance, I would like to input [2,1] for top and [1] for bot and get

[[2,1],[2],[1]]

[[2,1],[1,1],[1]]

as my outputs. (I want to do this because it's useful for some computations with Littlewood-Richardson coefficients; having the lists that give each partition in a path between top and bot will be useful for other computations.)

My code at present has an echo, and worse, I can't figure out where to initialize path_list. Where do I put path_list = [] -- or create other lists -- to make sure that:

1. I get a separate list for each path, and
2. Calling the function again clears path_list?

(2) is worst: right now, since path_list is an internally-defined variable, I get the following bad behavior:

sage: get_path([1],[1])

[[1]]

[[1]]

sage: get_path([1],[1])

[[1], [1]]

[[1], [1]]

sage: get_path([1],[1])

[[1], [1], [1]]

[[1], [1], [1]]

because path_list is not cleared when I call get_path again (which I'd hoped putting path_list = [] in the arguments would accomplish).

The code:

def get_path(top, bot, path_list = []):
path_list.append(top)
if top == bot:
print path_list
return path_list
if not Partition(top).contains(Partition(bot)):
return None
for i in range(0,len(Partition(top).down_list())):
p = Partition(top).down_list()[i]
if Partition(p).contains(bot):
path_list.append(p)
get_path(p, bot, path_list)


I'm using Sage 5.0.1 with Sage-combinat providing the Partition function and others.

edit retag close merge delete

Sort by » oldest newest most voted

I think the following code gives the good output (but is far from optimal, many computations are repeated again and again, as in the naive recursive computation of the Fibonacci sequence), here parameters are assumed to be partitions:

def get_paths(top, bot):
if top == bot:
return [[top]]
path_list = []
for p in top.down_list():
if p.contains(bot):
path_list += get_paths(p, bot)
for u in path_list:
u.append(top)
return path_list


For example:

sage: gp = get_paths (Partition([3,3,1]),Partition([2,1])); len(gp)
8
sage: len (get_paths (Partition([3,3,2]),Partition([1])))
42


Actually we are computing functions already defined in Sage:

sage: sst = StandardSkewTableaux([[3, 3, 1], [2, 1]])
sage: sst.cardinality()
8
sage: StandardTableaux([3,3,2]).cardinality()
42


Use sst.list() to get the "same" list as the one computed by get_paths(). You may eventually look at the source code of these functions, in the modules sage.combinat.tableau and sage.combinat.skew_tableau .

Amitiés.

more

Wonderful, and many thanks! I am testing this and your code above seems to do exactly what I'd like. It seems that += rather than append is the way to go -- a key improvement -- and I will think about exactly how the placement of path_list = [] helped as well.

( 2013-01-08 14:47:44 -0600 )edit

I am not getting the same result with sst.list() though, so will look at that. It did occur to me that the tableau packages might be able to help but I could not quite see what to do.

( 2013-01-08 14:48:38 -0600 )edit

Look at the first path returned by get_paths in my example: [[2, 1], [2, 1, 1], [2, 2, 1], [3, 2, 1], [3, 3, 1]], it's coded by the last skew tableau returned by sst.list(): [[None, None, 3], [None, 2, 4], [1]], because we add the first cell in a third new row, the second one is appended to the second row, the third one to the first row, and the fourth one to the second row (again). Anybody familiar with the subject may explain you the correspondence, it's easier on a sheet of paper or on a blackboard :-)

( 2013-01-09 07:24:11 -0600 )edit

This is a very partial answer, but in a Python crash course (by William Stein I presume, now I can't find the link) I learned this example:

def f(a, L=[]):
L.append(a)
return L


with the following astonishing successive outputs:

sage: f(2)
[2]
sage: f(5)
[2, 5]
sage: f(4)
[2, 5, 4]


(this is pure Python, Sage is not guilty).

more