用Gurobi+python求解设施选址问题(facility location)

news2025/1/12 6:10:48

参考:Gurobi 官方资源

设施选址(Facility Location)

1.背景介绍

设施选址问题在许多工业领域如物流,通信等都有应用,在本案例中展示如何解决设施选址问题,决策出仓库的数量和地点,为一些超市供应。求解思路:问题建模成混合整数规划问题,用python调用Gurobi求解器实现。

设施选址问题也称为选址分析(location analysis),是运筹优化领域的一个重要分支,要求选出设施的最佳位置,从而减小运输成本,同时考虑一些其它因素,如安全(避免在靠近居民地的地方存储有害物质)和竞争者的设施位置。

设施选址问题在很多领域都有应用,对于供应链和物流管理,这个问题可以用来找到商店,工厂和仓库的最佳位置,其它应用如公共策略(在城市中部署警局),通信(网络中的手机信号塔),甚至是粒子物理学(排斥电荷之间的间隔距离),天然气输送装备的选址等。最后,可以将设施点位置问题应用于聚类分析。

2.问题描述

一个大型的超市连锁店想要为它的一些超市修建仓库,超市的位置都已知,但是仓库的位置还没决定。
仓库选址有几个候选地,需要决定出修建几个仓库和确定这些仓库的位置。
修建仓库越多,就能减少卡车从仓库到超市的运输距离,因此减少运输成本,但是开设一个仓库有一个固定成本。
优化目标是最小化总成本=开始仓库固定成本+仓库到超市运输成本。

3.MIP模型

建立数学规划模型用gurobi求解,一个数学优化模型有5个部分:

  • 集合和索引(Sets and indices)
  • 参数(Parameters)
  • 决策变量(Decision variables)
  • 目标函数(Objective function(s))
  • 约束条件(Constraints)

接下来为设施选址问题构建MIP模型

(1)集合和索引

i ∈ I i \in I iI: 超市(顾客)位置的索引和集合.

j ∈ J j \in J jJ: 候选仓库(设施)位置的索引和集合.

(2)参数

f j ∈ R + f_{j} \in \mathbb{R}^+ fjR+: 修建设施 j ∈ J j \in J jJ 的固定成本.

d i , j ∈ R + d_{i,j} \in \mathbb{R}^+ di,jR+: 设施 j ∈ J j \in J jJ 和客户 i ∈ I i \in I iI 的距离.

c i , j ∈ R + c_{i,j} \in \mathbb{R}^+ ci,jR+: 候选设施地点 j ∈ J j \in J jJ 和客户点 i ∈ I i \in I iI 的运输成本. 假设成本和距离成比例. 因此 c i , j = α ⋅ d i , j c_{i,j} = \alpha \cdot d_{i,j} ci,j=αdi,j, α \alpha α 是单位运输成本.

(3)决策变量

s e l e c t j ∈ { 0 , 1 } select_{j} \in \{0, 1 \} selectj{0,1}: 如果在候选设施点 j ∈ J j \in J jJ 修建,值为1; 否则为0

0 ≤ a s s i g n i , j ≤ 1 0 \leq assign_{i,j} \leq 1 0assigni,j1: 非负连续变量,表明客户 i ∈ I i \in I iI 从设施 j ∈ J j \in J jJ 接收需求的比例.

(4)目标函数

在这里插入图片描述

(5)约束条件

在这里插入图片描述

4.python调用gurobi实现

本例中考虑2个超市和9个候选仓库,每个超市的位置坐标如下

Coordinates
Supermarket 1(0,1.5)
Supermarket 2(2.5,1.2)

下面的表格是候选仓库的坐标和修建固定成本,单位millions GBP

coordinatesfixed cost
Warehouse 1(0,0)3
Warehouse 2(0,1)2
Warehouse 3(0,2)3
Warehouse 4(1,0)1
Warehouse 5(1,1)3
Warehouse 6(1,2)3
Warehouse 7(2,0)4
Warehouse 8(2,1)3
Warehouse 9(2,2)2

每mile的运输成本是1 million GBP

现在导入gurobi和其它python库,初始化给定数据的数据结构

from itertools import product
from math import sqrt

import gurobipy as gp
from gurobipy import GRB

customers = [(0,1.5), (2.5,1.2)]
facilities = [(0,0), (0,1), (0,2), (1,0), (1,1), (1,2), (2,0), (2,1), (2,2)]
setup_cost = [3,2,3,1,3,3,4,3,2]
cost_per_mile = 1

(1)预处理

定义一个函数,用于计算每个设施和客户之间的欧式距离,获取MIP模型需要的关键参数

# 计算两个地方的欧式距离
def compute_distance(loc1, loc2):
    dx = loc1[0] - loc2[0]
    dy = loc1[1] - loc2[1]
    return sqrt(dx*dx + dy*dy)

num_facilities = len(facilities)
num_customers = len(customers)
cartesian_prod = list(product(range(num_customers), range(num_facilities)))

# 每对客户和设施的运输成本
shipping_cost = {(c,f):cost_per_mile * compute_distance(customers[c], facilities[f]) 
                 for c,f in cartesian_prod}

shipping_cost
{(0, 0): 1.5,
 (0, 1): 0.5,
 (0, 2): 0.5,
 (0, 3): 1.8027756377319946,
 (0, 4): 1.118033988749895,
 (0, 5): 1.118033988749895,
 (0, 6): 2.5,
 (0, 7): 2.0615528128088303,
 (0, 8): 2.0615528128088303,
 (1, 0): 2.773084924772409,
 (1, 1): 2.5079872407968904,
 (1, 2): 2.6248809496813377,
 (1, 3): 1.9209372712298547,
 (1, 4): 1.5132745950421556,
 (1, 5): 1.7,
 (1, 6): 1.3,
 (1, 7): 0.5385164807134504,
 (1, 8): 0.9433981132056605}

(2)模型部署

现在定义设施选址问题的MIP模型,包括决策变量,约束和目标函数。然后开始优化过程,Gurobi找到能最小化总成本的修建方案

# 模型
m = gp.Model('facility_location')

# 两个决策变量
select = m.addVars(num_facilities, vtype=GRB.BINARY, name='select')
assign = m.addVars(cartesian_prod, ub=1, vtype=GRB.CONTINUOUS, name='assign')

# 两个约束条件
m.addConstrs((assign[c,f] <= select[f] for c,f in cartesian_prod), name='Setup2ship')
m.addConstrs((gp.quicksum(assign[c,f] for f in range(num_facilities)) == 1 for c in range(num_customers)),name='demand')

# 目标函数
m.setObjective(select.prod(setup_cost) + assign.prod(shipping_cost), GRB.MINIMIZE)

# 优化
m.optimize()
Set parameter Username
Academic license - for non-commercial use only - expires 2023-10-24
Gurobi Optimizer version 9.5.2 build v9.5.2rc0 (mac64[rosetta2])
Thread count: 8 physical cores, 8 logical processors, using up to 8 threads
Optimize a model with 20 rows, 27 columns and 54 nonzeros
Model fingerprint: 0x0939f503
Variable types: 18 continuous, 9 integer (9 binary)
Coefficient statistics:
  Matrix range     [1e+00, 1e+00]
  Objective range  [5e-01, 4e+00]
  Bounds range     [1e+00, 1e+00]
  RHS range        [1e+00, 1e+00]
Presolve time: 0.01s
Presolved: 20 rows, 27 columns, 54 nonzeros
Variable types: 18 continuous, 9 integer (9 binary)
Found heuristic solution: objective 6.0385165

Root relaxation: objective 4.723713e+00, 15 iterations, 0.00 seconds (0.00 work units)

    Nodes    |    Current Node    |     Objective Bounds      |     Work
 Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time

*    0     0               0       4.7237129    4.72371  0.00%     -    0s

Explored 1 nodes (15 simplex iterations) in 0.03 seconds (0.00 work units)
Thread count was 8 (of 8 available processors)

Solution count 2: 4.72371 6.03852 

Optimal solution found (tolerance 1.00e-04)
Best objective 4.723712908962e+00, best bound 4.723712908962e+00, gap 0.0000%

5.结果分析

优化模型结果显示最小成本是4.72 million GBP

(1)仓库修建计划

接下来看一下仓库修建选址决策:在位置4修建一个仓库

for facility in select.keys():
    if (abs(select[facility].x) > 1e-6):
        print(f"\n Build a warehouse at location {facility + 1}.")
 Build a warehouse at location 4.

(2)运输计划

运输计划表明了从每个修建的设施运送到每个客户的比例:两个超市都由仓库4供货

for customer, facility in assign.keys():
    if (abs(assign[customer, facility].x)) > 1e-6:
        print(f"\n Supermarket {customer + 1} receives {round(100*assign[customer, facility].x, 2)} % of its demand  from Warehouse {facility + 1} .")
 Supermarket 1 receives 100.0 % of its demand  from Warehouse 4 .

 Supermarket 2 receives 100.0 % of its demand  from Warehouse 4 .

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

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

相关文章

Crash Consistency on File Systems: 文件系统一致性保证 (1) Journaling File System

文件系统是操作系统中管理用户数据的重要模块。其中一项重要的任务就是确保用户数据的在系统突然崩溃之后&#xff0c;系统能够恢复出完整、一致的用户数据。本文将会分析两种流行的文件系统&#xff0c;Journaling File System 和 Log-structured File System是如何确保数据的…

dataFactory连接mysql详细配置教程

场景&#xff1a;最近项目提出机构用户中其中一个部门下用户人数有20万&#xff0c;加载的时候十分缓慢&#xff0c;本地想重现的一下&#xff0c;这就需要在本地表中生成>20万的数据&#xff0c;搜索了网上的教程写的都是很粗略。 目录 dataFactory连接mysql配置 安装包下…

第二证券|“20cm”涨停!盘中暴涨110%,又有港股暴力拉升

A股商场今日上午窄幅动摇&#xff0c;电子等板块领涨。北向资金半响净买入额到达26.10亿元。 港股商场今日上午动摇也较为温和。不过&#xff0c;仍有个股剧烈动摇。比如浦江世界上午暴升&#xff0c;盘中涨幅一度超过110%。 A股窄幅动摇 电子板块领涨 今日上午A股商场全体体…

STL六大组件之算法

文章目录56、STL六大组件之遍历算法57、STL六大组件之查找算法158、STL六大组件之查找算法259、STL六大组件之统计算法60、STL六大组件之合并算法61、随机数&#xff08;rand&#xff09;和随机数种子&#xff08;srand&#xff09;的理解62、STL六大组件之随机算法(洗牌算法)6…

javaweb笔记

javaweb数据库jdbcmaven数据库 1.chart定长 2.分组查询:where>聚合函数>having 3.分页查询: select 字段列表 from limit 起始索引&#xff0c; 查询条目数 计算公式: 起始索引&#xff08;当前页码-1&#xff09;每页显示的条数 不同数据库分页查询不一样 4.like模糊查…

8种常见python运行错误,看看你中招了没?

人生苦短 我用python 对于刚入门Python的新手同学来说&#xff0c; 在运行代码时总免不了报错。 如何通过报错查找错误代码&#xff1f; 今天给大家总结了一些常见的报错类型&#xff0c; 每种报错都会有标有错误细节和错误行。 大家以后看到了&#xff0c;就更容易找出自…

使用navicat工具生成表的新增字段sql

1、在需要的表右键&#xff0c;设计表 2、点击【添加字段】 3、创建字段及注释&#xff0c;不要点【保存】和CtrlS 4、点击【SQL预览】 5、复制生成的sql语句

iframe 标签

一. 什么是 iframe 1. iframe 是 HTML元素,用于在网页中内嵌另外一个网页. 2. iframe 默认有一个宽高,存在边界. 3. iframe 是一个行内块级元素,可以通过 display 修改. 二. iframe 元素属性 1. src : 指定内联网页的地址 2. frameborder : iframe 默认有个边界,可以设置fram…

深入剖析Linux RCU原理(一)初窥门径

说明&#xff1a; Kernel版本&#xff1a;4.14ARM64处理器&#xff0c;Contex-A53&#xff0c;双核使用工具&#xff1a;Source Insight 3.5&#xff0c; Visio 1. 概述 RCU, Read-Copy-Update&#xff0c;是Linux内核中的一种同步机制。RCU常被描述为读写锁的替代品&#xf…

Openssl 1024bit RSA算法---公私钥获取和处理(一)

1.简介 使用OpenSSL生成公私钥文件&#xff0c;然后再将文件中的信息读出的操作。 由于要对设备升级&#xff0c;需要用到RSA算法对一部分验证信息进行加密. 2.使用OpenSSL获取公私钥 我在window系统尝试安装OpenSSL&#xff0c;但是安装不上&#xff0c;我们可以使用linux…

模式识别 第7、8章 特征的选择和提取

基本概念 问题的提出 特征→ 特征空间&#xff1a; 每一个特征对应特征空间的一个维度 &#xff1b;特征越多&#xff0c;特征空间的维度越高原则&#xff1a;在保证分类效果的前提下用尽量少的特征来完成分类基本概念 &#xff08;1&#xff09;特征形成&#xff1a;由仪器…

如何去除图片雾化?给你推荐图片去雾怎么去除的方法

小伙伴们会不会和我一样喜欢外出爬山呢&#xff1f;为了留住美好记忆&#xff0c;我们会在途中拍照记录。但是山上很经常会有雾气&#xff0c;会容易导致我们拍出来的图片模糊不清。那应该怎么办呢&#xff1f;其实&#xff0c;我们只要对图片进行去雾处理就可以很好解决这个问…

[附源码]Nodejs计算机毕业设计基于的校园疫情防控管理Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分…

Web(十一)JavaScript知识训练-数学对象

1、Math.ceil(-3.14)的结果是&#xff08; B&#xff09;。 A、 -3.14 B、 -3 C、 -4 D、 3.14 2、Math.floor(-3.14)的结果是&#xff08; C&#xff09;。 A、 -3.14 B、 -3 C、 -4 D、 3.14 3、Math.round(-3.14)的结果是&#xff08; B&#xff09;。 A、 -3.14 B、 -3 C…

Spring Cloud Openfeign微服务接口调用与Hystrix集成实战

关于openfeign 可以认为OpenFeign是Feign的增强版&#xff0c;不同的是OpenFeign支持Spring MVC注解。OpenFeign和Feign底层都内置了Ribbon负载均衡组件&#xff0c;在导入OpenFeign依赖后无需专门导入Ribbon依赖&#xff0c;用做客户端负载均衡&#xff0c;去调用注册中心服务…

dataFactory向mysql批量插入测试数据

目录 第一步&#xff1a;准备阶段&#xff1a;datafactory已连接app_user的表 第二步&#xff1a; 点击原表app_user,其中属性界面properties中配置含义如下&#xff1a; 第三步&#xff1a;根据需要设置插入字段 第四步&#xff1a;设置每个字段的规则后&#xff0c;点击se…

病毒之Worm.Win32.AutoRun

题外话&#xff1a;在被奥密克戎包围的我(两个室友和我&#xff0c;一个低烧、一个咳嗽、就差我了&#xff0c;这属实是真被包围了丫)在和Worm.Win32.AutoRun决一死战… 本次Worm.Win32.AutoRun的来源&#xff1a; windows电脑上重装vscode&#xff0c;然后没有 mingw-get-setu…

浏览器兼容模式如何设置?只需要跟着下面的步骤设置

许多考生在报考教师资格证或者其他的考试报名&#xff0c;会遇到浏览器兼容设置的问题。与其到时急急忙忙来设置浏览器的兼容模式&#xff0c;不如提前设置好&#xff0c;免了后顾之忧。浏览器兼容模式怎么设置&#xff1f;一起来看看关于浏览器兼容模式的含义以及设置方式吧&a…

《Python代码审计》(1)一款超好用的代码扫描工具

1.前言 从本文开始&#xff0c;我将开始介绍Python源代码审计&#xff0c;代码审计是检查源代码中的安全缺陷&#xff0c;检查源代码是否存在安全隐患&#xff0c;或者编码不规范的地方。通常使用自动化工具或者人工审查的方式&#xff0c;自动化工具效率高&#xff0c;但是误…

【浅学Java】Linux系统中的硬连接和软连接

Linux系统中的软连接和硬连接1. 前置知识1.1 文件的存储1.2 inode——索引节点1.3 Linux系统查找文件的过程2. Linux系统中的硬连接2.1 硬连接的实现原理2.2 实现硬连接的指令3. Linux系统中的软连接3.1 软连接的实现原理3.2 实现硬连接的指令4. 软连接和硬连接的区别1. 前置知…