Программа 26, с. 131 Кирсанов М.Н. Графы в Maple , М.: Физматлит 2007
Наибольшее паросочетание в графе
> | restart: with(networks):with(LinearAlgebra): |
Процедура поиска матрицы паросочетания
> | BipartCard:=proc(A) |
> | global B; |
> | local i,j,X,Y,nxt,Usl,else1,C,C1,R,j1,nj,nf1, |
> | nof1r,is1c,cnv1; |
Процедура подсчета 1 в строке х
> | nof1r:=proc(x) local i,j; |
> | i:=0: for j to n do |
> | if B[x,j]=1 then i:=i+1 fi: |
> | od: i; |
> | end proc: |
Процедура поиска помеченного столбца без 1
> | is1c:=(x)->not is(1 in convert(Column(B,x),set)) and R[x]<>0: |
Процедура преобразование в матрицу
> | cnv1:=(x)->convert(x,Matrix): |
> | X:={$1..n}: Y:={$1..n}: |
> | for i to n do |
> | for j to n do |
> | if A[i,j]=0 then B[i,j]:=`*`: fi; |
> | if i in X and j in Y and A[i,j]=1 then B[i,j]:=A[i,j]: |
> | X:=X minus {i}: Y:=Y minus {j}: fi: |
> | od; |
> | od: |
> | nxt:=true: |
> | while nxt do |
> | C:=[seq(0,i=1..n)]: |
> | R:=[seq(0,i=1..n)]: |
> | Usl:=true; |
Первоначальные метки строк
> | while Usl do |
> | for i to n do |
> | if nof1r(i)=0 then C[i]:=`*`; fi; |
> | od; |
Метки столбцов
> | for i to n do |
> | if C[i]<>0 then |
> | for j to n do |
> | if B[i,j]=0 and R[j]=0 then R[j]:=i; fi; |
> | od; |
> | fi; |
> | od; |
> | C1:=C; |
Метки строк
> | for j to n do |
> | if R[j]<>0 then |
> | for i to n do |
> | if B[i,j]=1 and C[i]=0 then C[i]:=j; fi; |
> | od; |
> | fi; |
> | od: |
Проверка зацикливания
> | Usl:=not Equal(cnv1(C),cnv1(C1)); |
> | od: |
> | nxt:=false: |
Поиск помеченного столбца без 1
> | for j to n do |
> | if is1c(j) then nxt:=true: j1:=j; fi; |
> | od; |
> | if nxt then |
> | j:=j1; i:=0; nj:=0; else1:=true; |
> | while else1 do |
> | i:=i+1: |
> | while B[i,j1]<>0 do i:=i+1; od; #Поиск 0 по столбцу |
> | B[i,j1]:=1; # Вместо 0 |
> | nf1:=nof1r(i); |
> | # В новой строке находим другую 1 |
> | while nf1=2 do |
> | j:=1: while B[i,j]<>1 or j=j1 do j:=j+1; od; |
> | nj:=R[j]; |
> | if nj=0 # Если столбец без метки |
> | then |
> | B[i,j1]:=0;# Вместо ошибочной 1 |
> | nf1:=1;# Для выхода из цикла |
> | else |
> | B[nj,j]:=1; # Перенесли 1 по адресу из столбца j |
> | B[i,j]:=0; # Вместо 1 |
> | nf1:=nof1r(nj); |
> | i:=nj; else1:=false; |
> | fi; |
> | od; |
> | od; |
> | fi;#if nxt |
> | od: |
> | B:=subs(`*`=0,B); |
> | end proc: |
> | save BipartCard, "C:\\bipart.m"; |