Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added example dijkstra algorithm #1572

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/Dijkstra Algorithm/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/target
8 changes: 8 additions & 0 deletions examples/Dijkstra Algorithm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "graph-in-rust"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
5 changes: 5 additions & 0 deletions examples/Dijkstra Algorithm/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## Dijsktra Algorithm in Rust

The `src` directory consist of 2 files: `main.rs` and `graph.in`. The `graph.in` file consist of a `vec![]` which is a `vector` of data as: `(source, destination, cost)`. This graph is comprised of `6` nodes and their `cost`.

The algorithm returns the shortest path between 2 nodes. The function `shortest_path(g: &Graph, start: Node, goal: Node)` takes start and end nodes and returns the total cost to reach the goal.
9 changes: 9 additions & 0 deletions examples/Dijkstra Algorithm/src/graph.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
vec![
(0, 1, 5),
(0, 2, 10),
(1, 2, 7),
(1, 4, 3),
(2, 4, 5),
(4, 5, 10),
(5, 6, 7)
]
132 changes: 132 additions & 0 deletions examples/Dijkstra Algorithm/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
use std::cmp::Ordering;
use std::collections::{BinaryHeap, HashMap, HashSet};
type Node = usize;
type Cost = usize;

struct Graph {
edges: HashMap<Node, Vec<(Node, Cost)>>,
nodes: HashSet<Node>,
}
#[warn(clippy::redundant_closure)]
// The graph is created from the list provided by file graph.in
impl Graph {
fn from_edge_list(edge_list: &[(Node, Node, Cost)]) -> Self {
let mut adjacency_list: HashMap<Node, Vec<(Node, Cost)>> = HashMap::new();
let mut nodes = HashSet::new();

for &(source, destination, cost) in edge_list.iter() {
let destinations = adjacency_list.entry(source).or_insert_with(|| Vec::new());

destinations.push((destination, cost));
nodes.insert(source);
nodes.insert(destination);
}

Graph {
edges: adjacency_list,
nodes,
}
}
}

// #[derive(Clone, PartialEq, Eq)]
#[derive(Eq, PartialEq)]
struct Curr {
cost: Cost,
position: Node,
path: Vec<Node>,
}
impl Curr {
fn new(position: Node, cost: Cost, path: Vec<Node>) -> Self {
Curr {
cost,
position,
path,
}
}
fn new_start(start: Node) -> Self {
Curr {
cost: 0,
position: start,
path: vec![],
}
}
}


impl Ord for Curr {
fn cmp(&self, other: &Self) -> Ordering {
other
.cost
.cmp(&self.cost)
.then_with(|| self.position.cmp(&other.position))
}
}

impl PartialOrd for Curr {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}

fn shortest_path(g: &Graph, start: Node, goal: Node) -> Option<(Vec<Node>, Cost)> {
let mut priority_queue = BinaryHeap::new();
priority_queue.push(Curr::new_start(start));

let mut dist: HashMap<Node, Cost> = g
.nodes
.iter()
.map(|&x| if x == start { (x, 0) } else { (x, usize::MAX) })
.collect();

while let Some(Curr {
cost,
position,
mut path,
}) = priority_queue.pop()
{
if position == goal {
path.push(position);
return Some((path, cost));
}

// pq. push (cost+ currcost, start->next, path.add(start) )
// So iterate, through all the nodes of start node which are in g
// g[start]= Vec[node, cost]

if let Some(connected_nodes) = &g.edges.get(&position) {
for &(next_node, next_cost) in connected_nodes.iter() {
if next_cost < dist[&next_node] {
let mut next = Curr::new(next_node, cost + next_cost, path.clone());
next.path.push(position);
priority_queue.push(next);

if let Some(past_cost) = dist.get_mut(&next_node) {
*past_cost = next_cost;
}
}
}
}
}

None
}

fn main() {
let edge_list = include!("graph.in");
let g = Graph::from_edge_list(&edge_list);

if let Some((path, cost)) = shortest_path(&g, 1, 6) {
println!("Shortest distance from 1 to 6 is: , {path:?} {cost}");
};
}

#[test]
fn large_graph() {
let edge_list = include!("graph.in");
let g = Graph::from_edge_list(&edge_list);

let path = shortest_path(&g, 1, 6);
assert!(path.is_some());
assert_eq!(path.unwrap().1, 20);
}
28 changes: 28 additions & 0 deletions examples/dns/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# DNS Smart contract

The DNS smart contract is our showcase for decentralizing the Domain naming system.



> This contract compiles with ink! 4.0-beta version

Domain name service contract inspired by
[this blog post on medium](https://medium.com/@chainx_org/secure-and-decentralized-polkadot-domain-name-system-e06c35c2a48d).

### Description
The registration of a new Domain works by the function `register` defined in the contract which takes 2 parameters: name and hash. Client sends a request to the DNS system such as "polka.dot" which returns the resolver address as shown below. The "polka.dot" is resolved by mapping the it to a `hash value` from the function named `Get_address` in the `lib.rs` file.

<br>
<br>

![Image](images/dns_diagram.png)

## Functionalities provided:

- Registration of a new Domain Name
- Transfer the (already exsiting) owner to new Address
- Change the Domain Name




Binary file added examples/dns/images/dns_diagram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.