如何在OrientDB中计算无环图的生成树
我需要计算在OrientDB上实现的非循环图的生成树。我正在寻找的生成树是这样构建的,即只应保留从根到分支或叶的最长路径。例如,如果您可以在树根和给定分支之间的直接链接(边)与穿过同一根和同一分支之间多个分支的第二条路径之间进行选择,则只应保留后一条路径(边)来构建最终的树(生成树:) 如何在OrientDB中计算生成树?OrientDB中是否有类似于ShortestPath()或dijkstra()的函数,可以轻松地完成此任务?非常感谢你的帮助 问候如何在OrientDB中计算无环图的生成树,orientdb,Orientdb,我需要计算在OrientDB上实现的非循环图的生成树。我正在寻找的生成树是这样构建的,即只应保留从根到分支或叶的最长路径。例如,如果您可以在树根和给定分支之间的直接链接(边)与穿过同一根和同一分支之间多个分支的第二条路径之间进行选择,则只应保留后一条路径(边)来构建最终的树(生成树:) 如何在OrientDB中计算生成树?OrientDB中是否有类似于ShortestPath()或dijkstra()的函数,可以轻松地完成此任务?非常感谢你的帮助 问候 在java中,您可以使用类似的代码 imp
在java中,您可以使用类似的代码
import java.util.ArrayList;
import java.util.List;
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.orient.OrientGraph;
public class LongestPath {
private boolean stop=false;
private Vertex vertex_from=null;
private List<Vertex> vertexPreviousStep=new ArrayList<Vertex>();
private List<Vertex> vertexCurrently=new ArrayList<Vertex>();
private List<List<Vertex>> paths=new ArrayList<List<Vertex>>();
private OrientGraph g;
public LongestPath(OrientGraph g) {
this.g=g;
}
protected List<Vertex> getPath(String rid_from, String rid_to) {
if(!checkIfExistsNodes(rid_from,rid_to))
return new ArrayList<Vertex>();
vertexPreviousStep.add(vertex_from);
List<Vertex> p=new ArrayList<Vertex>();
Vertex from=g.getVertex(rid_from);
Vertex to=g.getVertex(rid_to);
p.add(from);
paths.add(p);
int step=1;
do{
stop=false;
for(Vertex v: vertexPreviousStep){
Vertex rid_previousVertex=v;
List<Vertex> rid_toAdd=new ArrayList<Vertex>();
Iterable<Vertex> nodes = (Iterable<Vertex>) v.getVertices(Direction.OUT);
for(Vertex v1:nodes){
rid_toAdd.add(v1);
String rid=v1.getId().toString();
if(!rid.equals(rid_to)) // non sono arrivato al nodo finale
vertexCurrently.add(v1);
}
if(rid_toAdd.size()!=0)
setPaths(rid_previousVertex,rid_toAdd,step);
}
change();
step++;
}while(stop==true);
cleanPaths(to);
return getLongestPath();
}
private boolean checkIfExistsNodes(String rid_from,String rid_to) {
boolean find_from=false;
boolean find_to=false;
for(Vertex v:g.getVertices()){
if(v.getId().toString().equals(rid_from)){
find_from=true;
vertex_from=v;
}
else if(v.getId().toString().equals(rid_to))
find_to=true;
}
if(find_from==false || find_to==false)
return false;
return true;
}
public void change(){
vertexPreviousStep.clear();
for(Vertex v:vertexCurrently)
vertexPreviousStep.add(v);
vertexCurrently.clear();
}
private void setPaths(Vertex previousVertex,List<Vertex> rid_toAdd,int step) {
for(int i=0;i<paths.size();i++){
List<Vertex> list=paths.get(i);
Vertex last=list.get(list.size()-1);
if(last.getId().toString().equals(previousVertex.getId().toString()) && list.size()==step){
int j=0;
for(Vertex rid:rid_toAdd){
boolean rid_found=false;
for(Vertex p:list){
if(p.equals(rid))
rid_found=true;
}
if(rid_found==false){
List<Vertex> p2=new ArrayList<Vertex>();
for(Vertex p:list)
p2.add(p);
p2.add(rid);
if(j==0){
stop=true;
paths.set(i, p2);
j++;
}
else
paths.add(p2);
}
}
}
}
}
public void cleanPaths(Vertex to){
for(int i=0;i<paths.size();i++){
List<Vertex> list=paths.get(i);
if(!list.get(list.size()-1).equals(to)){
paths.remove(i);
i--;
}
}
}
public List<Vertex> getLongestPath(){
if(paths.size()==0)
return new ArrayList<Vertex>();
else{
List<Vertex> list=paths.get(0);
int max_size= list.size();
for(int i=1;i<paths.size();i++){
if(paths.get(i).size()>max_size){
max_size=paths.get(i).size();
list=paths.get(i);
}
}
return list;
}
}
public static void main(String[] args) {
OrientGraph g=new OrientGraph("remote:localhost/39697129");
LongestPath longest= new LongestPath(g);
String id_vertex_from="#9:0";
String id_vertex_to="#10:1";
List<Vertex> list=longest.getPath(id_vertex_from,id_vertex_to);
System.out.println(list);
g.shutdown();
}
}
import java.util.ArrayList;
导入java.util.List;
导入com.tinkerop.blueprints.Direction;
导入com.tinkerpop.blueprints.Vertex;
导入com.tinkerpop.blueprints.impls.orient.OrientGraph;
公共类最长路径{
私有布尔停止=false;
私有顶点顶点_from=null;
私有列表vertexPreviousStep=new ArrayList();
private List vertexcurrency=new ArrayList();
私有列表路径=新的ArrayList();
私有定向图g;
公共最长路径(方向图g){
这个.g=g;
}
受保护列表getPath(字符串rid\u from,字符串rid\u to){
如果(!checkIfExistsNodes(删除自,删除至))
返回新的ArrayList();
添加(顶点从);
列表p=新的ArrayList();
顶点自=g.getVertex(从中删除);
顶点到=g.getVertex(rid_to);
p、 添加(来自);
添加(p);
int步长=1;
做{
停止=错误;
用于(顶点v:顶点上一步){
顶点rid_previousVertex=v;
List rid_toAdd=new ArrayList();
Iterable节点=(Iterable)v.get顶点(Direction.OUT);
对于(顶点v1:节点){
删除至添加(v1);
String rid=v1.getId().toString();
如果(!rid.equals(rid_to))//非sono到达al nodo结局
vertexcurrent.add(v1);
}
如果(rid_toAdd.size()!=0)
设置路径(rid_previousVertex、rid_toAdd、step);
}
改变();
step++;
}while(stop==true);
清洁道路(至);
返回getLongestPath();
}
私有布尔校验现有节点(字符串rid\U from,字符串rid\U to){
布尔值find_from=false;
布尔值find_to=false;
对于(顶点v:g.getVertexs()){
if(v.getId().toString().equals(rid_from)){
从中查找=真;
顶点_from=v;
}
else如果(v.getId().toString().equals(rid_to))
发现_to=true;
}
if(find_from==false | | find_to==false)
返回false;
返回true;
}
公共空间更改(){
vertexPreviousStep.clear();
用于(顶点v:顶点当前)
vertexPreviousStep.添加(v);
vertexcurrent.clear();
}
私有void setpath(顶点上一个顶点,列表rid\u toAdd,int step){
对于(int i=0;i你能更好地解释你想要什么吗?你想选择一些路径并删除其他路径吗?嗨,Alessandro,确切地说,我需要从非循环图中筛选出从根到分支或叶子的任何路径,当存在从根到相同分支或叶子的替代最长路径时。更准确地说,我需要在有向非循环图中,当存在替代的最长路径(遍历多条边)时,从一个顶点到另一个顶点的任何边从相同的两个顶点和每对顶点,最终得到有向无环图的生成树。你想要javascript还是java?如果可以的话,我的首选是OrientDB SQL。其他的是用javascript编写的OrientDB函数。这也很好,尽管我从未尝试过实现到目前为止,ng在ODB中的函数。非常感谢。感谢Alessandro在Java中的回答。我需要ODB SQL或javascript中的解决方案集成为ODB中的函数。除此之外,您建议的解决方案仅适用于图形中两个顶点之间的最长路径。对每对顶点使用此解决方案来计算跨距g树在复杂性方面不是最优的。生成树算法的复杂性为0(N)。如果你想要一个新的ODB SQL,你能在github上打开一个请求吗?嗨,Alessandro,我会在github上打开一个请求。我肯定认为这个功能可能对ODB社区有帮助。如果在此期间我找到了一个基于ODB SQL的解决方案,我会在这里发布:-)非常感谢你的帮助!干杯,Allein Worker