We want to order elements, in increasing order, from a given set of relations.
Test case #1 states :
a0 > b20
a1 > b18
a2 > b4
a3 > b1
a4 > b38
a5 > b35
a6 > b7
a7 > b4
a8 > b32
a9 > b2
a10 > b31
a11 > b25
a12 > b2
a13 > b29
a14 > b7
a15 > b26
a16 > b0
a17 > b36
a18 > b27
a19 > b25
a20 > b13
a21 > b35
a22 > b18
a23 > b38
a24 > b21
a25 > b18
a26 > b7
a27 > b33
a28 > b5
a29 > b7
a30 > b17
a31 > b39
a32 > b3
a33 > b39
a34 > b15
a35 > b1
a36 > b2
a37 > b6
a38 > b6
a39 > b37
a0 > a1
b0 > b1
a1 > a2
b1 > b2
a2 > a3
b2 > b3
a3 > a4
b3 > b4
a4 > a5
b4 > b5
a5 > a6
b5 > b6
a6 > a7
b6 > b7
a7 > a8
b7 > b8
a8 > a9
b8 > b9
a9 > a10
b9 > b10
a10 > a11
b10 > b11
a11 > a12
b11 > b12
a12 > a13
b12 > b13
a13 > a14
b13 > b14
a14 > a15
b14 > b15
a15 > a16
b15 > b16
a16 > a17
b16 > b17
a17 > a18
b17 > b18
a18 > a19
b18 > b19
a19 > a20
b19 > b20
a20 > a21
b20 > b21
a21 > a22
b21 > b22
a22 > a23
b22 > b23
a23 > a24
b23 > b24
a24 > a25
b24 > b25
a25 > a26
b25 > b26
a26 > a27
b26 > b27
a27 > a28
b27 > b28
a28 > a29
b28 > b29
a29 > a30
b29 > b30
a30 > a31
b30 > b31
a31 > a32
b31 > b32
a32 > a33
b32 > b33
a33 > a34
b33 > b34
a34 > a35
b34 > b35
a35 > a36
b35 > b36
a36 > a37
b36 > b37
a37 > a38
b37 > b38
a38 > a39
b38 > b39
Let's encode this as a graph, in python :
graph = {'a20': ['b13', 'a21'], 'a21': ['b35', 'a22'], 'a22': ['b18', 'a23'],
'a23': ['b38', 'a24'], 'a24': ['b21', 'a25'], 'a25': ['b18', 'a26'],
'a26': ['b7', 'a27'], 'a27': ['b33', 'a28'], 'a28': ['b5', 'a29'],
'a29': ['b7', 'a30'], 'b25': ['b26'], 'b24': ['b25'], 'b23': ['b24'],
'a31': ['b39', 'a32'], 'b21': ['b22'], 'b20': ['b21'], 'b4': ['b5'],
'b5': ['b6'], 'b6': ['b7'], 'a30': ['b17', 'a31'], 'b0': ['b1'],
'b1': ['b2'], 'b2': ['b3'], 'b3': ['b4'], 'b26': ['b27'],
'a37': ['b6', 'a38'], 'b29': ['b30'], 'b8': ['b9'], 'b9': ['b10'],
'a36': ['b2', 'a37'], 'a33': ['b39', 'a34'], 'b31': ['b32'],
'a35': ['b1', 'a36'], 'b35': ['b36'], 'a34': ['b15', 'a35'],
'b16': ['b17'], 'b17': ['b18'], 'b14': ['b15'], 'b15': ['b16'],
'b12': ['b13'], 'b13': ['b14'], 'b10': ['b11'], 'b11': ['b12'],
'b36': ['b37'], 'a32': ['b3', 'a33'], 'b19': ['b20'],
'a15': ['b26', 'a16'], 'a14': ['b7', 'a15'], 'a17': ['b36', 'a18'],
'a16': ['b0', 'a17'], 'a11': ['b25', 'a12'], 'a10': ['b31', 'a11'],
'a13': ['b29', 'a14'], 'a12': ['b2', 'a13'], 'b34': ['b35'],
'b30': ['b31'], 'a39': ['b37'], 'a38': ['b6', 'a39'],
'a19': ['b25', 'a20'], 'a18': ['b27', 'a19'], 'b32': ['b33'],
'b22': ['b23'], 'a1': ['b18', 'a2'], 'a0': ['b20', 'a1'],
'a3': ['b1', 'a4'], 'a2': ['b4', 'a3'], 'a5': ['b35', 'a6'],
'a4': ['b38', 'a5'], 'a7': ['b4', 'a8'], 'a6': ['b7', 'a7'],
'a9': ['b2', 'a10'], 'a8': ['b32', 'a9'], 'b38': ['b39'],
'b33': ['b34'], 'b28': ['b29'], 'b37': ['b38'],
'b7': ['b8'], 'b18': ['b19'], 'b27': ['b28'], 'b39': [] }
To sum up things, here's the picture of the relations.
The algorithm for sorting this kind of thing is quite classical :
- find a node that has no successors (ie, that is "smaller" than any other one)
- if more than one node has no successors, we can't order the set (it's a tie) -> exit
- push that node to our results
- remove that node from our graph
- iterate to 1. until there are no more nodes in the graph
In python :
def reduce(g):
lasts = [i for i in g.keys() if not g[i]]
if len(lasts) == 0:
# no more nodes : done
return None
if len(lasts) > 1:
print "Can't order : %s" % lasts
return None
last = lasts[0]
print "removing %s" % last
for i in g.keys():
if last in g[i]:
g[i].remove(last)
del g[last]
return g
Running this claims :
removing b39removing b38removing b37Can't order : ['a39', 'b36']
I honestly can't find where I'm wrong there. Any clue ?