java - Find number of unique routes to specific node using Depth First Search -


i have directed graph vertexes 123456. using depth first search, if wanted able find number of unique routes 1-4 (for example), how go doing it? here current dfs.

private final map<character, node> mnodes; private final list<edge> medges; private list<node> mvisited = new arraylist<>(); int weight; int numberofpaths;  public depthfirstsearch(graph graph){     mnodes = graph.getnodes();     medges = new arraylist<>(graph.getedges());     for(node node : mnodes.values()){         node.setvisited(false);     } }  public void depthfirstsearch(node source){      source.setvisited(true);     list<edge> neighbours = source.getneighbouringedges(medges);     for(edge edge : neighbours){         system.out.println(edge.getfrom().getname()+"-"+edge.getto().getname());         if(!edge.getto().isvisited()){              mvisited.add(edge.getto());             weight += edge.getweight();             depthfirstsearch(edge.getto());          }     }  } 

since cycles aren't allowed, have dag (directed acyclid graph).

these questions related topic:

basically, idea topological sort of dag, iterate nodes starting destination node backwards source node, calculating how many paths node.

since array haven't cycles , nodes topological sorted, when visit node, nodes can reached node appears latter in sort , visited. so, count of paths node target sum of counts of nodes adjacent it.

models:

class graph {     private list<node> nodes;     private list<edge> edges;      public graph() {         nodes = new arraylist<>();         edges = new arraylist<>();     }      public list<node> getnodes() { return nodes; }         public list<edge> getedges() { return edges; }      public void addnode(node node) { nodes.add(node); }         public void addedge(edge edge) {         edges.add(edge);                 edge.getfrom().addedge(edge);         edge.getto().addedge(edge);     } }  class node {     private list<edge> outgoings, incomings;      public node() {         outgoings = new arraylist<>();         incomings = new arraylist<>();     }      public list<edge> getoutgoings() { return outgoings; }         public list<edge> getincomings() { return incomings; }      public void addedge(edge edge) {         if (edge.getfrom() == this) outgoings.add(edge);         if (edge.getto() == this) incomings.add(edge);     } }  class edge {     private node from, to;      public edge(node from, node to) {         this.from = from;         this.to = to;     }      public node getfrom() { return from; }         public node getto() { return to; } } 

algorithm:

static int countpaths(graph graph, node source, node target) {     list<node> nodes = topologicalsort(graph);     int[] counts = new int[nodes.size()];      int srcindex = nodes.indexof(source);     int tgtindex = nodes.indexof(target);      counts[tgtindex] = 1;      (int = tgtindex; >= srcindex; i--) {         (edge edge : nodes.get(i).getoutgoings())             counts[i] += counts[nodes.indexof(edge.getto())];     }      return counts[srcindex]; }  static list<node> topologicalsort(graph g) {     list<node> result = new arraylist<>();     set<node> visited = new hashset<>();     set<node> expanded = new hashset<>();      (node node: g.getnodes())         explore(node, g, result, visited, expanded);      return result; }  static void explore(node node, graph g, list<node> ordering, set<node> visited, set<node> expanded) {     if (visited.contains(node)) {                     if (expanded.contains(node)) return;         throw new illegalargumentexception("graph contains cycle.");     }      visited.add(node);      (edge edge: node.getincomings())         explore(edge.getfrom(), g, ordering, visited, expanded);      ordering.add(node);     expanded.add(node); } 

usage:

graph g = new graph();  node = new node(); node b = new node(); node c = new node(); node d = new node(); node e = new node();  edge ab = new edge(a, b); edge bc = new edge(b, c); edge cd = new edge(c, d); edge ad = new edge(a, d); edge ae = new edge(a, e); edge ed = new edge(e, d); edge = new edge(b, e); edge ec = new edge(e, c);  g.addnode(a); g.addnode(b); g.addnode(c); g.addnode(d); g.addnode(e);  g.addedge(ab); g.addedge(bc); g.addedge(cd); g.addedge(ad); g.addedge(ae); g.addedge(ed); g.addedge(be); g.addedge(ec);  int count = countpaths(g, a, d);   //count: 6  // paths: //1. a->b->c->d //2. a->d //3. a->e->d //4. a->b->e->c->d //5. a->b->e->d //6. a->e->c->d 

but, if want using bfs, can try doing backtrack resetting visited nodes:

static int countpaths(graph graph, node source, node target) {     set<node> visiteds = new hashset<>();     return bfs(source, target, visiteds); }  static int bfs(node current, node target, set<node> visiteds) {     if (current == target) return 1;     else     {         int count = 0;         visiteds.add(current);          (edge edge : current.getoutgoings())             if (!visiteds.contains(edge.getto()))                 count += bfs(edge.getto(), target, visiteds);          visiteds.remove(current);         return count;     } }     

however, increase performance, can implement kind of memoization:

static int countpaths(graph graph, node source, node target) {     set<node> visiteds = new hashset<>();     map<node, integer> memoize = new hashmap<>();      (node node : graph.getnodes())         memoize.put(node, -1);      memoize.put(target, 1);      return bfs(source, visiteds, memoize); }  static int bfs(node current, set<node> visiteds, map<node, integer> memoize) {     if (memoize.get(current) != -1) return memoize.get(current);     else     {         int count = 0;         visiteds.add(current);          (edge edge : current.getoutgoings())             if (!visiteds.contains(edge.getto()))                 count += bfs(edge.getto(), visiteds, memoize);          visiteds.remove(current);         memoize.put(current, count);         return count;     } }   

Comments

Popular posts from this blog

ios - RestKit 0.20 — CoreData: error: Failed to call designated initializer on NSManagedObject class (again) -

laravel - PDOException in Connector.php line 55: SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: YES) -

java - Digest auth with Spring Security using javaconfig -