Esempio n. 1
0
def bipartiteGraph(g, rL, cL):
    gb = [[] for n in range(rL + cL)]
    for edges in g:
        for e in edges:
            gb[e.src].append(Edge(e.src, e.dst + rL))
            gb[e.dst + rL].append(Edge(e.dst + rL, e.src))
    return gb
Esempio n. 2
0
def bipartiteMatching(g, L, matching):
    n = len(g)
    matchTo = [-1 for n in range(n)]
    match = 0
    for u in range(L):
        visited = [False] * n
        if augment(g, u, matchTo, visited):
            match += 1
    for u in range(L):
        if matchTo[u] >= 0:
            matching.append(Edge(u, matchTo[u]))
    return match
Esempio n. 3
0
    def construct_gb(self):
        # construct graph of dm-decomped blocks' dependency
        nb = len(self.rss)
        self.endossb = [set() for n in range(nb)]
        for k in range(nb):
            for e in self.rss[k]:
                self.endossb[k] |= {
                    self.find_css_block(v.dst)
                    for v in self.g[e]
                }

        self.gb = [[] for n in range(nb)]
        for k in range(nb):
            for v in self.endossb[k]:
                self.gb[k].append(Edge(k, v))
Esempio n. 4
0
def DulmageMendelsohnDecomposition(g, rs, cs):
    rL = len(g)
    cL = max([e.dst for edges in g for e in edges]) + 1

    # step0: generate bipartite graph
    gb = bipartiteGraph(g, rL, cL)

    # step1: find bipartiteMatching
    matching = []
    bipartiteMatching(gb, rL, matching)

    # step2: modify graph i.e. birateral M and R -> C edges
    gb[rL:] = [[] for n in range(cL)]
    for m in matching:
        r = min(m.src, m.dst)
        c = max(m.src, m.dst)
        gb[c].append(Edge(c, r))

    # step3: find V0 and Vinf
    matched = [m.src for m in matching]
    matched += [m.dst for m in matching]
    rsrc = [n for n in range(rL) if not n in matched]
    cdst = [n for n in range(rL, rL + cL) if not n in matched]
    Vinf = getDst(gb, rsrc)
    V0 = getDst(reverse(gb), cdst)

    # step4: find scc of g without V0 and Vinf
    # Kosaraju's algorithm to preserve topological order of scc
    V = V0 + Vinf
    gb[:] = [[e for e in edges if not (e.dst in V or e.src in V)]
             for edges in gb]
    scc = []
    stronglyConnectedComponents(gb, scc)
    scc[:] = [c for c in scc if not c[0] in V]  # remove V0 and Vinf
    scc[:] = [V0] + scc + [Vinf]

    rs[:] = [[n for n in c if n < rL] for c in scc]
    cs[:] = [[n - rL for n in c if n >= rL] for c in scc]
Esempio n. 5
0
    return False


# g: bipartite graph
# L: size of the left side
def bipartiteMatching(g, L, matching):
    n = len(g)
    matchTo = [-1 for n in range(n)]
    match = 0
    for u in range(L):
        visited = [False] * n
        if augment(g, u, matchTo, visited):
            match += 1
    for u in range(L):
        if matchTo[u] >= 0:
            matching.append(Edge(u, matchTo[u]))
    return match


# -*- sample code -*-
if __name__ == '__main__':
    from algorithm.graph import Edge
    matching = []
    L = 3
    g = [[Edge(0, 3), Edge(0, 4)], [Edge(1, 4), Edge(1, 5)], [Edge(2, 5)],
         [Edge(3, 0)], [Edge(4, 0), Edge(4, 1)], [Edge(5, 1),
                                                  Edge(5, 2)]]
    bipartiteMatching(g, L, matching)
    for e in matching:
        print(e)
            if v == w: break


# Tarjan's algorithm
def stronglyConnectedComponents(g, scc):
    n = len(g)
    num = [0] * n
    low = [0] * n
    inS = [False] * n
    S = []
    del scc[:]
    time = 0
    for u in range(n):
        if num[u] == 0:
            visit(g, u, scc, S, inS, low, num, time)


# -*- sample code -*-
if __name__ == '__main__':
    scc = []

    g = [[Edge(0, 6)], [Edge(1, 0)], [Edge(2, 6)], [Edge(3, 4)], [Edge(4, 3)],
         [Edge(5, 0), Edge(5, 4)],
         [Edge(6, 1), Edge(6, 3),
          Edge(6, 4), Edge(6, 5)]]

    stronglyConnectedComponents(g, scc)

    print(scc)
    #-> [[4, 3], [5, 1, 6, 0], [2]]
Esempio n. 7
0
 def construct_g(self):
     # construct graph of endogenous vars' dependency
     self.g = [[] for n in range(len(self.d))]
     for e in range(len(self.endoss)):
         for v in sorted(self.endoss[e]):
             self.g[e].append(Edge(e, self.d[v]))