加强图形metric_tsp_approx解决方案不遵循图形边缘

问题描述

我正在尝试使用boost :: adjacency_list创建的图表解决旅行商问题。我正在使用metric_tsp_approx解决茶匙。 我面临的问题是解决方案不遵循图形的边缘。解决方案连接图中未直接连接的顶点。我想知道这是图书馆的工作方式还是做错了什么。解决方案也不正确。我有4个顶点形成一个正方形,解决方案本来应该沿着周边,但它却沿着对角线。对角线上没有边缘。

这是我的邻接表:

boost::adjacency_list<boost::setS,boost::listS,boost::undirectedS,boost::property<boost::vertex_index_t,int>,boost::property<boost::edge_weight_t,double>,boost::no_property>

添加顶点并添加边缘功能

boost::add_vertex(id,graph);
boost::add_edge(id1,id2,weight,graph);  // weight is euclidean distance

TSP求解器:

std::vector<VertexDescriptor> tsp_path;  //VertexDescriptor is adjacency_list::vertex_descriptor
metric_tsp_approx_tour(graph,back_inserter(tsp_path));

我还尝试将权重图传递给metric_tsp_approx_tour,但仍然存在相同的问题。

有人可以帮我解决这个问题吗?如果boost metric_tsp_approx_tour不考虑图形的边缘,是否有办法使其考虑它们?

解决方法

文档:https://www.boost.org/doc/libs/1_74_0/libs/graph/doc/metric_tsp_approx.html

这是一个旅行销售人员的启发式方法,用于为具有加权边且服从三角形不等式的完全连接无向图生成顶点游。

(重点是我的)

"fully connected graph"子句确实声明假定所有顶点都已连接。

还要注意,假设顶点索引映射到[0,num_vertices(graph))。

奖金

作为奖励,我尝试为该算法制定一个最小的工作示例。它似乎确实如广告所述:

Live On Coliru

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_utility.hpp>
#include <boost/graph/metric_tsp_approx.hpp>

using Graph = 
    boost::adjacency_list<boost::setS,boost::listS,boost::undirectedS,boost::property<boost::vertex_index_t,int>,boost::property<boost::edge_weight_t,double>,boost::no_property>;

using VertexDescriptor = Graph::vertex_descriptor;

int main() {
    std::vector const points { std::pair
        { 4.,9. },// these can be randomized
        { 2.,6. },{ 4.,1. },{ 1.,};

    Graph graph;
    for (auto i = 0u; i < points.size(); ++i) {
        add_vertex(i,graph);
    }

    for (auto i = 0u; i < points.size(); ++i) {
        auto va = vertex(i,graph);

        // undirected,so only need traverse higher vertices for connections
        for (auto j = i+1; j < points.size(); ++j) {
            auto vb = vertex(j,graph);

            auto const [ax,ay] = points.at(i);
            auto const [bx,by] = points.at(j);
            auto const dx = bx - ax;
            auto const dy = by - ay;

            add_edge(va,vb,sqrt(dx*dx + dy*dy),graph); // weight is euclidean distance
        }
    }

    print_graph(graph);

    std::vector<VertexDescriptor> tsp_path(num_vertices(graph));  //VertexDescriptor is adjacency_list::vertex_descriptor
    metric_tsp_approx_tour(graph,back_inserter(tsp_path));

    auto idmap = get(boost::vertex_index,graph);
    for (auto vd : tsp_path) {
        if (vd != graph.null_vertex()) {
            auto [x,y] = points.at(idmap[vd]); 
            std::cout << " {" << x << "," << y << "}";
        }
    }
}

打印

0 <--> 1 2 3 
1 <--> 0 2 3 
2 <--> 0 1 3 
3 <--> 0 1 2 
 {4,9} {2,6} {1,1} {4,9}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...