从X,Y坐标找到最短路径(起始≠end)

时间:2014-12-08 17:38:09

标签: r igraph traveling-salesman hamiltonian-cycle

我有一个带有X和Y坐标的数据框,如下所示:

structure(list(X = c(666L, 779L, 176L, 272L, 232L, 74L, 928L, 
667L, 1126L, 919L), Y = c(807, 518, 724, 221, 182, 807, 604, 
384, 142, 728)), .Names = c("X", "Y"), row.names = c(NA, 10L), class = "data.frame")

我只想找出连接所有这些点的最短路径,并返回其总距离。没有其他条件:每个点都可以连接到任何其他点,没有特定的点开始或结束,没有权重等...我发现了很多关于igraph包的主题但我无法弄清楚如何提供我的数据进去。找到this但不是R语言。 也许一个“蛮力”剧本会很好,因为我得到的分数不超过20分。 谢谢

1 个答案:

答案 0 :(得分:7)

正如评论所示,您的问题与旅行商问题相关。它实际上是哈密尔顿路径的一个例子(一个路径,它访问每个节点一次,但不会在它开始的地方结束)。正如您所料,在R中已经有了一个包:TSP。请参阅thisthis

旅行推销员问题非常难以准确解决(在合理的时间内),因此大多数算法都是近似和迭代的:他们使用“可能”生成的算法从随机起点探索各种路径短路,但不一定是绝对最短路径。

在您的示例中,只有10个节点,可以执行详尽(强力)搜索。这很有用,因为我们可以将近似TSP解决方案与精确解决方案进行比较。但请注意,即使只有10个节点,强力方法也需要检查约360万个路径,大约需要2分钟。对于20个节点,路径数量为~2.5×10 18

# Hamiltonian Path via traveling salesman problem
library(TSP)
tsp <- TSP(dist(df))
tsp <- insert_dummy(tsp, label = "cut")
tour <- solve_TSP(tsp, method="2-opt", control=list(rep=10))
path.tsp <- unname(cut_tour(tour, "cut"))
path.tsp
#  [1]  6  3  5  4  8  2  1 10  7  9

# Hamiltonian Path via brute force
library(combinat)
M  <- as.matrix(dist(df))     # distance matrix
paths   <- permn(nrow(M))     # all possible paths (~ 3.6e6 !!!)
lengths <- sapply(paths,function(p)sum(M[cbind(p[-nrow(M)],p[-1])]))
path.bf <- paths[[which.min(lengths)]]
path.bf
#  [1]  9  7 10  1  2  8  4  5  3  6

# plot the results
par(mfrow=c(1,2))
plot(Y~X,df[s.path.tsp,],type="b",asp=1)
plot(Y~X,df[s.path.bf,],type="b",asp=1)

要将TSP问题转换为哈密尔顿路径问题,我们必须添加一个“虚拟顶点”,它距离每个其他节点的距离为0(参见上面引用的插图)。然后,哈密顿路径是从虚拟之后的节点开始并且在虚拟之前的节点处结束的TSP路径。

请注意,暴力和TSP解决方案确定完全相同的路径,但顺序相反。这是因为,当然,两条路径的长度相同。