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;
}