def topsort(pairlist): numpreds = OrderedDict() # elt -> # of predecessors successors = OrderedDict() # elt -> list of successors for first, second in pairlist: # make sure every elt is a key in numpreds if first not in numpreds: numpreds[first] = 0 if second not in numpreds: numpreds[second] = 0 # if they're the same, there's no real dependence if first == second: continue # since first < second, second gains a pred ... numpreds[second] = numpreds[second] + 1 # ... and first gains a succ if first in successors: successors[first].append(second) else: successors[first] = [second] # suck up everything without a predecessor answer = filter(lambda x, numpreds=numpreds: numpreds[x] == 0, numpreds.keys()) # for everything in answer, knock down the pred count on # its successors; note that answer grows *in* the loop for x in answer: assert numpreds[x] == 0 del numpreds[x] if x in successors: for y in successors[x]: numpreds[y] = numpreds[y] - 1 if numpreds[y] == 0: answer.append(y) # following "del" isn't needed; just makes # CycleError details easier to grasp del successors[x] if numpreds: # everything in numpreds has at least one predecessor -> # there's a cycle if __debug__: for x in numpreds.keys(): assert numpreds[x] > 0 raise CycleError(answer, numpreds, successors) return answer
def topsort_levels(pairlist): numpreds = OrderedDict() # elt -> # of predecessors successors = OrderedDict() # elt -> list of successors for first, second in pairlist: # make sure every elt is a key in numpreds if first not in numpreds: numpreds[first] = 0 if second not in numpreds: numpreds[second] = 0 # if they're the same, there's no real dependence if first == second: continue # since first < second, second gains a pred ... numpreds[second] = numpreds[second] + 1 # ... and first gains a succ if first in successors: successors[first].append(second) else: successors[first] = [second] answer = [] while 1: # Suck up everything without a predecessor. levparents = [x for x in numpreds.keys() if numpreds[x] == 0] if not levparents: break answer.append(levparents) for levparent in levparents: del numpreds[levparent] if levparent in successors: for levparentsucc in successors[levparent]: numpreds[levparentsucc] -= 1 del successors[levparent] if numpreds: # Everything in num_parents has at least one child -> # there's a cycle. raise CycleError(answer, numpreds, successors) return answer
def topsort_levels(pairlist): numpreds = OrderedDict() # elt -> # of predecessors successors = OrderedDict() # elt -> list of successors for first, second in pairlist: # make sure every elt is a key in numpreds if first not in numpreds: numpreds[first] = 0 if second not in numpreds: numpreds[second] = 0 # if they're the same, there's no real dependence if first == second: continue # since first < second, second gains a pred ... numpreds[second] = numpreds[second] + 1 # ... and first gains a succ if first in successors: successors[first].append(second) else: successors[first] = [second] answer = [] while 1: # Suck up everything without a predecessor. levparents = [x for x in numpreds.keys() if numpreds[x] == 0] if not levparents: break answer.append( levparents ) for levparent in levparents: del numpreds[levparent] if levparent in successors: for levparentsucc in successors[levparent]: numpreds[levparentsucc] -= 1 del successors[levparent] if numpreds: # Everything in num_parents has at least one child -> # there's a cycle. raise CycleError( answer, numpreds, successors ) return answer