图算法:寻找网络最大流-Edmonds-Karp算法-js实现

文章介绍了如何使用Edmonds-Karp算法来寻找网络中的最大流,该算法通过初始化ResidualGraph并在其上迭代,每次寻找s到t的最短路径并更新流量,直至无法找到路径为止。文中还提供了JS代码示例,展示了算法的具体实现过程。
摘要由CSDN通过智能技术生成

1. 题目

        寻找网络最大流。

 2. 基本思想

        1. 初始化建立Residual Graph

        2. 在Residual Graph中迭代,直至未找到s->t的路径

                a. 寻找一条s->t的边数最短的路径

                b. 找到该路径最大的流量(等于路径上的最小容量)

                c. 更新Residual Graph

                d. 添加回溯路径

3. js代码实现

console.log(Edmonds_Karp());
// 寻找网络最大流:Edmonds-Karp算法
function Edmonds_Karp(){
    v_num=6;
    G=new Array(v_num).fill(0).map(()=>new Array(v_num).fill(0));
    G[0][1]=4;G[0][2]=2;G[1][2]=1;G[1][3]=2;G[2][4]=2;G[1][4]=4;G[3][5]=3;G[4][5]=3;

    ResG=new Array(v_num).fill(0).map(()=>new Array(v_num).fill(0));            // Residual Graph: 用于记录剩余容量
    for(i=0;i<ResG.length;i++){                                                 // 二维数组的深度复制
        for(j=0;j<ResG[0].length;j++){
            ResG[i][j]=G[i][j];
        }
    }

    while(1){                                                                   
        start=0;                                                                // 起点
        end=v_num-1;                                                            // 终点
        visit=new Array(v_num).fill(-1);                                        // 访问标记
        path=new Array(v_num).fill(-1);                                         // 路径存储
        visit[start]=1;

        flag=route(start);                                                      // 寻找有效路径
        
        if(flag==-1){
            break;
        }else{
            edge=new Array();
            min_dist=-1;
            node=start;

            while(node!=end){                                                   // 读出路径
                next_node=path[node];
                edge.push([node,next_node]);
                if(min_dist==-1||min_dist>ResG[node][next_node]){
                    min_dist=ResG[node][next_node];
                }
                node=next_node;
            }
            for(i=0;i<edge.length;i++){                                         // 更新ResG
                ResG[edge[i][0]][edge[i][1]]-=min_dist;
                ResG[edge[i][1]][edge[i][0]]+=min_dist;
            }
        }

        function route(node){
            if(node==end){                                                      // 是否为终点
                return 0;
            }else{
                var dist=-1;                                                    // 声明局部变量
                var i;
                for(i=0;i<v_num;i++){
                    if(ResG[node][i]>0&&visit[i]==-1){                          // 是否路径容量大于0且结点i未被访问
                        visit[i]=1;                                             // 标记访问结点
                        i_dist=route(i);                                        // 递归调用,寻找下一结点
                        if(i_dist!=-1&&(dist==-1||i_dist+1<dist)){              // 判断是否连通终点且路径边数最小
                            dist=i_dist+1;
                            path[node]=i;                                       // 存储路径
                        }
                        visit[i]=-1;                                            // 恢复前向访问节点
                    }
                }
                return dist;
            }
        }
    }
    
    flow=0; 
    for(i=0;i<v_num;i++){                                                       // flow=Graph-ResGraph
        flow+=G[0][i]-ResG[0][i];
    }
    return flow;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值