Find a maximum matching - algorithm

Let G(A,B,V), a bipartite graph where |A|=|B|=n. There's a matching, M subset of E where |M| = n-2013. Describe an efficient algorithm to determine if a maximal matching exists.
Basically the given solution is building a flow-network from the graph, by adding s,t vertices, connecting s to each vertex v in A and each vertex v in B to t. All capacities are 1.
Now, we give a starting flow for all edges M (And all edges connected to edges of M, from s and to t)
Now we just need to run Fold-Falkerson (or Edmond-Karp) Algorithm and check if we were able to improve 2013 paths (i.e. adding more flow for some path). More precisely, we need, at most, to run BFS, 2013 times to decide
My question is:
Why does it work? As I see it, M is just an arbitrary match. It's like we are assuming that M is part of a maximal-matching.
I'd be glad for a clarification!
Thanks

IIUC, the algorithms is this:
Create the flow network s → A → B → t
On this network, calculate the flow induced by M.
Now create the residual flow graph, and continue Edmonds-Karp from here.
Why does this work? The Ford-Fulkerson method guarantees that, given any valid flow (in particular, in this case the one given by M, while the maximal flow is not yet achieved, there is an augmenting path in the residual network. Here, each augmentation increases the flow (and hence the matching) by 1. Hence, if the maximal flow is q, then within q - |M| iterations, it will be achieved.
The point which seems to confuse you is that it seems that the optimal matching necessarily includes M. This is not the case. Augmentation along the residual network can actually cancel flows in the original network. Hence, the augmentations can actually "reverse" some of the matchings of M.

Related

Path double cover, recursion set up

I'm working on path double cover problem. I have undirected connected graph G and and I change every edge to 2 directed edges and each of them is in opposite direction. Then the goal is to find set of paths(no loops) in this directed graph so that every vertex is used once as start of path and once as end of another path. Each of directed edges are used exactly once.
undirected graph G
directed graph G
For this example there is set of paths P={(1,2,4),(4,3,1),(2,1,3),(3,4,2)}.
There are currently known 2 graphs K3 and K5 (fully connected graphs with 3 and 5 vertices) which cannot be covered in this way.
I want to make script which will find me this covering or tell me if there isn't one. I tried to generate all possible paths and then search in them but for bigger graph this approach isn't usable (n! complexity). I don't know how to set up the recursion so I can keep track of what I've used. I don't care about time complexity but it would be awesome if you had any tip for doing it more quickly. :D
Thanks for any suggestions. :D
Your definition is a bit confusing- you say that you need to find a set of paths (no loops) in the directed graph, with 1 outgoing edge per vertex. There is no way for these edges not to form a loop (at most n - 1 edges can be tree edges).
I'm going to assume that you instead mean "only one cycle; no subcycles".
In that case, your task becomes that of determining whether your graph has a Hamiltonian Cycle or not.
We can use Ore's Theorem as a quick check:
If deg v + deg w ≥ n for every pair of distinct non-adjacent vertices v and w of G then G is Hamiltonian.
Note that this says "if" and not "iif" / "if and only if", so a graph be Hamiltonian, and not satisfy this check.
To take things one step further, we can use the Bondy–Chvátal theorem:
A graph is Hamiltonian if and only if its closure is Hamiltonian.
And we obtain its closure in a similar method to what we did for Ore's Theorem check- we repeatedly add a new edge connecting a nonadjacent pair of vertices u and v with deg(v) + deg(u) ≥ n until no more pairs with this property can be found.
Once this is done, we check whether the closure is Hamiltonian. If the closure is a complete graph, then it is Hamiltonian. I was unable to find any proof that the closure will be complete iif the graph g is Hamiltonian, however it does seem to happen with every example graph I can conjure up, so at least it may be a stronger correlation than Ore's Theorem.
In the end, you just need to determine if the graph has Hamiltonian Cycle. I've listed above two ways you can perform quadratic-time checks to positively identify some of such graph (maybe all, again- not sure of the completeness of the closure bit).

Compute all edge-disjoint paths between two given vertices of a simple directed graph

Many similar questions have been asked, but non addresses exactly my situation: Given two vertices in a simple directed unweighed graph, and an integer k, how can I find all k-tuples of edge-disjoint paths between the vertices? (In particular, I'm interested in the case that k is the outdegree of the start vertex.)
I know Suurballe's algorithm will give me k edge-disjoint paths, but it will (non-deterministically) settle on one solution, instead of giving me all of them.
It seems maximum-flow algorithms like Edmonds-Karp are related, but they don't compute paths.
Is there any algorithm already in JGraphT that does what I want?
Here's a simple recursive method:
if k is 0, output [] and return
otherwise, choose an arbitrary arc from the source vertex
for all paths p that start with that arc and end at the sink,
for all k-1 tuples T in the graph where the arcs in p are removed,
output [p] + T
This method can be improved by pruning parts of the recursion tree. The easiest idea is to remove all arcs to the source vertex, since if a path uses two arcs from the source vertex, we won't get to k before disconnecting the source and sink.
A broader version of that idea uses maximum flow to identify arcs that can be part of a solution. Compute the max flow from the source to the sink. By the flow decomposition theorem, there is at least one k-tuple of edge disjoint paths if and only if the value of the flow is at least k. If these conditions are true, then there is a solution that uses the set of arcs carrying flow, so this set needs to be retained. To test the others, compute the strongly connected components of the residual graph (arcs without flow appear forward, arcs with flow appear backward). All arcs without flow that go from one SCC to another can be safely discarded.

Use O(n^2) time to fix a mistake in bipartite matching

This is a problem from Algorithm Design book.
Given a bipartite graph with vertices G=(V,E) where V=(A,B) such that |A|=|B|=n.
We manage to perfectly match n-2 nodes in A to n-2 nodes in B. However, for the remaining two nodes in A we map them both to a certain node in B (not one of the n-2 nodes in B that are already matched to.)
Given the information from the "matching" above, how to use O(n^2) time to decide whether a perfect matching between A and B actually exists? A hint is fine. Thank you.
Let's have u and v be the two nodes in A that match to the same node x in B. Pick one of those two nodes - call it u - and remove the edge to x from the matching. You are now left with a graph where you have a matching between n - 1 of the nodes from A and n - 1 of the nodes from B. The question now is whether you can extend this matching to make it even bigger.
There's a really nice way to do this using Berge's theorem, which says that a matching in a graph is maximum if and only if there is no alternating path between two unmatched nodes. (An alternating path is one that alternates between using edges not included in the matching and edges included in the matching). You can find a path like this by starting from the node u and trying to find a path to x by doing a modified binary search, where when you go from A to B you only follow unmatched edges and when you go from B back to A you only follow matched edges. If an alternating path exists from u to x, then you'll be sure to find it this way, and if no such path exists, then you can be certain of that as well.
If you do find an alternating path from u to x, you can "flip" it to increase the size of the matching by one. Specifically, take all the edges in the path that aren't in the matching and add them in, and take all the edges that were in the matching and delete them. The resulting is still a valid matching that has one more edge in it than what you started with (if you don't see why this is, play around with some examples and see what you find, or look at the proof of Berge's theorem).
Overall, this approach will require time O(m + n), where m is the number of edges in the graph and n is the number of nodes. The number of edges m is at most O(n2) in a bipartite graph, so this matches your time bound (and, in fact, is actually a bit tighter!)
Transform this problem to the max flow min cut problem by adding a source s which is connected to A by unit capacity edges and a sink t to which B is connected by unit capacity edges.
As templatetypedef said in their answer, we already have a flow of size n-1 on this network.
The problem is now to determine whether the size of the flow can be increased to n. This can be achieved by running one round of Edmonds-Karp heuristic which takes O(E)=O(n^2) time (i.e find the shortest path in the residual graph of the flow of size n-1 above and look for the bottleneck edge.)

A network flow with different constraints

Considering a simple network flow model: G = (V,E), source node S, and sink node T. For each edge E[i], its capacity is C[i].
Then the flow F[i] on edge E[i] is constrained to be either C[i] or 0, that is, F[i] belongs to {0, C[i]}.
How to compute the maximum flow from S to T? Is this still a network flow problem?
The decision variant of your modified flow problem is NP-complete, as evidenced by the fact that the subset sum problem can be reduced to it: For given items w_1, ..., w_n and a sum W, just create a source S connected to every item i via an edge S -> i of capacity w_i. Then connect every item i to a sink t via another edge i -> t of capacity w_i. Add an edge t -> T of capacity W. There exists a subset of items with cumulative weight W iif the S-T max-flow in the graph is W with your modifications.
That said, there is likely no algorithm that solves this problem efficiently in every case, but for instances not specifically designed to be hard, you can try an integer linear program formulation of the problem and use a general ILP solver to find a solution.
There might be a pseudopolynomial algorithm if your capacities are integers bounded by a value polynomial in the input size.
Um, no its no longer a well defined flow problem, for the reason that Heuster gives, which is that given two edges connected through a node (with no other connections) the flow must be zero unless the two capacities equal each other. Most generic flow algorithms will fail as they cannot sequentially increase the flow.
Given the extreme restrictivity of this condition on a general graph, I would fall back on a game tree working backwards from the sink. Most nodes of the game tree will terminate quickly as there will be no combination of flows into a node that exactly match the needed outflows. With a reasonable heuristic you can probably find a reasonable search order and terminate the tree without having to search every branch.
In fact, you can probably exclude lots of nodes and remove lots of edges before you start, on the grounds that flows through certain nodes will be trivially impossible.

How to find ALL Eulerian paths in directed graph

I have a directed graph and I want to find all existing eulerian paths (in my graph I actually know that those will be circuits).
I have done some research so I can use for example Hierholzer's algorithm as in here: http://stones333.blogspot.co.uk/2013/11/find-eulerian-path-in-directed-graph.html to find a path from given node but this algorithm returns only one path I believe.
My idea to solve this is to have an algorithm that will return ALL existing Eulerian paths / circuits starting from given node. Then I will run this algorithms for all nodes and get the results. This will have n^2 or n^3 complexity which is great.
So my question is if there is an algorithm that will find all Eulerian paths / circuits in directed graph from given node? Or maybe someone knows another solution to my problem.
EDIT:
after Gassa comment I think that the solution with Euler paths might be an overkill for my problem. Problem is as follows: for given n we create a pairs of integers which sum is <= n. For those pairs find all paths that connects all of the pairs such that second value of previous pair equals to the first value from next pair (like domino).
Example: n = 2, then available pairs = {(0,0), (0,1),(1,0),(1,1),(2,0),(0,2)}. One of the valid chains = (0,0)=>(0,1)=>(1,1)=> (1,0)=>(0,2)=>(2,0). I preferred algorithm using graphs because for example (0,0) might not be valid sometimes, but let's say it is valid for the sake of this question. Brute force solution to this problem is to of course create all permutations of available pairs and then see if they are valid but this is obviously O(n!) complex. I am pretty sure this could be done in some "smart" way.
In the general case, the number of distinct Eulerian paths is exponential in the number of vertices n. Just counting the number of Eulerian circuits in an undirected graph is proven to be #P-complete (see Note on Counting Eulerian Circuits by Graham R. Brightwell and Peter Winkler). Quoting Wikipedia:
A polynomial-time algorithm for solving a #P-complete problem, if it
existed, would imply P = NP, and thus P = PH. No such algorithm is
currently known.
So perhaps you will need another approach.
If however your graph has certain properties which make the exponential number of Eulerian circuits impossible, do tell us these properties.
If you want to enumerate all Eulerian paths (and, like Gassa, I have my doubts), then the following simple output-sensitive algorithm has polynomial overhead, which, since n will be very small, should suffice. There's a recursive procedure for enumerating all paths from v that goes like this in Python.
def paths(v, neighbors, path): # call initially with path=[]
yield path[:] # return a copy of the mutable list
for w in list(neighbors[v]):
neighbors[v].remove(w) # remove the edge from the graph
path.append((v, w)) # add the edge to the path
yield from paths(w, neighbors, path) # recursively enumerate
# all path extensions from w
# in the residual graph
path.pop() # remove the edge from the path
neighbors[v].add(w) # add the edge to the graph
To return Eulerian paths only, we make two modifications. First, we prune the recursion if there is no Eulerian path extending the current path. Second, we do the first yield only when neighbors[v] is empty, i.e., the only extension is the trivial one, so path is Eulerian. Since the degree balance condition is satisfied, we prune by just checking strong connectivity of the non-isolated vertices at each recursive call, given that we add an arc from the starting vertex to v. This can be accomplished with two traversals, one to verify that every non-isolated vertex can reach the starting vertex and one to verify that every non-isolated vertex is reachable from v. (Alternatively, you could add the arc temporarily and do one traversal, but then you'd have to handle multigraphs, which you may not want to.)

Resources