最大團問題的java實現(回溯法)
具體問題描述以及C/C++實現參見網址
http://blog.csdn.net/liufeng_king/article/details/8781554
/**
* 最大團問題--回溯法
* @author Lican
*
*/
public class Maxclique {
public int[] x;//當前解(x[i]=1表示i點在最大團中,=0表示不在團中)
public int n;//圖G的頂點數
public int cn;//當前頂點數
public int bestn;//當前最大頂點數
public int[] bestx;//當前最優解
public int[][] a;//圖G的鄰接矩陣,0:不連通;1:連通
public int count;//圖G的最大團個數
public void backtrack(int i){
if(i>n){
for(int j=1;j<=n;j++){
bestx[j]=x[j];
System.out.print(x[j]+" ");
}
System.out.println();
bestn=cn;
count++;
return;
}
else{
boolean ok=true;
for(int j=1;j<i;j++){//檢查頂點i是否與當前團全部連接
if(x[j]==1&&a[i][j]==0){
ok=false;
break;
}
}
if(ok){//從頂點i到已選入的頂點集中每一個頂點都有邊相連
//進入左子樹
x[i]=1;
cn++;
backtrack(i+1);
x[i]=0;
cn--;
}
if(cn+n-i>=bestn){//當前頂點數加上未遍歷的課選擇頂點>=當前最優頂點數目時才進入右子樹;如果不需要找到所有的解,則不需要等於
//進入右子樹
x[i]=0;
backtrack(i+1);
}
}
}
public int maxclique(int nn,int[][] aa){
//初始化
n=nn;
a=aa;
x=new int[n+1];
bestx=x;
cn=0;
bestn=0;
count=0;
backtrack(1);
return bestn;
}
public static void main(String[] args) {
int[][] a={{-1,-1,-1,-1,-1,-1},{-1,0,1,0,1,1},{-1,1,0,1,0,1},{-1,0,1,0,0,1},{-1,1,0,0,0,1},{-1,1,1,1,1,0}};//a的下標從1開始,-1的值無用
int n=5;
Maxclique m=new Maxclique();
System.out.println("圖G的最大團解向量爲:");
System.out.println("圖G的最大團頂點數爲:"+m.maxclique(n, a));
System.out.println("圖G的最大團個爲:"+m.count);
}
}
/*
輸出:
圖G的最大團解向量爲:
1 1 0 0 1
1 0 0 1 1
0 1 1 0 1
圖G的最大團頂點數爲:3
圖G的最大團個爲:3
*/