运筹系列85:求解大规模tsp问题的julia代码

news2024/9/28 21:19:44

1. 大规模tsp问题的挑战

数学模型和精确解法见《运筹系列65:TSP问题的精确求解法概述》和《运筹系列80:使用Julia精确求解tsp问题》:

@variable(m, x[1:n,1:n], Bin,Symmetric) # 0-1约束
@objective(model, Min, sum(x.*distmat)/2)
@constraint(model, [i = 1:n], sum(x[i, :]) == 2)
@constraint(model, [j = 1:n], sum(x[:, j]) == 2)
for subset in subsets # 防subtour约束,需要遍历所有的子集合
	@constraint(model,sum(x[subset[i],subset[i]])<=2*length(subset[i])-2) 
end
optimize!(m)
objective_value(model)

主要的挑战包括:

  1. 求解整数规划比较耗时,并且遍历子集难度很大,大规模问题时需要自定义高效的cut和price策略
  2. 变量数量过多,需要使用列生成方法来减少求解变量

2. 使用列生成减少求解变量

关于列生成的列子,可以参考《运筹系列8:Set partitioning问题的列生成方法》。对于tsp问题,我们使用列生成的步骤是:

  1. 首先将问题变量限制在每个点最邻近的k条边上,求解限制主问题
  2. 迭代求解子问题(sub problem)。如果目标函数最优值<0,就将新生成的列yk+1转入基变量,生成新的限制主问题进行求解。如此往复,直至子问题的目标函数≥0。

我们以u159问题为例,原始模型一共有25281个变量:

using TSPLIB, LinearAlgebra, JuMP,HiGHS,PyPlot
#读取数据
tsp = readTSPLIB(:u159)
n = tsp.dimension
distmat = [round(Int64,norm(tsp.nodes[i,:] - tsp.nodes[j,:])) for i in 1:n, j in 1:n];
for i in 1:n;distmat[i,i] = 10^9;end

#完整模型
model = Model(HiGHS.Optimizer)
set_silent(model)
@variable(model, 0<=x[i in 1:n,j in js[i]]<=1)
@info "variable size:",length(x)
@objective(model, Min, sum([x[i,j]*distmat[i,j]/2 for i in 1:n for j in js[i]]))
c = @constraint(model, [i = 1:n], sum([x[i, j] for j in js[i]]) >= 2)
e = @constraint(model, [i = 1:n], sum([x[j, i] for j in js[i]]) >= 2)
optimize!(model)
@info "objective:",objective_value(model)

主问题限制在每个点最近的3条边中,此时只有604个变量,第一轮列生成后为686个变量(此时已经得到最优解了),最终经过7轮列生成迭代,变量个数为716:

# js为初始下标合集,我们将变量下标限制在这个集合内。注意需要保持对称性:
idx = Index(2)
add(idx, tsp.nodes)
c = search(idx,tsp.nodes,4)[2];
js = Vector{Vector{Int}}()
for i in 1:n
   push!(js,c[i,2:end])
end
for i in 1:n
   for j in c[i,2:end]
       union!(js[j],i)
   end
end

求解主问题,然后找到检验数<0的列。令对偶变量 p = C B B − 1 p=C_B B^{-1} p=CBB1, 则检验数 σ = C N − p ∗ N \sigma= C_N-p*N σ=CNpN 。我们将所有检验数小于0的列进基,迭代直至an ==0,此部分完整代码如下:

an = 1
while an >0
    model = Model(HiGHS.Optimizer)
    set_silent(model)
    @variable(model, 0<=x[i in 1:n,j in js[i]]<=1)
    @info "variable size:",length(x)
    @objective(model, Min, sum([x[i,j]*distmat[i,j]/2 for i in 1:n for j in js[i]]))
    c = @constraint(model, [i = 1:n], sum([x[i, j] for j in js[i]]) >= 2)
    e = @constraint(model, [i = 1:n], sum([x[j, i] for j in js[i]]) >= 2)
    optimize!(model)
    @info objective_value(model)
    p1 = [dual(c[i]) for i in 1:n]
    p2 = [dual(e[i]) for i in 1:n];
    an = 0
    for i in 1:n
        for j in setdiff(1:n,js[i])
            sigma = distmat[i,j]/2 - p1[i]-p2[j]
            if sigma < 0;push!(js[i],j);push!(js[j],i);an+=2;end
        end
    end
    @info "add size:",an
end

3. 使用行生成添加约束

我们观察att48使用lp求解后的结果:
在这里插入图片描述

有很多子环,需要添加去除环的约束。
首先添加subtour约束,去除所有的子环约束:

using Graphs
paths = strongly_connected_components(SimpleDiGraph(round.(x_val,digits = 2)))
if length(paths)>1
    for path in paths
        @constraint(model,sum(x[path,path])<=2*length(path)-2)
    end
    optimize!(model)
    x_val = round.(JuMP.value.(x),digits = 2)
    paths = strongly_connected_components(SimpleDiGraph(x_val))
end

迭代求解,并绘制结果如下:
在这里插入图片描述

然后添加comb约束,约束介绍参见《运筹系列65:TSP问题的精确求解法概述》,julia代码参见《运筹系列80: 使用Julia精确求解tsp问题》的4.2节,求解后得到两个comb:
在这里插入图片描述
然后添加进约束,迭代求解:
在这里插入图片描述
迭代得到如下图:
在这里插入图片描述

4. 使用分枝定界求解整数规划问题

我们这里使用priority queue存储分枝节点,按照最简单的下标顺序,对所有非整数变量进行分枝。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/984651.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux——线程详解(一)

索引 初识线程1.inux下的线程2.再谈进程3.理解页表4. 再次理解虚拟到物理的转化 线程的控制1.线程的创建2.线程异常3.验证pthread_join 的第二个参数4.线程的退出方式5. 线程的公有和私有6.pthread_t 与线程独立栈7.线程的局部性存储8.线程分离 初识线程 1.inux下的线程 之前了…

通过RTSP协议接入RTSP流媒体服务器EasyNVR视频监控汇聚平台的设备显示离线是什么原因?

EasyNVR安防视频云服务是基于RTSP/Onvif协议接入的视频平台&#xff0c;可支持将接入的视频流进行全平台、全终端的分发&#xff0c;分发的视频流包括RTSP、RTMP、HTTP-FLV、WS-FLV、HLS、WebRTC等。平台丰富灵活的视频能力&#xff0c;可应用在智慧校园、智慧工厂、智慧水利等…

028:vue上传解析excel文件,列表中输出内容

第028个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 &#xff08;1&#xff09;提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使…

静态路由 网络实验

静态路由 网络实验 拓扑图初步配置R1 ip 配置R2 ip 配置R3 ip 配置查看当前的路由表信息查看路由表信息配置静态路由测试 拓扑图 需求&#xff1a;实现 ip 192.168.1.1 到 192.168.2.1 的通信。 初步配置 R1 ip 配置 system-view sysname R1 undo info-center enable # 忽略…

超图聚类论文阅读1:Kumar算法

超图聚类论文阅读1&#xff1a;Kumar算法 《超图中模块化的新度量&#xff1a;有效聚类的理论见解和启示》 《A New Measure of Modularity in Hypergraphs: Theoretical Insights and Implications for Effective Clustering》 COMPLEX NETWORKS 2020, SCI 3区 具体实现源码见…

【SWT】 Button 处理 Checkbox 按钮的选中与反选事件

介绍&#xff1a; 在使用 Java SWT&#xff08;Standard Widget Toolkit&#xff09;创建图形用户界面时&#xff0c;经常需要处理按钮的选中和反选事件。本文将介绍如何通过添加 SelectionListener 监听器来实现按钮选中与反选事件的处理&#xff0c;并相应地修改相关变量的值…

2023国赛数学建模B题思路分析 - 多波束测线问题

# 1 赛题 B 题 多波束测线问题 单波束测深是利用声波在水中的传播特性来测量水体深度的技术。声波在均匀介质中作匀 速直线传播&#xff0c; 在不同界面上产生反射&#xff0c; 利用这一原理&#xff0c;从测量船换能器垂直向海底发射声波信 号&#xff0c;并记录从声波发射到…

【MySQL系列】MySQL的事务管理的学习(一)_ 事务概念 | 事务操作方式 | 事务隔离级别

「前言」文章内容大致是MySQL事务管理。 「归属专栏」MySQL 「主页链接」个人主页 「笔者」枫叶先生(fy) 目录 一、事务概念二、事务的版本支持三、事务提交方式四、事务常见的操作方式4.1 事务正常操作4.2 事务异常验证 五、事务隔离级别5.1 查看与设置隔离性5.2 读未提交&…

flutter报错-cmdline-tools component is missing

安装完androidsdk和android studio后&#xff0c;打开控制台&#xff0c;出现错误 解决办法 找到自己安装android sdk的位置&#xff0c;然后安装上&#xff0c;并将下面的勾选上 再次运行 flutter doctor 不报错&#xff0c;出现以下画面 Doctor summary (to see all det…

视频融合平台EasyCVR综合管理平台加密机授权报错invalid character是什么原因

视频融合平台EasyCVR综合管理平台具备视频融合汇聚能力&#xff0c;作为安防视频监控综合管理平台&#xff0c;它支持多协议接入、多格式视频流分发&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包…

Java版 招投标系统简介 招投标系统源码 java招投标系统 招投标系统功能设计

项目说明 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大&#xff0c;公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境&#xff0c;最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范&#xff0c;以及…

【pytorch】数据加载dataset和dataloader的使用

1、dataset加载数据集 dataset_tranform torchvision.transforms.Compose([torchvision.transforms.ToTensor(),])train_set torchvision.datasets.CIFAR10(root"./train_dataset",trainTrue,transformdataset_tranform,downloadTrue) test_set torchvision.data…

高德地图,绘制矢量图形并获取经纬度

效果如图 我用的是AMapLoader这个地图插件,会省去很多配置的步骤,非常方便 首先下载插件,然后在局部引入 import AMapLoader from "amap/amap-jsapi-loader";然后在methods里面使用 // 打开地图弹窗mapShow() {this.innerVisible true;this.$nextTick(() > {…

祝贺!Databend Cloud 入驻 AWS 云市场

关于 Databend Cloud Databend Cloud 是基于开源云原生数仓项目 Databend 打造的一款易用、低成本、高性能的新一代大数据分析平台&#xff0c;提供一站式 SaaS 服务&#xff0c;免运维、开箱即用。 Databend Cloud 架构如下&#xff1a; 存储层完全面向对象存储而设计。 计算…

2023年海外推广怎么做?

答案是&#xff1a;2023海外推广可以选择谷歌SEO谷歌Ads双向运营。 理解当地文化 成功的海外推广首先是建立在对当地文化的深入了解和尊重的基础上。 本土化策略 为了更好地与当地用户互动&#xff0c;你的品牌、产品或服务需要与他们的文化和生活方式紧密相连。 例如&…

Linux/Windows中根据端口号关闭进程及关闭Java进程

目录 Linux 根据端口号关闭进程 关闭Java服务进程 Windows 根据端口号关闭进程 Linux 根据端口号关闭进程 第一步&#xff1a;根据端口号查询进程PID&#xff0c;可使用如下命令 netstat -anp | grep 8088&#xff08;以8088端口号为例&#xff09; 第二步&#xff1a;…

【大数据之Kafka】九、Kafka Broker之文件存储及高效读写数据

1 文件存储 1.1 文件存储机制 Topic是逻辑上的概念&#xff0c;而partition是物理上的概念&#xff0c;每个partition对应于一个log文件&#xff0c;该log文件中存储的是Producer生产的数据。 Producer生产的数据会被不断追加到该log文件末端&#xff0c;为防止log文件过大导致…

【网络编程】深入了解UDP协议:快速数据传输的利器

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言&#xff0c;数据结构&#xff0c;Linux基础&#xff0c;ARM开发板&#xff0c;网络编程等领域UP&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff0…

MILP(混合整数线性规划)

线性规划定义 线性规划问题需要满足以下三个条件&#xff1a; 1.每一个问题用一组决策变量表示某一方案 2.约束条件可以用一组线性等式或者线性不等式来表示 3.目标函数为由决策变量及其有关的价值系数构成线性函数 ILP与MILP定义 整数线性规划中如果所有的变量被限制为&a…

闭包的详细认识与实例

参考https://www.bilibili.com/video/BV1sY4y1U7BT/?spm_id_from333.337.search-card.all.click&vd_source2a0404a7c8f40ef37a32eed32030aa18 一、什么叫闭包 1、问题引出&#xff1a; 不准用全局变量&#xff0c;也不准在调用代码块使用变量&#xff0c;实现计数…