/* A V program for Bellman-Ford's single source shortest path algorithm. literally adapted from: https://www.geeksforgeeks.org/bellman-ford-algorithm-dp-23/ // Adapted from this site... from C++ and Python codes For Portuguese reference http://rascunhointeligente.blogspot.com/2010/10/o-algoritmo-de-bellman-ford-um.html code by CCS */ const large = 999999 // almost inifinity // a structure to represent a weighted edge in graph struct EDGE { mut: src int dest int weight int } // building a map of with all edges etc of a graph, represented from a matrix adjacency // Input: matrix adjacency --> Output: edges list of src, dest and weight fn build_map_edges_from_graph[T](g [][]T) map[T]EDGE { n := g.len // TOTAL OF NODES for this graph -- its dimensions mut edges_map := map[int]EDGE{} // a graph represented by map of edges mut edge := 0 // a counter of edges for i in 0 .. n { for j in 0 .. n { // if exist an arc ... include as new edge if g[i][j] != 0 { edges_map[edge] = EDGE{i, j, g[i][j]} edge++ } } } // print('${edges_map}') return edges_map } fn print_sol(dist []int) { n_vertex := dist.len print('\n Vertex Distance from Source') for i in 0 .. n_vertex { print('\n ${i} --> ${dist[i]}') } } // The main function that finds shortest distances from src // to all other vertices using Bellman-Ford algorithm. The // function also detects negative weight cycle fn bellman_ford[T](graph [][]T, src int) { mut edges := build_map_edges_from_graph(graph) // this function was done to adapt a graph representation // by a adjacency matrix, to list of adjacency (using a MAP) n_edges := edges.len // number of EDGES // Step 1: Initialize distances from src to all other // vertices as INFINITE n_vertex := graph.len // adjc matrix ... n nodes or vertex mut dist := []int{len: n_vertex, init: large} // dist with -1 instead of INFINITY // mut path := []int{len: n , init:-1} // previous node of each shortest path dist[src] = 0 // Step 2: Relax all edges |V| - 1 times. A simple // shortest path from src to any other vertex can have // at-most |V| - 1 edges for _ in 0 .. n_vertex { for j in 0 .. n_edges { mut u := edges[j].src mut v := edges[j].dest mut weight := edges[j].weight if dist[u] != large && dist[u] + weight < dist[v] { dist[v] = dist[u] + weight } } } // Step 3: check for negative-weight cycles. The above // step guarantees shortest distances if graph doesn't // contain negative weight cycle. If we get a shorter // path, then there is a cycle. for j in 0 .. n_vertex { mut u := edges[j].src mut v := edges[j].dest mut weight := edges[j].weight if dist[u] != large && dist[u] + weight < dist[v] { print('\n Graph contains negative weight cycle') // If negative cycle is detected, simply // return or an exit(1) return } } print_sol(dist) } fn main() { // adjacency matrix = cost or weight graph_01 := [ [0, -1, 4, 0, 0], [0, 0, 3, 2, 2], [0, 0, 0, 0, 0], [0, 1, 5, 0, 0], [0, 0, 0, -3, 0], ] // data from https://www.geeksforgeeks.org/bellman-ford-algorithm-dp-23/ graph_02 := [ [0, 2, 0, 6, 0], [2, 0, 3, 8, 5], [0, 3, 0, 0, 7], [6, 8, 0, 0, 9], [0, 5, 7, 9, 0], ] // data from https://www.geeksforgeeks.org/prims-minimum-spanning-tree-mst-greedy-algo-5/ /* The graph: 2 3 (0)--(1)--(2) | / \ | 6| 8/ \5 |7 | / \ | (3)-------(4) 9 */ /* Let us create following weighted graph From https://www.geeksforgeeks.org/kruskals-minimum-spanning-tree-algorithm-greedy-algo-2/?ref=lbp 10 0--------1 | \ | 6| 5\ |15 | \ | 2--------3 4 */ graph_03 := [ [0, 10, 6, 5], [10, 0, 0, 15], [6, 0, 0, 4], [5, 15, 4, 0], ] // To find number of columns // mut cols := an_array[0].len mut graph := [][]int{} // the graph: adjacency matrix // for index, g_value in [graph_01, graph_02, graph_03] { for index, g_value in [graph_01, graph_02, graph_03] { graph = g_value.clone() // graphs_sample[g].clone() // choice your SAMPLE // always starting by node 0 start_node := 0 println('\n\n Graph ${index + 1} using Bellman-Ford algorithm (source node: ${start_node})') bellman_ford(graph, start_node) } println('\n BYE -- OK') }