, }% O/ J! o- Q2 j* i% F: vCNCT = [To,Te,To,Te,To,Te,To,Te] # CNC上下料时间 / M; A- z _, z6 \3 O: k: g0 g r
N = 50. X! e% u4 N" H1 m
L = 17. m8 j0 k: W! R' k
/ b( n" N) E! T0 M
varP = 0.1 4 [4 j! ~. b- ]" Z$ PcroP = 0.6 , s0 Q. V- N9 I2 d2 N! W: Q& V+ k2 D: e
croL = 40 ?& W3 b" u5 {$ k
e = 0.99% b4 U, i6 Q* Q$ ~
% |( I) O! k/ A F3 b; ltm = [ 3 U& b2 r r+ u6 K4 I2 ?! S [0,0,d1,d1,d2,d2,d3,d3], + v/ N; A" G; B: } [0,0,d1,d1,d2,d2,d3,d3], + Y# J5 Y+ P: U, D& k0 a. \ [d1,d1,0,0,d1,d1,d2,d2],# d1 ]) e; Y* b3 b
[d1,d1,0,0,d1,d1,d2,d2], 5 e. ]- }, e) h7 z5 c [d2,d2,d1,d1,0,0,d1,d1], 9 }' `: }! J) }0 k) o [d2,d2,d1,d1,0,0,d1,d1],+ ~7 v9 ` _' y
[d3,d3,d2,d2,d1,d1,0,0], + s8 u" v2 y9 O1 Y% C P7 y [d3,d3,d2,d2,d1,d1,0,0], . v; e% @* ]- g]9 V: a% o" v+ @5 w3 s
7 i8 w4 T( [& T! s( d& g3 Udef update_state(state,t):- O4 y# \. h) a" t; o2 O9 w
length = len(state) 4 g9 [- l: q; D8 M9 ^! s7 S! i0 I- A( L for i in range(length):' X. `* b2 s/ V6 f! k/ Y
if state < t:: L* q* b: @% K. a
state = 0 ! e' C& j/ Z% K: Z6 g6 j# Z else: / A5 E/ |, J4 i) e% o" u( i; K state -= t - z1 E2 D! {# B( O return state( U! _% X# F/ E
% g: P) Y+ [7 N
def time_calc(seq):) n6 m( }( s1 p7 W+ m. ]. O% m
state = [0 for i in range(8)] # 记录CNC状态 $ j$ i3 w/ M; X/ ^& V% W isEmpty = [1 for i in range(8)] # CNC是否为空? $ q" T; C! k3 s) f currP = 05 E+ @6 d' K. K, E
total = 0; j- C1 c i; r/ t! I- r
length = len(seq), f& R4 o9 u, g+ W0 O6 ?4 F
for No in seq: 3 L1 ^# W9 k2 U( {1 A nextP = No 8 m9 w$ _, ^ X. Q3 R( ^- n/ J t = tm[currP][nextP]% R* ^ H' V% _# _
total += t # rgv移动 & Y& X5 }: C6 J6 ? state = update_state(state,t) # 更新state " a1 A4 L. G" p. j if state[No]==0: # 表明CNC等待5 T+ l( ]/ m, h" O4 C
if isEmpty[No]: # 当前CNC空. Y/ y: q3 G$ K) ~; e9 l) T
t = CNCT[No]4 A* A0 l5 @, [/ N0 f' Q: H n9 N
isEmpty[No] = 0 1 a1 p. \+ A& Y$ G: @ else: P: k, \0 C( Z' s t = CNCT[No]+Tc 6 e6 D) w. A( p! m total += t* k" D& @ ^3 ]2 n
state = update_state(state,t)( L# W. M6 p( k1 q! M- s
state[No] = T+ o% ?6 Y, m k' z
else: # 当前CNC忙9 N3 q) C. |5 @
total += state[No] # 先等当前CNC结束 + N/ V( T+ ]1 K) a* }) ?. a state = update_state(state,state[No]) 1 y! Q3 W. _8 H r1 K
t = CNCT[No]+Tc, d9 W1 v0 Q5 r* Q; a
total += t* @6 {" _/ b V( t; h. o
state = update_state(state,t)" i$ b$ u, j8 i' v* @% E
state[No] = T 2 l- ?2 z, w4 ^( L) F currP = No / q3 N' s, e& v9 q" t+ b& d' a total += tm[currP][0]5 ^0 @ c: r5 R% M4 o* o L
return total! J# m4 f5 @5 O% N
! A$ w6 R) W. j" ydef init_prob(sample):9 a. @6 c+ c9 x
prob = []) B o- D+ S7 g8 }+ Q# q
for seq in sample: 2 ^) A8 U# t4 Y# d9 c prob.append(time_calc(seq)) . M0 H8 u+ Z+ e/ y/ U2 G% U5 U5 e maxi = max(prob) $ g4 k( Z) V3 x( {- ?! B/ g prob = [maxi-prob+1 for i in range(N)] 0 @6 P- g1 w' k" ^. J% O3 ? temp = 0 , ^! G: S# ~9 M2 [ d9 V for p in prob: , U/ y \7 }) v: M temp += p R. _3 G. }: g r prob = [prob/temp for i in range(N)] }" |! s$ V8 h8 j6 x w' Z- r for i in range(1,len(prob)): * n8 y# q: E9 Q2 P1 t- f prob += prob[i-1]$ y: r, y9 Z; G
prob[-1] = 1 # 精度有时候很出问题 & R& Q6 |7 y, Q1 m return prob , w' _1 m( g1 H " m& b e) k' u- t) xdef minT_calc(sample):) I3 ?3 `$ N( X+ b3 d
minT = time_calc(sample[0])1 v% Z, ]7 e$ V& J0 F
index = 0 - C/ Y) u) a4 {# D6 }+ K for i in range(1,len(sample)): n9 d/ A4 }! b
t = time_calc(sample) ; S4 `# `5 G$ X% v3 S7 } if t < minT:! G2 ~5 c' O' D8 ^4 S4 ?, z% s
index = i2 {9 [' Q! p0 p& R* }1 ]: W
minT = t ) O( b* a+ O) Y: l) Z+ @& n$ P t return minT,index 7 A1 t& {! g6 }: @# ?9 Y ' b3 x1 Y- N* U$ [def init():2 R( [3 d* E3 M$ v
sample = []% D3 L- Q" D; X
for i in range(N):: f. Y! J$ F* |% q' }
sample.append([]) 6 e0 }% ^# {2 w. \2 {" c1 J2 { for j in range(L):. {& g0 B& R! w2 H6 |
sample[-1].append(random.randint(0,7))4 V i6 D; H( \5 S
return sample / c1 L& d: y! f; D' d Q- T) u7 P# k8 q0 t& Y
def select(sample,prob): # 选择) C1 [" B3 K: l
sampleEX = []6 }# U2 G: K) t& J' y3 a2 P) ?
for i in range(N): # 取出N个样本- o j2 z& H5 x8 P7 ?: B
rand = random.random()( z+ W# H$ z+ o2 a
for j in range(len(prob)):* b. i' s! r! ~. q) Q, c) V" s
if rand<=prob[j]:' B9 a% X- O$ n! {( w
sampleEX.append(sample[j]) ; N3 k6 s0 d! I* H$ R break 8 }& n: W$ i/ d$ a7 g# ?' j return sampleEX ' U$ r( M8 p3 k0 h: C! R5 _, f 0 v/ T% ?) Y( r1 Y9 v! Idef cross(sample,i): # 交叉 + o$ r( a4 L9 x1 D for i in range(len(sample)-1): 0 Z1 q; F' r" _! o0 m for j in range(i,len(sample)):" Y2 A. M7 t6 `: {; y2 k
rand = random.random()% u6 o/ ?7 K" H2 o0 X6 j3 c
if rand<=croP*(e**i): # 执行交叉0 @8 ]6 |1 h1 o2 a& V
loc = random.randint(0,L-croL-1)9 q# k3 J$ [8 l+ f
temp1 = sample[loc:loc+croL]9 u8 |& }; H8 b# `0 v: v4 G
temp2 = sample[j][loc:loc+croL] T- U+ V& I. ~, ?. h( ^. N
for k in range(loc,loc+croL): & _; x. d! q. _0 O9 A [2 l1 G sample[k] = temp2[k-loc]- H( J$ o I! c+ L. F: D& a
sample[j][k] = temp1[k-loc]8 x/ C$ `- D) l9 c; b; `* {
return sample C, x/ q8 _$ }6 ^0 A; J9 `
* c7 h: I8 Y0 H/ c( i
def variance(sample,i): # 变异算子 M3 z- B" b7 T6 u( Y
for i in range(len(sample)): ! L( z% z0 L4 y- W rand = random.random() 4 J) ]& k8 L! m* k/ } if rand<varP*(e**i): 0 z' R- y7 D3 a9 x/ R! k2 n rand1 = random.randint(0,L-1): p/ v" U3 c6 Y' N& Y8 \
rand2 = random.randint(0,L-1) h4 z# l$ c3 G) A+ ? temp = sample[rand1] : s; a3 W4 i; S& i sample[rand1] = sample[rand2] 7 X7 M. j; }: k; Q% `: B' r sample[rand2] = temp 8 f) |& _# H8 i6 A: B: i0 x3 e7 v7 ? return sample& H% U6 ~) {3 h. E o
' q0 q) b. p7 Gdef main():6 R! |; T8 Z- g
sample = init()5 P% A4 k3 p+ r3 y+ O( n
mini,index = minT_calc(sample) % g1 N& f; J( P0 m! ^ best = sample[index][:]% J8 H, J, n+ Q6 Y- l. y$ U
print(best) 4 U' r1 Z* }2 r* S' H for i in range(10000):; |0 V0 J9 }# p8 B ~
print(i,'\t',minT_calc(sample),end="\t")' B+ Q: C5 [1 m5 Q7 [2 X* j6 z$ E# M
prob = init_prob(sample); O) v. a0 d% p# U3 L3 n
sample = select(sample,prob) ' @3 x; ]3 c7 w' h8 _) F: x sample = cross(sample,i) 5 J5 X( i' I3 q( T0 z2 V sample = variance(sample,i) & I. S9 t( F. j! y2 @ mi,index = minT_calc(sample)5 H7 i- ]8 A0 k0 R
if mi>mini and random.random()<e**i: # 精英保留策略8 }( q6 A: S6 c9 C* D/ G. X8 p; b
rand = random.randint(0,N-1)% Q" }4 {2 p3 F( s" F2 \- d0 p
sample[rand] = best[:] ' M3 d7 ^7 p7 ]; P mini,index = minT_calc(sample)" }. k3 q5 N0 z# n" c8 _; f# a
best = sample[index][:] + u' v" I1 d8 s6 J& X O0 Y/ ~ i+ U print(best)% b7 `3 T& W6 ^6 r1 W( }( |+ s
print(sample)! L! x! t& a; d- n& w5 w
3 q( V; I& O: R4 E# W" [if __name__ == "__main__": : K l% t' R7 k K main1()+ B" {8 G* n/ S2 X; u7 X
""" 穷举搜索验证 """ + j% \4 R- \ _- y# J a = list(itertools.permutations([1,2,3,4,5,6,7],7)) 1 o$ M" N# E/ }/ p5 ^% Y ts = [] ) m% G G7 K: U first = [0,1,2,3,4,5,6,7,0] 8 Y$ ~- \- c% }5 u% N7 d8 w" }3 a for i in a: 8 ]4 j( @- B1 J# c temp = first+list(i)9 c* D- J4 j' y: s- p3 E
temp.append(0), M8 B) m# M3 y8 A7 O; z% a6 ?
t = time_calc(temp) * p2 h$ q9 a% A& e o ts.append(t)9 V/ L" ?0 d8 O4 @$ R: k: y! o
print(min(ts)) 0 e# [- H! M, i* v
print(time_calc([0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0])), \( S$ i- j" G$ ]
$ ^$ Z: n2 g& |% `( c7 I) v
$ d- \8 t5 d" k一道工序有故障6 o, S `7 z4 ]' y5 x
" f+ h: H0 {% V2 {这部分是学姐做的,学姐用了偏数学的思考方式,仍然从循环的角度去考虑,主要考虑故障发生是否会影响当前循环,是否需要建立新的循环。因此就没有写代码处理问题了。具体的思路我确实不是很能讲清楚。但是这里面有一个非常大的问题,就是如果出现多台CNC同时发生故障怎么办。关于多台机器同时发生故障的概率,我们通过估算认为以给定的三组数据8小时内会出现这种特殊情况的可能性大约为30%。这个问题是我无法很好严格处理的(当然如果用贪心算法也就没这么多事了)。 " K1 |8 b4 M2 F2 s4 }) ^3 W/ K* p' f: s4 s
两道工序无故障 & 两道工序有故障! U! c& b* C1 K
2 ]- c* v: v0 V3 Q" |: V这两个部分都是我来处理的,因为使用的方法大致相同,就并在一起说了。 a) m3 D( B4 O; S3 I 3 p9 z& M: C; @8 y0 B0 y, \* l两道工序与一道工序最大的区别在于三点: $ ?* V+ U& r: Y% t" k( `# D: r! d3 Q7 h9 W0 C2 w n
1、开始要处理CNC任务分配:分配给第一道工序几台CNC,分配给第二道工序几台CNC?具体怎么布局? / P; j5 q% H' w& A; j- h: j. Y$ x& k- a) L2 ~4 m+ @
2、加工过程可能仍然是一个循环,但是这个循环将可能会非常的庞大以至于不可能直观的看出来。 F, K1 N d$ u+ x
8 N8 M; Y6 D+ H% _/ [: m: ?cncT = [To,Te,To,Te,To,Te,To,Te] ) z( ]9 B+ \ stm = [0 e2 d! n( _% u9 \/ b+ d
[0,0,d1,d1,d2,d2,d3,d3], 5 N0 @7 R2 a% h' Q$ Y$ @* m7 p [0,0,d1,d1,d2,d2,d3,d3], $ P) J9 R6 c# B7 @7 m& U [d1,d1,0,0,d1,d1,d2,d2], - B3 D# p5 ] i6 l4 f# _8 N* V [d1,d1,0,0,d1,d1,d2,d2],2 ?# X' J7 M7 I; L& |
[d2,d2,d1,d1,0,0,d1,d1],$ K; S. b Q# W) i" J, v b) n5 P
[d2,d2,d1,d1,0,0,d1,d1],9 b% |' H6 h `4 M! @. Q+ u$ V
[d3,d3,d2,d2,d1,d1,0,0],5 M) {- w5 o% l* B3 O2 J
[d3,d3,d2,d2,d1,d1,0,0],' ]! `2 o5 J4 c; }7 w' |, ]9 j' R
]. i$ @! b6 h+ H4 I
Type = [0,1,0,1,1,1,0,1] # CNC刀具分类% T0 T) `, Y$ N
+ X. \3 s( C/ `8 p- ^! J5 {8 E4 w0 A2 pA = [] # 储存第一道工序的CNC编号: M" @5 q2 v; }' f# O( z/ d
B = [] # 储存第二道工序的CNC编号 " g. x% x: Z" ?7 P1 ~for i in range(len(Type)):- d- s- k& t- g; E$ H/ a* d
if Type: + V, R+ k9 o5 ~& ]) E B.append(i) 3 U3 d' ^( q! a% z+ B else:4 n" G R' l: g$ l6 j
A.append(i)- p% d1 l+ k' W! ?9 }* B0 `
5 m) ~# s% U7 \- k7 x0 gdef init_first_round(): # 第一圈初始化(默认把所有第一道CNC按顺序加满再回到当前位置全部加满) e5 ^* N; Y% E( V4 v, N, M: x state = [0 for i in range(8)] # 记录CNC状态(还剩多少秒结束,0表示空闲)1 R" g" X% D0 V5 `6 G
isEmpty = [1 for i in range(8)] # CNC是否为空' M5 W' I9 |1 U) |3 T* r5 J. y5 Y
log = [0 for i in range(8)] # 记录每台CNC正在加工第几件物料 % h) [ T) A. |9 K% W$ @ count1 = 0 % N9 z" t3 A8 R* S3 Q$ v rgv = 0 # rgv状态(0表示空车,1表示载着半成品) 2 R' {5 ^3 X4 J7 P currP = 0( {0 ~$ f# p. ^/ }
total = 0! x; C X. J: _, O# o
seq = [], {% G0 {+ b+ [% Z# E0 D: p
flag = False% U$ B: a3 T9 |( l
for i in range(len(Type)): 6 S4 p# u, m6 W) n! n if Type==0: + u# T% \0 O q5 |# m' M seq.append(i) . x# @9 A% w+ E( F6 m flag = True ( ?& B# H& v! e* w2 ]. F& S currP = seq[0] 9 b3 O/ C( ^- J+ L, P/ `% N seq.append(currP)! z- e* Q$ }# P6 ]8 r: C# m
count1,rgv,currP,total = simulate(seq,state,isEmpty,log,count1,rgv,currP,total) ( s. q2 K0 _ \- `- i, P return state,isEmpty,log,count1,rgv,currP,total,seq# W; K3 x" d% M* G' u) A
$ E* g5 k( H: x( q
def update(state,t): . k, l7 \, ?; D9 x& g& s+ y# ` for i in range(len(state)): / t9 l* @2 t' }0 ?4 x if state < t:# ] Y( R6 k, H( P$ B% ]
state = 0 6 w) R+ l3 K% n" [% ?3 v1 ` else: ! W1 K- p/ O, S: a9 c state -= t5 h& V5 _; U$ D
1 @* X" w* n, v% z4 i9 ?& \
def simulate(seq,state,isEmpty,log,count1,rgv,currP,total,fpath="log.txt"): # 给定了一个序列模拟它的过程以及返回结果(主要用于模拟并记录) # Q) V7 m! U9 U: g) h9 A index = 0% m6 M& u! Z) w8 }3 i) z
temp = 01 k. }' E' S- f1 g3 D" e
pro1 = {} # 第一道工序的上下料开始时间5 N1 G+ j" G: W
pro2 = {} # 第二道工序的上下料开始时间* A# @& x: A1 w' J7 N
f = open(fpath,"a"): s* ?& r* u% w. R$ x9 x# p
while index<len(seq): , R; D ~3 H- q! ]+ S$ Q/ Q" N$ {- j print(isEmpty) # P0 p$ y0 e. _$ q, E6 X& U4 ~ nextP = seq[index]7 t# e1 K! E2 {8 C
t = tm[currP][nextP]; e+ a7 j3 K J$ h$ k# Y
total += t [% J9 m3 n; k3 L6 e0 O" K5 N- {! R7 ? update(state,t)8 N8 |( S9 Z7 g
if Type[nextP]==0: # 如果下一个位置是第一道工作点 4 F. a( p, p. D. I: y8 g* \ count1 += 1 3 T# x( _! u! e1 A2 G5 D: L- L9 n if isEmpty[nextP]: # 如果下一个位置是空的0 q& O. `6 t! x* _
f.write("第{}个物料的工序一上料开始时间为{}\tCNC编号为{}号\n".format(count1,total,nextP+1)) + L0 V* ] N# s0 a' w t = cncT[nextP] * Q4 d4 V, D( H" p total += t, h, X$ p' j3 r; K& w9 p
update(state,t)* a( ?4 z g+ [% V
state[nextP] = T1 # 更新当前的CNC状态8 d8 |5 w: t1 t! F3 B
isEmpty[nextP] = 0 # 就不空闲了. n5 ?5 g+ l2 R/ s) c
else: # 如果没有空闲0 Y" R+ z0 W' p- X
if state[nextP] > 0: # 如果还在工作就等待结束, H) e M& g7 B' U. c) |' u
t = state[nextP]+ F8 A. j o" [5 X: N; @. Q% ]" d) {
total += t # A; z! |# c6 R) I! t3 G8 L3 b update(state,t) : T+ n& ~; ^2 L' ^2 I6 f f.write("第{}个物料的工序一下料开始时间为{}\tCNC编号为{}号\n".format(log[nextP],total,nextP+1))' Z: H7 C5 o H0 G
f.write("第{}个物料的工序一上料开始时间为{}\tCNC编号为{}号\n".format(count1,total,nextP+1))4 h; Q# N( f ?/ B) r+ f
t = cncT[nextP] # 完成一次上下料 ) M$ Y4 j. @; e# `2 y: a total += t 0 B! Z$ A. z7 k* i ] update(state,t): L/ L4 A- h" J1 L
state[nextP] = T1 0 m! Y3 p" ~" n rgv = log[nextP] 9 r8 B) p0 {; i- L# o% g1 N log[nextP] = count1: ^0 |* }+ G# ?! L" ?
else: # 如果下一个位置是第二道工作点 / A1 I$ M0 e& Z+ H- k if isEmpty[nextP]: # 如果下一个位置是空的, R, s8 F9 O! c0 L5 F7 l# ?
f.write("第{}个物料的工序二上料开始时间为{}\tCNC编号为{}号\n".format(rgv,total,nextP+1))/ s+ S% `+ M: S( ^( V" i
t = cncT[nextP]5 b% V" c1 y3 C8 c2 L3 Q& Q, s
total += t " m1 ]+ w+ }, K: A' h; i; t7 J update(state,t) # a3 j, i4 u0 A9 c6 \ state[nextP] = T2$ B8 i0 y9 _+ I
isEmpty[nextP] = 0 5 Q" }# G2 i; c5 N; [* O: Z9 X
else: # 如果没有空闲2 B+ `) e, f9 @/ {+ Q7 o
f.write("第{}个物料的工序二下料开始时间为{}\tCNC编号为{}号\n".format(log[nextP],total,nextP+1)) * v5 ~: v4 s5 d f.write("第{}个物料的工序二上料开始时间为{}\tCNC编号为{}号\n".format(rgv,total,nextP+1)) 5 D- c# y1 v4 N2 _: S! B9 l6 f$ f if state[nextP] > 0: # 如果还在工作就等待结束0 v% O( F+ `8 e: v2 T. K$ ~) Z
t = state[nextP] / @' W5 P1 u1 {0 P* L0 b7 b total += t) {4 x2 W2 @" J" p( {: u, d
update(state,t)6 V, u2 u! P3 V4 ?% A( _, G8 X
t = cncT[nextP]+Tc3 j5 N& y* N) b* C1 S( o# ]: D
total += t ( ~ c Z9 B3 R" b( G update(state,t) ) k$ l& I; K* C state[nextP] = T22 P }4 @4 M! f; k& l/ T O) A; o
log[nextP] = rgv0 a& ?" p7 T( z- N. D5 E( ]
rgv = 08 i6 C0 I& { p6 V8 W! f( ~. l
currP = nextP 0 A! @: B. G5 {, K temp = total 0 S6 Q8 M! Z+ B- [* q) y f index += 1 . r, t* P9 E2 G7 T1 t9 ~
f.close() 0 v5 u5 @2 A$ t4 B total += tm[currP][Type.index(0)] # 最后归到起始点/ `% t/ M6 p- `! d3 d
return count1,rgv,currP,total 4 l: K6 I5 z. d1 m ( q4 N& X9 V1 t) ndef time_calc(seq,state,isEmpty,rgv,currP,total): # 主要用于记录时间2 Z: f1 ^, M+ \% D8 j3 Q
index = 0/ a, t$ @$ _) m0 Q! I j9 I
temp = 0 0 Q9 G" Y5 a1 y2 B& R8 w& t3 _ while index<len(seq): ( I! S4 v5 _% z& @ nextP = seq[index] 9 n7 v& K$ E' ]- P0 R* d t = tm[currP][nextP]. D8 e) _; `9 U* @9 N2 ^0 U
total += t & M' T. q: ^( `5 r( m# U, L update(state,t)" B! y' Y8 @9 B# ?) V" O: P1 t
if Type[nextP]==0: # 如果下一个位置是第一道工作点 5 D/ e1 E2 Y' @6 N1 v if rgv==1: # 然而载着半成品 V; B; w) @: t; ?3 l! X6 ]
seq.pop(index) # 去掉这个元素并中止当次循环进入下一个循环 # k0 b* N3 l9 w1 s+ ~% } continue # E0 \8 _* x N" c5 s5 G if isEmpty[nextP]: # 如果下一个位置是空的5 L- n, L7 k0 a1 o, q4 r7 Q0 k3 B2 i$ h0 j
t = cncT[nextP] ) u! ~" a0 ^, C0 u0 Z total += t' y0 d \! \/ s: u$ N8 z" b
update(state,t)( `% T, E- J$ J( r0 i: }& B0 ]) S- o- ~
state[nextP] = T1 # 更新当前的CNC状态 : H" s' [& b2 Z# R# G a: e8 x isEmpty[nextP] = 0 # 就不空闲了 1 ^" i X2 x; z9 ^ else: # 如果没有空闲 , d* I# E0 b/ [7 z if state[nextP] > 0: # 如果还在工作就等待结束 9 b2 \8 \8 u# s1 j9 ?- X t = state[nextP] 9 z3 Y/ |6 s4 W& Q total += t 9 R( F( b) m! Z# ] update(state,t) ; j( y* g+ w$ r% L6 A7 o' i t = cncT[nextP] # 完成一次上下料 n5 g( z! |0 w* Z7 z7 D" M total += t * _+ |9 o, ? I: a& h2 ]; s update(state,t) ; N1 k3 D& ?; q2 x' f* a state[nextP] = T1" o6 v3 @$ Q* U4 L1 F$ i
rgv = 1 }# k1 ?- `6 [/ c$ J+ } else: # 如果下一个位置是第二道工作点& n9 ~/ K# @) ?. t# i2 \
if rgv==0: # 如果是个空车 2 R# U# k. @8 e$ r! _" s& K9 @ ^, Z seq.pop(index) # 删除当前节点 0 k; ]- F# E0 C5 Y continue. G/ W9 p0 ~, u8 G0 V0 `
if isEmpty[nextP]: # 如果下一个位置是空的# m; {, U4 @" E) J
t = cncT[nextP]. V" u7 ]4 H. P% w+ T
total += t % N) v. N0 I. V update(state,t)0 O" R* h$ O3 c2 b. a+ A
state[nextP] = T29 A% o' L% @/ Z6 s
isEmpty[nextP] = 0 . u+ b" r/ P* N
else: # 如果没有空闲 ! F* G& ~. N+ J" u# b- X if state[nextP] > 0: # 如果还在工作就等待结束6 q$ a$ k7 `( k! r
t = state[nextP]5 I5 g! ^# x% w: c* X/ y9 u; f* b3 F
total += t: |4 M- X# z' [7 J/ G& c. S0 ~$ ^
update(state,t) ! H& K0 P7 a' o9 X3 b: O2 y+ n( B t = cncT[nextP]+Tc% R8 C' Z+ _; S# O9 y' `
total += t 9 N9 C+ o$ s1 h0 ?: ~ update(state,t): ~; w& X+ w9 z
state[nextP] = T2" h; b; o! T' @# T- u
rgv = 03 d* \: P: r4 o- L
currP = nextP% {, x; k" ~$ I C
temp = total + u& f" g9 l0 ~, _0 S0 ^ s$ N" n index += 1 1 b: u6 I# U1 a return rgv,currP,total9 `/ r9 y: I$ b! M
; X' k7 X; W* `& [def forward1(state,isEmpty,currP): # 一步最优: ^! e8 U8 P9 G
lists = [] g1 l' v. N3 c- g- C3 C if currP in A: 0 h7 A$ k. h5 u; ?+ i) b& t$ O rgv = 16 |8 L5 a: s& B5 v$ L4 K! k
for e1 in B:4 U7 X/ i$ v3 p3 ]$ ?
lists.append([e1])- Y5 ?! ?- D$ K6 F' p; h
! ]! S) {' k- m+ [- H/ { else: " o/ K5 D. r& y$ w" } rgv = 0 9 `; r- d/ _' j. w& y% r for e1 in A: ' u u! z8 Q5 C/ X" O7 C lists.append([e1]) 7 o1 I5 g+ d& x : N: P; j6 d+ @8 ]2 Y minV = 288006 m5 f" L7 a% r4 g3 b6 g( Q
for i in range(len(lists)): Y8 W' B3 r0 w+ H1 `
t = time_calc(lists,state[:],isEmpty[:],rgv,currP,0)[-1]9 J6 `* S& ]: ^; v5 i
if t<minV:9 W6 U) p2 l* P. P! [9 H; ?# h3 R
minV = t9 l* H7 j4 [" {5 }' C z3 @ h
index = i5 y6 i% j: ^3 g9 @! g
return lists[index][0]- v1 h$ r8 @0 ~! g
- E0 K) g1 q* F, b* Fdef forward4(state,isEmpty,currP): # 四步最优3 p7 h, ~* L) [
lists = []4 h2 ~1 z# _3 F3 n& C9 p
""" 遍历所有的可能性 """0 U$ q- Y5 p; K; E2 q% D
if currP in A: # 如果当前在第二道工序CNC的位置! g. b& H+ B; R! |8 Q$ u2 Y
rgv = 1* U* E7 i+ a) M1 P
for e1 in B: & l5 e# Z5 d3 u, A p for e2 in A: 8 S0 F" e/ ?- w- j* w& h2 k for e3 in B:3 ^. ?) Y* |2 T5 Z7 b G
for e4 in A: & M0 b# X4 p' w% y$ V: K. _% T lists.append([e1,e2,e3,e4]) " e4 Y- ]9 F2 G4 j( W* D1 c else:5 o. k' V3 ~; ^ R9 t
rgv = 0 8 W" h7 A8 }( q- k" V for e1 in A: 8 I3 i3 f& d9 t0 ]9 J: f) _ for e2 in B: - C* E6 w3 k0 c3 i( r+ g for e3 in A:& j5 b! [+ _5 c# N3 R
for e4 in B:: X _# g% H/ Q6 ?
lists.append([e1,e2,e3,e4]) * D! ~2 A3 I) G. k) ?! d) b minV = 28800/ G! P0 L0 M( c" _
for i in range(len(lists)): , F3 j* b5 ?) v t = time_calc(lists,state[:],isEmpty[:],rgv,currP,0)[-1]7 I9 \7 B' w2 o
if t<minV: $ Y3 I- N8 r0 T+ _6 Z minV = t4 I9 @4 Y9 F. d @+ K7 r6 g+ r2 c. f) A4 L, c
index = i a, w+ E5 D! W: i/ J, }
return lists[index][0] # 给定下一步的4步计算最优 2 I/ ]; g i; a 3 r" B5 A2 g7 d7 \3 H- [; {7 E8 ~def forward5(state,isEmpty,currP): # 五步最优* ?; d" H/ _7 ~, h
lists = []# b# V; q8 B" U
""" 遍历所有的可能性 """ ]6 R4 C$ |$ S* c5 ]! D
if currP in A: # 如果当前在第二道工序CNC的位置 b3 Z: \, {/ v
rgv = 1/ v8 a& U5 J! U: D4 ^5 }
for e1 in B:: s4 S+ r4 i0 ^# l
for e2 in A:+ P! x, S3 p0 K _- J9 Y* |# m
for e3 in B:; [! s( b* H: r- K3 u8 ]3 R M2 g
for e4 in A: % P, @: W/ t2 e; u: } for e5 in B: ; J7 P: G% H2 s e7 k- x0 j lists.append([e1,e2,e3,e4,e5])5 v5 C# D- X# l% \
else:1 t0 A+ g$ s% j, g* B
rgv = 0" f* Y' z: D) g; [/ c( ]
for e1 in A: $ K6 x! W, C0 R9 z5 |7 r for e2 in B: + x: ~! w* Z9 X4 y1 u+ w5 [3 m for e3 in A:) R# r. d8 C" x' p- } K" a) b
for e4 in B: 4 \: {+ F; v. { l for e5 in A: , }( E6 H4 O: h. H3 E" p lists.append([e1,e2,e3,e4,e5]); a# ^+ R. O8 A$ a
minV = 288008 M8 F6 P2 }& b) l& F
for i in range(len(lists)): 2 h& A; J! l# Q: U' D t = time_calc(lists,state[:],isEmpty[:],rgv,currP,0)[-1] * c0 ^ ? W' T9 U if t<minV:) b& R4 u$ Q* y5 A5 U
minV = t 5 i: [; ~! L0 z9 ^1 d) [( t% z5 d index = i 5 O$ e; f5 R+ k; ? m0 ^ return lists[index][0] # 给定下一步的5步计算最优 ) U$ Q8 \" i+ b4 [1 Y' L: j 9 M& w" L! g1 k- Rdef forward6(state,isEmpty,currP): # 六步最优- N2 o4 }5 Q5 k( s, `3 ?* R
lists = []) l: U" s7 E3 R& t& o ^# K- m
""" 遍历所有的可能性 """ - a4 Q% @2 b) \, A if currP in A: # 如果当前在第二道工序CNC的位置 ' `$ [$ g: W8 H, H* N rgv = 1 R/ s# u0 N3 D) ~. C+ Z
for e1 in B: & v8 X" Q8 W8 B& {" _ `2 \ for e2 in A:( P- p# _$ x, G( t9 E- n& M
for e3 in B: 7 l d+ c H3 O0 T9 \- \ for e4 in A:. t. y3 f5 o" f* R
for e5 in B:# v# E% g3 U! v
for e6 in A: % Y$ R, ]3 K2 d0 h7 ` lists.append([e1,e2,e3,e4,e5,e6]) `- g2 w+ b9 @. s. B
else:+ ?- i' J' b H
rgv = 0 \$ ]( I, `: s6 Y1 U" | for e1 in A: 7 s( G8 ~' _! s4 e; K( p for e2 in B:! w* _9 w" i( B, @" p2 f6 \
for e3 in A:* u; J3 q; E) l1 q. a
for e4 in B: 3 J4 ]. Y# ]; S/ k3 h _. N7 k for e5 in A: ' E- b) h! W( v! V: q+ Y for e6 in B: q, C5 }& x( M& P7 @2 j7 g lists.append([e1,e2,e3,e4,e5,e6])* f: ]) j n& j Z* d5 S/ _: n: ~
minV = 28800 1 D; }! w1 {4 {' b) @ for i in range(len(lists)): $ d3 d, b' N$ }- {" F t = time_calc(lists,state[:],isEmpty[:],rgv,currP,0)[-1]7 E* q9 E- F# t
if t<minV: 3 P2 ]4 [ C' S minV = t : y. g* [- E2 S {+ f index = i9 E0 R& |) O4 C2 Y& t
return lists[index][0] # 给定下一步的6步计算最优 9 T. U( j) r( e 5 ]0 _" K" K/ ^! Z% S9 Udef forward7(state,isEmpty,currP): # 七步最优 2 p9 C1 D X2 ~: i U lists = []+ i8 O3 i1 r: j
""" 遍历所有的可能性 """9 J7 Y+ m) x% h7 J1 b8 Y! g/ v
if currP in A: # 如果当前在第二道工序CNC的位置 8 Y9 Z3 I- B, f/ c rgv = 1: _4 U# J+ }0 }1 q* H5 D* c8 L3 z
for e1 in B:; i5 C, C2 }/ I6 n% n& j9 D9 W
for e2 in A:$ k- K3 v# `2 K
for e3 in B: 1 f _% s4 o, f' p for e4 in A:, E# ]+ Y# S. N: J1 {6 l
for e5 in B:5 h, e. Z0 {( |( w2 [4 m+ ]$ F
for e6 in A:% Z5 {/ s7 ?4 ]/ i5 p/ f
for e7 in B:4 B( d, Q$ z- ]
lists.append([e1,e2,e3,e4,e5,e6,e7]) 8 v/ ]9 x% ^- L' B9 S: L+ Y6 a2 Y else: , V* j# @8 @2 f/ ?2 d/ ?5 `* C rgv = 0 6 t: F# V4 y) r+ _- h8 ? for e1 in A:0 q' _3 M/ k, @, v9 ]5 m* A
for e2 in B: 8 P$ f! S5 m. B1 z4 U7 W for e3 in A:8 g4 t. \9 `# S W+ H* M) B
for e4 in B: 4 v. L1 b& z1 L for e5 in A: " p. z( I. W ^5 T' {0 b, | for e6 in B:; R/ A& \" r- [. x7 Z
for e7 in A:' h% F# w/ T; t2 z, u8 g/ s8 G
lists.append([e1,e2,e3,e4,e5,e6,e7]) 0 T. W9 e* ` X3 l' C7 Q0 @9 S+ q minV = 28800 8 @. q1 u y# n/ p8 f p for i in range(len(lists)):- J, ^# k" R& M2 P' x
t = time_calc(lists,state[:],isEmpty[:],rgv,currP,0)[-1]9 U6 } o$ a, c$ C' a, G
if t<minV:6 U; B& o+ [! _
minV = t ! K4 B$ K* v3 w) m index = i ) @( x3 u" }9 I6 j8 G! p return lists[index][0] # 给定下一步的7步计算最优 ' x/ R* |% U P' m) y9 G X: H: ]- ]' D$ {
def forward8(state,isEmpty,currP): # 八步最优 : y$ L$ z# N1 F' w lists = []3 c) \4 K7 q4 w& O" M! e8 y
""" 遍历所有的可能性 """ . A* x8 E' p" J if currP in A: # 如果当前在第二道工序CNC的位置 7 q4 \7 c; \7 w3 X0 M( ~2 ]: Q+ D rgv = 1 + ]2 t, k# t- o+ N9 L* J for e1 in B:+ ?4 W+ K% i0 o4 S# p& @
for e2 in A:6 u' h4 x' d* W9 T- t0 r4 z
for e3 in B: ( j. n; o( a- ]2 a# w/ H# } for e4 in A:6 d* k- w Y( ?5 T: p
for e5 in B: @2 x4 t; c7 E& u& A' H
for e6 in A: ' Q0 l0 K" s0 U+ L& G for e7 in B: * ?0 I# ^, W) F; o0 c for e8 in A:+ n" l) b# N% O
lists.append([e1,e2,e3,e4,e5,e6,e7,e8])) R- f& d; }; Y8 U/ N8 R# W
else: " M; @1 z* B: _2 K; }, W rgv = 0: f Z5 w- [- c9 [
for e1 in A: " d6 Y9 Q& V: N M( M+ s. n7 k: t1 f for e2 in B:0 \4 i" I- ^. w
for e3 in A: % N; z( c' R9 A/ j for e4 in B: 7 K) C: ^$ z& C* i; N2 n, M/ m/ |' W' p8 ~ for e5 in A:' {7 @) j! e- \. c* k
for e6 in B:+ }6 l2 T! g5 |; u5 f, v" `- l
for e7 in A: . F0 y4 O: H7 a2 Z/ K0 j2 r for e8 in B: , c4 Q9 D; ]5 X7 K/ m lists.append([e1,e2,e3,e4,e5,e6,e7,e8]) 4 _* [$ C0 r8 I minV = 28800. w6 h1 ^" Z% }
for i in range(len(lists)): + f$ Q, \# N" }0 H0 t7 D7 Y. _ t = time_calc(lists,state[:],isEmpty[:],rgv,currP,0)[-1] * D, N- W/ k B4 ~* `% {, C) ~ if t<minV:9 C) Z2 S! ~& w1 Y
minV = t ' ]5 N) S6 I. r6 R4 D2 {# A* F index = i% L9 Q$ m$ i1 B
return lists[index][0] # 给定下一步的8步计算最优 4 I$ ]( n: U1 Y; [ , T$ H- a: a1 C' z4 f1 xdef greedy(state,isEmpty,rgv,currP,total): # 贪婪算法0 H0 f8 ^+ N; v9 a
line = []/ Y0 Z8 ]& u; Q0 t G
count = 0 % \" m ` L1 L1 E) h! T while True: 8 g3 W7 k. n& I #nextP = forward4(state[:],isEmpty[:],currP) " r. X) A9 O3 O; P; L4 {# z/ [ nextP = forward5(state[:],isEmpty[:],currP) 9 B% b- k/ I" @: H! o& [
line.append(nextP) 8 w+ }7 y; Z$ F rgv,currP,t = time_calc([nextP],state,isEmpty,rgv,currP,0) 3 _+ V$ f( [2 a3 Q2 T total += t % s9 F7 D& y/ ?. v( r count += 1! {/ D3 N: M: \( H/ |( y
if total>=28800:( T1 M& O3 H9 a, U( B5 C
break $ j( H( f% K( Y1 V$ f return line- d2 I4 }0 T" u' e# M" Y4 X; z
$ z4 n+ o4 b- j% |& J* k/ u$ A
if __name__ == "__main__": 1 T5 P+ Z" a0 Y! r state,isEmpty,log,count1,rgv,currP,total,seq = init_first_round()1 \$ a+ k& F6 l1 m# c
print(state,isEmpty,log,count1,rgv,currP,total,seq)# A& m: N, q! Q! C
line = greedy(state[:],isEmpty[:],rgv,currP,total) : {- G! ^7 }, A; A simulate(line,state,isEmpty,log,count1,rgv,currP,total) 2 u7 @$ D1 X3 i+ Z& Q/ R. R 6 G8 o1 g3 h( Y. M8 K H
write_xlsx() - L; ^7 K) ~! v+ U8 @后记 3 m/ R' F# I0 V7 D% Y' K& p8 }# A , T- `( Q! _3 q( D& _9 b3 c这次博客有点赶,所以质量有点差,很多点没有具体说清楚。主要最近事情比较多。本来也没想写这篇博客,但是觉得人还是要善始善终,虽然没有人来阅读,但是学习的路上还是要多做小结,另外也是万一有需要的朋友也可以给一些参考。虽然我的水平很差劲,但是我希望能够通过交流学习提高更多人包括我自己的水平。不喜勿喷! 7 Y4 [+ `, L1 J! P. I& F--------------------- % @- O8 z( M* P5 @* p4 |: E) F0 J - D; `$ }6 P C0 i# |6 R0 G7 Q3 h2 l0 e" T$ z/ E
9 ?( P4 ^0 }6 p. R
% U0 e" [$ y; N7 }6 u5 |2 l/ C$ D- i
$ }- h1 h$ D7 h' \/ w, Q
3 D2 Q% ]( b o& D" q U
* s0 B; w- C' b