Add initial automatic roboport placement
This commit is contained in:
parent
1680fef14d
commit
caea696dd7
6 changed files with 203 additions and 1 deletions
|
|
@ -1,2 +1,3 @@
|
|||
pub mod priority_queue;
|
||||
pub mod set_cover;
|
||||
pub mod wheighted_graph;
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ where
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::PriorityQueue;
|
||||
use super::binary_heap::{BinaryHeap, FastBinaryHeap};
|
||||
use super::fibonacci_heap::FibonacciHeap;
|
||||
use super::PriorityQueue;
|
||||
|
||||
macro_rules! test_generics {
|
||||
($($fun_mul:ident )+ ; $gen:ident $($gen_mul:ident)+) => {
|
||||
|
|
|
|||
141
factorio-graph/src/set_cover.rs
Normal file
141
factorio-graph/src/set_cover.rs
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use crate::priority_queue::PriorityQueue;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct SetUncovered {
|
||||
setIndex: usize,
|
||||
uncoveredElements: usize,
|
||||
}
|
||||
|
||||
impl PartialEq for SetUncovered {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.uncoveredElements.eq(&other.uncoveredElements)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for SetUncovered {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
self.uncoveredElements
|
||||
.partial_cmp(&other.uncoveredElements)
|
||||
.map(|o| o.reverse())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn greedy_set_cover_simple<S>(universe: usize, sets: &[S]) -> Vec<usize>
|
||||
where
|
||||
S: Deref<Target = [usize]>,
|
||||
{
|
||||
assert!(sets.len() > 0);
|
||||
|
||||
let mut r = Vec::new();
|
||||
|
||||
let mut covered = vec![false; universe];
|
||||
let mut covered_count = 0;
|
||||
|
||||
while covered_count < universe {
|
||||
let i = sets
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(i, _)| !r.contains(i))
|
||||
.max_by_key(|&(_, s)| s.iter().filter(|&&e| !covered[e]).count())
|
||||
.unwrap()
|
||||
.0;
|
||||
|
||||
r.push(i);
|
||||
|
||||
for &e in sets[i].deref() {
|
||||
if !covered[e] {
|
||||
covered_count += 1;
|
||||
covered[e] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r
|
||||
}
|
||||
|
||||
pub fn greedy_set_cover_priority_queue<S, P>(universe: usize, sets: &[S]) -> Vec<usize>
|
||||
where
|
||||
S: Deref<Target = [usize]>,
|
||||
P: PriorityQueue<SetUncovered>,
|
||||
{
|
||||
let mut covered = vec![false; universe];
|
||||
let mut covered_count = 0;
|
||||
|
||||
let mut p = P::new();
|
||||
|
||||
let mut handles = sets
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, s)| {
|
||||
Some(p.insert(SetUncovered {
|
||||
setIndex: i,
|
||||
uncoveredElements: s.len(),
|
||||
}))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut r = Vec::new();
|
||||
|
||||
while covered_count < universe {
|
||||
let SetUncovered {
|
||||
setIndex: i,
|
||||
uncoveredElements: _,
|
||||
} = p.pop_min().unwrap();
|
||||
|
||||
r.push(i);
|
||||
handles[i] = None;
|
||||
|
||||
for (h, s) in handles
|
||||
.iter()
|
||||
.zip(sets.iter())
|
||||
.filter_map(|(h, s)| h.as_ref().map(|h| (h, s)))
|
||||
{
|
||||
let mut decrease = 0;
|
||||
for &e in sets[i].deref() {
|
||||
if !covered[e] && s.contains(&e) {
|
||||
decrease += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// dbg!(decrease, i, s.deref());
|
||||
p.decrease_key(h, |e| e.uncoveredElements -= decrease);
|
||||
}
|
||||
|
||||
for &e in sets[i].deref() {
|
||||
if !covered[e] {
|
||||
covered_count += 1;
|
||||
covered[e] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::{
|
||||
priority_queue::binary_heap::FastBinaryHeap, set_cover::greedy_set_cover_priority_queue,
|
||||
};
|
||||
|
||||
use super::greedy_set_cover_simple;
|
||||
|
||||
#[test]
|
||||
fn wikipedia() {
|
||||
let u = 5;
|
||||
|
||||
let s = vec![vec![0, 1, 2], vec![1, 3], vec![2, 3], vec![3, 4]];
|
||||
|
||||
let mut r = greedy_set_cover_simple::<_>(u, &s);
|
||||
|
||||
r.sort();
|
||||
|
||||
assert_eq!(&r, &[0, 3]);
|
||||
|
||||
let mut r2 = greedy_set_cover_priority_queue::<_, FastBinaryHeap<_>>(u, &s);
|
||||
r2.sort();
|
||||
assert_eq!(&r, &r2);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue