Add a star for shortest path
This commit is contained in:
parent
b96ef6f2c1
commit
b53d1e87bc
4 changed files with 65 additions and 19 deletions
|
|
@ -29,20 +29,20 @@ fn main() {
|
||||||
let l = ValidLayout {
|
let l = ValidLayout {
|
||||||
max_tries: 4,
|
max_tries: 4,
|
||||||
retries: 4,
|
retries: 4,
|
||||||
start_size: Position::new(128, 128),
|
start_size: Position::new(256, 256),
|
||||||
growth: Position::new(16, 16),
|
growth: Position::new(16, 16),
|
||||||
};
|
};
|
||||||
|
|
||||||
let l = GeneticAlgorithm {
|
let l = GeneticAlgorithm {
|
||||||
mutation_retries: 20,
|
mutation_retries: 20,
|
||||||
population_size: 40,
|
population_size: 5,
|
||||||
population_keep: 8,
|
population_keep: 8,
|
||||||
population_new: 2,
|
population_new: 2,
|
||||||
generations: 40,
|
generations: 5,
|
||||||
valid_layout: l,
|
valid_layout: l,
|
||||||
};
|
};
|
||||||
let p = ConflictAvoidance {
|
let p = ConflictAvoidance {
|
||||||
timeout: Some(std::time::Duration::from_millis(20)),
|
timeout: Some(std::time::Duration::from_millis(100)),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut rng = SmallRng::seed_from_u64(args.seed);
|
let mut rng = SmallRng::seed_from_u64(args.seed);
|
||||||
|
|
|
||||||
|
|
@ -90,14 +90,14 @@ pub fn generate_factory<L: Layouter, P: Pathfinder>(
|
||||||
input_connections.first_chunk()
|
input_connections.first_chunk()
|
||||||
{
|
{
|
||||||
let c0_bigger = c0.amount > c1.amount + c2.amount;
|
let c0_bigger = c0.amount > c1.amount + c2.amount;
|
||||||
intermediate_connections.push(dbg!((
|
intermediate_connections.push((
|
||||||
HashMap::from([
|
HashMap::from([
|
||||||
(connection_id0, (block_index, if c0_bigger { 1 } else { 0 })),
|
(connection_id0, (block_index, if c0_bigger { 1 } else { 0 })),
|
||||||
(connection_id1, (block_index + 1, 0)),
|
(connection_id1, (block_index + 1, 0)),
|
||||||
(connection_id2, (block_index + 1, 1)),
|
(connection_id2, (block_index + 1, 1)),
|
||||||
]),
|
]),
|
||||||
intermediate_output_connection,
|
intermediate_output_connection,
|
||||||
)));
|
));
|
||||||
|
|
||||||
let beltspeed =
|
let beltspeed =
|
||||||
Beltspeed::from_items_per_second(2.0 * f64::max(c1.amount, c2.amount));
|
Beltspeed::from_items_per_second(2.0 * f64::max(c1.amount, c2.amount));
|
||||||
|
|
@ -144,13 +144,13 @@ pub fn generate_factory<L: Layouter, P: Pathfinder>(
|
||||||
} else if let Some(&[(connection_id0, c0), (connection_id1, c1)]) =
|
} else if let Some(&[(connection_id0, c0), (connection_id1, c1)]) =
|
||||||
input_connections.first_chunk()
|
input_connections.first_chunk()
|
||||||
{
|
{
|
||||||
intermediate_connections.push(dbg!((
|
intermediate_connections.push((
|
||||||
HashMap::from([
|
HashMap::from([
|
||||||
(connection_id0, (block_index, 0)),
|
(connection_id0, (block_index, 0)),
|
||||||
(connection_id1, (block_index, 1)),
|
(connection_id1, (block_index, 1)),
|
||||||
]),
|
]),
|
||||||
intermediate_output_connection,
|
intermediate_output_connection,
|
||||||
)));
|
));
|
||||||
(
|
(
|
||||||
Beltspeed::from_items_per_second(c0.amount),
|
Beltspeed::from_items_per_second(c0.amount),
|
||||||
Some(Beltspeed::from_items_per_second(c1.amount)),
|
Some(Beltspeed::from_items_per_second(c1.amount)),
|
||||||
|
|
@ -201,17 +201,18 @@ pub fn generate_factory<L: Layouter, P: Pathfinder>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Building::ExternalConnection { inputs, outputs } => {
|
Building::ExternalConnection { inputs, outputs } => {
|
||||||
|
let step = 4;
|
||||||
blocks.push(MacroBlock {
|
blocks.push(MacroBlock {
|
||||||
size: Position::new(1, (inputs + outputs) as PositionType),
|
size: Position::new(1, step * (inputs + outputs) as PositionType),
|
||||||
input: (0..*inputs)
|
input: (0..*inputs)
|
||||||
.map(|y| Interface {
|
.map(|y| Interface {
|
||||||
offset: Position::new(0, y as PositionType),
|
offset: Position::new(0, step * y as PositionType),
|
||||||
dir: Direction::Left,
|
dir: Direction::Left,
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
output: (0..*outputs)
|
output: (0..*outputs)
|
||||||
.map(|y| Interface {
|
.map(|y| Interface {
|
||||||
offset: Position::new(0, (inputs + y) as PositionType),
|
offset: Position::new(0, step * (inputs + y) as PositionType),
|
||||||
dir: Direction::Right,
|
dir: Direction::Right,
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
|
|
@ -279,7 +280,12 @@ pub fn generate_factory<L: Layouter, P: Pathfinder>(
|
||||||
let mut blueprint = Blueprint::new();
|
let mut blueprint = Blueprint::new();
|
||||||
blueprint.add_entity(Entity::new_splitter(
|
blueprint.add_entity(Entity::new_splitter(
|
||||||
Beltspeed::from_items_per_second(
|
Beltspeed::from_items_per_second(
|
||||||
input_connections.iter().map(|&(_, c)| c.amount).sum(),
|
input_connections
|
||||||
|
.iter()
|
||||||
|
.chain(output_connections.iter())
|
||||||
|
.map(|&(_, c)| c.amount)
|
||||||
|
.max_by(|x, y| x.partial_cmp(y).unwrap())
|
||||||
|
.unwrap_or(1.0),
|
||||||
),
|
),
|
||||||
Position::new(2, 1),
|
Position::new(2, 1),
|
||||||
Direction::Up,
|
Direction::Up,
|
||||||
|
|
@ -324,10 +330,10 @@ pub fn generate_factory<L: Layouter, P: Pathfinder>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbg!(&intermediate_connections);
|
// dbg!(&intermediate_connections);
|
||||||
|
|
||||||
for (i, c) in factory_graph.factory_connections.iter().enumerate() {
|
for (i, c) in factory_graph.factory_connections.iter().enumerate() {
|
||||||
dbg!(i, c);
|
// dbg!(i, c);
|
||||||
connections.push(Connection {
|
connections.push(Connection {
|
||||||
startblock: intermediate_connections[c.from].1[&i].0,
|
startblock: intermediate_connections[c.from].1[&i].0,
|
||||||
startpoint: intermediate_connections[c.from].1[&i].1,
|
startpoint: intermediate_connections[c.from].1[&i].1,
|
||||||
|
|
@ -338,8 +344,8 @@ pub fn generate_factory<L: Layouter, P: Pathfinder>(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg!(&blocks);
|
// dbg!(&blocks);
|
||||||
dbg!(&connections);
|
// dbg!(&connections);
|
||||||
|
|
||||||
let layout_input = LayoutInput {
|
let layout_input = LayoutInput {
|
||||||
blocks,
|
blocks,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::examples::HashMapMap;
|
use crate::examples::HashMapMap;
|
||||||
|
use crate::graph::wheighted_graph::shortest_path::a_star;
|
||||||
use crate::graph::wheighted_graph::WheightedGraph;
|
use crate::graph::wheighted_graph::WheightedGraph;
|
||||||
use crate::misc::Map;
|
use crate::misc::Map;
|
||||||
use crate::priority_queue::binary_heap::BinaryHeap;
|
use crate::priority_queue::binary_heap::BinaryHeap;
|
||||||
|
|
@ -107,7 +108,7 @@ impl Problem {
|
||||||
let mut weight = 0.0;
|
let mut weight = 0.0;
|
||||||
|
|
||||||
if self.map.get(x, y).blocked {
|
if self.map.get(x, y).blocked {
|
||||||
weight += 100.0;
|
weight += 10000.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.map.get_mut(x, y).weight = weight;
|
self.map.get_mut(x, y).weight = weight;
|
||||||
|
|
@ -117,7 +118,7 @@ impl Problem {
|
||||||
for (i, path) in self.path.iter().enumerate() {
|
for (i, path) in self.path.iter().enumerate() {
|
||||||
if i != without {
|
if i != without {
|
||||||
for p in path {
|
for p in path {
|
||||||
let weight = 10.0;
|
let weight = 1000.0;
|
||||||
let x = p.0.x as usize;
|
let x = p.0.x as usize;
|
||||||
let y = p.0.y as usize;
|
let y = p.0.y as usize;
|
||||||
|
|
||||||
|
|
@ -269,7 +270,17 @@ impl Problem {
|
||||||
map: &self.map,
|
map: &self.map,
|
||||||
end: self.end[i],
|
end: self.end[i],
|
||||||
};
|
};
|
||||||
let p = dijkstra::<MapInternal, FastBinaryHeap<_>>(&m, self.start[i], self.end[i]);
|
// let p = dijkstra::<MapInternal, FastBinaryHeap<_>>(&m, self.start[i], self.end[i]);
|
||||||
|
let p = a_star::<MapInternal, FastBinaryHeap<_>, _>(
|
||||||
|
&m,
|
||||||
|
self.start[i],
|
||||||
|
self.end[i],
|
||||||
|
|&(p, _)| {
|
||||||
|
1.5 * (PositionType::abs_diff(p.x, self.end[i].0.x)
|
||||||
|
+ PositionType::abs_diff(p.y, self.end[i].0.y))
|
||||||
|
as f64
|
||||||
|
},
|
||||||
|
);
|
||||||
if let Some(p) = p {
|
if let Some(p) = p {
|
||||||
self.path[i] = p;
|
self.path[i] = p;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,35 @@ where
|
||||||
Some(result)
|
Some(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct GraphWrapper<'a, G, F> {
|
||||||
|
g: &'a G,
|
||||||
|
f: F,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<G: WheightedGraph, F: Fn(&G::Node) -> f64> WheightedGraph for GraphWrapper<'_, G, F> {
|
||||||
|
type Node = G::Node;
|
||||||
|
|
||||||
|
fn edge(&self, node: &Self::Node, num: usize) -> Option<(Self::Node, f64)> {
|
||||||
|
self.g.edge(node, num).map(|(n, s)| {
|
||||||
|
let s = s - (self.f)(node) + (self.f)(&n);
|
||||||
|
(n, s)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn a_star<G, P, F>(graph: &G, start: G::Node, end: G::Node, dist: F) -> Option<Vec<G::Node>>
|
||||||
|
where
|
||||||
|
P: PriorityQueue<QueueObject<G::Node>> + Debug,
|
||||||
|
P::Handle: Debug,
|
||||||
|
G::Node: Eq + Hash + Clone + Debug,
|
||||||
|
G: WheightedGraph,
|
||||||
|
F: Fn(&G::Node) -> f64,
|
||||||
|
{
|
||||||
|
let g = GraphWrapper { g: graph, f: dist };
|
||||||
|
|
||||||
|
dijkstra::<GraphWrapper<G, F>, P>(&g, start, end)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue