Программа 24, с. 123 Кирсанов М.Н. Графы в Maple ,   М.: Физматлит 2007

 Поток в сети

>    restart: with(networks):

>    new(G):V:=$1..8: addvertex([V],G):

>    v1:=1:# Источник

>    v2:=8:# Сток

>    E:=[[1,3],[3,5],[5,7],[7,8],[1,2],[2,4],[4,6],[6,8],[3,2],[2,5],[5,4],[4,7],[7,6]]:

>    w:=[6,9,7,4,6,4,4,7,5,2,8,2,11]:   #Пропускная способность

>    addedge(E,weights=w,G):

>    draw(Linear([1],[3,2],[5,4],[7,6],[8]),G);

>    Поток=flow(G,v1,v2,ed);

>    ed;              # Насыщенные дуги

[Maple Plot]

`Поток` = 11

{{1, 2}, {2, 4}, {2, 5}, {4, 6}, {4, 7}, {6, 8}, {7, 8}}

>    m:=nops(edges(G)):

>    H:=duplicate(G):

>    potok1:=table([seq(e||i=0,i=1..m)]):# Начальное значение потока

>    while (v1 in vertices(G)) do

>    s:=[]: d:={v1}: d2:=v1:

>    c1:={v1}: ndep1:=v1:

>    while d2<>v2 and ndep1<>0 do

>      d1:=d[1]:           # Начало следующей дуги

>      d:=departures(d1,G):# Множество возможных концов      

>      ndep1:=nops(d);

>      if ndep1=0 then delete(d1,G); else

>        d:=d minus c1;    # Исключаем пройденные вершины

>        d2:=d[1]:# Конец дуги

>        nd:=op(edges([d1,d2],G));

>        c1:= c1 union {d2}; # Пополняем список пройденных

>        s:=[op(s),nd]:# Список пройденных дуг

>      fi;

>    od:#while

>    if v2 in c1 then  # Если образовалась цепь

>     n1:=nops(s);     # Длина цепи

>     pt:=[potok1[s[j]]$j=1..n1];

>     sp:=[op(eweight(s,H))];

>     potok2:=map(`+`,pt,min(op(sp-pt)));      #новый поток

>     for i to n1 do potok1[s[i]]:=potok2[i];

>       if potok1[s[i]]=eweight(s[i],H) then

>       delete(s[i],G); end;# Удаляем из графа насыщ дуги

>     od:

>    fi:

>    end:#while

Перераспределение

>    H2:=duplicate(H):

>    while (v1 in vertices(H2))  do

>    c1:={}: # Множество пройденных вершин

>    in2:={}: # Множество входящих дуг

>    out2:={}: # Множество выходящих дуг

>    d1:=v1: # Первая вершина

>    notupik1:=true;

>    while d1<>v2 and notupik1 do

>     out0 :=departures(d1,H2) minus c1;

>     out1:={};

>     for i in  out0 do

>      nd:=op(edges([d1,i],H2));

>      if eweight(nd,H2)<>potok1[nd] then

>      d2:=i; out1:=edges([d1,i],H2) end;#Не рассматриваем полные выходящие  

>     od;

>     out2:=out2 union out1;#Множество прямых дуг в цепи

>    in0:=arrivals(d1,H2) minus c1;

>    in1:={};

>    for i in  in0  do  

>      nd:=op(edges([i,d1],H2));

>      if potok1[nd]<>0 then

>      d2:=i; in1:=edges([i,d1],H2); end;#Не рассматриваем пустые входящие

>    od;

>    in2:=in2 union in1;    #Множество обратных дуг в цепи

>    if nops(in1 union out1)=0 then

>     delete(d1,H2); notupik1:=false; else

>     c1:=c1 union {d1};

>     d1:=d2;# Конец(начало) последней дуги - новая вершина для поиска

>    end;

>    od;

>      pr1:=(x)->eweight(x,H)-potok1[x];

>      pr2:=(x)->potok1[x]:

>    if notupik1 then# Перераспределяем поток

>      m1:=min(op(map(pr1,out2)));

>      m2:=min(op(map(pr2,in2)));

>      ptk:=min(m1,m2);

>      for i in in2 do potok1[i]:=potok1[i]-ptk;od:

>      for i in out2 do potok1[i]:=potok1[i]+ptk;od:

>    fi;

>    od:#while

>    edg2:=incident(v2, H, 'In'):# Множество дуг, входящих в сток

>    Поток=map(`+`,op(eweight([op(edg2)],H)));

>    satur1:=[]:

>    for x in edges(H) do

>    if pr1(x)=0 then satur1:=[op(satur1),x];end; od;

>    satur1;  # Насыщенные дуги

`Поток` = 11

[e10, e12, e4, e5, e6, e7, e8]