Search code examples
javajgraphtdigraphs

Reach n-th successor of a vertex in a branch


I created a digraph using the jgrapht library. I use the successorListOf() method to access a vertex's successor, but I'd like to be able to reach the n-th successor of a given vertex (which are Point objects in my case). My digraph has two branches (named B and C here). I made a simple and shorter code to make it easier:

public static DirectedGraph<Point, DefaultEdge> directedGraph = new DefaultDirectedGraph<Point, DefaultEdge>(DefaultEdge.class);
public static Point startPoint = new Point(2, 6, "S");
public static Point firstPoint = new Point(2, 7, "A");
public static Point secondPoint = new Point(2, 8, "B");
public static Point thirdPoint = new Point(2, 9, "B");
public static Point fourthPoint = new Point(2, 10, "B");
public static Point fifthPoint = new Point(3, 7, "C");
public static Point sixthPoint = new Point(4, 7, "C");
public static Point seventhPoint = new Point(5, 7, "C");


void setup ()  {
  directedGraph.addVertex(startPoint);
  directedGraph.addVertex(firstPoint);
  directedGraph.addVertex(secondPoint);
  directedGraph.addVertex(thirdPoint);
  directedGraph.addVertex(fourthPoint);
  directedGraph.addVertex(fifthPoint);
  directedGraph.addVertex(sixthPoint);
  directedGraph.addVertex(seventhPoint);
  directedGraph.addEdge(startPoint, firstPoint);
  directedGraph.addEdge(firstPoint, secondPoint);
  directedGraph.addEdge(firstPoint, thirdPoint);
  directedGraph.addEdge(firstPoint, fourthPoint);
}

// --------------------------------------------------------------
public static ArrayList<Point> pointList = new ArrayList<Point>();
public static class Point {

  public int x;
  public int y;
  public String iD;
  public  Point(int x, int y, String iD) 
  {

    this.x = x;
    this.y = y;
    this.iD= iD;
  }
  @Override
    public String toString() {
    return ("[x="+x+" y="+y+" iD="+iD+ "]");
  }

  @Override
    public int hashCode() {
    int hash = 7;
    hash = 71 * hash + this.x;
    hash = 71 * hash + this.y;

    return hash;
  }



  @Override
    public boolean equals(Object other) 
  {
    if (this == other)
      return true;

    if (!(other instanceof Point))
      return false;

    Point otherPoint = (Point) other;
    return otherPoint.x == x && otherPoint.y == y;
  }
}

I'd like to add an edge between the firstPoint and each point of the "B" branch, and instead of having:

directedGraph.addEdge(firstPoint, secondPoint);
  directedGraph.addEdge(firstPoint, thirdPoint);
  directedGraph.addEdge(firstPoint, fourthPoint);

I'd like to use:

for (Point successor : Graphs.successorListOf (directedGraph, firstPoint)) {
        if (successor.type.equals("B") {
               directedGraph.addEdge(firstPoint, successor);
        }
}

But here I can only reach the first successor of the branch B. How can I reach the successor of the successor etc, in the case of n-th successor ? The number of vertices in the B branch may change, that's why I'm looking for a way to do this automatically instead of Point by Point.

How could I do this ?

On the drawing,1 would be my startPoint, 2 would be my firstPoint, and then there are two branches which would be my B & C branches

On the drawing,1 would be my startPoint, 2 would be my firstPoint, and then there are two branches which would be my B & C branches


Solution

  • I wrote the following code, but it's not tested and you might need to modify it to fit your requirements.

    This code is running a DFS (depth first search) to a predefined depth using the variables and instances you used in your provided examples.

    public void getSuccessor(DirectedGraph<Point, DefaultEdge> graph, Point point, String type, int depth) {
        List<Point> visitedPoints = new ArrayList<>();
        _getSuccessor(graph, point, visitedPoints, type, depth);
    }
    
    private void _getSuccessor(DirectedGraph<Point, DefaultEdge> graph, Point point, List<Point> visitedPoints, String type, int depth){
    
        if(depth == 0)
            return;
    
        // Mark node as visited
        visitedPoints.add(point);
    
        // Loop on all its successors
        for(Point successor : Graphs.successorListOf (directedGraph, point)){
    
            // If node not already visited
            if(!visitedPoints.contains(successor) && successor.type.equals(type)) {
                directedGraph.addEdge(firstPoint, successor);
                _getSuccessor(graph, successor, visitedPoints, type, depth-1);
            }
        }
    }