You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在R语言中无需Cygwin能否精确求解旅行商问题(TSP)?

在R中不依赖Concorde求解旅行商问题(TSP)

如果不能使用Concorde求解器,你可以通过以下几种高效的方式在R中求解TSP,覆盖从精确解到启发式近似解的场景:

1. 用lpSolve构建整数规划模型(精确解,适合小规模问题)

对于节点数小于20的小规模TSP,可以直接通过整数规划模型求解精确解。lpSolve是R中常用的线性/整数规划包,无需外部依赖。

# 安装并加载lpSolve
install.packages("lpSolve")
library(lpSolve)

# 示例:5个节点的距离矩阵
dist_matrix <- matrix(c(
  0, 10, 15, 20, 5,
  10, 0, 35, 25, 15,
  15, 35, 0, 30, 20,
  20, 25, 30, 0, 25,
  5, 15, 20, 25, 0
), nrow = 5, byrow = TRUE)

n <- nrow(dist_matrix)
# 目标函数:最小化总旅行距离
obj <- as.vector(dist_matrix)

# 构建约束条件:每个城市进、出各一次
constraints <- list()
# 出度约束:每个城市恰好出发一次
for (i in 1:n) {
  constraints[[length(constraints) + 1]] <- c(rep(0, (i-1)*n), rep(1, n), rep(0, (n-i)*n))
}
# 入度约束:每个城市恰好到达一次
for (j in 1:n) {
  constraints[[length(constraints) + 1]] <- rep(c(rep(0, j-1), 1, rep(0, n-j)), n)
}
# 添加Miller-Tucker-Zemlin约束,消除子回路
mtz_constraints <- list()
for (i in 2:n) {
  for (j in 2:n) {
    if (i != j) {
      row <- rep(0, n^2)
      row[(i-1)*n + j] <- n - 1
      mtz_constraints[[length(mtz_constraints) + 1]] <- row
    }
  }
}
constraints <- c(constraints, mtz_constraints)

# 约束方向与右侧值
dir <- c(rep("=", 2*n), rep(">=", length(mtz_constraints)))
rhs <- c(rep(1, 2*n), rep(1, length(mtz_constraints)))

# 求解二进制整数规划
lp_result <- lp("min", obj, matrix(unlist(constraints), ncol = n^2, byrow = TRUE), dir, rhs, all.bin = TRUE)

# 解析最优路径
solution <- matrix(lp_result$solution, nrow = n, byrow = TRUE)
path <- c()
current <- 1
while (length(path) < n) {
  next_node <- which(solution[current,] == 1)
  path <- c(path, current)
  current <- next_node
}
path <- c(path, 1)  # 回到起点

cat("最优路径:", path, "\n总距离:", lp_result$objval, "\n")

注意:这种方法的求解时间会随节点数指数增长,节点数超过20后效率会显著下降。

2. 使用heuristicsTSP的改进启发式算法(近似解,适合中等规模问题)

如果处理中等规模(100-500个节点)的TSP,推荐使用heuristicsTSP包,它提供了遗传算法、模拟退火、蚁群优化等确定性启发式方法,结果稳定性优于TSP包的随机启发式,且无需外部求解器。

# 安装并加载heuristicsTSP
install.packages("heuristicsTSP")
library(heuristicsTSP)

# 沿用之前的距离矩阵
# 遗传算法求解
ga_result <- geneticAlgorithmTSP(dist_matrix, populationSize = 100, generations = 500)
cat("遗传算法最优路径:", ga_result$tour, "\n总距离:", ga_result$distance, "\n")

# 模拟退火求解
sa_result <- simulatedAnnealingTSP(dist_matrix, initial_temperature = 1000, cooling_rate = 0.95)
cat("模拟退火最优路径:", sa_result$tour, "\n总距离:", sa_result$distance, "\n")

这些方法能在合理时间内得到接近最优的解,你可以通过调整参数(比如种群规模、迭代次数)平衡求解速度与解的质量。

3. 用ROI生态系统结合GLPK求解器(精确/近似解,灵活适配)

ROI是R的优化统一接口,搭配ROI.plugin.glpk可以调用开源的GLPK求解器——GLPK支持整数规划,Windows下可直接通过R包安装,无需Cygwin,适合节点数30以内的问题,求解效率比lpSolve更高。

# 安装相关包
install.packages(c("ROI", "ROI.plugin.glpk", "ROI.models.tsp"))
library(ROI)
library(ROI.plugin.glpk)
library(ROI.models.tsp)

# 构建TSP优化模型
tsp_model <- OP(objective = tsp_objective(dist_matrix),
                constraints = tsp_constraints(dist_matrix))

# 调用GLPK求解
result <- ROI_solve(tsp_model, solver = "glpk")

# 提取路径
path <- as.integer(result$solution)
path <- c(path, path[1])  # 回到起点

cat("GLPK求解的最优路径:", path, "\n总距离:", result$objval, "\n")

内容的提问来源于stack exchange,提问作者L. Mann

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 03:46:07