java中使用es的dsl

我们大多数人已经编写了一些处理图论算法的程序,例如找到两个顶点之间的最短路径,找到给定图的最小生成树等等。 在这些算法的每一种中,表示图形的编程方式是使用邻接矩阵或邻接列表 。 两者都不是定义图形输入的非常直观的方法。 例如,如果未在正确的列和行中进行输入,则邻接矩阵可能会导致错误。 此外,在运行时,您不太确定哪个行/列代表哪个边,当涉及到具有大量顶点的图形的输入时,事情会变得更加复杂。

在我的工程研究期间,我已经用Java实现了许多图形算法,并且在所有这些图形算法中,我都嵌套了for循环以获取邻接矩阵输入。 最近,当我阅读Martin Fowlers的DSL书籍时,我想到了创建DSL来提供图形输入的想法,即DSL,它将允许用户指定顶点,边及其权重。 我选择了已实现的图形算法,只是去除了邻接矩阵输入,而是使用了我创建的DSL。 该算法就像一个魅力。

在这篇文章中,我将通过采用不同的图形输入并为它们显示DSL来显示DSL的有效语法。 然后,我将向您展示我创建的库,该库由图的语义模型,DSL的解析器和词法分析器以及一个简单的构建器API组成,该API从DSL脚本中填充语义模型。 解析器和词法分析器是使用ANTLR生成的,因此该库要求ANTLR Jar在类路径中可用。 最后,我将展示如何使用Kruskals算法将该DSL用于查找最小生成树。

DSL语法和一些示例

下图(g1)的DSL:

图表G1

Graph {A1 -> B2 (12.3)B2 -> C3(0.98)C3->D4 (2)D4 ->E5 (12.45)
}

请注意,上述DSL中的元素之间存在不同的空间。 这只是为了显示可以编写DSL的不同方式。

下图(g2)的DSL为:

图G2

Graph{A1 -> B2 (12.3)B2 -> C3 (0.98)C3 -> D4 (2)E5
}

请注意,“图形”和“ {”之间没有空格。 这只是为了显示它的不同编写方式。

下图(g3)的DSL为:

图G3

Graph {A -> B (12.3)B -> C (0.98)C -> D (2)D -> E (12.45)
}

现在显示一些无效的DSL脚本:

Graph {1A -> B (12.3)B -> C (0.98)
}

上面的无效,因为顶点名称以数字开头。

Graph {
}

上面的方法无效,因为Graph希望至少定义一个顶点。 但是它可以具有零个或多个边。

基于DSL的图形输入库

我已经利用ANTLR来完成为我为DSL定义的语法创建词法分析器和解析器的所有任务。 这样,我不必担心创建解析器或担心从DSL输入脚本创建令牌。

解析器和词法分析器类以及语义模型类一起打包到一个jar中,并且必须将这个jar与ANTLR jar一起包括在内,以利用编写用于图形输入的DSL来使用。

DSL jar的结构可以在下面的屏幕截图中看到:

GraphDSL Jar

图形包中的类与语义模型相对应,即,它们是通用类,可以在不考虑是否有人在使用DSL的情况下使用。 graph.dsl中的类对应于ANTLR为lexer和parser生成的Java类。

ANTLR用于词法分析和解析的语法为:

grammar Graph;graph: GRAPH_START (edge|vertex)+ GRAPH_END;
edge: (vertex) TO (vertex) weight;
vertex: ID;
weight: '(' NUM ')';
GRAPH_START : 'Graph'([ ])*'{';
GRAPH_END : '}';
WEIGHT_START: '(';
WEIGHT_END: ')';
TO: '->';
ID: ^[a-zA-Z][a-zA-Z0-9]*;
NUM: [0-9]*[.]?[0-9]+;
WS: [ \t\r\n]+ -> skip;

上面的语法有待改进,但作为我的第一次尝试,我试图将其保持在这个水平。

  • 从此处下载DSL jar(GraphDSL.jar)。
  • 从此处下载ANTLR jar(antlr-4.1-complete.jar)。

注意:此DSL是使用ANTLR版本4开发的。

对于使用ANTLR的外部DSL的推荐书是《 语言实现模式:创建自己的域》特定和通用编程语言

Kruskals算法找到最小生成树

用于测试此算法实现的图形为:

样本图

和DSL相同的是:

Graph  {A -> B (7)B -> C (8)A -> D (5)B -> D (9)D -> E (15)D -> F (6)E -> F (8)E -> C (5)B -> E (7)E -> G (9)F -> G (11)
}

让我们看一下实现:

package kruskalsalgo;import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
import graph.Edge;
import graph.Graph;
import graph.Vertex;
import graph.GraphBuilder;
import java.io.IOException;
import java.util.Comparator;public class KruskalsAlgorithm {public static void main(String[] args) throws IOException {//Load the graph data from the DSLGraph g = new GraphBuilder().buildGraph("graph.gr");ArrayList<Set> forest = new ArrayList<Set>();ArrayList<Edge> finalEdgeSet = new ArrayList<Edge>();//Creating disjoint set of vertices which represents the initial forestfor (Vertex v : g.getVertices()) {Set newSet = new Set();newSet.getVertexList().add(v);forest.add(newSet); //Creating Disjoint Sets}//sort the edges in the graph based on their weightCollections.sort(g.getEdges(), new Comparator<Edge>(){public int compare(Edge o1, Edge o2) {return o1.getWeight().compareTo(o2.getWeight());}});for (Edge edge : g.getEdges()) {//Find in which set the vertices in the edges belongint rep1 = Set.findRep(edge.getFromVertex(), forest);int rep2 = Set.findRep(edge.getToVertex(), forest);//If in different sets then merge them into one set and pick the edge.if (rep1 != rep2) {finalEdgeSet.add(edge);Set.Union(rep1, rep2, forest);}}System.out.println("The Minimum Spanning tree is");for (Edge edge : finalEdgeSet) {System.out.println("Vertex: " + edge.getFromVertex().getLabel() + " to Vertex: " + edge.getToVertex().getLabel());}System.out.println("");}//End of Main
}class Set {private ArrayList<Vertex> vertexList;private int representative;static int count;public Set() {vertexList = new ArrayList<Vertex>();this.representative = ++(Set.count);}//Find the set identifier in which the given vertex belongs to.public static int findRep(Vertex vertex, ArrayList<Set> forest) {int rep = 0;for (Set set : forest) {for (Vertex v : set.getVertexList()) {if (v.getLabel().equals(vertex.getLabel())) {return set.getRepresentative();}}}return rep;}//Find the set given the step identifier.public static Set findSet(int rep, ArrayList<Set> forest) {Set resultSet = null;for (Set set : forest) {if (set.getRepresentative() == rep) {return set;}}return resultSet;}//Merge the set into another and remove it from the main set.public static void Union(int rep1, int rep2, ArrayList<Set> forest) {Set set1 = Set.findSet(rep1, forest);Set set2 = Set.findSet(rep2, forest);for (Vertex v : set2.getVertexList()) {set1.getVertexList().add(v);}forest.remove(set2);}public ArrayList<Vertex> getVertexList() {return vertexList;}public int getRepresentative() {return representative;}
}

上面的代码从dslgraph.gr加载图形数据。 DSL脚本必须放置在资源包中,以便DSL库可以找到它。

上面代码的输出:

The Minimum Spanning tree is
Vertex: A to Vertex: D
Vertex: E to Vertex: C
Vertex: D to Vertex: F
Vertex: A to Vertex: B
Vertex: B to Vertex: E
Vertex: E to Vertex: G

并以图解方式显示相同的内容

最小生成树

参考:来自CG的合作伙伴 Mohamed Sanaulla在Experiences Unlimited博客上的基于DSL的方法,用于在基于图论的Java程序中输入图数据 。

翻译自: https://www.javacodegeeks.com/2013/07/dsl-based-approach-to-input-graph-data-in-graph-theory-based-java-programs.html

java中使用es的dsl

java中使用es的dsl_基于DSL的基于图论的Java程序中输入图数据的方法相关推荐

  1. 在基于图论的Java程序中基于DSL的输入图数据的方法

    我们大多数人已经编写了一些程序来处理图论算法,例如查找两个顶点之间的最短路径,查找给定图的最小生成树等等. 在这些算法的每一种中,表示图形的编程方式是使用邻接矩阵或邻接表 . 两者都不是定义图形输入的 ...

  2. Clipper: 开源的基于图论框架的鲁棒点云数据关联方法(ICRA2021)

    <CLIPPER: A Graph-Theoretic Framework for Robust Data Association>(ICRA 2021 ) 基于图论的点云数据关联方法,通 ...

  3. Java读取修改xlsm格式表格_Android Excel电子表格API – 在Android应用程序中读取编辑XLS CSV XLSX XLSM HTML格式...

    Android Excel Spreadsheet API 更多高级特征 具备格式化工作表,行,列,单元格等能力 Array,ArrayList 和 Recordset / Resultset数据导入 ...

  4. java中write方法作用_java中的封装,继承,多态,这3个在程序中起着重要作用

    一.封装 1. 封装概述 面向对象编程语言是对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界无法直接操作和修改. 封装可以被认为是一个保护屏障,防止该类的代码和数据被其他类随意访问.要访 ...

  5. C语言字符串哪个头文件,如果在程序中要使用C语言的字符串处理函数,应在程序中包含这哪个头文件。...

    程程下列不是K均值聚类的缺点的是() 神--申--电,序中序中这三个字是从一个词分化出来的."神"写作"申",也就是"电",是让人恐怖,让人 ...

  6. java 获取网络带宽_Java开发网 - 一个测网络延迟和带宽的程序,发10M的数据有问题...

    我的想法是客户端发10M的string给服务器,服务器把收到的数据返回给客户端, 客户端记下发送的时刻和收完数据的时刻,两者相减再除2就是传输用的时间. 发1M没有问题,现在要发10M,就循环10次, ...

  7. 在c51语言的程序中 注释一般采用,【判断题】在 C51 语言的程序中,注释一般采用 /* */ 和 // 来实现。 (3.0分)...

    当ab<0时,化简a2b的结果是()A.-abB.a-bC.-a-bD.ab (-5)2的化简结果为()A.25B.5C.-5D.-25 计算:-12764=______. 已知两圆的半径分别3 ...

  8. 基于51单片机的DS18B20测温程序与仿真图

    一.基础介绍 时序介绍就暂不介绍,可以网上搜集资料 二.proteus仿真图 三.程序代码 #include<reg51.h> #include"temp.h"#def ...

  9. java集成lucene_将Lucene搜索集成到应用程序中

    java集成lucene 本文是我们名为" Apache Lucene基础知识 "的学院课程的一部分. 在本课程中,您将了解Lucene. 您将了解为什么这样的库很重要,然后了解L ...

最新文章

  1. asp.net客户端脚本验证小技巧
  2. Windows 7键盘失灵导致无法输入登录密码问题解决方案
  3. python file operations
  4. MySQL 5.7 安装指南
  5. 2017年10月08日普及组 世界语
  6. OpenCASCADE:可视化简介
  7. 更换checkbox的原有样式
  8. SpringBoot2.1+SpringCloud:注册中心搭建(Eureka)
  9. 数组指定位置添加元素_数据结构--顺序表的9种基本运算,初始化,销毁,判断是否为空表,长度,求指定位置的元素值......
  10. 苹果appID的获取方法
  11. 分享,用sql快速创建MODEL,快速提高工作效率哦
  12. linux制作img镜像文件,制作img镜像文件的5种方法 .
  13. keil编译出现多重定义的问题
  14. PR连接蓝牙后无声音
  15. XTOOL EZ500全系统的诊断和特殊功能超越Xtool EZ400 EZ300 Xtool PAD
  16. Win10 内置 OpenSSH 使用密钥连不上的问题解决
  17. win10注册mysql到windows服务报错:Install/Remove of the Service Denied
  18. 基于深度学习的自动识别夹取机械臂
  19. 如何引用阿里巴巴矢量图标库的图标
  20. 深度调研:日本老年消费市场商业成功案例与发展经验成果分享

热门文章

  1. Java 并发总结——AQS
  2. 从 Linux 源码看 Socket 的阻塞和非阻塞
  3. 前后端分离项目部署上线详细教程
  4. struts基本概念(1)
  5. Sublime Text 3 快捷键总结(拿走)
  6. Redis(案例五:Set数据)
  7. 负载均衡Ribbon和Feign---SpringCloud
  8. java 为文件及文件夹添加权限
  9. Ubuntu下C++代码调用可执行文件。
  10. spring boot建立项目 git推送giteee