Rust 如何修改过滤后的Petgraph图的边权重?

Rust 如何修改过滤后的Petgraph图的边权重?,rust,borrow-checker,petgraph,Rust,Borrow Checker,Petgraph,我正在为图形使用边过滤器,并希望更新边权重: 使用petgraph::prelude::*; 使用petgraph::graph; 使用petgraph::Visite:{Dfs,EdgeFiltered,IntoEdge}; fn过滤器_边(边:图形::边引用)->bool{ 匹配边。权重(){ 0=>true, _=>错误, } } fn main(){ 让mut-graph:graph::graph=graph::graph::new(); 设a=graph.add_节点(1); 设b=图

我正在为图形使用边过滤器,并希望更新边权重:

使用petgraph::prelude::*;
使用petgraph::graph;
使用petgraph::Visite:{Dfs,EdgeFiltered,IntoEdge};
fn过滤器_边(边:图形::边引用)->bool{
匹配边。权重(){
0=>true,
_=>错误,
}
}
fn main(){
让mut-graph:graph::graph=graph::graph::new();
设a=graph.add_节点(1);
设b=图。添加_节点(2);
设e=图,加上边(a,b,0);
设mut filtered_graph=EdgeFiltered::from_fn(&graph,filter_edges);
让mut dfs=dfs::new(&filtered_图,a);
而让一些(节点索引)=dfs.next(&filtered\u图){
用于过滤图中的边。边(节点索引){
过滤的_图。更新_边(edge.source(),edge.target(),1);
//graph.update_edge(edge.source(),edge.target(),1);
}
}
}
但此错误是因为
edgefilted
没有
update\u edge
功能:

error[E0599]: no method named `update_edge` found for struct `EdgeFiltered<&Graph<u32, u32>, for<'r> fn(petgraph::graph::EdgeReference<'r, u32>) -> bool {filter_edges}>` in the current scope
  --> src/main.rs:22:28
   |
22 |             filtered_graph.update_edge(edge.source(), edge.target(), 1);
   |                            ^^^^^^^^^^^ method not found in `EdgeFiltered<&Graph<u32, u32>, for<'r> fn(petgraph::graph::EdgeReference<'r, u32>) -> bool {filter_edges}>`


edgefilted
是非常小的,并且似乎没有任何用于可变图形操作的东西。Petgraph附带的东西有什么方法可以做到这一点,或者我必须编写自己版本的
update\u edge
showhow吗?

FilteredGraph
借用了
Graph
,因此只要
FilteredGraph
存在,就无法获得对
Graph
的可变引用

您可以在每个
dfs.next()
调用上重新创建一个
FilteredGraph
,以解决此问题,例如,此操作:

use petgraph::graph;
use petgraph::visit::{Dfs, EdgeFiltered};

fn filter_edges(edge: graph::EdgeReference<u32>) -> bool {
    match edge.weight() {
        0 => true,
        _ => false,
    }
}

fn main() {
    let mut graph: graph::Graph<u32, u32> = graph::Graph::new();
    let a = graph.add_node(1);
    let b = graph.add_node(2);
    let e = graph.add_edge(a, b, 0);
    let filtered_graph = EdgeFiltered::from_fn(&graph, filter_edges);
    let mut dfs = Dfs::new(&filtered_graph, a);
    while let Some(node_index) = dfs.next(&EdgeFiltered::from_fn(&graph, filter_edges)) {
        let mut neighbors = graph.neighbors(node_index).detach();
        while let Some((edge_idx, _)) = neighbors.next(&graph) {
            graph[edge_idx] = 1;
        }
    }
}

如果没有更好的方法,我可能会制作一个边ID的vec,在遍历过程中填写,然后稍后修改边。再次感谢。但是如果我正确地读取了第二个代码块,Dfs不是完全未过滤吗?对于我的用例(我在问题中只给出了非常简化的代码),我也需要对Dfs进行过滤。这使得它更复杂。是的,这是一个未过滤的遍历。您可能能够实现一个拥有的包装器类型
struct FilteredGraph(graph::graph)
,并为它实现
GraphRef+Visitable
,这样您就可以在
Dfs
中使用它了。遍历之后,您可以再次将图形移出包装器。尽管在这一点上,您最初建议将指数收集到
Vec
中可能更可取。
use petgraph::graph;
use petgraph::visit::{Dfs, EdgeFiltered};

fn filter_edges(edge: graph::EdgeReference<u32>) -> bool {
    match edge.weight() {
        0 => true,
        _ => false,
    }
}

fn main() {
    let mut graph: graph::Graph<u32, u32> = graph::Graph::new();
    let a = graph.add_node(1);
    let b = graph.add_node(2);
    let e = graph.add_edge(a, b, 0);
    let filtered_graph = EdgeFiltered::from_fn(&graph, filter_edges);
    let mut dfs = Dfs::new(&filtered_graph, a);
    while let Some(node_index) = dfs.next(&EdgeFiltered::from_fn(&graph, filter_edges)) {
        let mut neighbors = graph.neighbors(node_index).detach();
        while let Some((edge_idx, _)) = neighbors.next(&graph) {
            graph[edge_idx] = 1;
        }
    }
}
fn main() {
    let mut graph: graph::Graph<u32, u32> = graph::Graph::new();
    let a = graph.add_node(1);
    let b = graph.add_node(2);
    let e = graph.add_edge(a, b, 0);
    let mut dfs = Dfs::new(&graph, a);
    while let Some(node_index) = dfs.next(&graph) {
        let mut neighbors = graph.neighbors(node_index).detach();
        while let Some((edge_idx, _)) = neighbors.next(&graph) {
            let edge_weight = &mut graph[edge_idx]; 
            if *edge_weight == 0 {
                *edge_weight = 1;
            }
        }
    }
}