后端 绘制有向无环图(DAG图)
因为公司的某个系统比较古老,里面的 job 的管理几乎都是直接通过操作数据库来实现的,对于一般的操作还可以忍受,但是每次想知道 job 之间的依赖关系的时候,就会相当难受,于是便脑袋很抽地一定要写一个查询系统能快速查询 job 之间的依赖关系。
分析
在项目开始之前,大概稍微估算了一下难点,大概可以分为以下两点:
如何在前端显示该依赖图
如何提高查询效率
此篇文章只看第一个问题,由于是本人是前端渣,于是只能去网上搜相应图形显示插件。
前端插件选择
找了很久,终于在 echarts 上找到了一个稍微适合自己的图形插件了,
http://echarts.baidu.com/examples/editor.html?c=graph-simple
不过,这个插件只是一个简单图的插件,也就是说这个插件并不会帮你进行自动定位相应的点,我们需要自己确定各个点的坐标。
解决方案
通过观察发现,该插件上的坐标只需要确定相对坐标就行了,它会根据相对位置进行自动定位,于是感觉瞬间轻松了许多。
仔细思考,发现 job 之间的依赖关系是一个有向无环图,于是开始构思。
要求:
将点按层次显示,保证前面层的点只依赖后面层的点 (同一层也禁止存在依赖关系)。
使得图尽可能整洁,尽量减少线段之间的交叉
解决方案:
通过拓扑排序来实现点的层次选择,每次将所有入度为 0 的点分为同一层即可
通过与前面层的点之间的关系设置相应的权重,同层之间根据权重来排序。我记得好像可以通过动态规划得到最优解的,不过实现起来太麻烦了,就算了
代码如下:
import java.util.*;* 作用: 绘制有向无环图(DAG图)** 说明:* 配合Echarts的simple graph使用,地址见http://echarts.baidu.com/examples/editor.html?c=graph-simple* 用来进行点的坐标定位** 使用条件: 图必须是一个有向无环图(DAG图)** 调用方式: return new DagGraphUtil(points, links).drawDagGraph()** 参数:* points的格式为 ['点1','点2','点3','点4']* links的格式为 [{"source":"点1","target":"点2"},{"source":"点2","target":"点3"},{"source":"点3","target":"点4"}]** 返回结果:* {* "points": [{"name": "点1","x":100,"y":100},{"name":"点2","x":200,"y":200}, ...],* "links": [{"source":"点1","target":"点2"},{"source":"点2","target":"点3"}, ...]* }*** 主要算法: 拓扑排序*/
public class {private final int MAX_LENGTH_X = 900;private final int MAX_LENGTH_Y = 1000;private int maxX;private Map<String, Integer> toNum;private Map<String, Integer> xPosition;private Map<String, Integer> yPosition;private Map<String, Integer> pointWeight;private List<Integer> ySize;private List<String> points;private List<Map<String, String>> links;public (List<String> points, List<Map<String, String>> links) {this.points = points;this.links = links;toNum = new HashMap<>(points.size());xPosition = new HashMap<>(points.size());yPosition = new HashMap<>(points.size());pointWeight = new HashMap<>(points.size());maxX = 0;ySize = new ArrayList<>();for (String point : points) {toNum.put(point, 0);pointWeight.put(point, 0);}for (Map<String, String> link : links) {String toPoint = link.get("target");addMapValue(toNum, toPoint, 1);}}public Map<String, Object> drawDagGraph() {Map<String, Object> result = new HashMap<>(3);dfs(0);List<Map<String, Object>> pList = new ArrayList<>(points.size());for (String point : points) {int xUnitLength = MAX_LENGTH_X / maxX;int x = xPosition.get(point) * xUnitLength + xUnitLength / 2;int yUnitLength = MAX_LENGTH_Y / ySize.get(xPosition.get(point));int y = yPosition.get(point) * yUnitLength + yUnitLength / 2;Map<String, Object> map = new HashMap<>(3);map.put("name", point);map.put("x", x);map.put("y", y);pList.add(map);}result.put("points", pList);result.put("links", links);return result;}private void dfs(int depth) {List<String> currentPoints = new ArrayList<>();for (String key : toNum.keySet()) {if (toNum.get(key) == 0) {currentPoints.add(key);addMapValue(toNum, key, -1);}}if (currentPoints.isEmpty()) {return;}maxX = depth + 1;ySize.add(currentPoints.size());Collections.sort(currentPoints, new Comparator<String>() {public int compare(String o1, String o2) {return pointWeight.get(o1) - pointWeight.get(o2);}});for (int i = 0, len = currentPoints.size(); i < len; i++) {String point = currentPoints.get(i);xPosition.put(point, depth);yPosition.put(point, i);for (Map<String, String> link : links) {if (link.get("source").equals(point)) {maxMapValue(pointWeight, link.get("target"), i + 1);addMapValue(toNum, link.get("target"), -1);}}}dfs(depth + 1);}private void addMapValue(Map<String, Integer> map, String key, Integer value) {if (map.containsKey(key)) {map.put(key, map.get(key) + value);} else {map.put(key, value);}}private void maxMapValue(Map<String, Integer> map, String key, Integer value) {if (!map.containsKey(key) || map.get(key) == 0 || map.get(key) < value) {map.put(key, value);}}
}
后端 绘制有向无环图(DAG图)相关推荐
- 使用R语言绘制graph:无向图(ug)和有向无环图(dag)
首先我们需要安装R语言,参考[软件]R语言-3.6.3 安装教程一文,安装完之后我们打开编辑器. 3.5版本之后,source命令不能用了,需要使用Bioconductor的话,我们需要在consol ...
- java 有向无环图 树_拓扑排序-有向无环图(DAG, Directed Acyclic Graph)
条件: 1.每个顶点出现且只出现一次. 2.若存在一条从顶点 A 到顶点 B 的路径,那么在序列中顶点 A 出现在顶点 B 的前面. 有向无环图(DAG)才有拓扑排序,非DAG图没有拓扑排序一说. 一 ...
- 随机生成一个有向无环图
写数据结构作业时想到的一个问题- 我们不妨先做一些这个随机的有向无环图的假设: 首先,它是个有向无环图,并且没有重边 假设随机从图中取出两个不相同的点,那么它们之间有边的概率为固定值(其实还可以有其他 ...
- java 有向无环图_数据调度系统中有向无环图的无环检测
点击上方蓝字关注DolphinScheduler(海豚调度) |作者:鲍亮 |编辑:卢凯瑞 1 名词解释 DAG,全称:Directed Acyclic Graph,中文:有向无环图 入度:有向图中某 ...
- 算法精解:DAG有向无环图
DAG是公认的下一代区块链的标志.本文从算法基础去研究分析DAG算法,以及它是如何运用到区块链中,解决了当前区块链的哪些问题. 关键字:DAG,有向无环图,算法,背包,深度优先搜索,栈,BlockCh ...
- C#实现有向无环图(DAG)拓扑排序
对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在 ...
- 有向无环图DAG 拓扑排序 代码解释
目录: DAG定义 举例描述 实际运用 算法描述 算法实战 算法可视化 定义 在图论中,由一个有向无环图的顶点组成的序列,当且仅当满足下列条件时,称为该图的一个拓扑排序(英语:Topological ...
- IPFS系列 - 默克有向无环图(Merkle DAG)
Merkle DAG的全称是Merkle Directed Acyclic Graph(默克有向无环图).它是在Merkle Tree的基础上构建的,Merkle Tree由美国计算机学家Merkle ...
- 使用R包topGO绘制GO有向无环图
GO有向无环图 topGO 官方说明链接:http://www.bioconductor.org/packages/release/bioc/html/topGO.html 实战代码 ##R脚本 bi ...
最新文章
- android的xml置底_Android布局之xml设置
- html css integrity,integrity 属性
- 最佳学习方法(3)听课--听一反三
- java左右三角_java打印一个顺序与倒序的杨辉三角,要求两个三角左右排列
- metinfov5.0.4漏洞复现
- 【搜索引擎基础知识1】搜索引擎的技术架构
- java批量处理数据库语句_Java项目中调用bat批处理进行多用户数据库备份
- Java JVM 汇编代码入门 GitChat链接
- MybatisPlus 的 MetaObjectHandler 与 @TableLogic
- Arts 第九周(5/13 ~ 5/19)
- python doc转pdf
- AmazeUI 图标的示例代码
- 图片标签及以图搜图场景应用
- linux启动lighttpd服务,Linux下Lighttpd的安装配置
- c#:list转datatable;xtraReport打印
- 深度学习入门(三)一种预测阶段使用任意参数的滑动平均的快捷方式
- php 递归无限极分类和层级展示(适用于权限管理和分类管理功能)
- 用Python画中国地图,实现各省份数据可视化!可视化简直了!
- 联想服务器rd系列,联想ThinkServer RD550服务器首发评测
- 050_阵列天线方向图乘积原理