2

Write an algorithm in Python which takes a prufer code as input and returns the edge set of the tree. Input: a list named "p" (the prufer code, zero-indexed) Example:

p = [3,1,0,0,3,2,9,9,2,3]

(The prufer code can be defined within the code block. You do not need to write a function which takes user input) Output: a list named "edges" (the edge set_ Example:

print(edges)

[[3, 4], [1, 5], [0, 1], [0, 6], [3, 0], [2, 7], [9, 8], [9, 10], [2, 9], [3, 2], [3,11]]

I am having trouble with this. How can i get the values for "p" so that it prints the output in "edges"?

Sandipan Dey
  • 21,482
  • 2
  • 51
  • 63
Lalo G
  • 37
  • 4

3 Answers3

2

Connect the first vertex in (what remains of) the sequence to the lowest vertex that doesn't appear in (what remains of) the sequence. Delete the first vertex in the sequence and repeat. Connect the two remaining vertices.

def decode(p):
    p = list(p)
    vertices = set(range(len(p) + 2))
    while p:
        v = min(vertices - set(p))
        vertices.remove(v)
        yield p.pop(0), v
    yield min(vertices), max(vertices)


print(list(decode([3, 1, 0, 0, 3, 2, 9, 9, 2, 3])))

Output:

[(3, 4), (1, 5), (0, 1), (0, 6), (3, 0), (2, 7), (9, 8), (9, 10), (2, 9), (3, 2), (3, 11)]
Aristide
  • 3,606
  • 2
  • 30
  • 50
David Eisenstat
  • 64,237
  • 7
  • 60
  • 120
0

Great algorithm from David Eisenstat. Some nitpicks:

  • .pop(0) is linear on lists: I would prefer to make the list traversal more explicit by replacing the while with a for ... enumerate;
  • .difference() would not require to convert the second operand into a set;
  • min() and max() are a little overkill, since we know that the remaining set has exactly two elements.
def decode(p):
    p = list(p)
    vertices = set(range(len(p) + 2))
    for (i, u) in enumerate(p):
        v = min(vertices.difference(p[i:]))
        vertices.remove(v)
        yield u, v
    yield tuple(vertices)


print(list(decode([3, 1, 0, 0, 3, 2, 9, 9, 2, 3])))

Output:

[(3, 4), (1, 5), (0, 1), (0, 6), (3, 0), (2, 7), (9, 8), (9, 10), (2, 9), (3, 2), (3, 11)]
Aristide
  • 3,606
  • 2
  • 30
  • 50
0

The following algorithm (refer to this) can be used to construct the spanning tree of Kn on n labeled vertices, given the corresponding Prufer sequence of length n-2:

enter image description here

The next code snippet implements the above algorithm to generate a labeled tree (by computing the edges) given the Prufer sequence (also note that we have zero-based indexing in python):

def get_tree(S):
    n = len(S)
    L = set(range(n+2))
    tree_edges = []
    for i in range(n):
        u, v = S[0], min(L - set(S))
        S.pop(0)
        L.remove(v)
        tree_edges.append((u,v))
    tree_edges.append((L.pop(), L.pop()))
    return tree_edges

Invoking the above function on the input Prufer sequence will generate the following tree, as shown in the next animation:

enter image description here

Sandipan Dey
  • 21,482
  • 2
  • 51
  • 63