def bipartite_vertex_cover(bigraph): """Bipartite minimum vertex cover by Koenig's theorem :param bigraph: adjacency list, index = vertex in U, value = neighbor list in V :assumption: U = V = {0, 1, 2, ..., n - 1} for n = len(bigraph) :returns: boolean table for U, boolean table for V :comment: selected vertices form a minimum vertex cover, i.e. every edge is adjacent to at least one selected vertex and number of selected vertices is minimum :complexity: `O(|V|*|E|)` """ V = range(len(bigraph)) matchV = max_bipartite_matching(bigraph) matchU = [None for u in V] for v in V: # -- build the mapping from U to V if matchV[v] is not None: matchU[matchV[v]] = v visitU = [False for u in V] # -- build max alternating forest visitV = [False for v in V] for u in V: if matchU[u] is None: # -- starting with free vertices in U _alternate(u, bigraph, visitU, visitV, matchV) inverse = [not b for b in visitU] return (inverse, visitV)
def bipartite_vertex_cover(bigraph): """Bipartie minimum vertex cover by Koenig's theorem :param bigraph: adjacency list, index = vertex in U, value = neighbor list in V :assumption: U = V = {0, 1, 2, ..., n - 1} for n = len(bigraph) :returns: boolean table for U, boolean table for V :comment: selected vertices form a minimum vertex cover, i.e. every edge is adjacent to at least one selected vertex and number of selected vertices is minimum :complexity: `O(|V|*|E|)` """ V = range(len(bigraph)) matchV = max_bipartite_matching(bigraph) matchU = [None for u in V] for v in V: # -- build the mapping from U to V if matchV[v] is not None: matchU[matchV[v]] = v visitU = [False for u in V] # -- build max alternating forest visitV = [False for v in V] for u in V: if matchU[u] is None: # -- starting with free vertices in U _alternate(u, bigraph, visitU, visitV, matchV) inverse = [not b for b in visitU] return (inverse, visitV)
def dilworth(graph): """Decompose a DAG into a minimum number of chains by Dilworth :param graph: directed graph in listlist or listdict format :assumes: graph is acyclic :returns: table giving for each vertex the number of its chains :complexity: same as matching """ n = len(graph) match = max_bipartite_matching(graph) # couplage maximum part = [None] * n # partition en chaînes nb_chains = 0 for v in range(n - 1, -1, -1): # dans l'ordre topologique inverse if part[v] is None: # début d'une chaîne u = v while u is not None: # suivre la chaîne part[u] = nb_chains # marquer u = match[u] nb_chains += 1 return part
def dilworth(graph): """Decompose a DAG into a minimum number of chains by Dilworth :param graph: directed graph in listlist or listdict format :assumes: graph is acyclic :returns: table giving for each vertex the number of its chains :complexity: same as matching """ n = len(graph) match = max_bipartite_matching(graph) # maximum matching part = [None] * n # partition into chains nb_chains = 0 for v in range(n - 1, -1, -1): # in inverse topological order if part[v] is None: # start of chain u = v while u is not None: # follow the chain part[u] = nb_chains # mark u = match[u] nb_chains += 1 return part