最大团问题-分支界限法
遍历所有点构造二叉树;
广度遍历树,遍历过程中判断当前结点的点数据时,是否构成完全子图,如果不能则只将右结点加入队列,每次选取队列中完全子图最大的结点作为活结点,无子结点时到达叶子结点,记录为一个完全子图,优先队列法中第一个完全子图即为最优解。
package test;
import java.util.*;
/**
* Created by saishangmingzhu on 2018/12/10.
* 最大团问题
*/
public class MaximumCliqueProblem {
//图
private int[][] pointIndex=new int[][]{
{1,1,0,1,1},
{1,1,1,0,1},
{0,1,1,0,1},
{1,0,0,1,1},
{1,1,1,1,1}};
public static void main(String[] arg){
new MaximumCliqueProblem().branchAndBoundMethod();
}
/**
* 分支界限法-优先队列式
* 优先队列式求解时,到达第一个没有子结点的活结点时,即为最优解
*/
public void branchAndBoundMethod() {
List<Point> pointList=new ArrayList<>();
pointList.add(new Point("1",0));
pointList.add(new Point("2",1));
pointList.add(new Point("3",2));
pointList.add(new Point("4",3));
pointList.add(new Point("5",4));
//【1】构建树
Node root=new Node();
createTree(pointList, root,0);
//【2】广度遍历
List<Node> currentLiveNodeList=new ArrayList<>();
currentLiveNodeList.add(root);
while (true) {
//排序
Node parent = currentLiveNodeList.get(0);
if (parent.leftNode==null){
//表示到了叶子结点,进行记录
//点不算子图,所以要去除点集为1的叶子
break;
}
List<Point> leftPointList = parent.leftNode.hasPointList;
if (judge(leftPointList) != 0) {
currentLiveNodeList.add(parent.leftNode);
}
//因为右结点是空,所以不需要判断
//List<Point> rightPointList=parent.rightNode.hasPointList;
currentLiveNodeList.add(parent.rightNode);
currentLiveNodeList.remove(parent);
Collections.sort(currentLiveNodeList, new Comparator<Node>() {
@Override
public int compare(Node o1, Node o2) {
return o2.hasPointList.size()-o1.hasPointList.size();
}
});
}
System.out.println("最大团");
for (Point point:currentLiveNodeList.get(0).hasPointList){
System.out.print(point.name+",");
}
}
/**
* 判断现有节点是否是完全子图 -1 表示不是
* @param pointList
* @return
*/
private int judge(List<Point> pointList){
for (int i=0;i<pointList.size();i++){
Point pointi=pointList.get(i);
int indexi=pointi.index;
for (int j=i+1;j<pointList.size();j++){
Point pointj=pointList.get(j);
int indexj=pointj.index;
//使用[indexi][indexj]是为了说明问题,可以直接使用[i][j]
if (pointIndex[indexi][indexj]!=1){
return 0;
}
}
}
return 1;
}
private void createTree(List<Point> pointList, Node parent,int i) {
if (i>=pointList.size()){
return;
}
Node leftNode=new Node();
leftNode.hasPointList.addAll(parent.hasPointList);
leftNode.hasPointList.add(pointList.get(i));
i++;
createTree(pointList,leftNode,i);
parent.leftNode=leftNode;
Node rightNode=new Node();
rightNode.hasPointList.addAll(parent.hasPointList);
createTree(pointList,rightNode,i);
parent.rightNode=rightNode;
}
class Point{
private String name;
private int index;
public Point(String name,int index) {
this.name = name;
this.index = index;
}
}
class Node{
private Node leftNode;
private Node rightNode;
private List<Point> hasPointList=new ArrayList<>();
}
}
转载于:https://blog.51cto.com/zuohao1990/2328591