Skip to content
This repository was archived by the owner on Apr 10, 2020. It is now read-only.

Conversation

@selfeki
Copy link
Member

@selfeki selfeki commented Aug 31, 2018

Adds Dijkstra's shortest path algorithm with unit tests.

@selfeki selfeki requested a review from alireza-a August 31, 2018 20:43
@@ -0,0 +1,19 @@
type node = {
id: string,
neighbours: list(string),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does a node need a set of neighbors? We can calculate them based on the edges.

weight: int,
};

type directedGraph = list(node);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are you passing in the edges outside of the directedGraph?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why don't we only specify the edges and construct the nodes inside the module?

Copy link
Member Author

@selfeki selfeki Sep 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if a node does not have any incident edges? I think we still need a list of nodes but without the neighbours field.


let infinity = Pervasives.max_int;

let parseAdjList = adj_list => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should construct the adj_table from the edges instead. We don't need to specify the adj_list at all!

Hashtbl.add(weight_tbl, id, adj_edge_weights);
};

List.iter(initializeWeights, adj_list);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why creating a nested Hash here? Why not using a tuple as the key?

};

let add = (a, b) => {
if (a == infinity || b == infinity) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should use infinity. Pervasive.infinity is for floating points but here we are dealing with int. The distance hash_tbl can map to option(int)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used let infinity = Pervasives.max_int; not let infinity = Pervasives.infinity.
So should I still change this?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

debatable but i think it's fine.

};
};

let rec traverse = (~queue, ~adj_tbl, ~weight_tbl, ~dist, ~prev) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think queue should be renamed to frontier?

let edge_weight = getEdgeWeight(weight_tbl, current_id, neighbour_id);
let alt_dist = add(current_dist, edge_weight);

if (alt_dist < neighbour_dist) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should refactor this and call it relax?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean relax instead of alt_dist?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my comment was for the content of the if statement

Copy link
Collaborator

@alireza-a alireza-a left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A graph is a list of nodes and edges. Since we are dealing with a directed graph and all the edges have weights, we can simplify our interface by only requiring a list of node id's (when there is no edge to or from a node) and edge weight list (from, to, weight).

Using the weights we can create a set of helper functions for Adj, Weight ...

if (alt_dist < neighbour_dist) {
Hashtbl.replace(dist, neighbour_id, alt_dist);
Hashtbl.replace(prev, neighbour_id, Some(current_id));
Heap.remove(queue, (key, _) => key == neighbour_id) |> ignore;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we add update function to the Heap?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added an update function to the Heap

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I approved your PR

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants