选址问题是要选择设施位置使目标达到最优,是数模竞赛中的常见题型。

小白不一定要掌握所有的选址问题,但要能判断是哪一类问题,用哪个模型。

进一步学习 PuLP工具包中处理复杂问题的字典格式快捷建模方法。

欢迎关注『Python小白的数学建模课 @ Youcans』系列,每周持续更新


1. 选址问题

选址问题是指在某个区域内选择设施的位置使所需的目标达到最优。选址问题也是一种互斥的计划问题。

例如投资场所的选址:企业要在 m 个候选位置选择若干个建厂,已知建厂费用、运输费及 n 个地区的产品需求量,应如何进行选址。

选址问题是运筹学中经典的问题之一,选址问题在生产生活、物流、甚至军事中都有着非常广泛的应用,如工厂、仓库、急救中心、消防站、垃圾处理中心、物流中心、导弹仓库的选址等。更重要的,选址问题也是数模竞赛的热点问题。

选址是重要的长期决策,选址的好坏直接影响到服务方式、服务质量、服务效率、服务成本等,从而影响到利润和市场竞争力,选址问题的研究有着重大的经济、社会和军事意义。

选址问题有四个基本要素:设施、区域、距离和优化目标。

1.1 设施

选址问题中所说的设施,在具体题目中可以是工厂、仓库、服务站等形式。

1.2 区域

选址问题中所说的区域,在具体题目中可以是工厂、车间的内部布局,也可以是给定的某个地区、甚至空间范围。

按照规划区域的特征,可以分为连续选址问题和离散选址问题。连续选址问题,设施可以布局在区域内的任意位置,就要求出最优选址的坐标;离散选址问题,只能从若干候选位置中进行选择,运筹学中的选址问题通常是这类离散选址问题。

1.3 距离

选址问题中所说的距离,是指设施到服务对象之间的距离,在具体题目中也可以是某个选址位置的服务时间、成本、覆盖范围。如果用图论方法求解,通常就是连接顶点的边的权值。

当问题所关注的是设施到服务对象之间的距离时,如果问题给出的不是顶点之间的距离,而是设施的位置坐标,要注意不是只有欧式距离,对于不同问题也可能是球面距离、曼哈顿距离、切比雪夫距离。

1.4 优化目标

选址问题要求选择最好的选址位置,但选址位置只是决策变量,选择的最终目的通常是实现加权距离最短、费用最小、利润最大、时间最短,这才是优化问题的目标函数。

按照目标函数的特点,可以分为:中位问题,要求总成本最小;中心问题,服务于每个客户的最大成本最小;反中心问题:服务于每个客户的最小成本最大。


2. 常见选址问题及建模

2.1 P-中位问题(P-median problem)

P-中位问题,假设有 N 个候选服务站和 M 个需求点,要从 N 个候选服务站中选择 P 个,使所有需求点到最近的服务站的加权距离 \(d_{ij}\) 的总和最小。需求点 i 的权值,通常是指该需求点的需求量。

这是一个 MinSum 问题,定义决策变量 \(x_j\) 为选中的服务站,\(y_{ij}\) 将各需求点匹配到最近的服务站:

\[x_j = \begin{cases}
1,& 服务站\ j\ 被选中\\
0,& 服务站\ j\ 未被选中
\end{cases}
\]
\[y_{ij} = \begin{cases}
1,& 需求点\ i\ 由服务站\ j\ 服务\\
0,& 需求点\ i\ 不由服务站\ j\ 服务
\end{cases}
\]

可以建立数学模型如下:

\[\begin{align*}
& min\;\sum_{i \in M}\sum_{j \in N} w_i d_{ij}y_{ij}\\
& s.t.:\;\begin{cases}
\sum_{j \in N} x_{j} = P\\
\sum_{j \in N} y_{ij} = 1,\forall i\\
y_{ij} - x_j \leq 0,\forall i,j\\
x_{j} \in \{0,1\}, \;y_{ij} \in \{0,1\}
\end{cases}
\end{align*}
\]

其中:j 为服务站,i 为需求点,\(w_i\) 为需求点 i 的需求量, \(d_{ij}\) 为需求点 i 到服务站 j 的距离。

2.2 P-中心问题

P-中心问题,假设有 N 个候选服务站和 M 个需求点,要从 N个候选服务站中选择 P个,使任一需求点到最近的服务站的最大距离最小。

这是一个 MinMax 问题,需要最小化任何需求点与其邻近设施点的最大距离。P-中位问题追求总和最小,可以理解为发展经济总量优先;P-中心问题关注最差个体的最好结果,可以理解为优先进行扶贫。

定义决策变量 \(x_j\) 为选中的服务站,\(y_{ij}\) 将各需求点匹配到最近的服务站:

\[x_j = \begin{cases} 1,& 服务站\ j\ 被选中\\ 0,& 服务站\ j\ 未被选中\end{cases}
\]
\[y_{ij} = \begin{cases} 1,& 需求点\ i\ 由服务站\ j\ 服务\\ 0,& 需求点\ i\ 不由服务站\ j\ 服务\end{cases}
\]

可以建立数学模型如下:

\[\begin{align*}
& min\; D\\
& s.t.:\;\begin{cases}
\sum_{j \in N} w_i d_{ij} y_{ij} \leq D, \forall i\\
\sum_{j \in N} x_{j} = P\\
\sum_{j \in N} y_{ij} = 1, \forall i\\
y_{ij} - x_j \leq 0, \forall i,j\\
x_{j} \in \{0,1\}, \;y_{ij} \in \{0,1\}
\end{cases}
\end{align*}
\]

其中:j 为服务站,i 为需求点, \(d_{ij}\) 为需求点 i 到服务站 j 的距离。如果只求需求点到最近的服务站的最大距离,则 \(w_i = 1\) ;如果要求任一需求点到最近的服务站的最大运费,则 \(w_i\) 为需求点 i 的需求量,即加权最大距离。

2.3 集合覆盖问题

覆盖模型适用于一些特殊场景,例如消防中心、救护车、巡逻车等应急设施的区位选址问题。覆盖问题分为集合覆盖问题(Set covering problem)和最大覆盖问题(Maximal covering problem)。

集合覆盖问题研究满足覆盖所有需求点顾客的前提下,服务站的最少个数或建设费用最小的问题。假设有 N 个候选服务站和 M 个需求点,已知每个服务站的服务范围(或服务容量),要从 N个候选服务站中选择若干个,使所有需求点得到服务(到所属服务站的距离或时间小于给定的临界值),服务站的个数最少或成本最小。

定义参数 \(a_{ij}\) 为每个服务站的覆盖范围:

\[a_{ij} =
\begin{cases}
1,& 服务站\ j\ 可以覆盖需求点\ i\\
0,& 服务站\ j\ 不能覆盖需求点\ i
\end{cases}
\]

定义决策变量 \(x_j\) 为选中的服务站:

\[x_j = \begin{cases} 1,& 服务站\ j\ 被选中\\ 0,& 服务站\ j\ 未被选中\end{cases}
\]

可以建立数学模型如下:

\[\begin{align*}
& min\; \sum_{j \in N} c_j x_{j}\\
& s.t.:\;\begin{cases}
\sum_{j \in N_i} x_j \geq 1, \forall i \in M\\
x_{j} \in \{0,1\}
\end{cases}
\end{align*}
\]

其中:j 为服务站,i 为需求点,\(c_j\) 为服务站 j 的建设费用(最少个数问题中不需要考虑),\(N_i=\{j:a_{ij}=1\}\) 是覆盖需求点 i 的候选服务站的集合。

2.4 最大覆盖问题

最大覆盖问题研究在已知服务站的数目和服务半径的条件下,如何设立 P个服务站使得可接受的服务需求最大的问题。

定义决策变量 \(x_j\) 为选中的服务站:

\[x_j =
\begin{cases}
1,& 服务站\ j\ 被选中\\
0,& 服务站\ j\ 未被选中
\end{cases}
\]
\[z_i =
\begin{cases}
1,& 需求点\ i\ 被覆盖\\
0,& 需求点\ i\ 未被覆盖\
\end{cases}
\]

可以建立数学模型如下:

\[\begin{align*}
& max\; \sum_{i \in N_i} w_i z_i\\
& s.t.:\;
\begin{cases}
z_i \leq \sum_{j \in N_i} x_j , \forall i \in M\\
\sum_{j \in M} x_j = p\\
x_{j} \in \{0,1\}, z_{i} \in \{0,1\}
\end{cases}
\end{align*}
\]

其中:j 为服务站,i 为需求点,\(w_i\) 为需求点 i 的需求量。

2.5 其它选址问题

其它选址问题,在数学建模中应用相对较少,限于篇幅不能逐一介绍其数学模型。在此将各模型的特点简要介绍,以便判断问题的类型。

带固定费用和容量限制的选址问题

服务站建站的固定费用和服务站的容量(能力)限制这两个因素具有很强的实际意义,经常作为基本选址问题的深化研究课题。

无容量限制的固定费用下的选址问题,就是去掉服务站个数的约束,并将固定建站费用加到 P-中位问题的目标函数上。

选址分配问题

选址分配问题类似于 P-中位问题,有 m 个服务站需要选址,n 个已知位置的顾客分配给不同的设施,已知每个服务站的能力和每个顾客的需求,要求服务站的选址和顾客对服务站的分配,使顾客与所分配服务站的距离总和最小。

随机选址问题

服务站的运行时间、建设成本、需求点位置、需求数量等全部或部分参数是不确定的,但服从某种随机分布。

动态选址问题

研究未来若干时间段内服务站的最优选址问题,在不同时间段内动态选址模型的参数是变化的,但在某一时间段内模型参数是确定的。

竞争选址问题

研究考虑市场上存在两个以上同类产品或服务的提供者,或服务站提供多个产品或服务。


2.6 选址问题的求解算法与编程实现

设施选址问题通常是是 NP 问题,不存在多项式时间算法。常用的近似解法有:

线性规划舍入算法,相当于整数规划问题的求解算法。首先给出原问题的整数规划模型,然后求解相应的线性规划松弛问题得到分数最优解,根据可行要求对分数最优解进行改造,构造原问题的整数可行解。

原始对偶算法,首先找到对偶问题的一个可行解,再根据该对偶可行解构造原始问题的整数可行解,不断调整对偶问题的可行解,直到找到最优解为止。

局部搜索算法:给定初始可行解,定义适当的邻域,通过引入恰当的调整策略,在邻域中得到改进的可行解,依次迭代,直到调整策略不能改进为止

启发式算法或随机优化算法。

本节作为线性规划问题系列的一篇,仍然选择 PuLP工具包求解选址问题。很多选址问题适合用图论方法描述和求解,这将在后续课程中进行介绍。


3. 案例 1:PuLP求解指派问题

说明:本案例是指派问题,不是选址问题。因指派问题未单独成文,因此将该案例放在本文中。

另外,本案例给出了 PuLP 工具包使用字典方式快捷编程的使用方法,这在选址问题中是非常方便的。

3.1 游泳接力赛的指派问题

游泳队中 A、B、C、D 四名运动员组成 4x100米混合泳接力队,运动员各种泳姿的成绩如下表所示:

队员\项目 自由泳 蛙泳 蝶泳 仰泳
A 56 74 61 63
B 63 69 65 71
C 57 77 63 67
D 55 76 62 62

如何安排 A、B、C、D 四名运动员的泳姿,才最有可能取得好成绩?

3.2 指派问题建模分析

引入 0-1 变量 \(x_{ij}\):

\[x_{i,j} = \begin{cases}
0,第\;i\;人不游第\;j\;种姿势\\
1,第\;i\;人游第\;j\;种姿势,i,j=1,...4
\end{cases}
\]

指派问题的数学模型就可以描述为:

\[\begin{align*}
& min\;f(x) = \sum_{i=1} ^n \sum_{j=1} ^n (c_{ij} x_{ij})\\
& s.t.:\;\begin{cases}
\sum_{j=1} ^n x_{ij} = 1,i=1,...,n\\
\sum_{i=1} ^n x_{ij} = 1,j=1,...,n\\
x_{ij} = 0,1,i,j=1,...,n
\end{cases}
\end{align*}
\]

其中:

\[c_{i,j}=\left(
\begin{matrix}
56 & 74 & 61 & 63 \\
63 & 69 & 65 & 71 \\
57 & 77 & 63 & 67 \\
55 & 76 & 62 & 62
\end{matrix}
\right)
\]

3.3 指派问题模型求解的编程

模型求解,用标准模型的优化算法对模型求解,得到优化结果。模型求解的编程步骤如下:

(0)导入 PuLP库函数

    import pulp

(1)定义一个规划问题

    AssignLP = pulp.LpProblem("Assignment_problem_for_swimming_relay_race", sense=pulp.LpMinimize)

pulp.LpProblem 用来定义问题的构造函数。参数 sense 指定问题求目标函数的最小值/最大值 。

(2)定义决策变量

    rows = cols = range(0, 4)
x = pulp.LpVariable.dicts("x", (rows, cols), cat="Binary")

pulp.LpVariable 用来定义决策变量的函数。参数 cat 设定变量类型,' Binary ' 表示 0/1 变量。

注意,指派问题、选址问题中都涉及 N*M 维矩阵变量,变量个数很多,如果逐一定义非常冗长,而且容易出错、不便修改。本例使用 pulp.LpVariable.dicts 提供的字典格式定义了 4*4 个变量 \(x_{ij}\),使程序大为简化。

(3)添加目标函数

    scoreM = [[56,74,61,63],[63,69,65,71],[57,77,63,67],[55,76,62,62]]
AssignLP += pulp.lpSum([[x[row][col]*scoreM[row][col] for row in rows] for col in cols])

本例程在语句内使用两重 for 循环遍历列表实现所有变量的线性组合 ,使程序大为简化。

(4)添加约束条件

    for row in rows:
AssignLP += pulp.lpSum([x[row][col] for col in cols]) == 1 # sum(x(i,j),j=1,4)=1, i=1,4
for col in cols:
AssignLP += pulp.lpSum([x[row][col] for row in rows]) == 1 # sum(x(i,j),i=1,4)=1, j=1,4

快捷方法对于约束条件的定义与对目标函数的定义相似,使用字典定义参数,使用循环定义约束条件,使程序简单、结构清楚。

(5)求解和结果输出

    AssignLP.solve()  # youcans
print(AssignLP.name)
member = ["队员A","队员B","队员C","队员D"]
style = ["自由泳","蛙泳","蝶泳","仰泳"]
if pulp.LpStatus[AssignLP.status] == "Optimal": # 获得最优解
xValue = [v.varValue for v in AssignLP.variables()]
# [0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]
xOpt = np.array(xValue).reshape((4, 4)) # 将 xValue 格式转换为 4x4 矩阵
print("最佳分配:" )
for row in rows:
print("{}\t{} 参加项目:{}".format(xOpt[row],member[row],style[np.argmax(xOpt[row])]))
print("预测最好成绩为:{}".format(pulp.value(AssignLP.objective)))

xValue 获得的是列表变量,通过 numpy 的 reshape() 函数转换为 4*4 矩阵,便于格式化输出。

3.4 指派问题 Python 例程

# mathmodel08_v1.py
# Demo08 of mathematical modeling algorithm
# Solving assignment problem with PuLP.
# Copyright 2021 Youcans, XUPT
# Crated:2021-06-02
# Python小白的数学建模课 @ Youcans import pulp # 导入 pulp 库
import numpy as np # 主程序
def main():
# 问题建模:
"""
决策变量:
x(i,j) = 0, 第 i 个人不游第 j 种姿势
x(i,j) = 1, 第 i 个人游第 j 种姿势
i=1,4, j=1,4
目标函数:
min time = sum(sum(c(i,j)*x(i,j))), i=1,4, j=1,4
约束条件:
sum(x(i,j),j=1,4)=1, i=1,4
sum(x(i,j),i=1,4)=1, j=1,4
变量取值范围:
x(i,j) = 0,1
""" # 游泳比赛的指派问题 (assignment problem)
# 1.建立优化问题 AssignLP: 求最小值(LpMinimize)
AssignLP = pulp.LpProblem("Assignment_problem_for_swimming_relay_race", sense=pulp.LpMinimize) # 定义问题,求最小值
# 2. 建立变量
rows = cols = range(0, 4)
x = pulp.LpVariable.dicts("x", (rows, cols), cat="Binary")
# 3. 设置目标函数
scoreM = [[56,74,61,63],[63,69,65,71],[57,77,63,67],[55,76,62,62]]
AssignLP += pulp.lpSum([[x[row][col]*scoreM[row][col] for row in rows] for col in cols])
# 4. 施加约束
for row in rows:
AssignLP += pulp.lpSum([x[row][col] for col in cols]) == 1 # sum(x(i,j),j=1,4)=1, i=1,4
for col in cols:
AssignLP += pulp.lpSum([x[row][col] for row in rows]) == 1 # sum(x(i,j),i=1,4)=1, j=1,4
# 5. 求解
AssignLP.solve() # youcans
# 6. 打印结果
print(AssignLP.name)
member = ["队员A","队员B","队员C","队员D"]
style = ["自由泳","蛙泳","蝶泳","仰泳"]
if pulp.LpStatus[AssignLP.status] == "Optimal": # 获得最优解
xValue = [v.varValue for v in AssignLP.variables()]
# [0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]
xOpt = np.array(xValue).reshape((4, 4)) # 将 xValue 格式转换为 4x4 矩阵
print("最佳分配:" )
for row in rows:
print("{}\t{} 参加项目:{}".format(xOpt[row],member[row],style[np.argmax(xOpt[row])]))
print("预测最好成绩为:{}".format(pulp.value(AssignLP.objective))) return if __name__ == '__main__': # Copyright 2021 YouCans, XUPT
main() # Python小白的数学建模课 @ Youcans

3.5 Python 例程运行结果

Welcome to the CBC MILP Solver
Version: 2.9.0
Build Date: Feb 12 2015 Result - Optimal solution found Assignment_problem_for_swimming_relay_race
最佳分配:
[0. 0. 1. 0.] 队员A 参加项目:蝶泳
[0. 1. 0. 0.] 队员B 参加项目:蛙泳
[1. 0. 0. 0.] 队员C 参加项目:自由泳
[0. 0. 0. 1.] 队员D 参加项目:仰泳
预测最好成绩为:249.0

4. 案例 2:PuLP求解选址问题

4.1 消防站的选址问题

例题 2:某城市有 8 个区,每个区最多建一个消防站,拟建设消防站到各区的最长时间如下表所示。现要求任何区域发生火警时,消防车能在 10分钟内赶到。在此条件下尽量减少消防站数量,应该在哪几个区建设消防站?

区域 1 2 3 4 5 6 7 8
1 7 12 18 20 24 26 25 28
2 14 5 8 15 16 18 18 18
3 19 9 4 14 10 22 16 13
4 14 15 15 10 18 15 14 18
5 20 18 12 20 9 25 14 12
6 18 21 20 16 20 6 10 15
7 22 18 20 15 16 15 5 9
8 30 22 15 20 14 18 8 6

4.2 选址问题建模分析

首先判断这是一个集合覆盖问题,要求从 8 个候选消防站中选择若干个,在所有需求点得到服务的时间都小于临界值 10分钟的条件下,选择消防站的数量最少。本问题不考虑各候选站点建设费用的差异,即不带权重。

定义参数 \(R_{ij}\) 为每个消防站的覆盖范围:

\[R_{ij} =
\begin{cases}
1,& 消防站\ j\ 可以覆盖区域\ i\\
0,& 消防站\ j\ 不能覆盖区域\ i
\end{cases}
\]

由拟建消防站到各区的最长时间表可以得到参数 \(R_{ij}\) 如下表:

区域 1 2 3 4 5 6 7 8
1 1 0 0 0 0 0 0 0
2 0 1 1 0 0 0 0 0
3 0 1 1 0 1 0 0 0
4 0 0 0 1 0 0 0 0
5 0 0 0 0 1 0 0 0
6 0 0 0 0 0 1 1 0
7 0 0 0 0 0 0 1 1
8 0 0 0 0 0 0 1 1

定义决策变量 \(x_j\) 为选中的服务站:

\[x_j = \begin{cases} 1,& 消防站\ j\ 被选中\\ 0,& 消防站\ j\ 未被选中\end{cases}
\]

可以建立数学模型如下:

\[\begin{align*}
& min\; f(x) = \sum_{j=1}^8 x_{j}\\
& s.t.:\;\begin{cases}
\sum_{j=1}^8 x_j R_{ij} \geq 1, &i=1,..8\\
x_{j} \in \{0,1\}, &j=1,..8
\end{cases}
\end{align*}
\]

选址问题的模型求解,用标准模型的优化算法对模型求解,得到优化结果。

模型求解的编程步骤与指派问题是一致的,且在例程中给出了详细的注释,就不再进行逐项解释了。

需要注意的是,选址问题的决策变量、参数、约束条件的数量较大(N*M),如果对变量、约束条件逐个进行定义,编程过程将是非常冗长和痛苦的,因此需要使用列表、字典等快捷方式进行定义。对于更大规模的问题,模型中的数据要通过读取数据文件获得,就更需要采用这种方式来编程。

4.3 选址问题 Python 例程

# mathmodel09_v1.py
# Demo08 of mathematical modeling algorithm
# Solving set covering problem with PuLP.
# Copyright 2021 Youcans, XUPT
# Crated:2021-06-06
# Python小白的数学建模课 @ Youcans import pulp # 导入 pulp 库 # 主程序
def main(): # 问题建模:
"""
决策变量:
x(j) = 0, 不选择第 j 个消防站
x(j) = 1, 选择第 j 个消防站, j=1,8
目标函数:
min fx = sum(x(j)), j=1,8
约束条件:
sum(x(j)*R(i,j),j=1,8) >=1, i=1,8
变量取值范围:
x(j) = 0,1
""" # 消防站的选址问题 (set covering problem, site selection of fire station)
# 1.建立优化问题 SetCoverLP: 求最小值(LpMinimize)
SetCoverLP = pulp.LpProblem("SetCover_problem_for_fire_station", sense=pulp.LpMinimize) # 定义问题,求最小值
# 2. 建立变量
zones = list(range(8)) # 定义各区域 youcans
x = pulp.LpVariable.dicts("zone", zones, cat="Binary") # 定义 0/1 变量,是否在该区域设消防站
# 3. 设置目标函数
SetCoverLP += pulp.lpSum([x[j] for j in range(8)]) # 设置消防站的个数
# 4. 施加约束
reachable = [[1, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 0, 0, 0, 0, 0],
[0, 1, 1, 0, 1, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 1, 0],
[0, 0, 0, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 0, 0, 1, 1]] # 参数矩阵,第 i 消防站能否在 10分钟内到达第 j 区域
for i in range(8):
SetCoverLP += pulp.lpSum([x[j]*reachable[j][i] for j in range(8)]) >= 1 # 5. 求解
SetCoverLP.solve()
# 6. 打印结果
print(SetCoverLP.name)
temple = "区域 %(zone)d 的决策是:%(status)s" # 格式化输出
if pulp.LpStatus[SetCoverLP.status] == "Optimal": # 获得最优解
for i in range(8):
output = {'zone': i+1, # 与问题中区域 1~8 一致
'status': '建站' if x[i].varValue else '--'}
print(temple % output)
print("需要建立 {} 个消防站。".format(pulp.value(SetCoverLP.objective))) return if __name__ == '__main__': # Copyright 2021 YouCans, XUPT
main() # Python小白的数学建模课 @ Youcans

4.4 Python 例程运行结果

Welcome to the CBC MILP Solver
Version: 2.9.0
Build Date: Feb 12 2015 Result - Optimal solution found SetCover_problem_for_fire_station
区域 1 的决策是:建站
区域 2 的决策是:--
区域 3 的决策是:建站
区域 4 的决策是:建站
区域 5 的决策是:--
区域 6 的决策是:建站
区域 7 的决策是:建站
区域 8 的决策是:--
需要建立 5.0 个消防站

5. 小结

  1. 关于规划问题,我们从线性规划、整数规划、0-1规划到一些特殊类型问题,用 5节课进行了介绍,到这里就暂告一段落了。后面根据需要,可能还会讲非线性规划,实际上主要是非线性优化问题了。
  2. 虽然各种规划问题的求解算法差别很大,但我们所用的编程实现方法都是基于 PuLP工具包,编程步骤都是一致的。
  3. 本系列集中体现了与其它课程的区别,没有展开讲算法的实现步骤,而是重点讲编程方法的选择、建立模型方程的过程和编程实现的步骤,这主要是为了便于小白学习和掌握。

【本节完】

版权声明:

欢迎关注『Python小白的数学建模课 @ Youcans』 原创作品

原创作品,转载必须标注原文链接。

Copyright 2021 Youcans, XUPT

Crated:2021-06-06

欢迎关注 『Python小白的数学建模课 @ Youcans』,每周更新数模笔记

Python小白的数学建模课-01.新手必读

Python小白的数学建模课-02.数据导入

Python小白的数学建模课-03.线性规划

Python小白的数学建模课-04.整数规划

Python小白的数学建模课-05.0-1规划

Python小白的数学建模课-A1.国赛赛题类型分析

Python小白的数学建模课-A2.2021年数维杯C题探讨

Python小白的数学建模课-A3.12个新冠疫情数模竞赛赛题及短评

Python数模笔记-PuLP库

Python数模笔记-StatsModels统计回归

Python数模笔记-Sklearn

Python数模笔记-NetworkX

Python数模笔记-模拟退火算法

Python小白的数学建模课-07 选址问题的更多相关文章

  1. Python小白的数学建模课-B5. 新冠疫情 SEIR模型

    传染病的数学模型是数学建模中的典型问题,常见的传染病模型有 SI.SIR.SIRS.SEIR 模型. 考虑存在易感者.暴露者.患病者和康复者四类人群,适用于具有潜伏期.治愈后获得终身免疫的传染病. 本 ...

  2. Python小白的数学建模课-B6. 新冠疫情 SEIR 改进模型

    传染病的数学模型是数学建模中的典型问题,常见的传染病模型有 SI.SIR.SIRS.SEIR 模型. SEIR 模型考虑存在易感者.暴露者.患病者和康复者四类人群,适用于具有潜伏期.治愈后获得终身免疫 ...

  3. Python小白的数学建模课-B4. 新冠疫情 SIR模型

    Python小白的数学建模课-B4. 新冠疫情 SIR模型 传染病的数学模型是数学建模中的典型问题,常见的传染病模型有 SI.SIR.SIRS.SEIR 模型. SIR 模型将人群分为易感者(S类). ...

  4. Python小白的数学建模课-16.最短路径算法

    最短路径问题是图论研究中的经典算法问题,用于计算图中一个顶点到另一个顶点的最短路径. 在图论中,最短路径长度与最短路径距离却是不同的概念和问题,经常会被混淆. 求最短路径长度的常用算法是 Dijkst ...

  5. Python小白的数学建模课-12.非线性规划

    非线性规划是指目标函数或约束条件中包含非线性函数的规划问题,实际就是非线性最优化问题. 从线性规划到非线性规划,不仅是数学方法的差异,更是解决问题的思想方法的转变. 非线性规划问题没有统一的通用方法, ...

  6. Python小白的数学建模课-15.图论基本概念

    图论中所说的图,不是图形图像或地图,而是指由顶点和边所构成的图形结构. 图论不仅与拓扑学.计算机数据结构和算法密切相关,而且正在成为机器学习的关键技术. 本系列结合数学建模的应用需求,来介绍 Netw ...

  7. Python小白的数学建模课-19.网络流优化问题

    流在生活中十分常见,例如交通系统中的人流.车流.物流,供水管网中的水流,金融系统中的现金流,网络中的信息流.网络流优化问题是基本的网络优化问题,应用非常广泛. 网络流优化问题最重要的指标是边的成本和容 ...

  8. Python小白的数学建模课-17.条件最短路径

    条件最短路径问题,指带有约束条件.限制条件的最短路径问题.例如: 顶点约束,包括必经点或禁止点的限制: 边的约束,包括必经路段.禁行路段和单向路段:无权路径长度的限制,如要求经过几步或不超过几步到达终 ...

  9. Python小白的数学建模课-18.最小生成树问题

    最小生成树(MST)是图论中的基本问题,具有广泛的实际应用,在数学建模中也经常出现. 路线设计.道路规划.官网布局.公交路线.网络设计,都可以转化为最小生成树问题,如要求总线路长度最短.材料最少.成本 ...

随机推荐

  1. Tomcat管理弱口令页面Getshell

    目录 弱口令Getshell 利用Burpsuite对tomcat账号密码进行爆破 弱口令Getshell Tomcat安装完成后会有如下页面,点击该页面的 Manager App 处会弹出输入用户名 ...

  2. JetBrains系列软件用法

    IDEA JSON格式化 IDEA的JSON_Formatter插件,下载地址 安装方式:File->Settings->Plugins,然后选择INstall plugin from d ...

  3. .NET Core with 微服务 - 什么是微服务

    微服务是这几年最流行的架构,说起架构不提微服务都不好意思跟人家打招呼.最近想要再梳理一下关于微服务的知识,并且结合本人的一些实践经验来做一些总结与分享.前面会分享一些概念性的东西,后面也会使用.net ...

  4. JavaScript 包管理器 -Yarn

    Fast, reliable, and secure dependency management. 官网地址 Github 特性 离线模式:如果您之前下载了软件包,则可以在没有任何互联网连接的情况下安 ...

  5. Linux 中如何使用 IP 命令

    老版本的 Linux 中都是使用 ifconfig 命令检查和配置网络接口,但是该命令目前已经没有维护了,取而代之的是 ip 命令 ip 命令和 ifconfig 命令很相似,但是 相比起来,ip命令 ...

  6. JVM核心技术(第一篇)

    目录 Java基础知识 一. 字节码技术 二.JVM类加载器 类的加载时机 三.JVM内存结构 四.JVM启动参数 4.1 系统属性参数 4.2 运行模式 4.3 堆内存 4.4 GC相关 4.5 分 ...

  7. Flutter 2.2 现已发布!

    在本次 Google I/O 2021 大会 上,我们正式发布了 Flutter 2.2.Flutter 2.2 是我们最新版的开源工具包,可让开发者立足单个平台构建适合任何设备的精美应用.Flutt ...

  8. [Linux]常用命令、组合命令以及输入输出重定向

    [Linux]常用命令.组合命令以及输入输出重定向 2020-03-10阅读 1580   原创文章 文章目录 0.切换目录 1.复制文件和目录`cp` 1.1.复制文件 1.2.复制目录 1.3.扩 ...

  9. Deepin/Uos系统更新源失败。提示:E: 仓库 “http://packages.chinauos.cn/uos eagle InRelease” 没有数字签名

    Deepin/Uos系统更新源失败.提示:E: 仓库 "http://packages.chinauos.cn/uos eagle InRelease" 没有数字签名 n大橘为重n ...

  10. Linux进阶之进程管理

    本节内容 1.进程管理 2.ps 3.uptime 4.top 5.ss -tnl------ lsof -i :22 一. 进程管理的概念 程序:二进制文件,静态 /bin/date,/usr/sb ...