For a given directed acyclic graph G I'm looking for a way to verify if a list L, containing the activities, is precedence feasible. A resource-saving solution would be nice since the size of G may increase drastically.
Example:
G = {0: [], 1: [0], 2: [0], 3: [0], 4: [1], 5: [1], 6: [4], 7: [4], 8: [3,6,7], 9: [2,5,6], 10: [2,5], 11: [8,9,10]}
Now this list
L1 = [0, 1, 2, 3, 4, 5, 10, 6, 7, 9, 8, 11]
for example is feasible but
L2 = [1, 0, 2, 3, 4, 10, 5, 6, 7, 9, 8, 11]
is not because activity 0 is a predecessor of 1 and activity 5 is a predecessor of 10.
As I understand the question you want to check whether a given ordering of nodes is consistent with partial ordering defined by the edges in the graph. Maybe I'm missing something, but for this it should be enough to check for all edges a ---> b
that the index of a
in the list is lower than the index of b
. If you create a dictionary mapping elements to their positions first, the complexity for this will be only O(e)
, e
being the number of edges.
def check(g, l):
pos = {x: i for i, x in enumerate(l)} # for O(1) index
return all(pos[a] < pos[b] for b in g for a in g[b])
G = {0: [], 1: [0], 2: [0], 3: [0], 4: [1], 5: [1], 6: [4],
7: [4], 8: [3,6,7], 9: [2,5,6], 10: [2,5], 11: [8,9,10]}
L1 = [0, 1, 2, 3, 4, 5, 10, 6, 7, 9, 8, 11]
L2 = [1, 0, 2, 3, 4, 10, 5, 6, 7, 9, 8, 11]
print(check(G, L1)) # True
print(check(G, L2)) # False