From f70e489fb8ff0d2300bcc7755949f973205a5010 Mon Sep 17 00:00:00 2001 From: PaulineChane Date: Thu, 25 Mar 2021 00:27:08 -0700 Subject: [PATCH 1/3] all tests passing, need to add time/space complexity --- lib/dijkstra.rb | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/lib/dijkstra.rb b/lib/dijkstra.rb index 83dbd1d..bb629fb 100644 --- a/lib/dijkstra.rb +++ b/lib/dijkstra.rb @@ -1,5 +1,44 @@ def dijkstra(adjacency_matrix, start_node) + shortest_distances = Array.new(adjacency_matrix[0].length){Float::INFINITY} + parent_list = Array.new(shortest_distances.length){nil} + tracking_q = Queue.new + visited_nodes = Set.new - + # start with start node + # start node has no previous node, marked as 0 + visited_nodes.add(start_node) + shortest_distances[start_node] = 0 + + adjacency_matrix[start_node].each_with_index do |weight, i| + if weight > 0 && i != start_node + parent_list[i] = start_node + shortest_distances[i] = weight + tracking_q.push(i) + end + end + + until (tracking_q.empty?) + cur_node = tracking_q.pop + # skip already visited nodes + next if visited_nodes.include?(cur_node) + # check all adjacent nodes + visited_nodes.add(cur_node) + + # check for adjacent nodes + adjacency_matrix[cur_node].each_with_index do |weight, i| + # ignore those with no weight + if weight > 0 && i != cur_node + if shortest_distances[cur_node] + weight < shortest_distances[i] + shortest_distances[i] = shortest_distances[cur_node] + weight + parent_list[i] = cur_node + end + tracking_q.push(i) + end + end + end + + return {start_node: start_node, + parent_list: parent_list, + shortest_distances: shortest_distances} end From 3af203d325cf2b98e6426c37c49e662031289211 Mon Sep 17 00:00:00 2001 From: PaulineChane Date: Thu, 25 Mar 2021 00:35:26 -0700 Subject: [PATCH 2/3] time/space complexity added --- lib/dijkstra.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/dijkstra.rb b/lib/dijkstra.rb index bb629fb..886f328 100644 --- a/lib/dijkstra.rb +++ b/lib/dijkstra.rb @@ -1,4 +1,12 @@ +# Time Complexity: O(v^2) - Since we are performing a variety of BFS on an adjacency matrix, +# the time complexity to search all edges will be, at worst case, O(v^2), assuming all vertices v +# are interconnected. This is because for each node visited, the entire associated row on the +# adjacency matrix has to be checked to confirm which edges are actual graph edges. +# Space Complexity: O(v) - A couple arrays are create, size directly equal to the number of vertices v. +# Likewise, the Queue and Set created to track nodes to visit and visited nodes are also directly +# equal to tne number of vertices in the graph. The return hash is simply a wrapper that envelops +# the shortest_distances and parent_list arrays. def dijkstra(adjacency_matrix, start_node) shortest_distances = Array.new(adjacency_matrix[0].length){Float::INFINITY} parent_list = Array.new(shortest_distances.length){nil} From 921b89a3fe50dbb9a962ae8ceeff45a880dbfac3 Mon Sep 17 00:00:00 2001 From: Pauline Chane Date: Mon, 19 Apr 2021 15:21:00 -0700 Subject: [PATCH 3/3] trying to switch fork --- lib/dijkstra.rb | 98 ++++++++++++++++++++++--------------------------- 1 file changed, 44 insertions(+), 54 deletions(-) diff --git a/lib/dijkstra.rb b/lib/dijkstra.rb index b01626d..dc9721b 100644 --- a/lib/dijkstra.rb +++ b/lib/dijkstra.rb @@ -1,62 +1,52 @@ - +# Time Complexity: O(v^2) - Since we are performing a variety of BFS on an adjacency matrix, +# the time complexity to search all edges will be, at worst case, O(v^2), assuming all vertices v +# are interconnected. This is because for each node visited, the entire associated row on the +# adjacency matrix has to be checked to confirm which edges are actual graph edges. + +# Space Complexity: O(v) - A couple arrays are create, size directly equal to the number of vertices v. +# Likewise, the Queue and Set created to track nodes to visit and visited nodes are also directly +# equal to tne number of vertices in the graph. The return hash is simply a wrapper that envelops +# the shortest_distances and parent_list arrays. def dijkstra(adjacency_matrix, start_node) - - #int nVertices = adjacencyMatrix[0].length; - num_nodes = adjacency_matrix.length - - # shortest_distances will hold the shortest distances from start_node to i - # it starts with infinity as the value - shortest_distances = Array.new(num_nodes, Float::INFINITY) - - - # added[i] will be true if the path to i - # from the source has been found - added = Array.new(num_nodes, false) - - - # Distance of source vertex from - # itself is always 0 + shortest_distances = Array.new(adjacency_matrix[0].length){Float::INFINITY} + parent_list = Array.new(shortest_distances.length){nil} + tracking_q = Queue.new + visited_nodes = Set.new + + # start with start node + # start node has no previous node, marked as 0 + visited_nodes.add(start_node) shortest_distances[start_node] = 0 - - # parent array to store the shortest path tree - parents = Array.new(num_nodes) - # no parent for the start node - parents[start_node] = nil - - - # Find shortest path for all nodes - (num_nodes - 1).times do - # Pick the minimum distance vertex - # from the set of vertices not yet - # processed. nearest_node is - # always equal to start_node in - # first iteration. - nearest_node = -1 - shortest_distance = Float::INFINITY - (0...num_nodes).each do |node_index| - if (!added[node_index] && - shortest_distances[node_index] < shortest_distance) - nearest_node = node_index - shortest_distance = shortest_distances[node_index] + adjacency_matrix[start_node].each_with_index do |weight, i| + if weight > 0 && i != start_node + parent_list[i] = start_node + shortest_distances[i] = weight + tracking_q.push(i) end - end - - # Mark the picked vertex as visited - added[nearest_node] = true; - # Update dist value of the - # adjacent nodes of the picked node. - (0...num_nodes).each do |node_index| - edge_distance = adjacency_matrix[nearest_node][node_index]; + end - if (edge_distance > 0 && - ((shortest_distance + edge_distance) < - shortest_distances[node_index])) - parents[node_index] = nearest_node; - shortest_distances[node_index] = shortest_distance + - edge_distance + until (tracking_q.empty?) + cur_node = tracking_q.pop + # skip already visited nodes + next if visited_nodes.include?(cur_node) + # check all adjacent nodes + visited_nodes.add(cur_node) + + # check for adjacent nodes + adjacency_matrix[cur_node].each_with_index do |weight, i| + # ignore those with no weight + if weight > 0 && i != cur_node + if shortest_distances[cur_node] + weight < shortest_distances[i] + shortest_distances[i] = shortest_distances[cur_node] + weight + parent_list[i] = cur_node + end + tracking_q.push(i) + end end - end end - return {start_node: start_node, parent_list: parents, shortest_distances: shortest_distances } + + return {start_node: start_node, + parent_list: parent_list, + shortest_distances: shortest_distances} end