有向图的最小流量最大费用

关于最小费用最大流的问题描述,这个ppt讲的很好   https://wenku.baidu.com/view/38c158d4c1c708a1284a44af.html

初始化费用矩阵和链路容量矩阵,费用矩阵中如果两个点之间不相连,则代价为inf,而链路容量矩阵中两个点不直连,则链路容量为0.

然后怎样在迭代中更新费用矩阵,有三条规则:

1、如果某条链路没有任何流量通过,则该条链路的费用不变。

2、如果某条链路上有流量但不饱和,则该条链路原本的前向链路的代价为a的话,则反向添加一条链路,其代价为-a。(例如原本图中是点i到j,费用为a,则现在代价矩阵中添加一条从j到i的链路,代价为-a),具体理解:称i到j为前向链路,j到i为后向链路,这样表明,如果后面继续会从前向链路上增加流量的话,费用会增加a*走过的流量,如果链路一开始走多了,那么要回退,即走后向链路,那么费用会以-a*退的流量而减少。

3、如果某条链路达到饱和,那么原来前向链路的费用为inf(即断开),后向链路的费用为-a,表示已经不能再从前向链路增加流量了,只能从后向退回原来多走的流量。


然后更新完代价矩阵之后,再根据实际走的流量情况更新走的流量矩阵。最终完成迭代,得到最小费用最大流。

附上matlab代码:

function [ f,MinCost,MaxFlow ] = MaxFlowMinCost( a,c,V,s,t )
%% 输入参数列表
%  a        单位流量的费用矩阵
%  c        链路容量矩阵
%  V        最大流的预设值,可为无穷大
%  s        源节点
%  t        目的节点
%% 输出参数列表
%  f        链路流量矩阵
%  MinCost  最小费用
%  MaxFlow  最大流量
%% 说明
%不断更新a和c矩阵,如果某两点之间的链路容量饱和,则该链路费用为inf,链路容量为0
%% 第一步:初始化
    NodeNum=size(a,1);%节点数目
    f=zeros(NodeNum,NodeNum);%流量矩阵,初始时为零流
    MaxFlow=0;%最大流量,初始时也为零
    MinCost=0;%初始化最小费用
    w=a;%权值费用矩阵
    %% 第二步:迭代过程
    while MaxFlow<V%停止条件为达到最大流的预设值
        [cost,path] = Floyd(w,s,t);
        
        %判断从s到t是否已经无路可走
        if cost==inf 
            break;
        end
        
        %求一条最小花费路径上的最大流量
        minflow=[];%以花费为权值的最小路径上的能通过的最大流量
        for i=1:(length(path)-1)     
            if c(path(i),path(i+1))>f(path(i),path(i+1))
                minflow=[minflow,c(path(i),path(i+1))-f(path(i),path(i+1))];
            elseif c(path(i+1),path(i))==f(path(i+1),path(i))
                minflow=[minflow,c(path(i+1),path(i))];
            else
                disp('出错啦1!');
            end
        end
        minflow=min(minflow);
        disp(['minflow为: ', num2str(minflow)]);
        disp(path);
        
        MaxFlow=MaxFlow+minflow;
        if MaxFlow>=V%如果最后流量过剩
           minflow=minflow-(MaxFlow-V);
           MinCost=MinCost+(cost*minflow);
           for i=1:(length(path)-1)
               if c(path(i),path(i+1))>f(path(i),path(i+1))
                   f(path(i),path(i+1))=f(path(i),path(i+1))+minflow;
               elseif c(path(i+1),path(i))==f(path(i+1),path(i))
                   f(path(i+1),path(i))=f(path(i+1),path(i))-minflow;
               else
                   disp('出错啦2!');
               end
           end
           MaxFlow=V;
           for i=1:(length(path)-1)
                if c(path(i),path(i+1))==f(path(i),path(i+1))%饱和链路
                    w(path(i+1),path(i))=-w(path(i),path(i+1));
                    w(path(i),path(i+1))=inf;
                elseif c(path(i),path(i+1))>f(path(i),path(i+1))
                    w(path(i+1),path(i))=-w(path(i),path(i+1));
                elseif c(path(i+1),path(i))>f(path(i+1),path(i))
                    w(path(i),path(i+1))=-w(path(i+1),path(i));
                else
                    disp('出错啦!3');
                end
           end
           break;
        end
        MinCost=MinCost+(cost*minflow);
        for i=1:(length(path)-1)
            if c(path(i),path(i+1))>f(path(i),path(i+1))
                   f(path(i),path(i+1))=f(path(i),path(i+1))+minflow;
            elseif c(path(i+1),path(i))==f(path(i+1),path(i))
                   f(path(i+1),path(i))=f(path(i+1),path(i))-minflow;
            else
                   disp('出错啦4!');
            end
        end 
        %更新a和c矩阵
        for i=1:(length(path)-1)
            if c(path(i),path(i+1))==f(path(i),path(i+1))%饱和链路
                    w(path(i+1),path(i))=-w(path(i),path(i+1));
                    w(path(i),path(i+1))=inf;
            elseif c(path(i),path(i+1))>f(path(i),path(i+1))
                    w(path(i+1),path(i))=-w(path(i),path(i+1));
            elseif c(path(i+1),path(i))>f(path(i+1),path(i))
                    w(path(i),path(i+1))=-w(path(i+1),path(i));
            else
                    disp('出错啦!5');
            end
        end
    end
end

function [ MinCost,path ] = Floyd( w,s,t )
%w:输入图的邻接矩阵
%s:源节点标号
%t:目的节点标号
%MinCost:费用
%path:最短路径
%D:D为路径的邻接矩阵
%path_matrix:路径所经过的端点

n=size(w,1);
%设初值
D=w;
path_matrix=zeros(n);%生成n*n的矩阵
for i=1:n
   for j=1:n
       if D(i,j)~=inf
           path_matrix(i,j)=j;
       end
   end
end %生成路径矩阵
%迭代,更新D path
for k=1:n
   for i=1:n
      for j=1:n
         if D(i,k)+D(k,j)<D(i,j)
            D(i,j)=D(i,k)+D(k,j);%更新路径的权值
            path_matrix(i,j)=path_matrix(i,k);%注意这里因为存的都是后一个点,所以(k,j)存的还是j,所以不用更新
         end
      end
   end
end
%%输出最小代价和路径
MinCost=D(s,t);
if MinCost==inf%注意这里加一个判断,不然当面临s到t无路径时会出错
    path=[];
    return
end
path=[s];
tmp=s;
while tmp~=t
    tmp=path_matrix(tmp,t);
    path=[path,tmp];
end
end




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 JavaScript 编写的记忆游戏(附源代码)   项目:JavaScript 记忆游戏(附源代码) 记忆检查游戏是一个使用 HTML5、CSS 和 JavaScript 开发的简单项目。这个游戏是关于测试你的短期 记忆技能。玩这个游戏 时,一系列图像会出现在一个盒子形状的区域中 。玩家必须找到两个相同的图像并单击它们以使它们消失。 如何运行游戏? 记忆游戏项目仅包含 HTML、CSS 和 JavaScript。谈到此游戏的功能,用户必须单击两个相同的图像才能使它们消失。 点击卡片或按下键盘键,通过 2 乘 2 旋转来重建鸟儿对,并发现隐藏在下面的图像! 如果翻开的牌面相同(一对),您就赢了,并且该对牌将从游戏中消失! 否则,卡片会自动翻面朝下,您需要重新尝试! 该游戏包含大量的 javascript 以确保游戏正常运行。 如何运行该项目? 要运行此游戏,您不需要任何类型的本地服务器,但需要浏览器。我们建议您使用现代浏览器,如 Google Chrome 和 Mozilla Firefox, 以获得更好、更优化的游戏体验。要玩游戏,首先,通过单击 memorygame-index.html 文件在浏览器中打开游戏。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值