简体   繁体   中英

how to find shortpath in Orientdb (edges instead of vertexes)

I have this graph: A-->B, A-->C, B-->C, C-->D, A-->E

I want to find the shortest path between "A" and "D" in java. I used:

s= select from ( select expand( shortestPath("+ first_vertex.getId() +", "+ second_vertex.getId() +").outE()))

    for (Edge edge : (Iterable<Edge>) g.command(
        new OCommandSQL(s)).execute()) {
            System.out.println(edge);
        }

The problem I get not the desired result:

      A - B
      A - C
      A - E 
      C - D

When I focus in vertex instead of Edges I got the correct short path which is: A -> C -> D

Why edges is not working as I did?

EDIT:

Updated graph

When I have the graph as it is in the attached image and I want to find the shortest path between "A" and "D" using your method still I got no edges: SHORTEST PATH (vertex): ACD SHORTEST PATH (edge): shouldn't the SHORTEST PATH (vertex) be: A, F, E, D ?. If I want to find the shortest path between "D" and "A" now I also get no edages after your update.

Using 'select expand(shortestpath(...))' only returns vertices.

Starting from your initial situation. 在此输入图像描述

Your goal is to extract the edges forming the shortest path (I think I understand), so to have the following result: 在此输入图像描述

One way to do this would be: - Find the shortest path (with Vertex) - get for individual Vertices of the shortest path, the edges connecting the first vertex until the last Vertex.

static final String REMOTE = "remote:localhost/";

static final String NOMEDB  = "shortpath";
static final String CURRENTPATH = REMOTE + NOMEDB;

public static void main(String[] args) throws IOException {
    OServerAdmin serverAdmin = new OServerAdmin(CURRENTPATH).connect("root", "root");

    OrientGraphNoTx g = new OrientGraphFactory(CURRENTPATH).getNoTx();

    showPath(g);
}

public static void showPath (OrientGraphNoTx  g) {
    String s = "";
    String V1 = "#12:0"; //Vertex A
    String V2 = "#12:3"; //Vertex D
    s= "select expand(shortestPath(" + V1 + ", " + V2+"))";

    Iterable<Vertex> result = g.command(new OSQLSynchQuery<Vertex>(s)).execute();
    List<OrientVertex> listaVertex = new ArrayList<OrientVertex>();
    CollectionUtils.addAll(listaVertex, result.iterator());

    List<String> out = new ArrayList<String>();
    List<String> in = new ArrayList<String>();
    List<String> edgePath = new ArrayList<String>();

    //for each vertices get edge out & in
    Iterable<Edge> tempOut;
    Iterable<Edge> tempIn;
    String singleIn = "";
    String singleOut = "";

    System.out.println("SHORTEST PATH (vertex):");
    for (int v=0; v<listaVertex.size(); v++) {
        System.out.print(listaVertex.get(v).getProperty("name")+ " " );
    }
    System.out.println("");

    for (int i=0; i<listaVertex.size(); i++) {

        tempOut = listaVertex.get(i).getEdges(Direction.OUT, "collega");
        tempIn = listaVertex.get(i).getEdges(Direction.IN, "collega");

        //get edge in
        for(Edge edgeIn : tempIn) {
            in.add(edgeIn.getId().toString());
        }

        //forech edge in, check if is in out
        for(int x=0; x<in.size(); x++) {
            singleIn = in.get(x);
            for(int z=0; z<out.size(); z++) {
                singleOut = out.get(z);
                if(singleIn.equals(singleOut)) {
                    edgePath.add(singleIn);
                }
            }
        }

        //to empty out list
        out.clear();

        //get edge out
        for(Edge edgeOut : tempOut) {
            out.add(edgeOut.getId().toString());
        }

        //to empty in list
        in.clear();

    }

    System.out.println("SHORTEST PATH (edge):");
    for (int ind=0; ind<edgePath.size(); ind++) {
        System.out.println(edgePath.get(ind));
    }

}

The result you get is this:

在此输入图像描述

A --#13:1--> C --13:4--> D

EDIT 1

Definitely an improvement is this:

//forech edge in, check if is in out
        boolean finded = false;                        //*******new
        for(int x=0; x<in.size(); x++) {
            singleIn = in.get(x);
            for(int z=0; z<out.size(); z++) {
                singleOut = out.get(z);
                if(singleIn.equals(singleOut)) {
                    edgePath.add(singleIn);
                    finded = true;          //*******new
                    break;              //*******new
                }
            } 
            if(finded)break;                //*******new
        }

avoids unnecessary checks.

EDIT 2

Added edge label in the result.

public static void showPath (OrientGraphNoTx  g) {
    String s = "";
    String V1 = "#12:0"; //Vertex A
    String V2 = "#12:3"; //Vertex D
    s= "select expand(shortestPath(" + V1 + ", " + V2+"))";

    Iterable<Vertex> result = g.command(new OSQLSynchQuery<Vertex>(s)).execute();
    List<OrientVertex> listaVertex = new ArrayList<OrientVertex>();
    CollectionUtils.addAll(listaVertex, result.iterator());

    List<String> out = new ArrayList<String>();
    List<String> in = new ArrayList<String>();
    List<String> inLabel = new ArrayList<String>();
    List<String> edgePath = new ArrayList<String>();

    //per ogni vertice recupera archi uscenti ed entranti
    Iterable<Edge> tempOut;
    Iterable<Edge> tempIn;
    String singleIn = "";
    String singleOut = "";

    System.out.println("SHORTEST PATH (vertex):");
    for (int v=0; v<listaVertex.size(); v++) {
        System.out.print(listaVertex.get(v).getProperty("name")+ " " );
    }
    System.out.println("");

    for (int i=0; i<listaVertex.size(); i++) {

        tempOut = listaVertex.get(i).getEdges(Direction.OUT, "collega");
        tempIn = listaVertex.get(i).getEdges(Direction.IN, "collega");

        //get edge in
        for(Edge edgeIn : tempIn) {
            in.add(edgeIn.getId().toString());  //list edge id
            inLabel.add(edgeIn.getLabel());     // list edge label
        }

        //forech edge in, check if is in out
        boolean finded = false;
        for(int x=0; x<in.size(); x++) {
            singleIn = in.get(x);
            for(int z=0; z<out.size(); z++) {
                singleOut = out.get(z);
                if(singleIn.equals(singleOut)) {
                    edgePath.add(singleIn);   //in edgePath[position] = id
                    edgePath.add(inLabel.get(x));   //in edgePAth[position+1] = label
                    finded = true;
                    break; 
                }
            } 
            if(finded)break;    
        }

        //to empty out list
        out.clear();

        //get edge out
        for(Edge edgeOut : tempOut) {
            out.add(edgeOut.getId().toString());
        }

        //to empty in list
        in.clear();

    }

    System.out.println("SHORTEST PATH (edge):");
    for (int ind=0; ind<edgePath.size(); ind=ind+2) {  //ind+2 so i get id[position x] and label [position x+1] 
        System.out.println("id:"+edgePath.get(ind)+", Label:"+edgePath.get(ind+1));
    }

}

This is the result:

在此输入图像描述

EDIT 3

With the addition of new vertices, the graph should be this. (Is it correct?) 在此输入图像描述

Starting from this graph, we have:

1) from "A" to "D" SHORTEST PATH(vertex): is ACD (correct with you) SHORTEST PATH(edge): is edgeA-C, edgeC-D

在此输入图像描述

2) from "D" to "A" SHORTEST PATH(vertex): is DCA (correct with you) SHORTEST PATH(edge): is edgeD-C, edgeC-A (is your #11:4, #11:1)

在此输入图像描述

Using the code, automatically extracts the shortest path (using the specific function of orient) and consequently the extraction of edges that are contained in this path. The only thing the manual, is that I put in V1 and V2 RID vertices Start and End.

EDIT 4

在此输入图像描述

I created a new answer because the code is quite different from the previous one. With this code you just set StartNode (Vstart) & endNode (Vend), and returns the ShortestPath (referring to edge) with direction 'out' (compared to the first node) and direction 'in' (if present) always compared to the first node. The operation is based on extracting vertices who returned from work ShortestPath() of orient,for each of these vertices controls the edge.

public class PathEdge {


    static final String REMOTE = "remote:localhost/";

    static final String NOMEDB  = "ShortestPath2";
    static final String CURRENTPATH = REMOTE + NOMEDB;

public static void main(String[] args) throws IOException {

    OServerAdmin serverAdmin = new OServerAdmin(CURRENTPATH).connect("root", "root");

    OrientGraphNoTx g = new OrientGraphFactory(CURRENTPATH).getNoTx();

    String Vstart   = "a";  //----- to set
    String Vend     = "d";  // ---- to set
    String queryClassName   = "Nodo";  //----- to set
    String queryProperty    = "name"; //----- to set
    String edgeNAme = "is_a";   //----- to set
    String direction = "'OUT'";  //----- to set "BOTH" (incoming and outgoing), "OUT" (outgoing) and "IN" (incoming)

    String query1 = "select from "+queryClassName+" where "+queryProperty+" = '"+Vstart+"'";
    Iterable<Vertex> start = g.command(new OSQLSynchQuery<Vertex>(query1)).execute();

    String query2 = "select from "+queryClassName+" where "+queryProperty+" = '"+Vend+"'";  
    Iterable<Vertex> end = g.command(new OSQLSynchQuery<Vertex>(query2)).execute();

    long startTime = System.currentTimeMillis();
    showPath(g, start.iterator().next().getId().toString(), end.iterator().next().getId().toString(), edgeNAme, direction);
    long estimatedTime = System.currentTimeMillis() - startTime;
    System.out.println("");
    System.out.println("TIME EXECUTE: "+estimatedTime+"ms");
}

public static void showPath (OrientGraphNoTx  g, String Vstart, String Vend , String edge, String direction) {

     String s = "";
     int position = 0;
     int maxsize = 0;

     s= "select expand(shortestPath(" + Vstart + ", " + Vend+", "+direction+"))";

    Iterable<Vertex> result = g.command(new OSQLSynchQuery<Vertex>(s)).execute();
    List<OrientVertex> listaVertex = new ArrayList<OrientVertex>();
    CollectionUtils.addAll(listaVertex, result.iterator());

    List<String> listPRECout = new ArrayList<String>();
    List<String> listPRECin = new ArrayList<String>();
    List<String> listFOLLout = new ArrayList<String>();
    List<String> listFOLLin = new ArrayList<String>();

    List<String> resultOut = new ArrayList<String>();
    List<String> resultIn = new ArrayList<String>();

    //per ogni vertice recupera archi uscenti ed entranti
    Iterable<Edge> tempOut;
    Iterable<Edge> tempIn;
    String singleIn = "";
    String singleOut = "";
    boolean finded = false;

    System.out.println("SHORTEST PATH (vertex [direction "+direction+"]):");
    for (int v=0; v<listaVertex.size(); v++) {
        System.out.print(listaVertex.get(v).getProperty("name")+ " " );
    }
    System.out.println("");
    System.out.println("");
    maxsize = listaVertex.size()-1;
    for (int v=0; v<maxsize; v++) {

        //--------FIRST VERTEX OF THE SHORTEST PATH
        tempOut = listaVertex.get(v).getEdges(Direction.OUT, edge);
        tempIn = listaVertex.get(v).getEdges(Direction.IN, edge);

        //set listPRECin 
        for(Edge edgeIn : tempIn) {
            listPRECin.add(edgeIn.getId().toString());  //position x   = rid
            listPRECin.add(edgeIn.getLabel());          //position x+1 = label
        }

        //set listPRECout 
        for(Edge edgeOut : tempOut) {
            listPRECout.add(edgeOut.getId().toString());  //position x   = rid
            listPRECout.add(edgeOut.getLabel());          //position x+1 = label
        }

        //--------SECOND VERTEX OF THE SHORTEST PATH
        tempOut = listaVertex.get(v+1).getEdges(Direction.OUT, edge);
        tempIn = listaVertex.get(v+1).getEdges(Direction.IN, edge);

        //set listFOLLin 
        for(Edge edgeIn : tempIn) {
            listFOLLin.add(edgeIn.getId().toString());  //position x   = rid
            listFOLLin.add(edgeIn.getLabel());          //position x+1 = label
        }

        //set listFOLLout 
        for(Edge edgeOut : tempOut) {
            listFOLLout.add(edgeOut.getId().toString());  //position x   = rid
            listFOLLout.add(edgeOut.getLabel());          //position x+1 = label
        }


        //------MATCH LOGIC
        //...compare PRECin with FOLLout
        finded = false;
        for(int i = 0; i<listPRECin.size(); i=i+2) {
            singleIn = listPRECin.get(i);
            for(int o = 0; o<listFOLLout.size(); o=o+2){
                singleOut = listFOLLout.get(o);
                if(singleIn.equals(singleOut)) {

                    //check is there a hole
                    if(v==0) {
                        resultIn.add(singleIn);  //rid
                        resultIn.add(listPRECin.get(i+1)); //label
                        finded = true;
                        break; 
                    } else if((v*2) == resultIn.size()) {
                        resultIn.add(singleIn);  //rid
                        resultIn.add(listPRECin.get(i+1)); //label
                        finded = true;
                        break; 
                    }
                }
            }
            if(finded)break;    
        }

        finded = false;
        //...compare PRECout with FOLLin
        for(int i = 0; i<listPRECout.size(); i=i+2) {
            singleOut = listPRECout.get(i);
            for(int o = 0; o<listFOLLin.size(); o=o+2){
                singleIn = listFOLLin.get(o);
                if(singleOut.equals(singleIn)) {
                    //check is there a hole
                    if(v==0) {
                        resultOut.add(singleOut);  //rid
                        resultOut.add(listPRECout.get(i+1)); //label
                        finded = true;
                        break; 
                    } else if((v*2) == resultOut.size()) {
                        resultOut.add(singleOut);  //rid
                        resultOut.add(listPRECout.get(i+1)); //label
                        finded = true;
                        break; 
                    }
                }
            }
            if(finded)break;    
        }

        //to empty out list
        listPRECin.clear();
        listPRECout.clear();    
        listFOLLin.clear();
        listFOLLout.clear();    

        //cheack if it's in the penultimate vertex
        position = v+1;
        if( position==maxsize) {
            break;
        }

    }


    System.out.println("SHORTEST PATH (edge, out direction):");
    if(resultOut.size()>0) {
        for (int ind=0; ind<resultOut.size(); ind=ind+2) {  //ind+2 so i get id[position x] and label [position x+1] 
            System.out.println("id:"+resultOut.get(ind)+", Label:"+resultOut.get(ind+1));
        }
    } else {
        System.out.println("No edge in this direction (OUT)");
    }

    System.out.println("");
    System.out.println("SHORTEST PATH (edge, in direction):");
    if(resultIn.size()>0) {
        for (int ind=0; ind<resultIn.size(); ind=ind+2) {  //ind+2 so i get id[position x] and label [position x+1] 
            System.out.println("id:"+resultIn.get(ind)+", Label:"+resultIn.get(ind+1));
        }
    }else {
        System.out.println("No edge in this direction (IN)");
    }

}

}

在此输入图像描述

EDIT 2

Using the 'direction' in the ShortestPath function. 在此输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM