将有向工作流图转为结构树的实现

引言

之前写了篇文章《轻流_用YAML风格文本表达串行&并行流程》,是看中它依据特点关系,能将批流图转为一棵以start节点开始的树。而这个转换过程,直接完成是很轻松的事情,只要明确了表达关系,可以瞬间表达出来。

比如:遵照如下约定

  • { } 表示并行执行的分支

  • [ ] 表示顺序执行的节点序列

    则上述批流图可以很轻易表达为

    [start, A, { [B1], [B2] }, C, D, { [D1, D2], [E1, E2], [F1, F2] }, K, end]

如果转为存储结构,则可以方便用程序结构来表达,达到图形即编程的效果。

只要有了这个表达树的数据结构,那么要呈现成怎样的图形效果,只需要选择好对应的展现工具软件(比如plantUml, d2等),按照它的语法规则,就可以完成效果展现------上图就是用d2生成的。

比如,可以用List存储的串行的元素,而用set来存储分支,set中的每个元素是一个list 或者嵌套的set分之。

落实问题

因为之前没怎么做过图的相关编程,因此这个转换过程在要实际落地的时候发现做起来很不顺畅。期间问qwen,让它来编程,结果不知道自己提问有问题还是怎样,经过七八轮的自我修正后,它决定余留问题并放弃继续优化。主要的问题:

  • 顺序结构,总是不断嵌套,要做到扁平化很不理想;
  • 然后节点的自然分配是个问题,同一个节点,在最后的树结构中出现好几次;

最后无赖至于,就自己手写码这个程序,最难的还是分析结构特点,然后纳入步骤的过程,这个事情花了好几天。

逻辑关键点

  • 有向批流图,有几种节点类型:
    • fork节点 -- 也就是分支节点: 如上图的A、D
    • join节点 -- 也就是汇聚节点:如上图的C、K
    • 开始节点、结束节点
    • 普通节点-- 单进单出
  • 先给节点归类,然后找出小的顺序节点顺序流
    • 类型1:以fork节点开始,到join节点
    • 类型2:以join节点开始,到fork节点 或 结束
    • 类型3:从批流的开始节点,到fork节点 或结束
    • 关键1:记录下每条路径的from、end
    • 关键2:要有明确规则,不同情况下,from、end到底要不要纳入小批流
  • 对这些小批流,进行归并处理(类似消消乐)
    • 每个顺序流的from、end相同的,则他们是并行关系,需要进行合并,最终同一个from、end的,只能合并到一起,如上所述的一个list
    • 不同顺序流建,A->...->K, K-> ...->M 这种,可以形成连线的顺序关系,要进行合并
    • 最后的最后,就是一个start -> ... -> end 的这么个单一的连线图。
    • 注意:合并的时候需要依据关系,来决定嵌套关系,不要随便加深这种嵌套,尽量扁平化

代码实现

作为javer,当然使用java来实现,代码放到了gitee: flowgraph-to-tree,欢迎点评指正。

约束:

  • 约定1: 同一个节点,不能多进多出
  • 约定2:整个批流图,必须有且仅有一个开始、结束节点

暂留缺陷:

  • 对于开始节点就分支的情况,目前的实现是有缺陷的,留给聪明的您来完善吧。

小结

代码落地的过程远不如预期顺利,主要还是之前这方面的算法设计较少,等关键点捋清楚之后实现起来就相对容易了,这个东西可以作为工作,在后续需要的时候可以随时拿出来用。

相关推荐
睡一觉就好了。2 小时前
快速排序——霍尔排序,前后指针排序,非递归排序
数据结构·算法·排序算法
齐落山大勇2 小时前
数据结构——单链表
数据结构
小突突突2 小时前
浅谈Java中的反射
java·开发语言
Anastasiozzzz2 小时前
LeetCode Hot100 295. 数据流的中位数 MedianFinder
java·服务器·前端
我真的是大笨蛋2 小时前
Redo Log详解
java·数据库·sql·mysql·性能优化
索荣荣3 小时前
Java动态代理实战:从原理到精通
java·开发语言
兩尛3 小时前
c++的数组和Java数组的不同
java·开发语言·c++
roman_日积跬步-终至千里3 小时前
【Java并发】多线程/并发问题集
java·开发语言
皮皮哎哟3 小时前
深入浅出双向链表与Linux内核链表 附数组链表核心区别解析
c语言·数据结构·内核链表·双向链表·循环链表·数组和链表的区别