Debugging 锈迹:树枝和束缚在难以捉摸的虫子里

Debugging 锈迹:树枝和束缚在难以捉摸的虫子里,debugging,rust,traveling-salesman,Debugging,Rust,Traveling Salesman,我可以再次需要你的帮助。我实现了TSP问题的分支定界解决方案,并偶然发现了一个错误。。。已经几个小时了,我还是不明白。最奇怪的是:首先访问城市0,但在日志的末尾,它试图将0连接到1,这毫无意义nextcity在初始递归级别之后不应变为0。但事实确实如此 fn solve (graph: &CompleteGraph, goal: f64, output: &str) { let mut path = Path { cities: Vec::<usize&g

我可以再次需要你的帮助。我实现了TSP问题的分支定界解决方案,并偶然发现了一个错误。。。已经几个小时了,我还是不明白。最奇怪的是:首先访问城市0,但在日志的末尾,它试图将0连接到1,这毫无意义
nextcity
在初始递归级别之后不应变为0。但事实确实如此

fn solve (graph: &CompleteGraph, goal: f64, output: &str) {
    
    let mut path = Path { cities: Vec::<usize>::new() };
    path.cities.push(0);
    let mut visited = Visited { cities: vec!(false; graph.numcities) };
    visited.cities[0] = true;
    let since = Instant::now();

    let mut besttotal = goal;

    solverec(&graph, 0, &mut path, 0.0, &mut visited, &mut besttotal, since, output);
}

fn solverec (graph: &CompleteGraph, nextcity: usize, mut path: &mut Path, pathtotal: f64, mut visited: &mut Visited, mut besttotal: &mut f64, since: Instant, output: &str) {

    // eprintln!("recursive on {:?} {}", path, pathtotal);

    if since.elapsed() > Duration::from_secs(5) {
        return;
    }
    // if pathtotal > *besttotal {
    //  return;
    // }

    if path.cities.len() == graph.numcities {
        path.cities.push(path.cities[0]);

        let cityindex = path.cities.len()-2;
        let pathtotal = pathtotal + graph.distances[path.cities[cityindex] * graph.numcities + path.cities[cityindex+1]];
        
        if pathtotal < *besttotal {
            *besttotal = pathtotal;
            // eprintln!("new best: {}", besttotal);
            // path.cities.dedup();
            path.write(output);
            path.cities.pop();
            return;
        } else {
            return;
        }
    }

    let mut edges: Vec::<(usize,usize,f64)> = (0..graph.numcities).map(|i| (nextcity, i, graph.distances[nextcity * graph.numcities + i])).collect();
    edges.sort_by(|(_from1,_to1,distance1),(_from2,_to2,distance2)| distance1.partial_cmp(&distance2).unwrap());

    for (_nextcity, adjcity, _distance) in edges {
        if adjcity != nextcity && visited.cities[adjcity] == false {

            if path.cities.contains(&adjcity) {
                eprintln!("found a bug: {} -> {} ; {:?} of length {}", nextcity, adjcity, path, path.cities.len());


            }

            path.cities.push(adjcity);
            visited.cities[adjcity] = true;
            let pathtotal = pathtotal + graph.distances[nextcity * graph.numcities + adjcity];

            solverec(&graph, adjcity, &mut path, pathtotal, &mut visited, &mut besttotal, since, output);

            visited.cities[adjcity] = false;
            path.cities.pop();
        }
    }
}

当我为你准备更新时,我注意到在日志的中间,路径超过45个城市,而图上只有40个城市。所以我看了看,发现在开头有一个push(),只有一个条件pop()。除此之外,没有pop()

if path.cities.len()==graph.numcities{
path.cities.push(path.cities[0]);
让cityindex=path.cities.len()-2;
设pathtotal=pathtotal+graph.distance[path.cities[cityindex]*graph.numcities+path.cities[cityindex+1];
如果pathtotal<*besttotal{
*最佳总数=路径总数;
写入(输出);
path.cities.pop();
返回;
}否则{
path.cities.pop();
返回;
}
}
found a bug: 31 -> 22 ; Path { cities: [0, 7, 8, 34, 3, 20, 27, 36, 1, 10, 5, 26, 23, 12, 14, 24, 38, 25, 9, 39, 30, 13, 11, 6, 28, 33, 32, 19, 37, 21, 15, 16, 17, 29, 4, 18, 35, 22, 31] } of length 39
found a bug: 18 -> 22 ; Path { cities: [0, 7, 8, 34, 3, 20, 27, 36, 1, 10, 5, 26, 23, 12, 14, 24, 38, 25, 9, 39, 30, 13, 11, 6, 28, 33, 32, 19, 37, 21, 15, 16, 17, 29, 4, 18, 35, 22] } of length 38
found a bug: 22 -> 35 ; Path { cities: [0, 7, 8, 34, 3, 20, 27, 36, 1, 10, 5, 26, 23, 12, 14, 24, 38, 25, 9, 39, 30, 13, 11, 6, 28, 33, 32, 19, 37, 21, 15, 16, 17, 29, 4, 18, 35, 22, 22, 2] } of length 40
found a bug: 31 -> 2 ; Path { cities: [0, 7, 8, 34, 3, 20, 27, 36, 1, 10, 5, 26, 23, 12, 14, 24, 38, 25, 9, 39, 30, 13, 11, 6, 28, 33, 32, 19, 37, 21, 15, 16, 17, 29, 4, 18, 35, 22, 22, 2, 35, 31] } of length 42
found a bug: 35 -> 2 ; Path { cities: [0, 7, 8, 34, 3, 20, 27, 36, 1, 10, 5, 26, 23, 12, 14, 24, 38, 25, 9, 39, 30, 13, 11, 6, 28, 33, 32, 19, 37, 21, 15, 16, 17, 29, 4, 18, 35, 22, 22, 2, 35] } of length 41
found a bug: 4 -> 35 ; Path { cities: [0, 7, 8, 34, 3, 20, 27, 36, 1, 10, 5, 26, 23, 12, 14, 24, 38, 25, 9, 39, 30, 13, 11, 6, 28, 33, 32, 19, 37, 21, 15, 16, 17, 29, 4, 18, 35, 22, 22] } of length 39
found a bug: 4 -> 22 ; Path { cities: [0, 7, 8, 34, 3, 20, 27, 36, 1, 10, 5, 26, 23, 12, 14, 24, 38, 25, 9, 39, 30, 13, 11, 6, 28, 33, 32, 19, 37, 21, 15, 16, 17, 29, 4, 18, 35, 22, 22] } of length 39
found a bug: 2 -> 22 ; Path { cities: [0, 7, 8, 34, 3, 20, 27, 36, 1, 10, 5, 26, 23, 12, 14, 24, 38, 25, 9, 39, 30, 13, 11, 6, 28, 33, 32, 19, 37, 21, 15, 16, 17, 29, 4, 18, 35, 22, 22, 22, 2] } of length 41
...
...
found a bug: 0 -> 34 ; Path { cities: [0, 7, 8, 34, 3, 20, 27, 36, 1] } of length 9
found a bug: 0 -> 8 ; Path { cities: [0, 7, 8, 34, 3, 20, 27, 36, 1] } of length 9
found a bug: 0 -> 3 ; Path { cities: [0, 7, 8, 34, 3, 20, 27, 36, 1] } of length 9
found a bug: 0 -> 36 ; Path { cities: [0, 7, 8, 34, 3, 20, 27, 36, 1] } of length 9
found a bug: 0 -> 20 ; Path { cities: [0, 7, 8, 34, 3, 20, 27, 36, 1] } of length 9
found a bug: 0 -> 27 ; Path { cities: [0, 7, 8, 34, 3, 20, 27, 36, 1] } of length 9
found a bug: 0 -> 1 ; Path { cities: [0, 7, 8, 34, 3, 20, 27, 36, 1] } of length 9
if path.cities.len() == graph.numcities {
    path.cities.push(path.cities[0]);
    let cityindex = path.cities.len()-2;
    let pathtotal = pathtotal + graph.distances[path.cities[cityindex] * graph.numcities + path.cities[cityindex+1]];
    
    if pathtotal < *besttotal {
        *besttotal = pathtotal;
        path.write(output);
        path.cities.pop();
        return;
    } else {
        path.cities.pop();
        return;
    }
}