add steiner tree solver based on shortest path
This commit is contained in:
parent
5d7668573a
commit
db7e0173c4
1 changed files with 87 additions and 6 deletions
|
@ -17,10 +17,14 @@ use {
|
|||
pub struct SteinerTree {
|
||||
weight: u64,
|
||||
goals: Vec< TypeTerm >,
|
||||
pub edges: Vec< MorphismType >,
|
||||
edges: Vec< MorphismType >,
|
||||
}
|
||||
|
||||
impl SteinerTree {
|
||||
pub fn into_edges(self) -> Vec< MorphismType > {
|
||||
self.edges
|
||||
}
|
||||
|
||||
fn add_edge(&mut self, ty: MorphismType) {
|
||||
self.weight += 1;
|
||||
|
||||
|
@ -71,6 +75,72 @@ impl SteinerTree {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
pub struct PathApproxSteinerTreeSolver {
|
||||
root: TypeTerm,
|
||||
leaves: Vec< TypeTerm >
|
||||
}
|
||||
|
||||
impl PathApproxSteinerTreeSolver {
|
||||
pub fn new(
|
||||
root: TypeTerm,
|
||||
leaves: Vec<TypeTerm>
|
||||
) -> Self {
|
||||
PathApproxSteinerTreeSolver {
|
||||
root, leaves
|
||||
}
|
||||
}
|
||||
|
||||
pub fn solve<M: Morphism + Clone>(self, morphisms: &MorphismBase<M>) -> Option< SteinerTree > {
|
||||
let mut tree = Vec::<MorphismType>::new();
|
||||
|
||||
for goal in self.leaves {
|
||||
// try to find shortest path from root to current leaf
|
||||
if let Some(new_path) = morphisms.find_morphism_path(
|
||||
MorphismType {
|
||||
src_type: self.root.clone(),
|
||||
dst_type: goal.clone()
|
||||
}
|
||||
) {
|
||||
// reduce new path so that it does not collide with any existing path
|
||||
let mut src_type = self.root.clone();
|
||||
let mut new_path_iter = new_path.into_iter().peekable();
|
||||
|
||||
// check all existing nodes..
|
||||
for mt in tree.iter() {
|
||||
// assert!( mt.src_type == &src_type );
|
||||
if let Some(t) = new_path_iter.peek() {
|
||||
if &mt.dst_type == t {
|
||||
// eliminate this node from new path
|
||||
src_type = new_path_iter.next().unwrap().clone();
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for dst_type in new_path_iter {
|
||||
tree.push(MorphismType {
|
||||
src_type: src_type.clone(),
|
||||
dst_type: dst_type.clone()
|
||||
});
|
||||
src_type = dst_type;
|
||||
}
|
||||
} else {
|
||||
eprintln!("could not find path\nfrom {:?}\nto {:?}", &self.root, &goal);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
Some(SteinerTree {
|
||||
weight: 0,
|
||||
goals: vec![],
|
||||
edges: tree
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* given a representation tree with the available
|
||||
* represenatations `src_types`, try to find
|
||||
* a sequence of morphisms that span up all
|
||||
|
@ -122,8 +192,15 @@ impl SteinerTreeProblem {
|
|||
);
|
||||
self.queue.pop()
|
||||
}
|
||||
/*
|
||||
pub fn solve_approx_path<M: Morphism + Clone>(&mut self, morphisms: &MorphismBase<M>) -> Option< SteinerTree > {
|
||||
if let Some(master) = self.src_types.first() {
|
||||
|
||||
pub fn solve_bfs<M: Morphism + Clone>(&mut self, dict: &crate::dict::TypeDict, morphisms: &MorphismBase<M>) -> Option< SteinerTree > {
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
pub fn solve_bfs<M: Morphism + Clone>(&mut self, morphisms: &MorphismBase<M>) -> Option< SteinerTree > {
|
||||
|
||||
// take the currently smallest tree and extend it by one step
|
||||
while let Some( mut current_tree ) = self.next() {
|
||||
|
@ -140,16 +217,20 @@ impl SteinerTreeProblem {
|
|||
}
|
||||
|
||||
// extend the tree by one edge and add it to the queue
|
||||
for src_type in current_nodes.iter() {
|
||||
for src_type in current_nodes {
|
||||
for (dst_halo,dst_ty) in morphisms.enum_morphisms_with_subtyping( &src_type ) {
|
||||
let dst_type = TypeTerm::Ladder(vec![
|
||||
dst_halo, dst_ty
|
||||
]).normalize();
|
||||
|
||||
if !current_nodes.contains( &dst_type ) {
|
||||
if current_tree.contains( &dst_type ).is_none() {
|
||||
let mut new_tree = current_tree.clone();
|
||||
let src_type = src_type.clone();
|
||||
new_tree.add_edge(MorphismType { src_type, dst_type }.normalize());
|
||||
{
|
||||
let src_type = src_type.clone();
|
||||
let dst_type = dst_type.clone();
|
||||
new_tree.add_edge(MorphismType { src_type, dst_type }.normalize());
|
||||
}
|
||||
|
||||
self.queue.push( new_tree );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue