如图,所示,最大匹配为4:.
如图所示,对于一个二分图,令已有的边的容量(Capacity)为无穷大,增加一个源点s和一个汇点t,令s和t分别连接二部图中的一个分步,并设置其容量为1。这时得到流网络G’,计算得到的最大流就等于最大二分匹配。
但是,我们还必须回答为什么这种方法是可行的呢?这里有一个简单的证明方法。首先假设,当前流网络有一个最大流,但它对应的不是最大匹配,那么,我们至少还可以向最大匹配中加入一条边,设为(u,v),显然我们还可以增加条增广路径,s->u->v->t。那么就得到一个更大的流,和假设矛盾。所以假设不成立。同理,假设当前有一个最大匹配,其对应的不是最大流,那么至少还存在一条增广路径,假设s->u->v->t。这时就可以增加边(u,v)到最大匹配中,矛盾。
package matchings;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import entry.Edge;
import entry.Node;
import maxflow.FordFulkerson;
public class Matching {
private double graph[][];
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
double graph[][]={
{0,0,0,1,1,0},
{0,0,0,0,1,1},
{0,0,0,0,0,1},
{0,0,0,0,0,0},
{0,0,0,0,0,0},
{0,0,0,0,0,0}
};
double graph2[][]={
{0,0,0,0,0,1,0,0,0},
{0,0,0,0,0,1,0,1,0},
{0,0,0,0,0,0,1,1,1},
{0,0,0,0,0,0,0,1,0},
{0,0,0,0,0,0,0,1,0},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0}
};
Matching m=new Matching(graph2);
int L[]={0,1,2,3,4};
int R[]={5,6,7,8};
/*
double flowNetwork[][]=m.getMaxMachingFromMaxFlow(graph2,L,R);
int length=flowNetwork.length;
for(int i=0;i0?flowNetwork[i][j]:0.0)+" ");
}
System.out.println();
}*/
System.out.println(m.getMaxMaching(graph2, L, R));
}
public Matching(double graph[][])
{
this.graph=graph;
}
/**
* Let G be a bipartite graph with partite sets U and W such that r=|U|<=|W|.
* Then G contains a matching of cardinality r if and only if U is neighborly.(which means that :For any nonempty subset X,N(X)>=X)
* 但是这种方法的复杂度为O(2^n),所以可以不如用下面两个算法直接求出最大匹配,然后比对是否是perfect matching
* @return
*/
public boolean hasPerfectMatching(double graph[][],int L[],int R[])
{
return false;
}
/**
* 利用最大流算法实现,返回最大流网络
* @param graph
* @param L
* @param R
* @return
*/
public double[][] getMaxMachingFromMaxFlow(double graph[][],int L[],int R[])
{
int length=graph.length;
double augGraph[][]=new double[length+2][length+2];
for(int i=0;i getMaxMaching(double graph[][],int L[],int R[])
{
int length=graph.length;
for(int i=0;i rSet=new HashSet();
Set lSet=new HashSet();
List list=new ArrayList();
for(int i=0;i list,Set rSet,Set lSet) {
int idx=0;
List oddEdge=new ArrayList();
List evenEdge=new ArrayList();
while(result.getParent()!=null)
{
Node parent=result.getParent();
if(idx%2==0)
{
Edge e=new Edge(parent.nodeId,result.nodeId,0);
evenEdge.add(e);
}
else
{
Edge e=new Edge(result.nodeId,parent.nodeId,0);
oddEdge.add(e);
}
idx++;
result=parent;
}
/**
* 检测第6条性质
*/
for(int i=0;i