• 计算流图中的循环集合




    继续以上流图为例,上篇只求了各节点的前必经节点集合。
    这篇中,计算以下几个元素:
    (1)直接前必经节点
    (2)求出所有的回边列表
    (3)求出图中所有的循环


    1
    import java.util.ArrayList; 2 import java.util.List; 3 4 public class Node { 5 // 序号 6 public int no; 7 // 后接节点列表 8 public List<Node> nextList = new ArrayList<Node>(); 9 // 前接节点列表 10 public List<Node> preList = new ArrayList<Node>(); 11 // 前必经节点 12 public List<Node> dominatorList = new ArrayList<Node>(); 13 //直接必经节点 14 public Node zDominator=null; 15 public Node(int no) { 16 this.no = no; 17 } 18 19 public void addNext(Node n){ 20 nextList.add(n); 21 n.preList.add(this); 22 } 23 24 public String toString(){ 25 return no+""; 26 } 27 }
     1 public class BackEdge {
     2 
     3     public Node fromNode;
     4     public Node toNode;
     5     
     6     public BackEdge(Node fromNode,Node toNode){
     7         this.fromNode=fromNode;
     8         this.toNode=toNode;
     9     }
    10 }
     1 import java.util.ArrayList;
     2 import java.util.List;
     3 
     4 
     5 public class Loop {
     6 
     7     BackEdge backEdge=null;
     8     List<Node> nodeList=new ArrayList<Node>();
     9     public Loop(BackEdge backEdge){
    10         this.backEdge=backEdge;
    11     }
    12     
    13     public void add(Node node){
    14         nodeList.add(node);
    15     }
    16     
    17     public boolean contains(Node node){
    18         if(nodeList.contains(node)){
    19             return true;
    20         }
    21         return false;
    22     }
    23     
    24     public String toString(){
    25         StringBuilder stb=new StringBuilder();
    26         stb.append("Loop{");
    27         for(int i=0;i<nodeList.size();i++){
    28             if(i!=0){
    29                 stb.append(",");
    30             }
    31             stb.append(nodeList.get(i).no);
    32         }
    33         stb.append("}");
    34         return stb.toString();
    35     }
    36 }
      1 import java.util.ArrayList;
      2 import java.util.LinkedList;
      3 import java.util.List;
      4 
      5 public class Dominator {
      6 
      7     public static void main(String[] args) {
      8         // 初期化所有节点 并设置节点间连接关系
      9         List<Node> nodeList = getNodeList(12);
     10         // 计算前必经节点
     11         doDominator(nodeList);
     12         // 计算直接必经节点
     13         doZDominator(nodeList);
     14         // 打印必经节点列表
     15         printResult(nodeList);
     16         // 检索回边
     17         List<BackEdge> backEdgeList=searchLoop(nodeList);
     18         //打印回边列表
     19         printBackEdgeList(backEdgeList);
     20         //根据回边求出自然循环
     21         List<Loop> loopList=getLoopList(backEdgeList);
     22         //打印循环集合
     23         printLoopList(loopList);
     24 
     25     }
     26 
     27     //打印循环集合
     28     public static void printLoopList(List<Loop> loopList){
     29         System.out.println("循环列表:");
     30         for(int i=0;i<loopList.size();i++){
     31             System.out.println(i+1+":"+loopList.get(i));
     32         }
     33     }
     34     
     35     //根据回边求出自然循环
     36     public static List<Loop> getLoopList(List<BackEdge> backEdgeList){
     37         List<Loop> loopList=new ArrayList<>();
     38         for(BackEdge be:backEdgeList){
     39             LinkedList<Node> stack=new LinkedList<>();
     40             Loop loop=new Loop(be);
     41             loop.add(be.toNode);
     42             insertNode(be.fromNode,loop,stack);
     43             while(!stack.isEmpty()){
     44                 Node m=stack.pop();
     45                 List<Node> preList=m.preList;
     46                 for(Node p:preList){
     47                     insertNode(p,loop,stack);
     48                 }
     49             }
     50             loopList.add(loop);
     51         }
     52         return loopList;
     53     }
     54     
     55     
     56     private static void insertNode(Node node,Loop loop,LinkedList<Node> stack){
     57         if(loop.contains(node)){
     58             return;
     59         }
     60         loop.add(node);
     61         stack.push(node);
     62     }
     63     
     64     //打印回边列表
     65     public static void printBackEdgeList(List<BackEdge> backEdgeList){
     66         System.out.println("回边列表:");
     67         int i=1;
     68         for(BackEdge be:backEdgeList){
     69             System.out.println(i+++":"+be.fromNode.no+"->"+be.toNode.no);
     70         }
     71     }
     72     
     73     
     74     // 检索循环
     75     public static List<BackEdge> searchLoop(List<Node> nodeList) {
     76         List<BackEdge> backEdgeList=new ArrayList<BackEdge>();
     77         for (Node node : nodeList) {
     78             List<Node> temList = new ArrayList<Node>();
     79             temList.addAll(node.nextList);
     80             temList.retainAll(node.dominatorList);
     81             if (!temList.isEmpty()) {
     82                 for (Node toNode : temList) {
     83                     BackEdge be = new BackEdge(node, toNode);
     84                     backEdgeList.add(be);
     85                 }
     86             }
     87         }
     88         return backEdgeList;
     89     }
     90 
     91     // 计算直接必经节点
     92     public static void doZDominator(List<Node> nodeList) {
     93         for (Node node : nodeList) {
     94             List<Node> dominatorList = node.dominatorList;
     95             if (dominatorList.size() == 1) {
     96                 continue;
     97             }
     98             int maxSize = 1;
     99             for (Node dNode : dominatorList) {
    100                 if (dNode == node) {
    101                     continue;
    102                 }
    103                 int size = dNode.dominatorList.size();
    104                 if (size >= maxSize) {
    105                     maxSize = size;
    106                     node.zDominator = dNode;
    107                 }
    108             }
    109 
    110         }
    111     }
    112 
    113     // 打印必经结果
    114     public static void printResult(List<Node> nodeList) {
    115         for (int i = 0; i < nodeList.size(); i++) {
    116             Node node = nodeList.get(i);
    117             System.out.println("*******************");
    118             System.out.println("node" + (i + 1));
    119             System.out.print("前必经节点:");
    120             printNodeListNo(node.dominatorList);
    121             System.out.println("直接必经节点:" + node.zDominator);
    122             System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!");
    123         }
    124     }
    125 
    126     // 打印节点NO
    127     public static void printNodeListNo(List<Node> nodeList) {
    128         for (int i = 0; i < nodeList.size(); i++) {
    129             if (i != 0) {
    130                 System.out.print(",");
    131             }
    132             System.out.print(nodeList.get(i).no);
    133         }
    134         System.out.println();
    135     }
    136 
    137     // 计算必经节点
    138     public static void doDominator(List<Node> nodeList) {
    139         // 迭代次数
    140         int n = 1;
    141         // 判断状态是否稳定Flag
    142         boolean changed = true;
    143         while (changed) {
    144             System.out.println("迭代次数:" + n++);
    145             changed = false;
    146             for (int i = 0; i < nodeList.size(); i++) {
    147                 Node node = nodeList.get(i);
    148                 List<Node> lastDominatorList = new ArrayList<Node>();
    149                 lastDominatorList.addAll(node.dominatorList);
    150                 List<Node> temList = new ArrayList<Node>();
    151 
    152                 for (Node preNode : node.preList) {
    153                     List<Node> preDomList = preNode.dominatorList;
    154                     if (temList.isEmpty()) {
    155                         temList.addAll(preDomList);
    156                     } else {
    157                         temList.retainAll(preDomList);
    158                     }
    159                 }
    160                 temList.add(node);
    161                 int lastSize = lastDominatorList.size();
    162                 lastDominatorList.retainAll(temList);
    163                 if (lastSize != lastDominatorList.size()) {
    164                     node.dominatorList = temList;
    165                     changed = true;
    166                 }
    167             }
    168         }
    169     }
    170 
    171     // 初期化所有节点 并设置节点间连接关系
    172     public static List<Node> getNodeList(int size) {
    173         List<Node> nodeList = new ArrayList<Node>(size);
    174         for (int i = 0; i < size; i++) {
    175             Node node = new Node(i + 1);
    176             nodeList.add(node);
    177         }
    178         Node node1 = nodeList.get(0);
    179         Node node2 = nodeList.get(1);
    180         Node node3 = nodeList.get(2);
    181         Node node4 = nodeList.get(3);
    182         Node node5 = nodeList.get(4);
    183         Node node6 = nodeList.get(5);
    184         Node node7 = nodeList.get(6);
    185         Node node8 = nodeList.get(7);
    186         Node node9 = nodeList.get(8);
    187         Node node10 = nodeList.get(9);
    188         Node node11 = nodeList.get(10);
    189         Node node12 = nodeList.get(11);
    190         // 节点之间关系设定
    191         node1.addNext(node2);
    192         //
    193         node2.addNext(node3);
    194         node2.addNext(node4);
    195         //
    196         node3.addNext(node2);
    197         //
    198         node4.addNext(node2);
    199         node4.addNext(node5);
    200         node4.addNext(node6);
    201         //
    202         node5.addNext(node7);
    203         node5.addNext(node8);
    204         //
    205         node6.addNext(node7);
    206         //
    207         node7.addNext(node11);
    208         //
    209         node8.addNext(node9);
    210         //
    211         node9.addNext(node8);
    212         node9.addNext(node10);
    213         //
    214         node10.addNext(node5);
    215         node10.addNext(node12);
    216         //
    217         node11.addNext(node12);
    218         // 初期化前必经节点的列表
    219         for (int i = 0; i < nodeList.size(); i++) {
    220             nodeList.get(i).dominatorList.addAll(nodeList);
    221         }
    222         return nodeList;
    223     }
    224 
    225 }
  • 相关阅读:
    拷贝本地文件到docker容器
    python3 使用pip安装(命令行中)失败或 “not a supported wheel” 解决方案!
    Scrapy框架爬虫
    2019227单词记录
    开班第一碗
    函数进阶
    Oracle数组
    oracle merge into使用
    oracle授权替代database link 速度加快
    ora01031:权限不足
  • 原文地址:https://www.cnblogs.com/zwm512327/p/3536484.html
Copyright © 2020-2023  润新知