最大團問題-分支界限法java
遍歷全部點構造二叉樹;ide
廣度遍歷樹,遍歷過程當中判斷當前結點的點數據時,是否構成徹底子圖,若是不能則只將右結點加入隊列,每次選取隊列中徹底子圖最大的結點做爲活結點,無子結點時到達葉子結點,記錄爲一個徹底子圖,優先隊列法中第一個徹底子圖即爲最優解。this
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<>(); } }