【回溯法】最大团问题【递归方法】


/**
*
5.7 最大团问题

G的最大团是指G中所含顶点数最多的团。
无向图的最大团和最大独立集问题都可以看作是图G的顶点集V的
子集选取问题可以用回溯法在O(n*(2^n))时间内解决。
************************************************************
*/
import java.util.*;

public class BigTuan {
static int[] x; // 当前解

static int n; // 图G的顶点数

static int cn; // 当前顶点数

static int bestn; // 当前最大顶点数

static int[] bestx; // 当前最优解

static boolean[][] matrix; // 图G的邻接矩阵

/**
* @param m
* 是邻接矩阵
* @param v
* out the best solution 最优解
* @return the best result 最优值
*/
public static int maxClique(boolean[][] m, int[] v) {
matrix = m; //邻接矩阵必然是正方形
n = matrix.length;
x = new int[n]; //当前解
cn = 0;
bestn = 0;
bestx = v; //刚开始V是什么都没有

trackback(0);
return bestn;
}

private static void trackback(int i) {

//只有到达5才到这里。
if (i == n) {
// 到达叶结点
for (int j = 0; j < n; j++) {
bestx[j] = x[j]; //把当前解复制到最优解
}
bestn = cn;
return;
}

// 检查顶点 i 与当前团的连接
boolean connected = true;
for (int j = 0; j < i; j++) {
if (x[j] == 1 && !matrix[i][j]) {
// i 和 j 不相连
connected = false;
break;
}
}
if (connected) {
// 进入左子树
x[i] = 1;
cn++; //当前进了几步
trackback(i + 1);
cn--;
}
if (cn + n - i > bestn) { //剪枝函数,如果比最优解还大,继续才有意义 n是可能的最优解有n个,加上cn表示已经找到解的个数,i表示已经走了的步数,才可能有最优解
// 进入右子树
x[i] = 0;
trackback(i + 1);
}
}

private static void test() {
boolean[][] matrix = { { false, true, false, true, true },
{ true, false, true, false, true },
{ false, true, false, false, true },
{ true, false, false, false, true },
{ true, true, true, true, false } };
int[] v = new int[matrix.length];
int bestn = maxClique(matrix, v); //返回值计算最大团个数
System.out.println("bestn is: " + bestn);
System.out.println(Arrays.toString(bestx));
}

public static void main(String[] args) {
test();
}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值