Given: A directed, weighted graph G=(V, E), some of the vertices are red, some blue, and the rest white, weight Ti which is the maximum weight allowed to go from any vertex red vertex to any blue vertex.
Problem: Create an algorithm that finds a path from source node S, to target node T with least weight and which at some point goes from a red vertex to a blue vertex in at most Ti weight before reaching vertex T. The algorithm should have time complexity O(n^3)
Comments: I'm not sure how to get started on this, I figure it's some variation of Dijkstra's algorithm and I've seen some people talking about making copies of the graphs and connecting the copies but beyond that, I'm not sure what the setup of this algorithm would look like. Any help would be appreciated.
Indeed, you can use the copy-strategy as follows:
Copy the graph G to G' and to G". Label all vertices in G' as in G, but with the apostrophe. So there is an S' and a T' in G'. Similarly, S" and T" belong to G".
Let S be the start vertex, and T" be the target. As it stands now, G, G' and G" are disconnected. But add the following zero-weight, directed edges:
Edges from each red vertex r in G, to its mirror r' in G'.
Edges from each blue vertex b' in G', to its mirror b" in G".
So there are no paths from G" to G', nor from G' to G, nor from G" to G.
Now start a Dijkstra algorithm in S, with an additional data attribute for each entry in the priority queue: the weight that a path accumulated by edges in G' only. Let's call this w'. This w' plays no role in the priority of the queue. The total weight of a path determines the priority as is standard in Dijkstra's algorithm. The algorithm should not expand paths whereby w' would exceed Ti. Besides that specific limitation, all the rest of the algorithm can remain as in the standard Dijkstra algorithm.
Related
we are given a directed graph G = (V, E) with positive and negative edge weights, but no cycles. Let s ∈ V be a given source vertex. How to find an algorithm that finds distance of all vertices from s, supposably runs faster than Bellman Ford's O(VE) time complexity.
If the graph has no cycles, then you can just process the vertices in topological order.
For each vertex v, if it is reachable from s at distance d, then for every edge (v,u) with weight w, mark u as reachable with weight d+w. If u is already reachable at a lower weight, then leave it alone.
Because you process the graph in topological order, you know that when you process a vertex v, you will already have processed all its predecessors, so you will know the length of its shortest path from s. The first reachable vertex will, of course, be s.
It's pretty easy to combine this with Kahn's algorithm for topological sorting, on the subgraph of vertices reachable from s.
First do a BFS search to find all the vertices reachable from s, and simultaneously count each vertex's incoming edges within this subset.
s will be the only vertex with count '0'. It also has a known 0 distance from s. Put it in a queue.
While there are vertexes in the queue:
Remove a vertex v from the queue
Adjust the distances to its neighbors
Reduce the incoming edge counts of it's neighbors. If any neighbor's count gets to 0, then put it in the queue.
When you're done, all reachable vertexes will be process and all their distances will be known.
I am looking back at some of my algorithms homework(exam soon haha), and I am having troubles understanding the solution to one of the questions.
The Question
Tutor Solution
I am having difficulties visualizing the solution, I understand that if you have an odd number of cycles than your graph cannot be bipartite. But as I stated, I don't understand the shortest path from s to u and v to s.
Let's say G is bipartite. Then the vertex set can be divided into V1 and V2 s.t. every edge of G includes a vertex from each set. Then the vertices of every path in G alternate between V1 and V2, so the parity of the length of every path between every pair of vertices is the same. I.e., if G is bipartite and v,w are two vertices of G, then the length of every path connecting v & w is either even or odd.
If there is an edge (u,v) connecting two vertices in the same layer then this is violated. The BFS path to v and u have the same length, so same parity, since v & u are in the same layer. The edge between v & u gives us a path longer by 1, so of a different parity. Contradiction.
The tutor's solution isn't as clear as it could be, since it talks about cycles, and the two paths don't necessarily form a cycle since they can share vertices. And the definition of bipartite graph is slightly wrong (or uses non-standard definitions of edges, cross-product etc. where the things aren't pairs but 2-element sets).
But instead of the definition as given, I'd just say that a graph is bipartite if the vertices can be coloured black or white, such that each edge goes between different-coloured vertices. (Equivalently you can simply say "the graph is 2-colourable").
From this definition, it follows that if there's an even length path between two vertices they must be the same colour, otherwise different colours. In the BFS on a bipartite graph, a vertex u is layer i has a path of length i from s to u, so all vertices in the same layer have the same colour. Thus there can be no edge between two vertices in the same layer.
Input: We have a directed graph G=(V,E) and each edge has a weight and a colour {red,green}. We are also given a starting node s.Problem/Algorithm: Can we find for all u edges of G, the shortest paths s-u with at most k red edges ? First approach: We save for each node the shortest path with 0,1...k red edges. We modify Dijkstra's algorithm and depending on the colour of the edges we are looking into, we update the distances respectively. This approach fails due to its complexity. Second approach: We make k copies of G graph (G1,G2 ...Gk+1). In order to utilise the k red edges constraint, while we are searching for shortest paths with Dijkstra, every time we "meet" a red edge {ui,vi} in Gi, we connect ui with vi+1 in Gi+1. Because Gk+1 doesn't have any red edges, we can only reach Gk+1 with at most k edges.But it fails. For example with k=2 if a 2 red edges shortest path is found to X node then will not take into consideration a heavier path with less red edges which could lead to an undiscovered node. (If i had enough reputation i could post an image as example). Any ideas ?
I think your approaches are actually equivalent, provided that for approach #1, you record only the shortest distance to each node for each number of red edges used -- you don't need to record the entire path (just as you don't need to record it for ordinary Dijkstra on an ordinary shortest path problem)
Also this approach is sound. In particular, your reasoning that approach #2 is faulty is itself wrong: for any node X in the original graph, there is no single corresponding node X in the new graph; instead there are separate vertices for each number of red edges used. So the two paths "to X" you are considering are not actually to the same node: one is to (X, 2 red edges used) and one is to e.g. (X, 1 red edge used). Then you can use a single Dijkstra run to calculate shortest paths to all k+1 copies of every vertex (i.e. to the vertices (v, i red edges used) for each 0 <= i <= k and for each v in V(G)), and return the lowest. (I'm assuming here that when you wrote "Can we find for all u edges of G, the shortest paths s-u", you meant "for all nodes u of G, the shortest paths s-u".)
Finally, you need to make sure that for any red edge {u, v} in G, you delete the corresponding edge {ui, vi} for all Gi (as well as add in the edge {ui, vi+1}). You probably intended this, but you weren't explicit about it.
How would I convert a simple directed graph to a simple undirected one?
Is this possible?
Assuming: (from here)
in a simple digraph loops are disallowed. (A loop is an arc that pairs a vertex to itself.)
and: (from here)
a simple [undirected] graph is an undirected graph that has no loops (edges connected at both ends to the same vertex) and no more than one edge between any two different vertices.
I'm assuming the edges are unweighted, otherwise this can't be done without specifying how this needs to be done.
AM = Adjacency matrix
AL = Adjacency list
Remove the direction of all edges.
AM: For each edge A->B, row A, column B would already be set. Also set row B, column A.
AL: For each edge A->B, the edge already appears in A's AL, also add the edge to B's AL.
Go through all edges, removing all edges for which we already found an edge between the two vertices that are the end-points of that edge (so if A-B has already been processed, if we find another A-B (or equivalently B-A), we must remove that edge). This needs to be done since there can be multiple edges between vertices in a simple directed graph, but this can't happen in a simple undirected graph.
AM: Nothing really needs to be done since an AM forces there to only be a single edge between vertices, so we'd just be overwriting the edges.
AL: For each vertex A, for each edge A-B or B-A in its adjacency list, remove all other edges A-B or B-A in the list.
Source and details...
For each directed edge e=(x,y), add new vertices ve1,…,ve5 and replace e with the edges xve1, ve1ve2, ve1ve3, ve3ve4, ve4ve5, ve3y.
To decode, every leaf (degree-1 vertex) whose neighbour has degree 2 must be ve5 for some edge e=(x,y); its neighbour is ve4 and the other neighbour of ve4 is ve3. ve3 has a unique neighbour that has both degree 3 and is adjacent to a leaf: the neighbour is ve1 and its leaf is ve2 (if ve1 has two leaf neighbours, pick one arbitrarily to be ve2). The other neighbour of ve1 is x and the other neighbour of ve3 is y. Restore the directed edge (x,y) and delete the vertices ve1,…,ve5.
G=(V,E) is a directed graph. (a,b) \in E is a directed edge.
G' = (V, E') is an equivalent undirected graph where (a,b) is transformed as (a,b) and (b,a).
Thus, edge directed edge becomes two edge (one in each direction).
Let G (U u V, E) be a weighted directed bipartite graph (i.e. U and V are the two sets of nodes of the bipartite graph and E contains directed weighted edges from U to V or from V to U). Here is an example:
In this case:
U = {A,B,C}
V = {D,E,F}
E = {(A->E,7), (B->D,1), (C->E,3), (F->A,9)}
Definition: DirectionalMatching (I made up this term just to make things clearer): set of directed edges that may share the start or end vertices. That is, if U->V and U'->V' both belong to a DirectionalMatching then V /= U' and V' /= U but it may be that U = U' or V = V'.
My question: How to efficiently find a DirectionalMatching, as defined above, for a bipartite directional weighted graph which maximizes the sum of the weights of its edges?
By efficiently, I mean polynomial complexity or faster, I already know how to implement a naive brute force approach.
In the example above the maximum weighted DirectionalMatching is: {F->A,C->E,B->D}, with a value of 13.
Formally demonstrating the equivalence of this problem to any other well known problem in graph theory would also be valuable.
Thanks!
Note 1: This question is based on Maximum weighted bipartite matching _with_ directed edges but with the extra relaxation that it is allowed for edges in the matching to share the origin or destination. Since that relaxation makes a big difference, I created an independent question.
Note 2: This is a maximum weight matching. Cardinality (how many edges are present) and the number of vertices covered by the matching is irrelevant for a correct result. Only the maximum weight matters.
Note 2: During my research to solve the problem I found this paper, I think it would be helpful to others trying to find a solution: Alternating cycles and paths in edge-coloured
multigraphs: a survey
Note 3: In case it helps, you can also think of the graph as its equivalent 2-edge coloured undirected bipartite multigraph. The problem formulation would then turn into: Find the set of edges without colour-alternating paths or cycles which has maximum weight sum.
Note 4: I suspect that the problem might be NP-hard, but I am not that experienced with reductions so I haven't managed to prove it yet.
Yet another example:
Imagine you had
4 vertices: {u1, u2} {v1, v2}
4 edges: {u1->v1, u1->v2, u2->v1, v2->u2}
Then, regardless of their weights, u1->v2 and v2->u2 cannot be in the same DirectionalMatching, neither can v2->u2 and u2->v1. However u1->v1 and u1->v2 can, and so can u1->v1 and u2->v1.
Define a new undirected graph G' from G as follows.
G' has a node (A, B) with weight w for each directed edge (A, B) with weight w in G
G' has undirected edge ((A, B),(B, C)) if (A, B) and (B, C) are both directed edges in G
http://en.wikipedia.org/wiki/Line_graph#Line_digraphs
Now find a maximal (weighted) independent vertex set in G'.
http://en.wikipedia.org/wiki/Vertex_independent_set
Edit: stuff after this point only works if all of the edge weights are the same - when the edge weights have different values its a more difficult problem (google "maximum weight independent vertex set" for possible algorithms)
Typically this would be an NP-hard problem. However, G' is a bipartite graph -- it contains only even cycles. Finding the maximal (weighted) independent vertex set in a bipartite graph is not NP-hard.
The algorithm you will run on G' is as follows.
Find the connected components of G', say H_1, H_2, ..., H_k
For each H_i do a 2-coloring (say red and blue) of the nodes. The cookbook approach here is to do a depth-first search on H_i alternating colors. A simple approach would be to color each vertex in H_i based on whether the corresponding edge in G goes from U to V (red) or from V to U (blue).
The two options for which nodes to select from H_i are either all the red nodes or all the blue nodes. Choose the colored node set with higher weight. For example, the red node set has weight equal to H_i.nodes.where(node => node.color == red).sum(node => node.w). Call the higher-weight node set N_i.
Your maximal weighted independent vertex set is now union(N_1, N_2, ..., N_k).
Since each vertex in G' corresponds to one of the directed edges in G, you have your maximal DirectionalMatching.
This problem can be solved in polynomial time using the Hungarian Algorithm. The "proof" by Vor above is wrong.
The method of structuring the problem for the above example is as follows:
D E F
A # 7 9
B 1 # #
C # 3 #
where "#" means negative infinity. You then resolve the matrix using the Hungarian algorithm to determine the maximum matching. You can multiply the numbers by -1 if you want to find a minimum matching.