问题
I'm having some trouble trying to represent and manipulate dependency graphs in this scenario:
- a node has some dependencies that have to be solved
- every path must not have dependencies loops (like in DAG graphs)
- every dependency could be solved by more than one other node
I starts from the target node and recursively look for its dependencies, but have to mantain the above properties, in particular the third one.
Just a little example here:
I would like to have a graph like the following one
(A)
/ \
/ \
/ \
[(B),(C),(D)] (E)
/\ \
/ \ (H)
(F) (G)
which means:
- F,G,C,H,E have no dependencies
- D dependends on H
- B depends on F and G
- A depends on E and
- B or
- C or
- D
So, if I write down all the possible topological-sorted paths to A I should have:
- E -> F -> G -> B -> A
- E -> C -> A
- E -> H -> D -> A
How can I model a graph with these properties? Which kind of data structure is the more suitable to do that?
回答1:
You should use a normal adjacency list, with an additional property, wherein a node knows its the other nodes that would also satisfy the same dependency. This means that B,C,D should all know that they belong to the same equivalence class. You can achieve this by inserting them all into a set.
Node:
List<Node> adjacencyList
Set<Node> equivalentDependencies
To use this data-structure in a topo-sort, whenever you remove a source, and remove all its outgoing edges, also remove the nodes in its equivalency class, their outgoing edges, and recursively remove the nodes that point to them. From wikipedia:
L ← Empty list that will contain the sorted elements
S ← Set of all nodes with no incoming edges
while S is non-empty do
remove a node n from S
add n to tail of L
for each node o in the equivalency class of n <===removing equivalent dependencies
remove j from S
for each node k with an edge e from j to k do
remove edge e from the graph
if k has no other incoming edges then
insert k into S
for each node m with an edge e from n to m do
remove edge e from the graph
if m has no other incoming edges then
insert m into S
if graph has edges then
return error (graph has at least one cycle)
else
return L (a topologically sorted order)
This algorithm will give you one of the modified topologicaly-sorted paths.
来源:https://stackoverflow.com/questions/26642346/how-to-represent-a-dependency-graph-with-alternative-paths