Quantcast
Channel: Active questions tagged ocaml - Stack Overflow
Viewing all articles
Browse latest Browse all 527

Find a path in a graph from source to destination using BFS

$
0
0

I have been through an issue while I was implementing a function that give me a path from a source node to a destination node using BFS. I'm using BFS to find a path because I want my path to have levels which are growing. For instance, in this graph, I would like to have the following path:[s,2,4,3,t] . But my path current path looks like this: [s,2,4,1,t].

Here my bfs implementation:

let rec bft_from dst node_to_string g acc (seen, to_treat) =          match G.NodeSet.choose_opt to_treat with          | None -> None  (* Plus de nœuds à traiter, chemin non trouvé *)          | Some (el, elw) ->            let _ = Printf.printf "starting new level on %s \n" (node_to_string el) in            let seen_after_level, to_treat_next_level =              G.NodeSet.fold                (fun (s, sw) (seen_before_s, to_treat_next_level_before_s) ->                  if G.NodeSet.exists (fun (a, _) -> a = s) seen_before_s then                    (seen_before_s, to_treat_next_level_before_s)                  else                    let _ = Printf.printf "visiting  %s  \n" (node_to_string s) in                    let seen_before_s_plus_s = G.NodeSet.add (s, sw) seen_before_s in                    let succs_s = G.succs g s in                    let to_treat_next_level_after_s =                      G.NodeSet.fold                        (fun (t, wt) to_treat_next_level_before_t ->                          if G.NodeSet.exists (fun(a,_) -> a=t) seen_before_s_plus_s then                            to_treat_next_level_before_t                          else                            let _ = Printf.printf "Ajout de %s à traiter\n" (node_to_string t) in                            G.NodeSet.add (t, wt) to_treat_next_level_before_t                        )                        succs_s                        to_treat_next_level_before_s                    in                    (seen_before_s_plus_s, to_treat_next_level_after_s)                )                to_treat                (seen, G.NodeSet.empty)            in            if G.NodeSet.exists (fun (a, _) -> a = dst) seen_after_level then              let _ = Printf.printf "\n" in              let _ = Printf.printf "ajout de %s \n" (node_to_string el) in              Some (List.rev (el :: acc))  (* Construire le chemin *)            else              let _ = Printf.printf "\n" in              let _ = Printf.printf "ajout de %s \n" (node_to_string el) in              bft_from dst node_to_string g (el :: acc) (seen_after_level, to_treat_next_level)
val bft_from : node -> (node->string) -> graph -> node list ->(G.NodeSet.t*G.NodeSet.t) -> node list option

It is an implementation for a weighted graph. To implement weighted graph, I decided that G.NodeSet.elt would be of type (node*int) with int the weight. So if I have to take all the successors of "4" for instance , I will have a NodeSet with {("1",6),("3,6)}.

Now, the problem is the path that the bfs give me.I have tried to put some Printf.printf to know what it happens. Always in this graph, I tried to use my function to find a path from s to t and here what happens:

starting new level on svisiting  sAdd 2 in to_treatAdd s in liststarting new level on 2visiting  2Add 4 in to_treatAdd 2 in liststarting new level on 4visiting  4Add 1 in to_treatAdd 3 in to_treatAdd 4 in liststarting new level on 1visiting  1visiting  3Add t in to_treatAdd 1 in liststarting new level on tvisiting  tAdd t in list

and here my path: [s 2 4 1 t]. Why is there a starting new level on "1" and not on "3" ? How can I go to a starting new level on "3" instead of "1" ? Because if we see the graph, there is no path from "1" to "t" .

Graph exemple


Viewing all articles
Browse latest Browse all 527

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>