例 1: 设备更新问题
某种工程设备的役龄为 4 年, 每年年初都面临着是否更新的问题: 若卖旧买新, 就要支付一定的购置费用; 若继续使用, 则要支付更多的维护费用, 且使用年限越长维护费用越多. 役龄期内每年的年初购置价格, 当年维护费用及年末剩余净值如下表所示. 为该设备制定一个 4 年役龄期内的更新计划, 使总的支付费用最少.
年份 | 1 | 2 | 3 | 4 |
---|---|---|---|---|
年初购置价格 (万元) | 25 | 26 | 28 | 31 |
当年维护费用 (万元) | 10 | 14 | 18 | 26 |
年末剩余净值 (万元) | 20 | 16 | 13 | 11 |
可以把这个问题化为图论中的最短路问题.
构造赋权有向图
D
=
(
V
,
A
,
W
)
D=(V, A, W)
D=(V,A,W), 其中顶点集
V
=
{
v
1
,
v
2
,
⋯
,
v
5
}
V=\left\{v_{1}, v_{2}, \cdots, v_{5}\right\}
V={v1,v2,⋯,v5}, 这里
v
i
v_{i}
vi
(
i
=
1
,
2
,
3
,
4
)
(i=1,2,3,4)
(i=1,2,3,4) 表示第
i
i
i 年年初的时刻,
v
5
v_{5}
v5 表示第 4 年年末的时刻,
A
A
A 为边集, 邻接矩阵
W
=
(
w
i
j
)
5
×
5
W=\left(w_{i j}\right)_{5 \times 5}
W=(wij)5×5, 这里
w
i
j
w_{i j}
wij 为第
i
i
i 年年初至第
j
j
j 年年初 (或
j
−
1
j-1
j−1 年年末) 期间所支付的费用, 计算公式为
w
i
j
=
p
i
+
∑
k
=
1
j
−
i
a
k
−
r
j
−
i
,
w_{i j}=p_{i}+\sum_{k=1}^{j-i} a_{k}-r_{j-i},
wij=pi+k=1∑j−iak−rj−i,
其中 p i p_{i} pi 为第 i i i 年年初的购置价格, a k a_{k} ak 为使用到第 k k k 年当年的维护费用, r i r_{i} ri 为使用 i i i 年旧设备的出售价格.
则邻接矩阵
W
=
[
0
15
33
54
82
∞
0
16
34
55
∞
∞
0
18
36
∞
∞
∞
0
21
∞
∞
∞
∞
0
]
.
W=\left[\begin{array}{ccccc} 0 & 15 & 33 & 54 & 82 \\ \infty & 0 & 16 & 34 & 55 \\ \infty & \infty & 0 & 18 & 36 \\ \infty & \infty & \infty & 0 & 21 \\ \infty & \infty & \infty & \infty & 0 \end{array}\right] .
W=⎣⎢⎢⎢⎢⎡0∞∞∞∞150∞∞∞33160∞∞5434180∞825536210⎦⎥⎥⎥⎥⎤.
则制定总的支付费用最小的设备更新计划, 就是求有向图 D D D 从顶点 v 1 v_{1} v1 到页点 v 5 v_{5} v5 的最短路.
import numpy as np
import networkx as nx
import pylab as plt
p=[25,26,28,31]; a=[10,14,18,26]; r=[20,16,13,11]
b=np.zeros((5,5)); #初始化邻接矩阵
for i in range(5):
for j in range(i+1,5):
b[i,j]=p[i]+np.sum(a[0:j-i])-r[j-i-1];
print(b)
G=nx.DiGraph(b)
p=nx.dijkstra_path(G, source=0, target=4, weight='weight') #求最短路径;
print("最短路径为:",np.array(p)+1) #python下标从0开始
d=nx.dijkstra_path_length(G, 0, 4, weight='weight') #求最短距离
print("所求的费用最小值为:",d)
s=dict(zip(range(5),range(1,6))) #构造用于顶点标注的标号字典
plt.rc('font',size=16)
pos=nx.shell_layout(G) #设置布局
w=nx.get_edge_attributes(G,'weight')
nx.draw(G,pos,font_weight='bold',labels=s,node_color='r')
nx.draw_networkx_edge_labels(G,pos,edge_labels=w)
path_edges=list(zip(p,p[1:]))
nx.draw_networkx_edges(G,pos,edgelist=path_edges,edge_color='r',width=3) #画出最短路径
#plt.savefig("figure10_9.png",pdi=500);
plt.show()
[[ 0. 15. 33. 54. 82.]
[ 0. 0. 16. 34. 55.]
[ 0. 0. 0. 18. 36.]
[ 0. 0. 0. 0. 21.]
[ 0. 0. 0. 0. 0.]]
最短路径为: [1 2 3 5]
所求的费用最小值为: 67.0
求得 v 1 v_{1} v1 到 v 5 v_{5} v5 的最短路径为 v 1 → v 2 → v 3 → v 5 v_{1} \rightarrow v_{2} \rightarrow v_{3} \rightarrow v_{5} v1→v2→v3→v5, 最短路径的长度为67. 即设备更新计划为第1年年初买进新设备, 使用到第 1 年年底, 第 2 年年初购进新设备, 使用到第 2 年年底, 第 3 年年初再购进新设备, 使用到第 4 年年底.
例 2: 重心问题
重心问题指有些公共服务设施 (例如邮局, 学校等) 的选址, 要求设施到所有服务对象点的距离总和最小. 一般要考虑人口密度问题, 或者全体被服务对象来往的总路程最短. 例如下面的问题:
某矿区有六个产矿点, 如图所示, 已知各产矿点每天的产矿量 (标在图中的各顶点旁) 为 q i ( i = 1 , 2 , ⋯ , 6 ) q_{i}(i=1,2, \cdots, 6) qi(i=1,2,⋯,6) 吨, 现要从这六个产矿点选一个来建造选矿厂, 问应选在哪个产矿点, 才能使各产矿点所产的矿石运到选矿厂所在地的总运力 (吨·公里) 最小.
令 d i j ( i , j = 1 , 2 , ⋯ , 6 ) d_{i j}(i, j=1,2, \cdots, 6) dij(i,j=1,2,⋯,6) 表示顶点 v i v_{i} vi 与 v j v_{j} vj 之间的距离. 若选矿厂设在 v i v_{i} vi 并且各产矿点到选矿厂的总运力为 m i m_{i} mi, 则确定选矿厂的位置就转化为求 m k m_{k} mk, 使得 m k = min 1 ≤ i ≤ 6 m i m_{k}=\min _{1 \leq i \leq 6} m_{i} mk=min1≤i≤6mi.
由于各产矿点到选矿厂的总运力依赖于任意两顶点之间的距离, 即任意两顶点之间最短路的长度, 因此可首先利用 Dijkstra (或 Floyd) 算法求出所有顶点对之间的最短距离, 然后计算出顶点
v
i
v_{i}
vi 设立选矿厂时各产矿点到
v
i
v_{i}
vi 的总运力
m
i
=
∑
j
=
1
6
q
j
d
i
j
,
i
=
1
,
2
,
⋯
,
6.
m_{i}=\sum_{j=1}^{6} q_{j} d_{i j}, \quad i=1,2, \cdots, 6.
mi=j=1∑6qjdij,i=1,2,⋯,6.
最后利用 min 1 ≤ i ≤ 6 m i \min _{1 \leq i \leq 6} m_{i} min1≤i≤6mi 选择设置选矿厂的位置.
计算的 Python 程序如下:文章来源:https://www.toymoban.com/news/detail-468397.html
import numpy as np
import networkx as nx
List=[(1,2,20),(1,5,15),(2,3,20),(2,4,40),
(2,5,25),(3,4,30),(3,5,10),(5,6,15)]
G=nx.Graph()
G.add_nodes_from(range(1,7))
G.add_weighted_edges_from(List)
c=dict(nx.shortest_path_length(G,weight='weight'))
d=np.zeros((6,6))
for i in range(1,7):
for j in range(1,7): d[i-1,j-1]=c[i][j]
print(d)
q=np.array([80,90,30,20,60,10])
m=d@q #计算运力,这里使用矩阵乘法
mm=m.min() #求运力的最小值
ind=np.where(m==mm)[0]+1 #python下标从0开始,np.where返回值为元组
print("运力m=",m,'\n最小运力mm=',mm,"\n选矿厂的设置位置为:",ind)
[[ 0. 20. 25. 55. 15. 30.]
[20. 0. 20. 40. 25. 40.]
[25. 20. 0. 30. 10. 25.]
[55. 40. 30. 0. 40. 55.]
[15. 25. 10. 40. 0. 15.]
[30. 40. 25. 55. 15. 0.]]
运力m= [ 4850. 4900. 5250. 11850. 4700. 8750.]
最小运力mm= 4700.0
选矿厂的设置位置为: [5]
min 1 ≤ i ≤ 6 m i = m 5 \min _{1 \leq i \leq 6} m_{i}=m_{5} min1≤i≤6mi=m5, 所以 v 5 v_{5} v5 为设置选矿厂的位置文章来源地址https://www.toymoban.com/news/detail-468397.html
到了这里,关于数学建模:图论模型 — 最短路模型示例 (Python 求解)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!