Skip to main content
 首页 » 编程设计

python之试图理解为什么这段 Python 代码有效

2025年05月04日15lovecherry

这是 Ford-Fulkerson algorithm 的一个实现维基百科上给出。我很好地理解算法,我的问题是:add_edge 和 max_flow 方法访问 的 redge(反向边缘) edge 为 edge.redge,但是 Edge 类没有名为 redge 的属性。尽管如此,代码运行良好。

class Edge(object): 
    def __init__(self, u, v, w): 
        self.source = u 
        self.sink = v   
        self.capacity = w 
    def __repr__(self): 
        return "%s->%s:%s" % (self.source, self.sink, self.capacity) 
 
class FlowNetwork(object): 
    def __init__(self): 
        self.adj = {} 
        self.flow = {} 
 
    def add_vertex(self, vertex): 
        self.adj[vertex] = [] 
 
    def get_edges(self, v): 
        return self.adj[v] 
 
    def add_edge(self, u, v, w=0): 
        if u == v: 
            raise ValueError("u == v") 
        edge = Edge(u,v,w) 
        redge = Edge(v,u,0) 
        edge.redge = redge 
        redge.redge = edge 
        self.adj[u].append(edge) 
        self.adj[v].append(redge) 
        self.flow[edge] = 0 
        self.flow[redge] = 0 
 
    def find_path(self, source, sink, path): 
        if source == sink: 
            return path 
        for edge in self.get_edges(source): 
            residual = edge.capacity - self.flow[edge] 
            if residual > 0 and edge not in path: 
                result = self.find_path( edge.sink, sink, path + [edge])  
                if result != None: 
                    return result 
 
    def max_flow(self, source, sink): 
        path = self.find_path(source, sink, []) 
        while path != None: 
            residuals = [edge.capacity - self.flow[edge] for edge in path] 
            flow = min(residuals) 
            for edge in path: 
                self.flow[edge] += flow 
                self.flow[edge.redge] -= flow 
            path = self.find_path(source, sink, []) 
        return sum(self.flow[edge] for edge in self.get_edges(source)) 

请您参考如下方法:

Python 类不声明对象属性,它们存储在每个实例的字典中。 Edge 对象恰好以三个属性开始,source、sink 和 capacity。后来它获得了一个新属性,redge。这是许多脚本语言的标准,包括 Python。

话虽如此,请注意稍后添加属性的做法被一些人认为是混淆的。为了清楚起见,最好初始化类打算在构造函数中使用的所有属性。