Rust 具有图形数据结构的多个可变借词

Rust 具有图形数据结构的多个可变借词,rust,directed-acyclic-graphs,Rust,Directed Acyclic Graphs,我正在尝试编写一个程序,为一个总是有根树或多根树的有向图找到图中的最长路径(即最大深度) 分配的规范要求我使用DFS和备忘录,但在执行DFS时会出现多个可变引用。还有别的办法吗 我曾考虑使用HashMaps而不是内部Graph字段,但它只会在HashMap的可变性上产生相同的错误。我在Rust用户论坛和这里发现了几个其他问题,但没有一个给出如何解决这个问题的建议。我应该使用“不安全”代码还是其他策略 use std::io; struct Node { neighbours: Vec&

我正在尝试编写一个程序,为一个总是有根树或多根树的有向图找到图中的最长路径(即最大深度)

分配的规范要求我使用DFS和备忘录,但在执行DFS时会出现多个可变引用。还有别的办法吗

我曾考虑使用
HashMap
s而不是内部
Graph
字段,但它只会在
HashMap
的可变性上产生相同的错误。我在Rust用户论坛和这里发现了几个其他问题,但没有一个给出如何解决这个问题的建议。我应该使用“不安全”代码还是其他策略

use std::io;

struct Node {
    neighbours: Vec<usize>,
    depth: usize,
    visited: bool,
}

impl Node {
    fn new() -> Node { Node { neighbours: Vec::new(), depth: 0, visited: false } }
    fn add_neighbour(&mut self, node: usize) { self.neighbours.push(node); }
    fn neighbourhood_size(&self) -> usize { self.neighbours.len() }
}

struct Graph {
    nodes: Vec<Node>,
    depth: usize,
}

impl Graph {
    fn new() -> Graph { Graph { nodes: Vec::new(), depth: 0} }
    fn nodes_number(&self) -> usize { self.nodes.len()}
    fn add_node(&mut self) { self.nodes.push(Node::new()); }
    fn node(&mut self, i: usize) -> &mut Node { &mut self.nodes[i] }

    fn dfs(graph: &mut Graph, index: usize) {
        if !graph.node(index).visited {
            graph.node(index).visited = true;
        }
        match graph.node(index).neighbourhood_size() == 0 {
            true => { graph.node(index).depth = 1; },
            false => {
                for &i in graph.node(index).neighbours.iter() {
                    // multiple mutable references 
                    Graph::dfs(graph, i);
                }
                graph.node(index).depth = 
                    1 + graph.node(index).
                    neighbours.iter().
                    map(|&x| graph.node(x).depth).
                    max().unwrap();
            }
        }
        if graph.node(index).depth > graph.depth {
            graph.depth = graph.node(index).depth;
        }
    }
}


fn main() {
    let mut input_line = String::new();
    io::stdin().read_line(&mut input_line);
    let n = input_line.trim().parse::<usize>().unwrap();
    // to avoid counting from 0 or excessive use of (-1)
    let mut graph = Graph::new(); graph.add_node();
    for _ in 0 .. n {
        let mut input_line = String::new();
        io::stdin().read_line(&mut input_line);
        let separated = input_line.
            split(" ").
            collect::<Vec<_>>();
        let u = separated[0].trim().parse::<usize>().unwrap();
        let v = separated[1].trim().parse::<usize>().unwrap();
        if graph.nodes_number() <= u { graph.add_node(); }
        if graph.nodes_number() <= v { graph.add_node(); }
        graph.node(u).add_neighbour(v);
    }
    let n = graph.nodes_number();
    for i in 1 .. n {
        if !graph.node(i).visited { Graph::dfs(&mut graph, i); }
    }
    println!("{}", graph.depth);
}
使用std::io;
结构节点{
邻居:Vec,,
深度:使用,
访问:布尔,
}
impl节点{
fn new()->Node{Node{neights:Vec::new(),深度:0,访问:false}
fn添加邻居(&mutself,node:usize){self.neights.push(node);}
fn neighbourth_size(&self)->使用{self.neighbourts.len()}
}
结构图{
节点:Vec,
深度:使用,
}
impl图{
fn new()->Graph{Graph{nodes:Vec::new(),深度:0}
fn nodes_number(&self)->使用{self.nodes.len()}
fn add_node(&mut self){self.nodes.push(node::new());}
fn节点(&mut self,i:usize)->&mut节点{&mut self.nodes[i]}
fn dfs(图:&mut图,索引:usize){
if!graph.node(index).已访问{
graph.node(index).visted=true;
}
匹配图.节点(索引).邻域大小()==0{
true=>{graph.node(index.depth=1;},
假=>{
for&i在graph.node(index.neights.iter()中{
//多个可变引用
图::dfs(图,i);
}
graph.node(索引)。深度=
1+图形节点(索引)。
iter()。
map(|&x | graph.node(x.depth)。
最大值()展开();
}
}
如果graph.node(index.depth>graph.depth{
graph.depth=graph.node(index.depth);
}
}
}
fn main(){
让mut input_line=String::new();
io::stdin().read_行(&mut input_行);
设n=input_line.trim().parse::().unwrap();
//避免从0开始计数或过度使用(-1)
让mut graph=graph::new();graph.add_node();
对于0..n中的uu{
让mut input_line=String::new();
io::stdin().read_行(&mut input_行);
让分离=输入_行。
拆分(“”)。
收集::();
设u=separated[0].trim().parse::().unwrap();
设v=separated[1].trim().parse::().unwrap();

如果graph.nodes_number()在遍历包含在其中的向量时,您正在修改
graph
结构。编译器无法验证您在迭代过程中没有添加或删除向量,这将使迭代器无效。这是错误的直观原因

避免这种情况的最简单方法是在对向量进行迭代之前获取向量的副本,这样编译器就可以看到迭代器没有改变。这有点次优,但现在可以解决错误。另一个生命周期错误也可以用类似的方法解决(但没有太多成本)在进行比较之前,将深度复制到变量中

use std::io;
use std::env;

struct Node {
    neighbours: Vec<usize>,
    depth: usize,
    visited: bool,
}

impl Node {
    fn new() -> Node {
        Node {
            neighbours: Vec::new(),
            depth: 0,
            visited: false,
        }
    }
    fn add_neighbour(&mut self, node: usize) {
        self.neighbours.push(node);
    }
    fn neighbourhood_size(&self) -> usize {
        self.neighbours.len()
    }
}

struct Graph {
    nodes: Vec<Node>,
    depth: usize,
}

impl Graph {
    fn new() -> Graph {
        Graph {
            nodes: Vec::new(),
            depth: 0,
        }
    }
    fn nodes_number(&self) -> usize {
        self.nodes.len()
    }
    fn add_node(&mut self) {
        self.nodes.push(Node::new());
    }
    fn node(&mut self, i: usize) -> &mut Node {
        &mut self.nodes[i]
    }

    fn dfs(graph: &mut Graph, index: usize) {
        if !graph.node(index).visited {
            graph.node(index).visited = true;
        }
        match graph.node(index).neighbourhood_size() == 0 {
            true => {
                graph.node(index).depth = 1;
            }
            false => {
                let neighbours = graph.node(index).neighbours.clone();
                for &i in neighbours.iter() {
                    // multiple mutable references
                    Graph::dfs(graph, i);
                }
                graph.node(index).depth = 1
                    + neighbours
                        .iter()
                        .map(|&x| graph.node(x).depth)
                        .max()
                        .unwrap();
            }
        }
        let depth = graph.node(index).depth;
        if depth > graph.depth {
            graph.depth = graph.node(index).depth;
        }
    }
}

fn main() {
    env::set_var("RUST_BACKTRACE", "1");
    let mut input_line = String::new();
    io::stdin().read_line(&mut input_line);
    let n = input_line.trim().parse::<usize>().unwrap();
    // to avoid counting from 0 or excessive use of (-1)
    let mut graph = Graph::new();
    graph.add_node();
    for _ in 0..n {
        let mut input_line = String::new();
        io::stdin().read_line(&mut input_line);
        let separated = input_line.split(" ").collect::<Vec<_>>();
        let u = separated[0].trim().parse::<usize>().unwrap();
        let v = separated[1].trim().parse::<usize>().unwrap();
        if graph.nodes_number() <= u {
            graph.add_node();
        }
        if graph.nodes_number() <= v {
            graph.add_node();
        }
        graph.node(u).add_neighbour(v);
    }
    let n = graph.nodes_number();
    for i in 1..n {
        if !graph.node(i).visited {
            Graph::dfs(&mut graph, i);
        }
    }
    println!("{}", graph.depth);
}
使用std::io;
使用std::env;
结构节点{
邻居:Vec,,
深度:使用,
访问:布尔,
}
impl节点{
fn new()->节点{
节点{
邻居:Vec::new(),
深度:0,
访问:错误,
}
}
fn添加相邻节点(&mut self,节点:usize){
self.neights.push(节点);
}
fn邻里大小(自我)->使用{
self.neights.len()
}
}
结构图{
节点:Vec,
深度:使用,
}
impl图{
fn new()->图形{
图表{
节点:Vec::new(),
深度:0,
}
}
fn节点\u编号(&self)->使用{
self.nodes.len()
}
fn添加节点(&mut self){
self.nodes.push(Node::new());
}
fn节点(&mut self,i:usize)->&mut节点{
&多个自组织节点[i]
}
fn dfs(图:&mut图,索引:usize){
if!graph.node(index).已访问{
graph.node(index).visted=true;
}
匹配图.节点(索引).邻域大小()==0{
真=>{
图.节点(索引).depth=1;
}
假=>{
让neights=graph.node(index.neights.clone();
for&i in neights.iter(){
//多个可变引用
图::dfs(图,i);
}
graph.node(index).depth=1
+邻居
.国际热核实验堆(iter)
.map(|&x | graph.node(x).depth)
.max()
.unwrap();
}
}
设depth=graph.node(index.depth);
如果深度>graph.depth{
graph.depth=graph.node(index.depth);
}
}
}
fn main(){
环境:设置变量(“生锈回溯”,“1”);
让mut input_line=String::new();
io::stdin().read_行(&mut input_行);
设n=input_line.trim().parse::().unwrap();
//避免从0开始计数或过度使用(-1)
让mut-graph=graph::new();
graph.add_node();
对于0..n中的uu{
让mut input_line=String::new();
io::stdin().read_行(&mut input_行);
let separated=input_line.split(“”)。collect::();
设u=separated[0].trim().parse::().unwrap();
设v=separated[1].trim().parse::().unwrap();

如果graph.nodes_number()不是在迭代向量之前获取向量的副本,还可以迭代索引:

for ni in 0..graph.node(index).neighbours.len() {
    let neighbour = graph.node(index).neighbours[ni];
    Graph::dfs(graph, neighbour);
}
邻近
v
fn node_mut(&mut self, i: usize) -> &mut Node {
    &mut self.nodes[i]
}
fn node(&self, i: usize) -> &Node {
    &self.nodes[i]
}