Подтвердить что ты не робот

Максимальный поток - Форд-Фулкерсон: Неописанный граф

Я пытаюсь решить проблему максимального потока для графика с использованием алгоритма Форда-Фулкерсона. Алгоритм описывается только ориентированным графом. Как насчет того, когда граф неориентирован?

То, что я сделал для имитации неориентированного графа, заключается в использовании двух направленных ребер между парой вершин. Меня смущает: если каждый из этих ребер имеет остаточный край или "противоположный" направленный край остаточного края?

Я предполагал, что последний, но мой алгоритм, кажется, идет в бесконечном цикле. Надеюсь, кто-нибудь из вас может мне помочь. Ниже приводится моя собственная реализация. Я использую DFS в поиске.

import sys
import fileinput

class Vertex(object):
    def __init__(self, name):
        self.name = name
        self.edges = []

    def find(self, sink, path):
        if(self == sink):
            return path
        for edge in self.edges:
            residual = edge.capacity - edge.flow
            if(residual > 0 or edge.inf):
                if(edge not in path and edge.oppositeEdge not in path):
                    toVertex = edge.toVertex
                    path.append(edge)
                    result = toVertex.find(sink, path)
                    if result != None:
                        return result

class Edge(object):
    def __init__(self, fromVertex, toVertex, capacity):
        self.fromVertex = fromVertex
        self.toVertex = toVertex
        self.capacity = capacity
        self.flow = 0
        self.inf = False
        if(capacity == -1):
            self.inf = True
    def __repr__(self):
        return self.fromVertex.name.strip() + " - " + self.toVertex.name.strip()

def buildGraph(vertices, edges):
    for edge in edges:
        sourceVertex = vertices[int(edge[0])]
        sinkVertex = vertices[int(edge[1])]
        capacity = int(edge[2])
        edge1 = Edge(sourceVertex, sinkVertex, capacity)
        edge2 = Edge(sinkVertex, sourceVertex, capacity)
        sourceVertex.edges.append(edge1)
        sinkVertex.edges.append(edge2)
        edge1.oppositeEdge = edge2
        edge2.oppositeEdge = edge1

def maxFlow(source, sink):
    path = source.find(sink, [])
    while path != None:
        minCap = sys.maxint
        for e in path:
            if(e.capacity < minCap and not e.inf):
                minCap = e.capacity

        for edge in path:
            edge.flow += minCap
            edge.oppositeEdge.flow -= minCap
        path = source.find(sink, [])

    return sum(e.flow for e in source.edges)

vertices, edges = parse()
buildGraph(vertices, edges)
source = vertices[0]
sink = vertices[len(vertices)-1]
maxFlow = maxFlow(source, sink)
4b9b3361

Ответ 1

Ваш подход использует два антипараллельных ребра. Если ваше ребро a->b (емкость 10, мы отправляем 7 над ним), мы вводим новый остаточный край (от b до a, который имеет остаточную емкость 17, остаточный край от a до b имеет оставшуюся емкость 3).

Исходный задний край (от b до a) может быть оставлен как есть, или новый остаточный край, а исходная база может быть расплавлена ​​в один край.

Я мог себе представить, что добавление остаточной емкости к исходному back-edge немного проще, но не уверен в этом.