Ask Your Question
0

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

asked 2013-01-04 18:50:38 +0100

anonymous user

Anonymous

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: load "makepartitionlist.sage"

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 flag offensive close merge delete

2 Answers

Sort by » oldest newest most voted
1

answered 2013-01-05 16:52:12 +0100

updated 2013-01-06 07:09:52 +0100

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.

edit flag offensive delete link more

Comments

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.

kaisat gravatar imagekaisat ( 2013-01-08 21:47:44 +0100 )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.

kaisat gravatar imagekaisat ( 2013-01-08 21:48:38 +0100 )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 :-)

Bétréma gravatar imageBétréma ( 2013-01-09 14:24:11 +0100 )edit
0

answered 2013-01-05 14:35:58 +0100

updated 2013-01-05 14:42:44 +0100

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).

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

Stats

Asked: 2013-01-04 18:50:38 +0100

Seen: 2,222 times

Last updated: Jan 06 '13