2021年高教杯数学建模国赛C题的解题过程附全部代码以及参赛论文(百度网盘) 2 \. Z& u1 [% O8 B3 q' p # {5 A" g1 B' G4 P, `7 `8 _4 T我们小组参加了2021年数学建模,本人负责代码方面,此文仅为自己的思考理解+代码分析+题目分析% N { }7 W( P8 F
题目: 9 \8 b& ^6 L1 I注:试题完整版和对应的附件在我另一篇文章里面+ D% H' P3 v8 S4 P# k/ T
. h0 C q+ i* N0 t某建筑和装饰板材的生产企业所用原材料主要是木质纤维和其他植物素纤维材料,总体可分为 A,B,C 三种类型。该企业每年按 48 周安排生产,需要提前制定 24 周的原材料订购和转运计划,即根据产能要求确定需要订购的原材料供应商(称为“供应商”)和相应每周的原材料订购数量(称为“订货量”),确定第三方物流公司(称为“转运商”)并委托其将供应商每周的原材料供货数量(称为“供货量”)转运到企业仓库。+ E( Z. `' Q. j# m" O
该企业每周的产能为 2.82 万立方米,每立方米产品需消耗 A 类原材料0.6 立方米,或 B 类原材料 0.66 立方米,或 C 类原材料 0.72 立方米。由于原材料的特殊性,供应商不能保证严格按订货量供货,实际供货量可能多于或少于订货量。为了保证正常生产的需要,该企业要尽可能保持不少于满足两周生产需求的原材料库存量,为此该企业对供应商实际提供的原材料总是全部收购。在实际转运过程中,原材料会有一定的损耗(损耗量占供货量的百分比称为“损耗率”),转运商实际运送到企业仓库的原材料数量称为“接收量”。每家转运商的运输能力为 6000 立方米/周。通常情况下,一家供应商每周供应的原材料尽量由一家转运商( ]" W8 c m5 B, W3 l
运输。原材料的采购成本直接影响到企业的生产效益,实际中 A 类和 B 类原材料的采购单价分别比 C 类原材料高 20%和 10%。三类原材料运输和储存的单位费用相同。附件 1 给出了该企业近 5 年 402 家原材料供应商的订货量和供货量数据。附件 2 给出了 8 家转运商的运输损耗率数据。请你们团队结合实际情况,对相关数据进行深入分析,研究下列问题: # \1 a! R! J* T4 U; x5 V( t1.根据附件 1,对 402 家供应商的供货特征进行量化分析,建立反映保障企业生产重要性的数学模型,在此基础上确定 50 家最重要的供应商,并在论文中列表给出结果。8 I6 l# P. P6 h% z# R' l
2.参考问题 1,该企业应至少选择多少家供应商供应原材料才可能满足生产的需求?针对这些供应商,为该企业制定未来 24 周每周最经济的原材料订购方案,并据此制定损耗最少的转运方案。试对订购方案和转运方案的实施效果进行分析。 ; T& j j% l5 k% s! l4 @3.该企业为了压缩生产成本,现计划尽量多地采购 A 类和尽量少地采购 C 类原材料,以减少转运及仓储的成本,同时希望转运商的转运损耗率尽量少。请制定新的订购方案及转运方案,并分析方案的实施效果。 ' o0 G1 f3 F( k, l& B4.该企业通过技术改造已具备了提高产能的潜力。根据现有原材料的供应商和转运商的实际情况,确定该企业每周的产能可以提高多少,并给出未来 24 周的订购和转运方案。 6 r: l1 J' L* h: t" \. S" [ + `* J, o" i- \3 A$ F$ y第一问: ; j. [' s/ g$ b7 [$ T+ L: {理论分析: 9 W1 ^$ w3 e8 `+ }该企业每周的产能为 2.82 万立方米,按照每立方米产品需消耗 A 类原材料 0.6 立方米,或 B 类原材料 0.66 立方米,或 C 类原材料 0.72 立方米。按原材料的最小需求量算是2.82万✖0.6=16920,按原材料的最大需求量算是2.82万✖0.72=20304。而我们根据excel表格计算402家每周所有的供应量仅仅只有40+周是肯定能满足要求的(即是该周供应量超过20304),有50+周是不一定能满足的(即是该周供应量在16920到20304之间),还有140周是一定不能满足要求的,既然402家供应商全部供应量加起来都不一定能达到所需产能,那选择最重要的50家企业就需要以这个供应量为标准,然后我们又考虑到了有些供应商的数据非常奇怪(连续几周供应量非常低,然后突然供应量达到最大值),如图0 S5 S# e! F( Z8 j
( U2 R* q! q" K6 I1 e, w0 z) C像这种我们就需要考虑他的方差,我们需要把这两个因素考虑进去,从而在402家供应商里面挑选50家最重要供应商,我们把每周的供应量进行排序,给每一家供应商一个排名,如果遇到供应量相同的供应商,给一个相同的排名,某家企业240周每周的排名的平均值即是以权值相等去同时考虑供应量和方差。以这个平均值去排序得到前50家供应商就是我们需要的最重要50家供应商。8 W: ^9 j8 A" w' z
代码分析:9 E L7 g' b( `6 U! S0 D7 Z
首先需要从excel表格中读取402家供应商的240周的数据, 1 Y7 V! j9 I2 s- R A. }+ N: U, ~0 k. Q1 e% ^$ s; H
import xlrd 3 x0 |; o, k! x) P0 Q; i; }3 [8 }file_location = "C:/Users/95870/Desktop/数学建模代码/a.xlsx"#这个位置需要更改,否则不能运行# K/ O- s7 n _9 \
data = xlrd.open_workbook(file_location) M O& W1 x5 ?2 Q- @ $ U( _) Z" B$ E6 ~; T) l/ |sheet = data.sheet_by_index(1) # 引用第二个表 $ c+ K: Q& W `" e) s: r8 P0 @5 xsheet2=data.sheet_by_index(0) # 引用第一个表 7 [: B) x' j/ R ]7 ^1 s0 _* A & H3 |: E6 `, i% V# m+ {& C3 ]0 X. b! m0 c3 m
4 C" ^/ ]9 j8 A( `, P3 b6 E& u
data = [[sheet.cell_value(r,c) for c in range(sheet.ncols)] for r in range(sheet.nrows)] #读取该表1中所有的数据 * L& Z, e3 ~' ~1 `# A' o/ P- E, Ndata_d=[[sheet2.cell_value(r,c) for c in range(sheet2.ncols)] for r in range(sheet2.nrows)] #读取该表2中所有的数据 ( m3 B, @6 j) t! Z. j: x, e1# Y8 D; ?; o' [2 ]
23 J3 @! I0 ]! d7 L1 f2 @6 N H
3 1 w* d, `* _' a! z4 V/ o2 [* |48 b- J9 T) _# F9 T! t& G- ]
53 }: E# _. q! b5 I: Q) u8 s
6 ' J0 y1 M6 h2 v- T8 _& g7 ; N' s8 Z6 g8 t; ~+ {" V8 . \: c& E" g) ]+ n$ H+ {( I% Y9 5 {; o3 `- N7 |" ], m; |10 - j$ i& y9 ^3 D3 e: ~2 ?# S' L11; O8 t7 |: L( m( x
定义了一个列表,num_list(402✖240),用以存放每家供应商每周的排名(这个排名是没有并序的,就是数据相同的按照供应商号码进行排序),然后用冒泡法把402家供应商240周的供应量进行排序,并根据供应商号有一个对应关系,然后将排名进行并行排序,然后算排名的平均值,根据平均值再进行排序,前50家就是我们需要的50家最重要供应商(结果如图)。( h2 L: D3 g/ f
: E1 l$ G: y% I/ v0 z代码如下:6 N, v7 _- k2 y2 p
" `9 o3 F" F9 e4 v
# -*- coding: utf-8 -*-9 q; d& i6 `8 ]0 X; M& z! D
import xlrd , b' W% M! @7 K7 M" o8 {* E( T* Dfile_location = "C:/Users/95870/Desktop/数学建模代码/a.xlsx" - \3 R, y+ B& p7 A& Bdata = xlrd.open_workbook(file_location) & ]( n; B; z1 A, _" [2 w( K / a4 v7 H- p1 T. V1 z+ S' Gsheet = data.sheet_by_index(1): v2 Z0 Q, B% h2 I* u
sheet2=data.sheet_by_index(0)* B1 _, q' ^+ d" M; D% ^# j. _
- p7 `( ?) Q3 z0 ~1 G K9 Z 9 Q7 _2 g+ M+ l v& \% H; ` 8 Q) a% G, H$ F6 ?5 |data = [[sheet.cell_value(r,c) for c in range(sheet.ncols)] for r in range(sheet.nrows)]8 ~) k) X* n0 P5 S. O9 u+ r
2 c3 p5 N J& y' h/ G% b+ K#排名 2 G. V! S! q2 U+ Z. nimport numpy 3 N! e5 F6 ^! \, f/ u, S. Cnum_list = numpy.zeros((402,240))) v8 F4 z! o, a
for i in range(0,402): , g/ k/ `2 z, t! B! E; m for j in range(0,240):# |3 A( v3 n) W5 u
num_list[i][j] = i+1 1 k6 N* p* p7 C; W6 C" {% Z" L5 O9 T' u1 D
9 h6 z) m- Y' u( q" l* U
#把数据按每周进行排序 ( a' g' L x$ E2 i2 L& h6 K0 ?4 Ofor k in range (240): 9 X0 E' p, H5 H( U for i in range (0,402):7 B# o M. Q- @- K9 W/ R
for j in range(0,401-i): W: v/ P- P: C& p$ T( U8 C. o/ y
if data[j+1][k+2]<data[j+2][k+2]: 3 \% P1 {$ T4 r9 S+ T (data[j+1][k+2],data[j+2][k+2])=(data[j+2][k+2],data[j+1][k+2])+ ^+ P% T9 k# @/ g* y
(num_list[j][k],num_list[j+1][k])=(num_list[j+1][k],num_list[j][k]) ) q9 H+ }6 e j Z + T" L# C& M( A6 y% G; y! H ( e) e3 @: G1 `1 U& F/ L#排名相同的同一个排名(进行并序排名) " O. l: l' A5 v2 W* ^: e & c: }* W. @. j3 [) a; c7 A; |y = numpy.zeros((402,240)) 2 Y' `/ m, M1 Ofor i in range (0,240): 9 L3 D, d' E- Q3 H$ H& s a=1 . s' e0 N& F5 B: ? y[0][i]=1. o' f% { H/ F! H: ?& k
n=1 ! f& b2 |) ^0 Q$ P3 E for j in range(0,401): x9 f# f5 r% T8 g" C. I& o; q5 }& I
if data[j+1][i+2]==data[j+2][i+2]:; n( S6 p3 E+ R# B* A& k( x* ?
y[j+1][i]=y[j][i]/ X3 `: E. a/ B! x
n=n+1 . l" K7 G$ o! B- D0 P+ B else :- a& K1 K1 n" @, R+ Q( t
y[j+1][i]=a+n6 c/ K3 n4 J5 V7 q! z4 X
a=a+n $ r; R3 m# b9 B5 V n=1# r& S$ ?- a) d+ a- q+ k
5 i: ] G0 v. W- F$ b#算每家供应商每周排名的平均值 6 W( }8 R7 f$ u% u3 e0 ~
list = numpy.zeros((402,2)) # p8 r0 P5 T4 l- b, R6 `5 s! {for k in range(1,403): 3 ~" v/ v( A# `0 h y3 O0 h+ x) | sum=0.0 ' ~4 M5 ]/ I; `+ L0 }# m" G
for i in range(0,402): 7 F' X$ ~2 P, l( W for j in range (0,240): ! S1 c9 B* y, l* i( P% r+ F3 O, i if num_list[i][j]==k: ; F+ M" D+ ^# x sum=sum+y[i][j]& C1 x% ]9 i4 Z6 |" l& O* h
sum=sum/240 * Q* m! `5 l; t
list[k-1][0]=sum 7 L% `3 d& n! T7 b* A; t, X9 ^ list[k-1][1]=k& u5 S$ `8 i5 Y
- |" V$ v7 e% }' a6 M" \
; ^& V; [* n0 ^* x5 t5 y, A " X+ [- n! g" T. A# 对每周排名的平均值进行排序 7 c! v( }. P9 } }# [0 O. U3 _for i in range (0,402):, Q. v% L3 y: Y& w+ c% n) Q
for j in range(0,401-i): % {. C5 @" U# }9 |$ A) v if list[j][0]>list[j+1][0]:, U$ R. z* o1 w% h' I6 Q( C" z$ u
(list[j][0],list[j+1][0])=(list[j+1][0],list[j][0]) 9 K- s- y$ d+ g } (list[j][1],list[j+1][1])=(list[j+1][1],list[j][1]) + M+ |$ Y- F( z5 N' O k9 f3 @( @1 N% {- q: F2 e+ Q& q' V
. L* J }, O! J' K#输出结果 : L' q& O8 @$ I: i6 T2 `( r/ H% j! x
for i in range(0,50): + y& i5 [2 j/ d; y print(list[i][1]) , k$ B: N. k: ?& m7 H$ V; \2 s h+ S2 e( e, f" U2 H+ \, m; ^. a' a
14 M1 C& N1 g7 R9 k2 Y% y
2/ W' ?: ?2 x" m& {
35 [8 I8 u8 @4 u9 n6 `8 D- I
48 _% D3 H- l' f+ v( q2 I) p$ W. t
5; r' S1 Q7 M7 n
6, W7 F& m/ U$ \2 M' p( U
72 O; d, P+ R! h- ` q
8 4 L% h `! z, M) k) H; D1 U9 % s& u& L$ A. }( P! \10 - l c* j4 g+ o: z0 g! N: i11 ' Y. p$ l; `- d8 x1 q6 D6 ?12 & Z* f% R: i% Z$ {( h0 }. h( a" A13* b( e0 z) u. |9 j; f7 m i
14 ]3 ^6 Y- q( y6 r6 e9 L1 c9 f15# M. y; T9 f5 `! n; V3 k
16 , I0 E, _* K5 S$ g3 k2 l$ F17. K# x4 I7 ?" m* Z
18% V( f* Q: _& W5 Z7 Q7 [
19 7 u' ~' ~+ O9 J" [20% K, P' u6 {+ S( Z! h6 h' w
21 5 D% @6 o! p6 W# Z& L22" n6 v8 Z3 d8 b% a9 o/ v
23 # W& J' I0 }9 t, I, {24 4 w( t$ _5 M' G# j+ x2 i256 V# p6 `( D; S3 R6 m7 h
26 3 F: c3 K% m2 A27 / z. y/ e9 @5 \& Z* B0 T9 z28 # W+ a9 y8 u% L g! Q29& }: R1 ]' d1 V: l
308 M' q3 q9 K7 U4 I% `+ c
31 3 S S* A. t& C. i325 j. o2 W$ @5 A8 X) o! C( L
332 ^5 L5 v: ?2 F# s
345 X" w, r* ^8 z
35 8 }+ U( F& ?8 e0 Y5 J36 ) u1 V+ u4 @2 A37. ?9 g/ Y, x$ ~6 _( U7 b0 R
38! z( r" C) q8 w8 D
39& ?- Q, g. `7 t' g/ [* k
40 & |0 P$ d C4 `+ R0 j5 A$ n$ x+ H41 " D0 e% W- J E" y0 s; v429 ^( ?! G5 _1 X8 H5 C/ z
43 # j% K" L" ~0 |8 f, h44 ) I9 t9 I! [3 W, V& `, M! ^45" q- [$ m9 s2 F$ r. H1 h
460 v) E% ^7 d" i, s D
47" ?% y4 o9 f. t! C: t
48 9 L) C( ~" a* f. q: b493 a3 `6 b2 p/ q! d7 l2 f
50 s5 d$ _9 F- q2 n7 Y! M
51/ G/ z; K) H) H d3 w
52 9 I- s) \( r3 z# i' t+ O- Q6 {53# V) v5 [ Q+ N5 `' ]
548 B4 k) N1 F3 v6 f9 a* g
55 4 r# c' Z1 R; b/ k1 E56 3 H# a+ j5 V9 b# B O/ y# l( u2 |57' Z& r. M/ f( O& _9 Q# O t# C7 @
58/ |( n1 l$ o- ~0 a! v t0 Q b
59 9 h' \* X. O4 ~4 L" w+ h! X60 ; A# @' l$ s$ v: w1 v8 L61 2 a" {4 q: ?1 X620 Z' P& u$ P U6 h. r1 M& ~% c
63 $ l! y1 N( T$ i. P' q0 U3 m9 I5 q64. w# @9 q' q9 P- |* J4 X
65& Z& D* D h4 N' u8 Z% X8 F
660 v/ }, O/ f. @" t1 r$ q
67. x" q' s4 D- C- [
688 ?( C; H# }: D; | T+ W0 w
69 t5 V; K* z" m5 i
70 ) ?7 x3 H6 ?' D1 {( a改进:# M/ m+ f7 P3 D1 X5 w7 N
最重要这个有三个因素去影响它,第一个是方差,第二个是供应量,第三个是供应量和订购量的差值,函数:f = 供应量-方差-差值(供应量和方差,差值不是一个数量级,可以用供应量除以最大供应量,还可以根据这三个因素的重要程度设置权值) 9 r: [; _/ x# k: l" N2 }" t' T当时我们小组因为时间不够,没有完善这个。- A- L3 s5 N& T1 }9 l2 i8 X* f9 {& D
! V2 r+ C5 y U" c
第二问: i2 w# q" `. F' ^4 I/ e思路:(具体分析可见论文)' A- n8 F( m3 {! k6 X* Q( i" u. R& C
对 402 家企业近 5 年的总产能进行排序,在总产能误差为 0.3%的限定条件下筛选,最终选择 37 家供应商。 $ a, Z2 `9 k+ F1 t: M# U; T D, ~
将 240 周 402 企业的订货量与供货量的差取绝对值,依次对上述连续两周所求的绝对值求均值后从小到大排序,选取位于前 12 位的连续两周,即选定 24 周,并得到订购方案 5 B+ L( P" @& t4 ~4 d7 z8 m6 t8 }; U9 ^8 N! ?0 j& H
转运方案是根据原材料有一定的损耗(损耗量占供货量的百分比称为“损耗率”),这个概率越小越好 ; Y/ c6 A" Q1 h3 Z" d$ m3 ?) O" z# I8 t, D; i( Z
还有一个限制,每家转运商的运输能力为6000立方米/周,根据每周需要转运的数量选择供应商 T" E7 K) |0 j" A- C, T$ e' A: l- C4 J7 N
代码:0 t: i0 B' ^! H8 w) u @4 C, A! n
首先是要对 402 家企业近 5 年的总产能进行排序 9 ?# X; s4 s$ E: g# k* X/ l7 L) |
import xlrd 7 d# D0 D: m' Simport numpy ; R" {2 E4 I0 ]; Y% i+ C kfile_location = "C:/Users/95870/Desktop/数学建模代码/a.xlsx" K# m0 ?" T2 ?1 a) I1 A
data = xlrd.open_workbook(file_location)8 F1 h( E* j% w8 Y5 x0 S) _9 S
sheet = data.sheet_by_index(1) ! S8 J8 c* c7 C6 a) z; m Isheet2=data.sheet_by_index(0) * [8 J8 Q( o% K' j) a7 j% [data1 = [[sheet.cell_value(r,c) for c in range(sheet.ncols)] for r in range(sheet.nrows)]#读取数据7 F1 n! m% Y, w& P. q
/ k% M! v' F/ a; ]! @8 ^1 F
#402家供应商240周供应量总和 7 Y0 x' _. _, B8 B; k) i2 dlist1 = numpy.zeros((402,2))#240周总共的- e( k5 F5 L7 E
for i in range(0,402): & }- s5 N3 j% `. y% [: I sum=0 : }+ @- _ S/ n+ K for j in range(0,240): 6 c, j9 t6 _& i4 d8 A! e6 I sum=sum+data1[i+1][j+2]5 l" K4 a+ G& Y: y; ~
list1[i][0]=sum ! u5 h Q2 X- {* n# { list1[i][1]=i+1 8 S6 {! z7 q+ C 1 P) b* G# \2 _3 I5 Y: o: Z#402家供应商240周供应量总和的排序 0 y _0 y9 k9 \9 hfor i in range (0,402):#排序 9 ^4 M7 [. ~; p: _( \+ K5 Y for j in range(0,401-i):& z7 P; f! A4 y8 H6 H8 v! D
if list1[j][0]<list1[j+1][0]: ( I. ?$ v: w+ o2 ]% E (list1[j][0],list1[j+1][0])=(list1[j+1][0],list1[j][0]): M% j2 |% J6 s8 @* ]9 l
(list1[j][1],list1[j+1][1])=(list1[j+1][1],list1[j][1]) 0 A2 o8 x0 T: l# t( N; o- ? ; f X; O: F! E. Y0 \! |) G/ u5 |1 a
1 * J4 C3 n9 u2 L1 J- K2 " |3 }7 Z( V8 a/ u0 w. g* x7 {3 3 }7 N4 a- m8 \( [4 _# W3 ^4- K) u# Q- L; n! @/ V0 k) f* F" Z
5 ! a0 S, W; n! Y# {0 P7 J6 1 J6 t( ^* B7 @ W4 _# G& P' A7 ( Y2 Q K- R8 \; r: y% n0 `1 ^7 Q8 8 T' ?% R$ l3 q2 k: r9 " m1 S* W4 [+ Q9 o5 a10 % \7 E+ K1 m* w7 ]; {+ l7 E, ]11; d- h: K! G' [2 i" d* g
12: ?( G Z' o6 v
13/ j) z* H( E& M6 G H* C
14 0 C7 L+ u' ~5 A& G. V1 s/ H# f151 @/ h; Q( L' m) n+ d/ a
16 . t) R" `) t! {2 R' i# m+ e. S" }17, w5 y1 r9 w+ ~; b5 m7 z+ h9 N$ f
183 h5 ]- Z3 d5 a" ]1 ^! n
196 h7 x1 f- t! ~7 j
20 7 O- j) {, H _% u6 O9 T N! M0 C1 Z5 w0 A21 2 |2 h0 D$ V0 n( @22 4 Z6 l5 M: l( d( U6 Q230 K* H3 R# P% a! z
24 + b# p2 z% h& M- O4 v在总产能误差为 0.3%的限定条件下筛选,即是按排名累加240周的供应量如果累加后和累加前的差值小于总产能误差为0.3%,我们则认为该家供应商不是必须的供应商,据此选取供应商。 % O* i0 u) @7 Y 7 i8 c: I8 v" i" Y. @+ z#0.3%:240*28200*0.3%=20304(这个不是排名,是实际值) + H( Z: M g E0 W: |4 D3 `3 a
qushu=0 ) }; R1 Y# L+ l6 ]for i in range (0,402):. O: x6 t: y9 l2 N
if list1[i][0]<20304: ; y( J! S, q, `% t; K# o qushu=i+1: f, U5 M8 C9 a5 ?. W
break , l' W. @, `- y( E" f2 J0 l9 n 3 Z# p! z/ l) r$ y/ Sprint(qushu) / O' y; b+ N9 u7 K! k+ xfor i in range(0,qushu): 2 D9 G# t4 j: g! l8 N" V( w; i print(list1[i][1]) , H$ Q( J% n4 V1* Z/ ? A0 r5 H* u- P& {7 @
2 9 E9 s& e: v2 J6 v' o. a3* l' x4 }" K) Y9 ^
42 p: v, I, P/ S% y
5) _8 k* f0 c& I& R5 X
6 5 q0 Z, r5 S" B! {: M2 k* K+ X7: p& N* S$ G1 u& m; n9 e8 a2 l% S
8 , ?4 b# u, X3 s5 R$ v7 Q9$ }) O, ~. b+ k3 T; f* Z
10' j7 g0 X) x, G: q. U6 c
最终得出的结果是选取了37家企业。1 l. r7 s& X3 G& u. U9 \