Breadth First Search (BFS) And Depth First Search (DFS) Code - Need suggestion on how can I improve it further - algorithm

I have written BFS and DFS code purely with my understanding as below. Which is along with the test example. Looking for the input - how I can make it better in terms of logic & data Structure. I know there are already cooked & may be perfect code in the internet but I wish to attempt mine.
PS: Code is not perfect however I have tested on given example. Apology if you find it messy. Your comments will be welcomed.
package com.company.graph;
import java.util.*;
public class BrethFirstSearch {
public static void main(String...args){
/*
Input Undirected Graph -
2 4 1
A-------B-------C-------D
| \ | \ |
7 | \9 13| 3\ |6
| \ | \ |
E----F----------G-------H
1 8 13
Task 1 - Represent this graph as Data Structure that have optimal Space & Time complexity for store & traversal
Task 2 - Perform "Breadth First Search"
Simplified Representation of Graph where replaced vertex names with numbers..
2 4 1
0-------1-------2-------3
| \ | \ |
7 | \9 13| 3\ |6
| \ | \ |
4----5----------6-------7
1 8 13
*/
// We store number instated of letters since in real world every vertex may have full qualified name ex - "LasVegas" instead of just "A"
Map<Integer,String> vertices = new HashMap<>();
vertices.put(0,"A");
vertices.put(1,"B");
vertices.put(2,"C");
vertices.put(3,"D");
vertices.put(4,"E");
vertices.put(5,"F");
vertices.put(6,"G");
vertices.put(7,"H");
Map<Edge, Integer> edges = new HashMap<>();
//Note - I have store both the side to make Graph search simpler. Comments will be welcomed!!
edges.put(new Edge(0,1), 2);
edges.put(new Edge(0,4), 7);
edges.put(new Edge(0,5), 9);
edges.put(new Edge(1,0), 2);
edges.put(new Edge(1,2), 4);
edges.put(new Edge(2,1), 4);
edges.put(new Edge(2,3), 1);
edges.put(new Edge(2,6), 13);
edges.put(new Edge(2,7), 3);
edges.put(new Edge(3,2), 1);
edges.put(new Edge(3,7), 6);
edges.put(new Edge(4,0), 7);
edges.put(new Edge(4,5), 1);
edges.put(new Edge(5,0), 9);
edges.put(new Edge(5,4), 1);
edges.put(new Edge(5,6), 8);
edges.put(new Edge(6,2), 13);
edges.put(new Edge(6,5), 8);
edges.put(new Edge(6,7), 13);
edges.put(new Edge(7,2), 3);
edges.put(new Edge(7,3), 6);
edges.put(new Edge(7,6), 13);
breadthFirstSearch(vertices, edges);
depthFirstSearch(vertices,edges);
}
static void depthFirstSearch(Map<Integer,String> vertices, Map<Edge, Integer> edges){
System.out.format("%n%n%n%n************ Depth First Search - DFS ***********%n%n");
LinkedList<Integer> listOfVertex = new LinkedList<>(vertices.keySet());
List<Edge> listOfEdges = new ArrayList<>(edges.keySet());
Stack<Integer> dfsStack = new Stack<>();
while (!listOfVertex.isEmpty()){
Integer v = listOfVertex.getFirst();
dfsStack.push(listOfVertex.remove());
System.out.format("*** Start DFS from Vertex %S ***%n", vertices.get(v));
while(!dfsStack.empty()){
Integer vO = v;
for (Edge edge: listOfEdges) {
if (v.equals(edge.getV1()) && listOfVertex.indexOf(edge.getV2()) != -1){ // found new vertex
Integer nextV = edge.getV2();
System.out.format(" Searching from Vertex %S -----> %S%n", vertices.get(edge.getV1()), vertices.get(nextV));
dfsStack.push(nextV);
listOfVertex.remove(nextV);
v = nextV;
break;
}
}
if(vO.equals(v)){ //means not new vertex found from current vertex
v = dfsStack.pop(); //Search for previous vertex
System.out.format("Vertex %S has been conquered %n", vertices.get(v));
}
}
}
}
static void breadthFirstSearch(Map<Integer,String> vertices, Map<Edge, Integer> edges){
System.out.format("************ Breadth First Search - BFS ***********%n%n");
LinkedList<Integer> listOfVertex = new LinkedList<>(vertices.keySet());
List<Edge> listOfEdges = new ArrayList<>(edges.keySet());
BfsQueue bfsQueue = new BfsQueue();
bfsQueue.add(listOfVertex.remove()); //start from 1st vertex = 0 alias A
while (!bfsQueue.isEmpty()){
//remove and start search from this vertex
Integer v = bfsQueue.remove();
System.out.format("Vertex %S has been conquered %n", vertices.get(v));
//Search the Vertices from v
listOfEdges.
forEach(edge -> {
if(v.equals(edge.getV1()) && listOfVertex.indexOf(edge.getV2()) != -1){
bfsQueue.add(edge.getV2());
}});
//Mark the Searched Vertex
Iterator<Integer> i = bfsQueue.getIterator();
while (i.hasNext()){
Integer vertex = i.next();
if (listOfVertex.remove(vertex)){
System.out.format(" Searching from Vertex %S ------> %S %n", vertices.get(v), vertices.get(vertex));
}
}
}
}
static class BfsQueue {
private LinkedList<Integer> list = new LinkedList<>();
Iterator<Integer> getIterator(){
return list.iterator();
}
Integer remove(){
Integer v = null;
if(!list.isEmpty()){
v = list.getFirst();
list.removeFirst();
}
return v;
}
void add(Integer v){
list.add(v);
}
boolean isEmpty(){
return list.isEmpty();
}
boolean isPresent(Integer v){
return list.indexOf(v) != -1;
}
}
static class Edge {
int v1; //1st vertex
int v2; //2nd vertex
public Edge(int v1, int v2) {
this.v1 = v1;
this.v2 = v2;
}
public int getV1() {
return v1;
}
public int getV2() {
return v2;
}
}
}
The Output is :
"C:\Program Files\Java\jdk-11.0.4\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.3.4\lib\idea_rt.jar=64975:C:\Program Files\JetBrains\IntelliJ IDEA 2018.3.4\bin" -Dfile.encoding=UTF-8 -classpath C:\CodeBase\Test\out\production\Test com.company.graph.BrethFirstSearch
************ Breadth First Search - BFS ***********
Vertex A has been conquered
Searching from Vertex A ------> E
Searching from Vertex A ------> B
Searching from Vertex A ------> F
Vertex E has been conquered
Vertex B has been conquered
Searching from Vertex B ------> C
Vertex F has been conquered
Searching from Vertex F ------> G
Vertex C has been conquered
Searching from Vertex C ------> H
Searching from Vertex C ------> D
Vertex G has been conquered
Vertex H has been conquered
Vertex D has been conquered
************ Depth First Search - DFS ***********
*** Start DFS from Vertex A ***
Searching from Vertex A -----> E
Searching from Vertex E -----> F
Searching from Vertex F -----> G
Searching from Vertex G -----> H
Searching from Vertex H -----> C
Searching from Vertex C -----> D
Vertex D has been conquered
Vertex C has been conquered
Searching from Vertex C -----> B
Vertex B has been conquered
Vertex H has been conquered
Vertex G has been conquered
Vertex F has been conquered
Vertex E has been conquered
Vertex A has been conquered
Process finished with exit code 0

One approach I tried is - Implemented edges as a Map where each entry has key as a vertex and value as a List containing edges i.e. all connecting vertices along with the weight. (I inspired through adjacency list approach over the internet and is more efficient than edge list as per my previous approach specially while searching connecting vertices from a
given vertex. The complexity of traversal could be n(n-1) i.e. O(n^2) in Edge List approach assuming all vertices connected to all vertices. Where as (n-1) i.e. O(n) in adjacency list approach as in n vertices graph n can be connected to all n-1 vertices)
i.e. if below is the graph -
2 4 1
0-------1-------2-------3
| \ | \ |
7 | \9 13| 3\ |6
| \ | \ |
4----5----------6-------7
1 8 13
then the map looks like -
Map<Integer, List<Edge>> verticesEdges = new HashMap<>();
verticesEdges.put(0, new LinkedList<>(List.of(new Edge(1,2), new Edge(4,7),new Edge(5,9) )));
verticesEdges.put(1, new LinkedList<>(List.of(new Edge(0,2),new Edge(2,4))) );
verticesEdges.put(2, new LinkedList<>(List.of(new Edge(1,4),new Edge(3,1),new Edge(6,13), new Edge(7,3))));
verticesEdges.put(3,new LinkedList<>(List.of( new Edge(2,1), new Edge(7,6))));
verticesEdges.put(4, new LinkedList<>(List.of(new Edge(0,7),new Edge(5,1) )));
verticesEdges.put(5, new LinkedList<>(List.of(new Edge(0,9), new Edge(4,1),new Edge(6,8) )));
verticesEdges.put(6, new LinkedList<>(List.of(new Edge(2,13), new Edge(5,8), new Edge(7,13))));
verticesEdges.put(7, new LinkedList<>(List.of(new Edge(2,3),new Edge(3,6),new Edge(6,13))));
Now the BFS and DFS code require minor modification. I have presented below just for verification perspective -
package com.company.graph;
import java.util.*;
public class GraphSearch {
public static void main(String...args){
/*
Input Undirected Graph -
2 4 1
A-------B-------C-------D
| \ | \ |
7 | \9 13| 3\ |6
| \ | \ |
E----F----------G-------H
1 8 13
Task 1 - Represent this graph as Data Structure that have optimal Space & Time complexity for store & traversal
Task 2 - Perform "Breadth First Search"
Simplified Representation of Graph where replaced vertex names with numbers..
2 4 1
0-------1-------2-------3
| \ | \ |
7 | \9 13| 3\ |6
| \ | \ |
4----5----------6-------7
1 8 13
*/
// We store number instated of letters since in real world every vertex may have full qualified name ex - "LasVegas" instead of just "A"
Map<Integer,String> vertices = new HashMap<>();
vertices.put(0,"A");
vertices.put(1,"B");
vertices.put(2,"C");
vertices.put(3,"D");
vertices.put(4,"E");
vertices.put(5,"F");
vertices.put(6,"G");
vertices.put(7,"H");
//Implemented edges as a Map where for each entry - key is a vertex and value is List containing edges i.e. all connecting vertices along with the weight !!
Map<Integer, List<Edge>> verticesEdges = new HashMap<>();
verticesEdges.put(0, new LinkedList<>(List.of(new Edge(1,2), new Edge(4,7),new Edge(5,9) )));
verticesEdges.put(1, new LinkedList<>(List.of(new Edge(0,2),new Edge(2,4))) );
verticesEdges.put(2, new LinkedList<>(List.of(new Edge(1,4),new Edge(3,1),new Edge(6,13), new Edge(7,3))));
verticesEdges.put(3,new LinkedList<>(List.of( new Edge(2,1), new Edge(7,6))));
verticesEdges.put(4, new LinkedList<>(List.of(new Edge(0,7),new Edge(5,1) )));
verticesEdges.put(5, new LinkedList<>(List.of(new Edge(0,9), new Edge(4,1),new Edge(6,8) )));
verticesEdges.put(6, new LinkedList<>(List.of(new Edge(2,13), new Edge(5,8), new Edge(7,13))));
verticesEdges.put(7, new LinkedList<>(List.of(new Edge(2,3),new Edge(3,6),new Edge(6,13))));
breadthFirstSearch(vertices, verticesEdges);
//depthFirstSearch(vertices,verticesEdges);
}
static void depthFirstSearch(Map<Integer,String> vertices, Map<Integer, List<Edge>> verticesEdges ){
System.out.format("%n%n%n%n************ Depth First Search - DFS ***********%n%n");
LinkedList<Integer> listOfVertex = new LinkedList<>(vertices.keySet());
Stack<Integer> dfsStack = new Stack<>();
while (!listOfVertex.isEmpty()){
Integer v = listOfVertex.getFirst();
dfsStack.push(listOfVertex.remove());
System.out.format("*** Start DFS from Vertex %S ***%n", vertices.get(v));
while(!dfsStack.empty()){
Integer vO = v;
for (Edge edge: verticesEdges.get(v)) {
if (listOfVertex.indexOf(edge.getV()) != -1){ // found new vertex
Integer nextV = edge.getV();
System.out.format(" Searching from Vertex %S -----> %S%n", vertices.get(v), vertices.get(nextV));
dfsStack.push(nextV);
listOfVertex.remove(nextV);
v = nextV;
break;
}
}
if(vO.equals(v)){ //means not new vertex found from current vertex
v = dfsStack.pop(); //Search for previous vertex
System.out.format("Vertex %S has been conquered %n", vertices.get(v));
}
}
}
}
static void breadthFirstSearch(Map<Integer,String> vertices, Map<Integer, List<Edge>> verticesEdges){
System.out.format("************ Breadth First Search - BFS ***********%n%n");
LinkedList<Integer> listOfVertex = new LinkedList<>(vertices.keySet());
BfsQueue bfsQueue = new BfsQueue();
bfsQueue.add(listOfVertex.remove()); //start from 1st vertex = 0 alias A
while (!bfsQueue.isEmpty()){
//remove and start search from this vertex
Integer v = bfsQueue.remove();
System.out.format("Vertex %S has been conquered %n", vertices.get(v));
//Search the Vertices from v
verticesEdges.get(v).forEach(edge -> {
if(listOfVertex.indexOf(edge.getV()) != -1){
bfsQueue.add(edge.getV());
}});
//Mark the Searched Vertex
Iterator<Integer> i = bfsQueue.getIterator();
while (i.hasNext()){
Integer vertex = i.next();
if (listOfVertex.remove(vertex)){
System.out.format(" Searching from Vertex %S ------> %S %n", vertices.get(v), vertices.get(vertex));
}
}
}
}
static class BfsQueue {
private LinkedList<Integer> list = new LinkedList<>();
Iterator<Integer> getIterator(){
return list.iterator();
}
Integer remove(){
Integer v = null;
if(!list.isEmpty()){
v = list.getFirst();
list.removeFirst();
}
return v;
}
void add(Integer v){
list.add(v);
}
boolean isEmpty(){
return list.isEmpty();
}
boolean isPresent(Integer v){
return list.indexOf(v) != -1;
}
}
static class Edge {
int v; //Connecting Vertex
int w; //weight Of edge
public Edge(int v, int w) {
this.v = v;
this.w = w;
}
public int getV() {
return v;
}
public int getW() {
return w;
}
}
}
When I have ran it -
"C:\Program Files\Java\jdk-11.0.4\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.3.4\lib\idea_rt.jar=50287:C:\Program Files\JetBrains\IntelliJ IDEA 2018.3.4\bin" -Dfile.encoding=UTF-8 -classpath C:\CodeBase\Test\out\production\Test com.company.graph.GraphSearch
************ Breadth First Search - BFS ***********
Vertex A has been conquered
Searching from Vertex A ------> B
Searching from Vertex A ------> E
Searching from Vertex A ------> F
Vertex B has been conquered
Searching from Vertex B ------> C
Vertex E has been conquered
Vertex F has been conquered
Searching from Vertex F ------> G
Vertex C has been conquered
Searching from Vertex C ------> D
Searching from Vertex C ------> H
Vertex G has been conquered
Vertex D has been conquered
Vertex H has been conquered
************ Depth First Search - DFS ***********
*** Start DFS from Vertex A ***
Searching from Vertex A -----> B
Searching from Vertex B -----> C
Searching from Vertex C -----> D
Searching from Vertex D -----> H
Searching from Vertex H -----> G
Searching from Vertex G -----> F
Searching from Vertex F -----> E
Vertex E has been conquered
Vertex F has been conquered
Vertex G has been conquered
Vertex H has been conquered
Vertex D has been conquered
Vertex C has been conquered
Vertex B has been conquered
Vertex A has been conquered
Process finished with exit code 0

Related

Once I reach the node e, what happens in the method? since on the node e, n, is reference to a null value.Where does program go after return from if

a
/ \
b g
/ \
c d
/
e
\
f
public static Node createData() { //this is the nodes which make up the tree structure
Node a = new Node( "a");
Node b = new Node( "b");
Node c = new Node( "c");
Node d = new Node( "d");
Node e = new Node( "e");
Node f = new Node( "f");
Node g = new Node( "g");
a.left = b; //this block of code connects the nodes to the specific tree should look
a.right = g;
b.left = c;
b.right = d;
c.left = e;
e.right = f;
public static void preOrderTraversal(Node n) { // method recursively traverses through using preOrder
if(n == null)
return;
System.out.println(n.value + " ");
preOrderTraversal(n.left);
preOrderTraversal(n.right);
}
//I understand how a, b, c, and e are being outputted. However, once we reach the node e, n is a reference to a null value. So when we enter the method with a null value, after we enter the if statement, where exactly do we "return" to? Like where does the program sort of jump to/which line is now being looked at at this point? I am struggling to understand how the method works once n is a reference to a null value. By the way, preOrder Traversal has these 3 steps in this order: Visit Node, Traverse left, Traverse right. and then repeats recursively

How to reduce a strongly connected component to one vertex?

From https://algs4.cs.princeton.edu/42digraph/
Reachable vertex in a digraph. Design a linear-time algorithm to determine whether a digraph has a vertex that is reachable from
every other vertex.
Kosaraju-Sharir algorithm gives us the strongly connected components. Java code for that can be seen here. Reducing each SCC to a single vertex, a vertex that has outdegree zero is reachable from every other.
Problem is, everyone seems to be talking about reducing a SCC without providing details. What is an efficient algorithm to do so?
Following is a Java solution to my own question. For the graph representation, it uses edu.princeton.cs:algs4:1.0.3 from https://github.com/kevin-wayne/algs4. There appears to be general algorithms for graph contraction, as outlined in this paper; however, for my purposes, the following is sufficient.
/**
* 43. <b>Reachable vertex.</b>
* <p>
* DAG: Design a linear-time algorithm to determine whether a DAG has a vertex that is reachable from every other
* vertex, and if so, find one.
* Digraph: Design a linear-time algorithm to determine whether a digraph has a vertex that is reachable from every
* other vertex, and if so, find one.
* <p>
* Answer:
* DAG: Consider an edge (u, v) ∈ E. Since the graph is acyclic, u is not reachable from v.
* Thus u cannot be the solution to the problem. From this it follows that only a vertex of
* outdegree zero can be a solution. Furthermore, there has to be exactly one vertex with outdegree zero,
* or the problem has no solution. This is because if there were multiple vertices with outdegree zero,
* they wouldn't be reachable from each other.
* <p>
* Digraph: Reduce the graph to it's Kernel DAG, then find a vertex of outdegree zero.
*/
public class Scc {
private final Digraph g;
private final Stack<Integer> s = new Stack<>();
private final boolean marked[];
private final Digraph r;
private final int[] scc;
private final Digraph kernelDag;
public Scc(Digraph g) {
this.g = g;
this.r = g.reverse();
marked = new boolean[g.V()];
scc = new int[g.V()];
Arrays.fill(scc, -1);
for (int v = 0; v < r.V(); v++) {
if (!marked[v]) visit(v);
}
int i = 0;
while (!s.isEmpty()) {
int v = s.pop();
if (scc[v] == -1) visit(v, i++);
}
Set<Integer> vPrime = new HashSet<>();
Set<Map.Entry<Integer, Integer>> ePrime = new HashSet<>();
for (int v = 0; v < scc.length; v++) {
vPrime.add(scc[v]);
for (int w : g.adj(v)) {
// no self-loops, no parallel edges
if (scc[v] != scc[w]) {
ePrime.add(new SimpleImmutableEntry<>(scc[v], scc[w]));
}
}
}
kernelDag = new Digraph(vPrime.size());
for (Map.Entry<Integer, Integer> e : ePrime) kernelDag.addEdge(e.getKey(), e.getValue());
}
public int reachableFromAllOther() {
for (int v = 0; v < kernelDag.V(); v++) {
if (kernelDag.outdegree(v) == 0) return v;
}
return -1;
}
// reverse postorder
private void visit(int v) {
marked[v] = true;
for (int w : r.adj(v)) {
if (!marked[w]) visit(w);
}
s.push(v);
}
private void visit(int v, int i) {
scc[v] = i;
for (int w : g.adj(v)) {
if (scc[w] == -1) visit(w, i);
}
}
}
Running it on the graph below produces the strongly-connected components as shown. Vertex 0 in the reduced DAG is reachable from every other vertex.
What I couldn't find anywhere is the kind of detail that I presented above. Comments like "well, this is easy, you do that, then you do something else" are thrown around without concrete details.
Suppose you already have a method to compute SCCs and the usual graph, vertex and edge methods. Then it's just creating a new graph, adding a vertex representative for each SCC and then adding edge representatives.
For the edges you need to be able to map an original vertex (the edge destination) to its representative in the new graph. You can model that in the first pass using a Map<Vertex, SCC> which maps vertices to their SCCs and a Map<SCC, Vertex> which maps SCCs to their representative vertices in the new graph. Or you directly have a Map<Vertex, Vertex> mapping original vertices to their representatives.
Here is a Java solution:
public static Graph graphToSccGraph(Graph graph) {
Collection<SCC> sccs = SccComputation.computeSccs(graph);
Graph sccGraph = new Graph();
Map<Vertex, SCC> vertexToScc = new HashMap<>();
Map<SCC, Vertex> sccToRep = new HashMap<>();
// Add a representative for each SCC (O(|V|))
for (SCC scc : sccs) {
Vertex rep = new Vertex();
sccGraph.addVertex(rep);
sccToRep.put(scc, rep);
for (Vertex vertex : scc.getVertices()) {
vertexToScc.put(vertex, scc);
}
}
// Add edge representatives (O(|E|))
for (Vertex vertex : graph.getVertices()) {
Vertex sourceRep = sccToRep.get(vertexToScc.get(vertex));
for (Edge edge : vertex.getOutgoingEdges()) {
Vertex destRep = sccToRep.get(vertexToScc.get(edge.getDestination()));
Edge edgeRep = new Edge(sourceRep, destRep);
if (!sccGraph.contains(edgeRep)) {
sccGraph.addEdge(edgeRep);
}
}
}
return sccGraph;
}
Time complexity is linear in the size of the graph (amount of vertices and edges), so optimal. That is Theta(|V| + |E|).
Usually people use a Union-Find (see Wikipedia) data-structure to make this even simpler and get rid of the Maps.

BFS stops after the starting vertex's neighbors have been visited

I'm attempting to implement a BFS search on a maze, specifically the Apollo and Diana maze puzzle. Upon running my BFS algorithm the initial neighbors of the starting vertex are added however subsequent neighbors are added causing the algorithm to terminate after three iterations when run using the example maze below. The code for my algorithm is:
BFS_Algo(){
NodeQueue.push(NodeMatrix[0][0]);
while( !NodeQueue.empty() )
{
Node current;
current = NodeQueue.front();
NodeQueue.pop();
if( !current.visited )
{
current.visited = true;
for ( int i = 0; i < current.neighbors.size(); ++i )
{
if ( !current.neighbors[i].visited )
{
NodeQueue.push(current.neighbors[i]);
current.neighbors[i].predecessor = &NodeMatrix[current.x][current.y];
}
}
}
}
}
I know that the neighbors vectors are properly filled since I have a helper function that prints the contents of all the vectors like so:
B E: |R SE|R SW|
R SE: |empty vector
R SW: |B N|B N|
R SE: |B E|
B N: |R SE|
R E: |empty vector
B N: |R SE|
B E: |O O|
O O: |empty vector
/empty vectors signify that there are no neighbors./
I don't believe this to be a logical error, but I feel this might be more in line with local references instead. Any guidance would be greatly appreciated.
Additional Info:
Ive read in the information for the graph from a file similar to this example:
B E |R SE|R SW|
R SE|B N |R E |
B N |B E |O O |
I have created a class that contains a node struct that holds all the appropriate data.
private:
struct Node{
int x; position in graph
int y; position in graph
std::string color; graph attr
std::string direction; graph attr
bool visited; bfs bool
Node * predecessor; ancestor for path backtracking
std::vector<Node> neighbors; vector of neighbors
};
short rows;
short columns;
Node **NodeMatrix;
std::queue<Node> NodeQueue;

Go, Dijkstra : print out the path, not just calculate the shortest distance

Go, Dijkstra : print out the path, not just calculate the shortest distance.
http://play.golang.org/p/A2jnzKcbWD
I was able to find the shortest distance using Dijkstra algorithm, maybe not.
The code can be found here.
But it would be useless if I can't print out the path.
With a lot of pointers going on, I can't figure out how to print out the final path that takes the least amount of weights.
In short, how do I not only find the shortest distance, but also print out the shortest path on this given code?
The link is here:
http://play.golang.org/p/A2jnzKcbWD
And the snippet of the code is below:
const MAXWEIGHT = 1000000
type MinDistanceFromSource map[*Vertex]int
func (G *Graph) Dijks(StartSource, TargetSource *Vertex) MinDistanceFromSource {
D := make(MinDistanceFromSource)
for _, vertex := range G.VertexArray {
D[vertex] = MAXWEIGHT
}
D[StartSource] = 0
for edge := range StartSource.GetAdEdg() {
D[edge.Destination] = edge.Weight
}
CalculateD(StartSource, TargetSource, D)
return D
}
func CalculateD(StartSource, TargetSource *Vertex, D MinDistanceFromSource) {
for edge := range StartSource.GetAdEdg() {
if D[edge.Destination] > D[edge.Source]+edge.Weight {
D[edge.Destination] = D[edge.Source] + edge.Weight
} else if D[edge.Destination] < D[edge.Source]+edge.Weight {
continue
}
CalculateD(edge.Destination, TargetSource, D)
}
}
I did something with array to see what is being updated.
http://play.golang.org/p/bRXYjnIGxy
This gives ms
[A->D D->E E->F F->T B->E E->D E->F F->T]
When you adjust the new path distance here
if D[edge.Destination] > D[edge.Source]+edge.Weight {
D[edge.Destination] = D[edge.Source] + edge.Weight
Set some array element (say, P for "parent") to point that you have come to Destination from Source.
P[edge.Destination] = edge.Source
After the algorithm ends, in this array each vertex will have its predecessor on the path leading from the starting vertex.
PS. OK, not with arrays and indices ...
Add a new field Prev to the Vertex:
type Vertex struct {
Id string
Visited bool
AdjEdge []*Edge
Prev *Vertex
}
When adjusting distance:
if D[edge.Destination] > D[edge.Source]+edge.Weight {
D[edge.Destination] = D[edge.Source] + edge.Weight
edge.Destination.Prev = edge.Source
And when you display the results:
for vertex1, distance1 := range distmap1 {
fmt.Println(vertex1.Id, "=", distance1)
if vertex1.Prev != nil {
fmt.Println (vertex1.Id, " -> ", vertex1.Prev.Id)
}
}
Shortest Path-Printing using Dijkstra's Algorithm for Graph (Here it is implemented for undirected Graph. The following code prints the shortest distance from the source_node to all the other nodes in the graph.
It also prints the shortest path from the source node to the node requested by the user.
Suppose,you need to find the shortest path from A to B in the graph. Then input A as the source node and B as the destination node.
Code
#include<bits/stdc++.h>
using namespace std;
#define INF (unsigned)!((int)0)
const int MAX=2e4;
vector<pair<int,int>> graph[MAX];
bool visit[MAX];
int dist[MAX];
multiset<pair<int,int>> s;
int parent[MAX]; // used to print the path
int main(){
memset(visit,false,sizeof(visit));
memset(dist,INF,sizeof(dist));
memset(parent,-1,sizeof(parent));
int nodes,edges; cin>>nodes>>edges;
for(auto i=0;i<edges;++i){
int a,b,w;
cin>>a>>b>>w;
graph[a].push_back(make_pair(b,w));
graph[b].push_back(make_pair(a,w)); //Comment it to make the Directed Graph
}
int source_node; cin>>source_node;
dist[source_node]=0;
s.insert(make_pair(0,source_node));
while(!s.empty()){
pair<int,int> elem=*s.begin();
s.erase(s.begin());
int node=elem.second;
if(visit[node])continue;
visit[node]=true;
for(auto i=0;i<graph[node].size();++i){
int dest=graph[node][i].first;
int w=graph[node][i].second;
if(dist[node]+w<dist[dest]){
dist[dest]=dist[node]+w;
parent[dest]=node;
s.insert(make_pair(dist[dest],dest));
}
}
}
cout<<"NODE"<<" "<<"DISTANCE"<<endl;
for(auto i=1;i<=nodes;++i){
cout<<i<<" "<<dist[i]<<endl;
}
/*----PRINT SHORTEST PATH FROM THE SOURCE NODE TO THE NODE REQUESTED-------*/
int node_for_path; cin>>node_for_path;
int dest_node=node_for_path;
stack<int> path;
while(parent[node_for_path]!=source_node){
path.push(node_for_path);
node_for_path=parent[node_for_path];
}
path.push(node_for_path);
path.push(source_node);
cout<<"Shortest Path from "<<source_node<<"to "<<dest_node<<":"<<endl;
while(!path.empty()){
if(path.size()==1) cout<<path.top();
else cout<<path.top()<<"->";
path.pop();
}
return 0;
}
/*TEST CASE*/
9 14 //---NODES,EDGES---
1 2 4 //---START,END,WEIGHT---FOR THE NO OF EDGES
2 3 8
3 4 7
4 5 9
5 6 10
6 7 2
7 8 1
8 1 8
2 8 11
8 9 7
9 7 6
9 3 2
6 3 4
4 6 14
1 //---SOURCE_NODE
5 //-----NODE TO WHICH PATH IS REQUIRED
---END---*/
hope it helps

DFS - finding Minimum Spanning Tree in a graph

l - adiacency list
x - starting vertex
dfst, q - empty array of vertex size
std::list <int> q;
std::vector<bool> visited(cols + 1);
for(int i = 0; i < cols; i++) visited[i] = false;
visited[x] = true;
if(!l[x].empty())
for(std::list<int>::iterator i = l[x].begin(); i != l[x].end(); i++)
{
q.push_back(x); q.push_back(* i);
}
while(!q.empty())
{
y = q.back(); q.pop_back();
x = q.back(); q.pop_back();
if(!visited[y])
{
visited[y] = true;
if(!l[y].empty())
for(std::list<int>::iterator i = l[y].begin(); i != l[y].end(); i++)
{
q.push_back(y); q.push_back(* i);
}
dfst[x].push_back(y);
dfst[y].push_back(x);
}
}
I just can't see why does this give wrong results...I don't know if you are familiar with this algorithm, but if you are, I hope you can see what's wrong here.
EDIT:
Adjacency list is:
1: 2, 3
2: 3
3: 4
4: 3
MST should here be something like:
1: 2, 3
3: 4
But instead it's:
2: 3
3: 2, 4
4: 3
And the current code is: (I used brackets where it was needed):
std::list <int> q;
std::vector<bool> visited(cols + 1);
for(int i = 0; i < cols; i++) visited[i] = false;
visited[x] = true;
if(!l[x].empty())
{
for(std::list<int>::iterator i = l[x].begin(); i != l[x].end(); i++)
{
q.push_back(x); q.push_back(* i);
}
while(!q.empty())
{
y = q.back(); q.pop_back();
x = q.back(); q.pop_back();
if(!visited[y])
{
visited[y] = true;
if(!l[y].empty())
for(std::list<int>::iterator i = l[y].begin(); i != l[y].end(); i++)
{
if(!visited[*i])
{q.push_back(y); q.push_back(* i);}
}
dfst[x].push_back(y);
dfst[y].push_back(x);
}
}
}
I worked through your code, it appears to be correct. However, keep in mind that there are multiple DFS trees if your input tree has a cycle. The tree that you get depends on the order in which you process your vertices. Perhaps your input has a cycle? If so, your code might be processing the nodes in an order different from the order that they are processed in the solution.
For example, take the following adjacency list for an input tree, where nodes are lettered:
a: b,c
b: a,d
c: a,c,e
d: b,c,e
e: c,d
Starting at a, if we look in the adjacency list for the next node based on alphabetical order, we get the following DFS tree:
a: b
b: a,d
c: d,e
d: b,d
e: c
Using your algorithm though, we get the following:
a: c
b: d
c: a,e
d: b,e
e: c,d
If this is happening, perhaps try a recursive approach.
Seeing some sample input and output would help further with ansering this question though, as this may not be your problem.
EDIT: I should clarify that the multiple DFS trees in a graph with a cycle applies where the cycle is bidirectional, such as with an undirected graph. The point is, you might be finding a DFS tree that is also correct, but not the same as the one that has been identified as correct.
EDIT (again): Another issue you may have: your algorithm appears to be for undirected graphs since you have the satements dfst[x].push_back(y); dfst[y].push_back(x);in your code, but your input graph given in your example looks like it's directed. Removing the second statement (dfst[y].push_back(x);) should correct this
Code looks little confusing actually i thought its BFS first..but its DFS
You should check if the node is visited before adding to the stack(back of list)
while(!q.empty())
{
y = q.back(); q.pop_back();
x = q.back(); q.pop_back();
if(!visited[y])
{
visited[y] = true;
if(!l[y].empty())
for(std::list<int>::iterator i = l[y].begin(); i != l[y].end(); i++)
{
if(!visited[*i])
{q.push_back(y); q.push_back(* i);}
}
dfst[x].push_back(y);
dfst[y].push_back(x);
}
}

Resources