diff --git a/lab5/zad1/src/main.rs b/lab5/zad1/src/main.rs index e144123..ff985a3 100644 --- a/lab5/zad1/src/main.rs +++ b/lab5/zad1/src/main.rs @@ -42,19 +42,24 @@ impl Ord for Edge { pub struct Graph { pub size: usize, - pub edges: Vec, + pub edges: Vec>, } impl Graph { pub fn new(size: usize) -> Self { Self { size, - edges: (0..size).map(|u| - (0..size).map(|v| - Edge { src: u, dst: v, weight: 0.0 } - ).collect::>() - ).flatten() - .collect::>(), + // edges: (0..size).map(|u| + // (0..size).map(|v| + // Edge { src: u, dst: v, weight: 0.0 } + // ).collect::>() + // ).flatten() + // .collect::>(), + edges: (0..size) + .map(|_| (0..size) + .map(|_| 0.0) + .collect::>()) + .collect::>(), } } @@ -63,112 +68,71 @@ impl Graph { size, edges: (0..size).map(|u| (0..size).map(|v| - Edge { - src: u, - dst: v, - weight: if u == v { 0.0 } - else { thread_rng().gen::() } - } - ).collect::>() - ).flatten() + if u == v { 0.0 } + else { thread_rng().gen::() } + ).collect::>()) .collect::>(), } } - pub fn vertex(&self, u: usize, v: usize) -> Option { - if u >= self.size || v >= self.size { - return None; - } - - Some(self.edges.iter().find(|e| e.src == u && e.dst == v).unwrap().weight) + pub fn edges(&self) -> Vec { + (0..self.size) + .map(|i| + (0..self.size) + .map(|j| Edge { + src: i, + dst: j, + weight: self.edges[i][j], + }) + .collect::>() + ) + .flatten() + .collect::>() } pub fn prim(&self) -> Vec { - // Associate with each vertex v of the graph a number C[v] (the cheapest cost of a connection to v) and an edge E[v] (the edge providing that cheapest connection). To initialize these values, set all values of C[v] to +∞ (or to any number larger than the maximum edge weight) and set each E[v] to a special flag value indicating that there is no edge connecting v to earlier vertices. - let mut min_edges = (0..self.size) - .map(|i| - *self.edges.iter() - .filter(|e| (e.src == i || e.dst == i) && e.src != e.dst) - .min() - .unwrap() - ).collect::>(); - // dbg!(&min_edges); + let mut parent = vec![0; self.size]; - // helper struct for the queue - #[derive(Clone, Debug)] - struct Vertex { - index: usize, - min_weight: f64, - } + let mut key = vec![f64::INFINITY; self.size]; - impl Hash for Vertex { - fn hash(&self, state: &mut H) { - self.index.hash(state); - } - } + let mut mst_set = vec![false; self.size]; - impl PartialEq for Vertex { - fn eq(&self, other: &Self) -> bool { - self.min_weight == other.min_weight - } - } + key[0] = 0.0; + parent[0] = usize::MAX; - impl Eq for Vertex {} + for _ in 0..(self.size - 1) { + let u = { + let mut min_index = 0; + let mut min = f64::MAX; - impl PartialOrd for Vertex { - fn partial_cmp(&self, other: &Self) -> Option { - self.min_weight.partial_cmp(&other.min_weight) - } - } + for k in 0..self.size { + if mst_set[k] == false && key[k] < min { + min = key[k]; + min_index = k; + } + } - impl Ord for Vertex { - fn cmp(&self, other: &Self) -> Ordering { - self.min_weight.total_cmp(&other.min_weight) - } - } + min_index + }; - // Initialize an empty forest F - let mut forest = vec![]; - // and a set Q of vertices - let mut queue = BinaryHeap::>::new(); + mst_set[u] = true; - // that have not yet been included in F (initially, all vertices). - (0..self.size) - .map(|i| Vertex { index: i, min_weight: min_edges[i].weight }) - .for_each(|v| queue.push(Reverse(v))); - - // Repeat the following steps until Q is empty: - // Find and remove a vertex v from Q having the minimum possible value of C[v] - while let Some(Reverse(v)) = queue.pop() { - // Add v to F - forest.push(v.clone()); - - // Loop over the edges vw connecting v to other vertices w. - for vw in self.edges.iter() - .filter(|e| (e.src == v.index || e.dst == v.index) && e.src != e.dst) { - - // the vertex in the current edge that isn't v.src - let w = if vw.src == v.index { vw.dst } else { vw.src }; - - // For each such edge, if w still belongs to Q and vw has smaller weight than C[w], perform the following steps: - if queue.clone().iter().any(|Reverse(e)| e.index == w || e.index == w) && vw.weight < min_edges[w].weight { - dbg!(&w); - // Set C[w] to the cost of edge vw - // Set E[w] to point to edge vw. - min_edges[w] = *vw; + for v in 0..self.size { + let w = self.edges[u][v]; + if u != v && mst_set[v] == false && w < key[v] { + parent[v] = u; + key[v] = w; } } } - // dbg!(&min_edges); - // Return F, which specifically includes the corresponding edges in E - forest.iter() - .map(|i| min_edges[i.index]) - // deduplication - .collect::>() - .iter() - .map(|e| *e) - .collect::>() + (1..self.size) + .map(|i| Edge { + src: parent[i], + dst: i, + weight: self.edges[i][parent[i]], + }) + .collect() } fn find_id(belongs: &mut Vec, i: usize) -> usize { @@ -194,7 +158,8 @@ impl Graph { } pub fn kruskal(&self) -> Vec { - let mut edges = self.edges.iter() + let edges = self.edges(); + let mut edges = edges.iter() .filter(|e| e.weight != 0.0) .collect::>(); @@ -224,7 +189,7 @@ impl Display for Graph { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { for i in 0..self.size { for j in 0..self.size { - write!(f, "{weight:.6} ", weight = self.vertex(i, j).unwrap())?; + write!(f, "{weight:.6} ", weight = self.edges[i][j])?; } write!(f, "\n")?; }