返回哈希表中所有连接到petgraph的组件

返回哈希表中所有连接到petgraph的组件,graph,rust,connected-components,petgraph,Graph,Rust,Connected Components,Petgraph,我正在使用petgraph,我想提取连接的组件 我想要一个HashMap u32作为连接组件的标识符,Vec作为容器,引用连接组件中的所有节点 如果这是一个糟糕的设计,不要犹豫,指出一个更好的;我是个铁锈初学者 我试过这样的方法: extern crate fnv; extern crate petgraph; use petgraph::visit::Dfs; use fnv::FnvHashMap; // a faster hash for small key use fnv::FnvH

我正在使用petgraph,我想提取连接的组件

我想要一个HashMap u32作为连接组件的标识符,Vec作为容器,引用连接组件中的所有节点

如果这是一个糟糕的设计,不要犹豫,指出一个更好的;我是个铁锈初学者

我试过这样的方法:

extern crate fnv;
extern crate petgraph;

use petgraph::visit::Dfs;

use fnv::FnvHashMap; // a faster hash for small key
use fnv::FnvHashSet;


// structure definition
pub struct NodeAttr {
    pub name_real: String,
}

impl Default for NodeAttr {
    fn default() -> Self {
        NodeAttr {
            name_real: "default_name_for_testing".to_string(),
        }
    }
}


pub struct EdgesAttr {
    pub eval: f64,
    pub pid: f32,
    pub cov: f32, // minimum coverage
}

impl Default for EdgesAttr {
    fn default() -> Self {
        EdgesAttr {
            eval: 0.0,
            pid: 100.0,
            cov: 100.0,
        }
    }
}

pub fn cc_dfs<'a>(
    myGraph: &petgraph::Graph<NodeAttr, EdgesAttr, petgraph::Undirected>,
) -> FnvHashMap<u32, Vec<&'a petgraph::graph::NodeIndex>> {
    let mut already_visited = FnvHashSet::<&petgraph::graph::NodeIndex>::default();
    let mut map_real_index: FnvHashMap<u32, Vec<&petgraph::graph::NodeIndex>> =
        FnvHashMap::with_capacity_and_hasher(myGraph.node_count(), Default::default());

    let mut cpt = 0;

    for current_node_indice in myGraph.node_indices() {
        let mut current_vec: Vec<&petgraph::graph::NodeIndex> = Vec::new();
        if already_visited.contains(&current_node_indice) {
            continue;
        }
        let mut dfs = Dfs::new(&myGraph, current_node_indice);
        while let Some(nx) = dfs.next(&myGraph) {
            // the problem is around here
            // I believe the just assigned nx live only for the while
            //But it should live for the upper for loop. What to do?
            current_vec.push(&nx);
            already_visited.insert(&nx);
        }
        map_real_index.insert(cpt, current_vec);
        cpt = cpt + 1
    }

    return map_real_index;
}

fn main() {}
出现编译器错误时:

错误[E0597]:`nx`的寿命不够长 ->src/main.rs:59:31 | 59 |当前向量推送&nx; |^^^活得不够长 60 |已访问。插入&nx; 61 | } |-借来的价值仅在此处有效 | 注意:借用值必须在函数体上定义的生命周期“a”内以40:1有效。。。 ->src/main.rs:40:1 | 40 |/pub fn cc|u dfs>{ 43 | |让mut已经访问=FnvHashSet:::默认值; ... | 66 | |返回地图|真实|索引; 67 | | } | |_^ 错误[E0597]:`nx`的寿命不够长 ->src/main.rs:61:9 | 60 |已访问。插入&nx; |-借用发生在这里 61 | } |^`nx`在仍然借来的时候掉到了这里 ... 67 | } |-借来的价值需要一直存在到这里 我在向量中克隆了节点索引,这很有效:

current_vec.push(nx.clone()); // instead of (&nx)
already_visited.insert(nx.clone());`

我可能错误地认为使用引用比复制更有效。

这段小得多的代码也存在同样的问题:

在您的原始代码中,修复也不例外

// nit: "indices" is the plural of "index"; there is no singular word "indice"
for current_node_index in myGraph.node_indices() {
    // actually you don't need to supply a type here, but if you did...
    let mut current_vec: Vec<petgraph::graph::NodeIndex> = Vec::new();
    if already_visited.contains(&current_node_index) {
        continue;
    }
    let mut dfs = Dfs::new(&myGraph, current_node_index);
    while let Some(nx) = dfs.next(&myGraph) {
        current_vec.push(nx);
        //               ^-----v- Look Ma, no &s!
        already_visited.insert(nx);
    }
    map_real_index.insert(cpt, current_vec);
    cpt = cpt + 1
}
NodeIndex只是一个Ix,如果您只查找u32的别名。在64位PC上,它实际上比您试图存储的指针要小,而在Rust中,您不需要为使用它支付任何额外费用-在运行时,它实际上只是一个u32


方便的是,当Ix是Copy时,您甚至不需要添加额外的.clone;您只需执行current_vec.pushnx,然后执行ready_visted.insertnx,就像我前面所做的那样。但即使您确实编写了.clone,您也不需要为此支付运行时成本;这是不必要的。

这段小得多的代码也存在同样的问题:

在您的原始代码中,修复也不例外

// nit: "indices" is the plural of "index"; there is no singular word "indice"
for current_node_index in myGraph.node_indices() {
    // actually you don't need to supply a type here, but if you did...
    let mut current_vec: Vec<petgraph::graph::NodeIndex> = Vec::new();
    if already_visited.contains(&current_node_index) {
        continue;
    }
    let mut dfs = Dfs::new(&myGraph, current_node_index);
    while let Some(nx) = dfs.next(&myGraph) {
        current_vec.push(nx);
        //               ^-----v- Look Ma, no &s!
        already_visited.insert(nx);
    }
    map_real_index.insert(cpt, current_vec);
    cpt = cpt + 1
}
NodeIndex只是一个Ix,如果您只查找u32的别名。在64位PC上,它实际上比您试图存储的指针要小,而在Rust中,您不需要为使用它支付任何额外费用-在运行时,它实际上只是一个u32


方便的是,当Ix是Copy时,您甚至不需要添加额外的.clone;您只需执行current_vec.pushnx,然后执行ready_visted.insertnx,就像我前面所做的那样。但即使您确实编写了.clone,您也不需要为此支付运行时成本;这是不必要的。

此问题的性质与搜索非常相似,或者任何数量的类似搜索都不会持续足够长的时间。此问题的性质与搜索非常相似,或者任何数量的类似搜索都不会持续足够长的时间。
    v.push(nx)
// nit: "indices" is the plural of "index"; there is no singular word "indice"
for current_node_index in myGraph.node_indices() {
    // actually you don't need to supply a type here, but if you did...
    let mut current_vec: Vec<petgraph::graph::NodeIndex> = Vec::new();
    if already_visited.contains(&current_node_index) {
        continue;
    }
    let mut dfs = Dfs::new(&myGraph, current_node_index);
    while let Some(nx) = dfs.next(&myGraph) {
        current_vec.push(nx);
        //               ^-----v- Look Ma, no &s!
        already_visited.insert(nx);
    }
    map_real_index.insert(cpt, current_vec);
    cpt = cpt + 1
}
pub struct NodeIndex<Ix=DefaultIx>(Ix);