still broken !
This commit is contained in:
parent
9c9b46d31d
commit
6f1a45c954
1 changed files with 61 additions and 96 deletions
|
@ -42,19 +42,24 @@ impl Ord for Edge {
|
|||
|
||||
pub struct Graph {
|
||||
pub size: usize,
|
||||
pub edges: Vec<Edge>,
|
||||
pub edges: Vec<Vec<f64>>,
|
||||
}
|
||||
|
||||
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::<Vec<_>>()
|
||||
).flatten()
|
||||
.collect::<Vec<_>>(),
|
||||
// edges: (0..size).map(|u|
|
||||
// (0..size).map(|v|
|
||||
// Edge { src: u, dst: v, weight: 0.0 }
|
||||
// ).collect::<Vec<_>>()
|
||||
// ).flatten()
|
||||
// .collect::<Vec<_>>(),
|
||||
edges: (0..size)
|
||||
.map(|_| (0..size)
|
||||
.map(|_| 0.0)
|
||||
.collect::<Vec<_>>())
|
||||
.collect::<Vec<_>>(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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::<f64>() }
|
||||
}
|
||||
).collect::<Vec<_>>()
|
||||
).flatten()
|
||||
if u == v { 0.0 }
|
||||
else { thread_rng().gen::<f64>() }
|
||||
).collect::<Vec<_>>())
|
||||
.collect::<Vec<_>>(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vertex(&self, u: usize, v: usize) -> Option<f64> {
|
||||
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<Edge> {
|
||||
(0..self.size)
|
||||
.map(|i|
|
||||
(0..self.size)
|
||||
.map(|j| Edge {
|
||||
src: i,
|
||||
dst: j,
|
||||
weight: self.edges[i][j],
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
)
|
||||
.flatten()
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
pub fn prim(&self) -> Vec<Edge> {
|
||||
// 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::<Vec<_>>();
|
||||
// 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<H: std::hash::Hasher>(&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<Ordering> {
|
||||
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::<Reverse<Vertex>>::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::<HashSet<_>>()
|
||||
.iter()
|
||||
.map(|e| *e)
|
||||
.collect::<Vec<_>>()
|
||||
(1..self.size)
|
||||
.map(|i| Edge {
|
||||
src: parent[i],
|
||||
dst: i,
|
||||
weight: self.edges[i][parent[i]],
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn find_id(belongs: &mut Vec<usize>, i: usize) -> usize {
|
||||
|
@ -194,7 +158,8 @@ impl Graph {
|
|||
}
|
||||
|
||||
pub fn kruskal(&self) -> Vec<Edge> {
|
||||
let mut edges = self.edges.iter()
|
||||
let edges = self.edges();
|
||||
let mut edges = edges.iter()
|
||||
.filter(|e| e.weight != 0.0)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
|
@ -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")?;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue