|
| 1 | +package main |
| 2 | + |
| 3 | +import ( |
| 4 | + "fmt" |
| 5 | + "math" |
| 6 | +) |
| 7 | + |
| 8 | +var graph map[string]map[string]float64 |
| 9 | +var costs map[string]float64 |
| 10 | +var parents map[string]string |
| 11 | +var processed []string |
| 12 | + |
| 13 | +func main() { |
| 14 | + // the graph |
| 15 | + graph = make(map[string]map[string]float64) |
| 16 | + graph["start"] = make(map[string]float64) |
| 17 | + graph["start"]["a"] = 6 |
| 18 | + graph["start"]["b"] = 2 |
| 19 | + |
| 20 | + graph["a"] = make(map[string]float64) |
| 21 | + graph["a"]["fin"] = 1 |
| 22 | + |
| 23 | + graph["b"] = make(map[string]float64) |
| 24 | + graph["b"]["a"] = 3 |
| 25 | + graph["b"]["fin"] = 5 |
| 26 | + |
| 27 | + graph["fin"] = make(map[string]float64) |
| 28 | + |
| 29 | + // the costs table |
| 30 | + costs = make(map[string]float64) |
| 31 | + costs["a"] = 6 |
| 32 | + costs["b"] = 2 |
| 33 | + costs["fin"] = math.Inf(1) |
| 34 | + |
| 35 | + // the parents table |
| 36 | + parents = make(map[string]string) |
| 37 | + parents["a"] = "start" |
| 38 | + parents["b"] = "start" |
| 39 | + parents["fin"] = "" |
| 40 | + |
| 41 | + // Find the lowest-cost node that you haven't processed yet. |
| 42 | + node := find_lowest_cost_node(costs) |
| 43 | + // If you've processed all the nodes, this while loop is done. |
| 44 | + |
| 45 | + for node != "" { |
| 46 | + cost := costs[node] |
| 47 | + // Go through all the neighbors of this node. |
| 48 | + neighbors := graph[node] |
| 49 | + |
| 50 | + for node, _ := range neighbors { |
| 51 | + new_cost := cost + neighbors[node] |
| 52 | + // If it's cheaper to get to this neighbor by going through this node... |
| 53 | + if costs[node] > new_cost { |
| 54 | + // ... update the cost for this node. |
| 55 | + costs[node] = new_cost |
| 56 | + // This node becomes the new parent for this neighbor. |
| 57 | + parents[node] = node |
| 58 | + } |
| 59 | + } |
| 60 | + // Mark the node as processed. |
| 61 | + processed = append(processed, node) |
| 62 | + // Find the next node to process, and loop. |
| 63 | + node = find_lowest_cost_node(costs) |
| 64 | + } |
| 65 | + |
| 66 | + fmt.Println(costs) |
| 67 | + |
| 68 | +} |
| 69 | + |
| 70 | +func find_lowest_cost_node(costs map[string]float64) string { |
| 71 | + lowest_cost := math.Inf(1) |
| 72 | + lowest_cost_node := "" |
| 73 | + |
| 74 | + for node, _ := range costs { |
| 75 | + // fmt.Println("Node:", node, "Value:", value) |
| 76 | + cost := costs[node] |
| 77 | + // If it's the lowest cost so far and hasn't been processed yet... |
| 78 | + if cost < lowest_cost && !contains(processed, node) { |
| 79 | + // ... set it as the new lowest-cost node. |
| 80 | + lowest_cost = cost |
| 81 | + lowest_cost_node = node |
| 82 | + } |
| 83 | + } |
| 84 | + return lowest_cost_node |
| 85 | +} |
| 86 | + |
| 87 | +func contains(s []string, e string) bool { |
| 88 | + for _, a := range s { |
| 89 | + if a == e { |
| 90 | + return true |
| 91 | + } |
| 92 | + } |
| 93 | + return false |
| 94 | +} |
0 commit comments