python调用求解器SCIP求解设施选址覆盖问题
文章目录
- 1. 设施选址集合覆盖问题
- 2. 算法实现
- 2.1 测试数据集 OR-Library
- 2.2 python调用SCIP求解设施选址覆盖问题完整代码:
- 2.3 数据结果
- 参考文献
1. 设施选址集合覆盖问题
选址问题(Facility location problem, FLP) 分为离散型和连续型两类。其中离散选址问题即设施点被选址的地点是离散的。此类问题往往设定设施点与需求点都位于在网络节点上,需求点区位确定,需求点与其 他一些节点作为设施被选点,需求点与设施被选点之间有连线相连。 离散选址问题纷繁复杂,在国外学者的研究基础上,我们认为主要的离散选址问题有:中值问题、覆盖问题、中心问题、多产品问题、动态选址问题、路径选址、多目标选址、网络中心选址问题。
集合覆盖问题(Set Covering Problem, SCP) 是经典组合优化问题之一,被广泛应用到航空的人员行程安排、电路设计、运输的车辆路线安排等领域。该问题已被证明是一个NP-C问题。
设施选址集合覆盖问题被分为集覆盖问题(完全覆盖问题)、最大覆盖问题:
- 集覆盖问题(Location Set Covering Problem,LSCP研究满足覆盖所有需求点顾客需求点的前提下,设施的建站个数或建设费用最小的问题;
- 数学模型
- 最大覆盖问题(Maximum Covering Location Problem,MCLP) 研究在备选物流中心里,如何选择p个设施,使得服务的需求点数最多或需求量最大;
- 数学模型
大白话:
1.集覆盖即要求所有的需求点都要被满足,就算为了某个需求点被覆盖满足,建立了成本很大的设施也没关系(前提假设是设施是肯定能满足所有的需求点的),所以目标是最小化成本。
2.最大覆盖问题在建造的设施数量是固定的约束下,尽可能满足足够多的需求,当然每个需求点可能有一定的权重(这个可以由需求点的人数、距离决定),所以目标是最大化满足的需求
2. 算法实现
2.1 测试数据集 OR-Library
OR-Library is a collection of test data sets for a variety of Operations Research (OR) problems.
- 测试算例直接使用 Set covering的测试算例,代码中给出了OR-Library数据集txt文件的解析的方式。
2.2 python调用SCIP求解设施选址覆盖问题完整代码:
import pandas as pd
import numpy as np
import pyscipopt as optclass SCP_FLP(object):def __init__(self):self.num_nodes = None # 需求点的数量self.num_facilities = None # 设施数量self.setup_cost = None # 每个设施的建造成本self.cover_matrix = 0 # cover_matrix[[i, j]], 需求点i能否被设施j是否能覆盖def prepare_data(self, filepath):# 获取数据集 OR-Library数据集数据,http://people.brunel.ac.uk/~mastjjb/jeb/orlib/scpinfo.html# 获取所有的行lines = []with open(filepath, 'r') as file:for line in file:lines.append(line)# 第一行获取服务点的数量num_nodes和仓库的数量num_facilitiesline_0 = lines[0].strip().split()self.num_nodes, self.num_facilities = list(map(int, line_0))iter_lines = iter(lines)next(iter_lines)# 从第二行开始获取num_facilities个设施的建造成本self.setup_cost = np.array([])for line in iter_lines:self.setup_cost = np.append(self.setup_cost, list(map(int, line.strip('\n').split())))if len(self.setup_cost) == self.num_facilities:break# 获取需求点是否能被设施覆盖矩阵。这段逻辑比较复杂,为了不同算例的通用性。idx_point = -1count_aux = 0mark_value = 0line_of_size = Trueself.cover_matrix = np.full((self.num_nodes, self.num_facilities), 0)for line in iter_lines:if line_of_size:# 一行只有一个数据的数据值mark_value,然后取下一行开始的长度为mark_value的数据集mark_value = int(line.strip('\n').split()[0])line_of_size = Falseidx_point += 1count_aux = 0else:line_search = line.strip('\n').split()count_aux += len(line_search)# 生成覆盖关系矩阵for j in line_search:self.cover_matrix[idx_point][int(j) - 1] = 1if count_aux == mark_value:line_of_size = Truedef cover_model(self):# 创建模型model = opt.Model('LSCP')# 添加变量:是否在j处建造设施,1则建造,0则不建造select = {}for n in range(self.num_facilities):select[n] = model.addVar(vtype='B', name='select_' + str(n))# 添加约束: 每个需求点至少被一个设施服务范围所覆盖for i in range(self.num_nodes):model.addCons(opt.quicksum(self.cover_matrix[i][j] * select[j] for j in range(self.num_facilities)) >= 1)# 设置目标model.setObjective(opt.quicksum(self.setup_cost[j] * select[j] for j in range(self.num_facilities)))model.setMinimize()# model.hideOutput()# 优化求解model.optimize()# 输出解print('model_obj =', model.getObjVal())select_facility = []for i in range(self.num_facilities):if model.getVal(select[i]) > 0:select_facility.append(i)print('select facility =', select_facility)def max_cover_model(self):np.random.seed(0)# 需求点权重(可以是和距离的正比的权重、需求点的需求量等等)weight_points = np.random.randint(10, size=self.num_nodes)fixed_facilities_num = int(self.num_facilities / 2)# 创建模型model = opt.Model('MCLP')# 添加变量1:设施j是否建造,0-1变量, 1则建造,0则不建造select = {}for n in range(self.num_facilities):select[n] = model.addVar(vtype='B', name='select_' + str(n))# 添加变量2:需求点i是否被覆盖,1则被覆盖,0则不被覆盖served = {}for n in range(self.num_nodes):served[n] = model.addVar(vtype='B', name='served_' + str(n))# 添加约束1: 从备选中选择的设施 = 决策设施数量model.addCons(opt.quicksum(select[j] for j in range(self.num_facilities)) == fixed_facilities_num)# 添加约束2: 若有设施j建造(select=1), 且覆盖需求点i,则由于目标最大化, served=1; 反之亦然for i in range(self.num_nodes):model.addCons(opt.quicksum(self.cover_matrix[i][j] * select[j] for j in range(self.num_facilities)) >= served[i])# 设置目标最大化: 在设施总数量确定的情况下,选择设施及服务点,使得需求量最大model.setObjective(opt.quicksum(weight_points[i] * served[i] for i in range(self.num_nodes)))model.setMaximize()# model.hideOutput()# 优化求解model.optimize()if __name__ == '__main__':flp = SCP_FLP()# 算例Scp41flp.prepare_data('./scp41.txt')# 集覆盖问题flp.cover_model()# 最大覆盖问题flp.max_cover_model()
2.3 数据结果
- 集覆盖问题结果
- 最大覆盖问题结果
参考文献
[1] Owen S H , Daskin M S . Strategic facility location: A review[J]. Euro.j.oper.res, 1998, 111(3):423-447.
python调用求解器SCIP求解设施选址覆盖问题相关推荐
- python调用开源求解器SCIP求解带时间窗车辆路径问题(VRPTW)
文章目录 1. 问题定义 2. 数学模型 3. python调用SCIP实现代码 4. 结果 参考文献 1. 问题定义 带时间窗车辆路径问题(vehicle routing problem with ...
- python调用开源求解器scip求解运输问题
运输问题 运输问题(transportation problem)一般是研究把某种商品从若干产地运至若干个销地而使总运费最小的一类问题.一种特殊的线性规划问题,由于其技术系数矩阵具有特殊的结构,可以使 ...
- 一站式解决数学规划求解器SCIP的安装与使用
安装Java的SCIP接口JSCIPOpt系列 https://blog.csdn.net/qq_40275637/article/details/109703216 安装python的SCIP接口P ...
- SCIP | 数学规划求解器SCIP超详细的使用教程
前言 小伙伴们大家好呀!继上次lp_solve规划求解器的推文出来以后,大家都期待着更多求解器的具体介绍和用法.小编哪敢偷懒,这不,赶在考试周之际,又在忙里偷闲中给大家送上一篇SCIP规划求解的推文教 ...
- 优化求解器SCIP介绍
SCIP(Solving Constraint Integer Programs)一款非常成熟的开源混合整数规划(MILP)框架,支持自定义搜索树中的各个模块,当然包括在分支限界(Branch and ...
- 线性规划整数规划求解器SCIP的失败使用 与 GLPK的成功使用
因本人科研需要,需要使用这两个求解器解数学模型. 本人的实现平台为window10,64位,基于C++,且之前已安装Visual Studio 2015. 但是SCIP的使用建议使用Linux,感觉可 ...
- 用Gurobi+python求解设施选址问题(facility location)
参考:Gurobi 官方资源 设施选址(Facility Location) 1.背景介绍 设施选址问题在许多工业领域如物流,通信等都有应用,在本案例中展示如何解决设施选址问题,决策出仓库的数量和地点 ...
- Python 调用 SCIP 求解器的选址模型代码示例
本文介绍 Python 语言调用 SCIP 求解器,求解选址模型的代码示例. 安装 SCIP 和 PySCIPOpt 安装 SCIP 求解器的教程: SCIP | 数学规划求解器SCIP超详细的使用教 ...
- Python调用Gurobi求解简单线性规划问题
前言 Gurobi是一款功能强大的商用求解器,支持Python.C.C++.Java等多种语言调用,相比于Cplex,Gurobi封装更高,更加方便,但是对于初学者而言会更难一些.Gurobi与Cpl ...
最新文章
- debian nvidia 安装_【折腾】openSUSE安装与配置——从入门到放弃
- android发短信乱码,android 音乐信息乱码处理
- unity项目中使用BUGLY遇到的的几个问题
- ABAP--使用SLIN事务码进行ABAP程序扩展语法检查,提高程序开发的质量
- java练习(数组工具类的封装)[目前写过最长的代码,虽然不难]
- StringBoot接收XML参数,Java解析XML参数并封装
- 基于gdal的格网插值
- 190112每日一句
- 怎么使用视频转换器把kux格式转换mp4
- robo 3t使用教程
- Java类加载机制--类加载过程(加载)
- AspUpload实时上传进度的AJAX方法
- 为什么html中图片显示不出来,网页图片显示不出来怎么办
- TI 杯2019年全国大学生电子设计竞赛题
- 12306 验证码验证流程
- 单个vue组件的打包和动态引入
- 王道书P41 T22(单链表实现)
- android关闭本应用的通知声音代码,关于android:当我的应用取消通知时,播放带有FLAG_INSISTENT通知的声音不会停止...
- 这次可能不是你所期待的牛市
- CAN通信标准帧和扩展帧
热门文章
- lgg6 android 9,【LGG6评测】18:9奇葩比例没采用骁龙835 LG G6解析(全文)_LG G6_手机评测-中关村在线...
- 随手拍能当副业靠谱不,每天拍车辆违规可以赚钱吗?
- CAD编辑指南11:CAD转PDF以及批量打印
- 五类和六类网络的区别
- Xilinx Zynq7000系列学习
- 天下最不能等待的事情莫过于孝敬自己的父母![转载]
- 手机免root安装kali linux 步骤,离线版(最终可行版)
- matlab 角度余弦,matlab产生扫频余弦信号
- 应对容器时代面临的挑战:长风破浪会有时、直挂云帆济沧海
- mit6.828 lab1 exercise11