题记: 今天在工作中,实现业务流程图中流程图形化 Node & Flow的计算方式,其中大概是将大的流程图集合拆解成若干个小的子流程,这样在计算的时候,只需要计算子流程的结果就可以实现流程自动化;
其中,复杂流程拆分成多个基本单路径流程用到了有向无环图的设计方式

如图:

流程X

如何拆分已有架构图 拆分流程图_流程图形化


如何拆分已有架构图 拆分流程图_有向无环图_02

简单来说一下上述的实现过程

  • 将复杂的流程图拆分成几个简单单路径的流程图
  • 各个流程节点相互独立
  • 在运行时,通过子节点的流程走向,将节点的输出数据当作下一个节点的输入数据
  • 在非运行时:通过节点模型中存在已连接的其他节点,进行计算就可以

具体文章可以参考知乎:流程图形化 Node & Flow

具体实现:

package Graph4;

import java.util.*;


/**
 * @author koala
 * @ClassName GraphFlow
 * @date 2019/6/11 20:06
 * @Description
 * @Version V1.0
 */

public class GraphFlow {

    // 节点数
    private int v;

    /**
     * 节点路径参照表
     */
    private ArrayList<String>[] adjList;

    /**
     *  可参与计算的节点
     */
    private Set<String> nodeSet = new HashSet<String>();


    private Map<String,List<String>> adjMapList = new HashMap<String,List<String>>();

    public GraphFlow(int vertices){

        // 初始化当前节点数
        this.v = vertices;

        // 判断
        initAdjList();
    }


    private void initAdjList()
    {
        // 初始化数组的长度
        adjList = new ArrayList[v];

    }

    /**
     * 所有参与计算的节点
     * @param u
     * @param v
     */
    public void addEdge(String u, String v)
    {
      if(adjMapList.containsKey(u)){
          adjMapList.get(u).add(v);
      }else{
          List<String> list = new ArrayList<>();
          list.add(v);
          adjMapList.put(u,list);
      }

    /**
     *  遍历节点时,需要判断节点是否已经遍历,需要用一个集合去存放所有的节点
     */
      nodeSet.add(u);
      nodeSet.add(v);

    }

    // 遍历所有的路径
    // 假设从路径S到路径D
    public void printAllPaths(String s, String d)
    {
        // 是否已经遍历
        Map<String,Boolean> isVisited = new HashMap<>();

        for(String str: nodeSet){
            isVisited.put(str,false);
        }


        ArrayList<String> pathList = new ArrayList<>();

        // 第一个节点加入到数组里面
        pathList.add(s);

        //Call recursive utility
        // 计算节点
        printAllPathsUtil(s, d, isVisited, pathList);
    }

    private void printAllPathsUtil(String start, String end,
                                   Map<String,Boolean> isVisited,
                                   List<String> localPathList) {


        // 标记当前节点
        if(isVisited.containsKey(start)){
            isVisited.put(start,false);
        }


        // 递归退出条件
        if (start.equals(end))
        {
            // 输入当前节点路径
            System.out.println(localPathList);
            // 如果找到了,则需要将当前的节重新标记
            isVisited.put(start,false);
            return ;
        }

        // 遍历当前节点的集合
        if(adjMapList.containsKey(start)){
            for (String str : adjMapList.get(start)){
                if(isVisited.containsKey(str)){
                    if(!isVisited.get(str)){
                        localPathList.add(str);
                        printAllPathsUtil(str,end,isVisited,localPathList);
                        // 在递归返回之后需要删除下一个递归的数据
                        localPathList.remove(str);
                    }
                }
            }
            isVisited.put(start,false);
        }else{
            System.out.println(localPathList);
        }

    }


    public static void main(String[] args)
    {
        // 构建图
        GraphFlow g = new GraphFlow(8);

        g.addEdge("A","B");
        g.addEdge("A","C");
        g.addEdge("B","D");
        g.addEdge("C","E");
        g.addEdge("C","F");
        g.addEdge("E","G");
        g.addEdge("F","G");
        g.addEdge("G","H");


        // arbitrary source
        String start = "A";

        // arbitrary destination
        String end = "G";

        System.out.println("Following are all different paths from "+start+" to "+end);
        g.printAllPaths(start, end);

    }
}

结果验证:

如何拆分已有架构图 拆分流程图_有向无环图_03

扩展:
上述的过程是计算2点之间所有的路径,其实还可以计算任意起点 到结束点的路径
`具体实现就是在 递归里面的退出节点,就需要重新调整递归函数的入参数,去掉end参数即可;

// 任意节点退出
        if(!adjMapList.containsKey(start)){
            // 输入当前节点路径
            System.out.println(localPathList);
            // 如果找到了,则需要将当前的节重新标记
            isVisited.put(start,false);
            return ;
        }

总结:

  1. 业务流程化的工作流模型关键在于如何设置节点模式和 流程模型,节点模型和流程模式又是相互独立的
  2. 将流程集合拆分成若干个子流程更好的处理流程之间的计算关系,(后面还有子流程合并的时候如何计算,下一章节再讲)

`