-1

I have a directed acyclic graph (given by an adjacency matrix), a source node and a sink node. I would like to find a set of paths P of cardinality no more than the number of edges, from the source to the sink, such that for each edge e in the graph, there exists a path p in P that such e is in p.

My idea was to find all paths in the graph and as soon as I cover all edges I stop. I think this idea is not the best and probably there is a better way.

I started from this code:

def all_paths(adjm, source, sink, path, edges):
    # def covered(E, P):
    #     e = []
    #     for p in P:
    #         e.extend([(p[i], p[i + 1]) for i in range(len(p) - 1)])
    #     if set(e) == set(E):
    #         return True
    #     else:
    #         return False

    path = path + [source]

    if source == sink:
        return [path]

    paths = []
    for child in range(source + 1, adjm.shape[0]):  # I assume that the nodes are ordered
        if adjm[source, child] == 1:
            if child not in path:
                # if not covered(edges, paths):
                paths.extend(all_paths(adjm, child, sink, path, edges))

    return paths
kaya3
  • 31,244
  • 3
  • 32
  • 61
zdm
  • 485
  • 2
  • 11

1 Answers1

1

"a set of paths P of cardinality no more than the number of edges"

Well, if you are allowed one path per edge, there is a very simple algorithm which works:

  • Precompute paths from source to all other nodes using Dijkstra's algorithm.
  • Precompute paths from all other nodes to sink using Dijkstra's algorithm but imagining that every edge goes in the opposite direction.
  • Initialise P as an empty set.
  • For each edge u-v in the graph:
    • Form a path by concatenating the precomputed path from source to u, then the edge u-v, then the precomputed path from v to sink.
    • Add this path to P.
  • Return P.

The resulting set contains paths such that every edge is included in at least one path, by construction.

You can also improve the algorithm quite easily, by maintaining a set of edges used so far, updating this set when you add a path to P, and skipping u-v in the loop if it's already in the set.

kaya3
  • 31,244
  • 3
  • 32
  • 61