最大团问题-分支界限法
遍历所有点构造二叉树;
广度遍历树,遍历过程中判断当前结点的点数据时,是否构成完全子图,如果不能则只将右结点加入队列,每次选取队列中完全子图最大的结点作为活结点,无子结点时到达叶子结点,记录为一个完全子图,优先队列法中第一个完全子图即为最优解。
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<>(); } }