" ]. Q2 a1 L" k' F7 Z5 ~* VcncT = [To,Te,To,Te,To,Te,To,Te]/ `& n* X( L% E7 G
tm = [ & }* I7 C; O; [% P [0,0,d1,d1,d2,d2,d3,d3],3 `4 |7 b& k9 O7 D: [4 U0 E
[0,0,d1,d1,d2,d2,d3,d3], * ^( G0 @9 `! |- V [d1,d1,0,0,d1,d1,d2,d2],+ a5 n) r: \7 v+ ~1 M
[d1,d1,0,0,d1,d1,d2,d2], ( F9 k: y- h9 P: _# L [d2,d2,d1,d1,0,0,d1,d1],+ Y& ^7 R! ^: p' J9 F% a
[d2,d2,d1,d1,0,0,d1,d1], ' ~( ~2 Y+ Y8 G1 k8 X9 X; K [d3,d3,d2,d2,d1,d1,0,0], * |3 q# H h" h( L; Z [d3,d3,d2,d2,d1,d1,0,0], 3 e& r6 `$ U* w# j2 O, F! W]) @, ?2 a/ g2 V0 N9 M3 {
Type = [1,0,1,0,1,0,0,0] # CNC刀具分类 6 g) K7 P' Z. R8 J) _/ x : ?- C" S V/ N, R7 Q6 SN = 64 9 e4 f1 S: ?* `+ g1 KL = 100 & v! p3 l2 w. B1 @! ivarP = 0.1: M" Z. g1 w# m S" l1 L T; j' X
croP = 0.63 c9 v) ]( Q+ s9 r) v, Y7 j
croL = 2 5 |! I' L/ [4 i7 _7 f, ~e = 0.99 " i& I- q/ r" z& L" A& C4 U) y; M5 Z* }, S! w. i! y
def init_first_round(): # 第一圈初始化(默认把所有第一道CNC按顺序加满再回到当前位置全部加满) ; t1 j4 V5 c6 u1 i3 @ q# T state = [0 for i in range(8)] # 记录CNC状态(还剩多少秒结束,0表示空闲) 5 n) Q4 T' k# Q& ]$ c isEmpty = [1 for i in range(8)] # CNC是否为空6 C# @( ?9 {# X! ], ~7 ]
rgv = 0 # rgv状态(0表示空车,1表示载着半成品)# j* G {. ^- u6 e; b2 w
currP = 0. {! _6 B! o7 C4 a$ s" m
total = 0 9 r( j2 i3 c0 P8 R2 c8 B0 K4 N seq = []# y G5 ^& I9 D9 b! C2 P2 O/ e5 K
flag = False5 a9 ^( b8 r8 U* m
for i in range(len(Type)):5 K4 ~& _8 V: g* k/ r# G+ K& u
if Type==0:' m. t, Z9 q3 Y. j( w
seq.append(i) + h+ M6 l9 J$ ~5 q: [7 f9 O flag = True 8 @7 Q" H: f' ?0 n currP = seq[0]/ P# T6 k1 v0 A' P( W
seq.append(currP)( [; f7 n5 F9 a N
rgv,currP,total = time_calc(seq,state,isEmpty,rgv,currP,total) # `; p9 j( n3 {1 I7 n return state,isEmpty,rgv,currP,total,seq0 ?) O4 J* ?. _0 T5 z" {
* k9 a* R) `1 j( @. z5 o8 @: B( _def update(state,t): + ]% ]9 }4 ?4 q5 e5 n: ^$ m for i in range(len(state)):3 {. e8 ?8 N3 G( I( m
if state < t:, I+ w' C* j! D
state = 0, F9 Z" ~, S$ i) ]( u
else:$ _# }' t$ T2 Y
state -= t/ Z# Q0 Z1 J! H/ z9 L5 i6 |2 l0 {! U! `5 l
2 r7 k0 Z A( N+ l
def time_calc(seq,state,isEmpty,rgv,currP,total): # 事实上sequence可能是无效的,所以可能需要 2 M' Z9 V E% y% S index = 0 4 [% ~4 R6 C- C+ k% w. A6 R, O temp = 0, B7 Q* T: b- W5 u- B
while index<len(seq): ; U( f- v$ N% w* o; W/ N """ 先移动到下一个位置 """ 6 `9 w& O+ H* h' X: F# l nextP = seq[index]' S' I# P. H( H4 ?7 o" U" [/ x
t = tm[currP][nextP] , q% T6 m$ ?; \/ w. b total += t2 V8 k5 x- C- e+ H& _$ `9 D
update(state,t)- b, }+ }1 i- n3 `! ~
if Type[nextP]==0: # 如果下一个位置是第一道工作点% e# ?, E0 I8 o* E" B& S$ B+ \
if rgv==1: # 然而载着半成品 7 p* A n" K/ E f seq.pop(index) # 去掉这个元素并中止当次循环进入下一个循环 4 u/ @3 E2 ]) }9 g+ S. ~6 L continue 7 r. c$ q; G& }' \3 b3 \ p) R
if isEmpty[nextP]: # 如果下一个位置是空的 ) M% Q1 m5 Z& S, h+ f t = cncT[nextP]+ K$ G' K1 H$ x5 u! J
total += t0 c4 D# s2 |0 D* j
update(state,t) 4 [9 G" `# G7 A% s9 K5 [ state[nextP] = T1 # 更新当前的CNC状态 4 h2 A/ r& {3 r& a. d; P6 ?! c; q isEmpty[nextP] = 0 # 就不空闲了 % @% Q, v4 b' Y- w$ ^ else: # 如果没有空闲 p. n; S& ?1 y' d& F
if state[nextP] > 0: # 如果还在工作就等待结束, d! f4 C1 C9 s# ?5 f& e& X: x
t = state[nextP]: [# H, L" t' M* z8 v; W& y: E
total += t 2 v% o0 \( f, Y& w, x" i- y' g4 v4 l update(state,t): A9 t* Q- D/ k; c ~' x$ j
t = cncT[nextP] # 完成一次上下料 ! [, Q1 ~% S0 k& F total += t2 S9 n; @5 ?$ s' ^& S; b* u6 ?
update(state,t)6 e: K5 R3 K) S) w- z" M
state[nextP] = T1 # L. d, J" x: B3 J" L rgv = 1 , d; q8 {/ h3 B% f else: # 如果下一个位置是第二道工作点 $ l' u3 b3 [& ^4 M if rgv==0: # 如果是个空车 H1 b) r- i& M
seq.pop(index) # 删除当前节点" f( r$ r6 x5 E- ^0 t' I6 g
continue9 B3 R# {+ ^0 L3 \9 ^: s E# V: [
if isEmpty[nextP]: # 如果下一个位置是空的# b8 `% Q+ C( L0 J' f7 p6 Q
t = cncT[nextP]; T: d% R* S" ^
total += t 5 d. s/ z* `4 ]$ n update(state,t) ( G9 \( d$ l& U+ E( x- P7 W state[nextP] = T2 3 G2 j; ]! {: G' ~$ r isEmpty[nextP] = 0 * N. |) l5 l* }
else: # 如果没有空闲 1 S5 s- R9 u8 @! q! R% ] if state[nextP] > 0: # 如果还在工作就等待结束- L3 k `, y0 Y. x9 w1 \
t = state[nextP]; ?! i2 G9 w+ I
total += t ( j( ], }5 {: [% s5 W update(state,t) 4 Z/ X' m" i9 t+ l% O" { t = cncT[nextP]+Tc / X) o! m* ~7 d/ \2 D total += t* Z3 @& e' Y; C9 c% I+ X
update(state,t), M( j$ ]6 R5 M# U8 I' @% T
state[nextP] = T2 5 B- l# ]% V) s$ l! ^. {4 f rgv = 08 @3 J8 n5 j! b" a4 s* A0 [
currP = nextP $ J- `9 C0 r8 d U" J temp = total / k. [ [7 N, C: O. g index += 1 ) v5 P$ {, o h' [
total += tm[currP][Type.index(0)] # 最后归零 % ^7 T& E1 s% ^" i return rgv,currP,total. J. ~) O! r& F! g0 q, X3 n
v5 F$ Q6 V2 j" @& E
def init_prob(sample,state,isEmpty,rgv,currP,total): # 计算所有sample的! H8 o: }5 a; c# Z1 W9 F
prob = []; `4 z, v' A. ?, d8 l
for seq in sample: 8 K+ ]5 H2 v; M# z/ _1 Z! q' r t = time_calc(seq,state[:],isEmpty[:],rgv,currP,total)[-1] / H1 A3 {3 [ t) ?* V/ R/ X! @' v prob.append(t) % d$ h5 B& r9 \- d1 ` maxi = max(prob)& f1 f: |, [0 s4 z7 f
prob = [maxi-prob+1 for i in range(N)] ; j0 R+ @* V& q1 h8 } temp = 0 7 ^/ ?+ X4 m! d9 {3 Q for p in prob: 9 S! h% [5 [3 y) O$ Z' a temp += p/ I4 r1 D9 Q( H# W2 |
prob = [prob/temp for i in range(N)]) x& o9 Z0 F! T
for i in range(1,len(prob)):' x) T7 i9 \9 s: [, K% n% ]
prob += prob[i-1] 5 H* S+ H/ a" p0 {/ U2 e! |% N" Y prob[-1] = 1 # 精度有时候很出问题 6 f2 o1 S/ F3 {4 b: u3 e2 e1 z( s4 k return prob ( G+ Q' G, `# J% Z p2 @6 K% u+ M" h, G$ S. p2 ^. S
def minT_calc(sample,state,isEmpty,rgv,currP,total):& A% \! u; s. F6 X
minT = time_calc(sample[0],state[:],isEmpty[:],rgv,currP,total)[-1]: q. X3 ?) G$ p: E5 l7 q- Z& N5 {0 c- w
index = 09 n& t* E+ R* W
for i in range(1,len(sample)):( a; h3 q1 h. s% S) O' A
t = time_calc(sample,state[:],isEmpty[:],rgv,currP,total)[-1], q: B6 e( N6 K9 y3 E2 z8 R& l4 L
if t < minT: & c5 R3 x' T% q" p' }. q index = i , g9 i5 t5 p# x3 y- q/ ?( F minT = t ( D# H; w9 w. v2 m' `2 b' g* H return minT,index * m u5 z+ J8 ?" B0 c$ C, m 9 ?- Z' J, M) M4 Edef init(): # 初始化种群(按照第二道工序,第一道工序,第二道工序,第一道工序顺序排列即可)( G% K9 p3 j9 A/ \% b; Z: C
sample = []. N6 e# ^1 r9 G$ ?% `1 \( o: `
refer0 = []0 N3 G; ^6 [) R. ~! L* X* P
refer1 = [] + H: n, D, y# W+ u( z8 y- x: h) y" Q for i in range(8): 4 f. r& [: A( h+ S" n. Z% r if Type==0:. y/ t) F6 k- u3 h
refer0.append(i); L) p+ U' K" P0 S
else:9 |; f, B% I* G( T
refer1.append(i) 3 F+ Z- H- u8 f& `9 ^ for i in range(N):7 s3 }5 u0 K. y1 K8 m
sample.append([]) - i0 \4 s0 L; p3 i) O/ V for j in range(L):; `) s6 v4 T- ? A$ D, U
if j%2==0: / P2 n4 F0 ]' r- ?4 B: D2 V sample[-1].append(refer1[random.randint(0,len(refer1)-1)]) : C$ [& t; [4 {; e8 ^, f else: " C) l- a: W. W5 \/ q" {3 m; Z sample[-1].append(refer0[random.randint(0,len(refer0)-1)]), S; V) O3 s% s0 j/ Q5 X+ Q: ~
return sample$ \/ ]5 Z, \( S: S
_7 o2 {$ |. o2 g$ [6 p( `def select(sample,prob): # 选择算子 % X* O0 f4 X# K& ~ sampleEX = [] / U9 _% |! L( s) e for i in range(N): # 取出N个样本% W' s& C- ~1 v; Q5 ^& ~. g. K/ S& _
rand = random.random() $ `" [+ H5 @- |( H for j in range(len(prob)):* A+ ]* w" k6 o! X
if rand<=prob[j]: ' n: R9 ^3 R4 `. `& Z sampleEX.append(sample[j])8 H; Z1 o( o' W$ j
break 4 E$ G. }% H) h" A0 p0 X return sampleEX : [* o, j8 v w* I8 o& i1 [6 u0 g
def cross(sample,i): # 交叉算子 5 S0 a% A+ U [) t, F V- N for i in range(len(sample)-1):( ~! m3 V7 X! q% Y* e9 \! ~
for j in range(i,len(sample)): 4 b$ _) k3 Z+ U9 `- J; S2 t7 t6 Q rand = random.random()( E B2 p5 E* ~# j! o* _
if rand<=croP*(e**i): # 执行交叉 % _# f+ g4 v* J! T% ]5 ?7 G loc = random.randint(0,L-croL-1) * p( I, X$ ]( M& \ ^$ @1 _- V temp1 = sample[loc:loc+croL]: Z: r8 N. r6 C7 @
temp2 = sample[j][loc:loc+croL] / J5 N$ s* i9 m9 a: v for k in range(loc,loc+croL):2 ?1 [* N4 R( x
sample[k] = temp2[k-loc]/ t: X- h. j) J; i, \2 `
sample[j][k] = temp1[k-loc] 7 l" B( b% o2 k5 U& T) I return sample2 N! e7 T6 }& D" x
& m/ s4 i) X d
def variance(sample,i): # 变异算子 8 I) @2 q4 {, Y* H j: q: l& T for i in range(len(sample)): ; b( g4 i, ^7 t: y7 l0 m rand = random.random()$ |; V# M, v' A% H7 ~% H3 }
if rand<varP*(e**i):1 m4 u! n; W/ u J& P5 y3 X' T- k
rand1 = random.randint(0,L-1) ) M- O, B0 S' ?: |* I. S% M randTemp = random.randint(0,int(L/2)-1) * I) Y( y6 H* l& O rand2 = 2*randTemp if rand1%2==0 else 2*randTemp+1( ]+ ] E5 Q; P' S; o* b
temp = sample[rand1] $ a! v% g# F; @5 @: U7 B sample[rand1] = sample[rand2]# Q; ]3 I0 t4 T) V. e
sample[rand2] = temp; h, {/ O4 s+ v4 O% h, Y
return sample ! f+ p+ W- U* b4 N" d5 W0 j $ b& Y Y! `4 \' F8 n: @if __name__ == "__main__": 8 l, W& S% a s state,isEmpty,rgv,currP,total,seq = init_first_round() 6 D* Y7 Y- y. Z8 [ print(state,isEmpty,rgv,currP,total)8 o, ?0 M0 ]0 B/ D1 z
sample = init() 6 k1 ^ v5 e3 O1 Z mini,index = minT_calc(sample,state[:],isEmpty[:],rgv,currP,total) 0 c q0 W* G4 m$ f
best = sample[index][:]' h% Z. k8 A0 D( ]! h
for i in range(100000):3 N: ?/ y+ D! P& C% f
f = open("GA.txt","a")* x# h* }! p/ N; X/ v' b
tmin = minT_calc(sample,state[:],isEmpty[:],rgv,currP,total)[0]# t+ @9 i1 y0 H5 h+ q" [/ l
f.write("{}\t{}\n".format(i,tmin)) . i! \8 m9 {3 C0 S print(i,"\t",tmin,end="\t")$ e3 P1 X# F7 f* O# O O& F( J4 M; h
prob = init_prob(sample,state[:],isEmpty[:],rgv,currP,total) + b( T7 u( i1 c/ C4 I sample = select(sample,prob)$ }8 t8 ~+ E) k2 d# V' \
sample = cross(sample,i)! D* i- e2 `- j1 p' I( J
sample = variance(sample,i)/ `8 p }( T2 \( Z
mi,index = minT_calc(sample,state[:],isEmpty[:],rgv,currP,total)1 {) M/ ?+ Q# g0 o
if mi>mini and random.random()<e**i: # 精英保留策略# g9 g/ B& e! |0 n3 B+ V# I
rand = random.randint(0,N-1)# D q# h" K( @. [1 r
sample[rand] = best[:] " }: K0 ^% J* ]& S# c; J mini,index = minT_calc(sample,state[:],isEmpty[:],rgv,currP,total)8 E7 Z. h, k! z. q* t# P0 C
best = sample[index][:]* b" u% p. B4 C, e4 ^
print(best) a: c4 R s! z+ Y/ u
f.close() ) u" ~" `! g* B, a3 i# ? print(sample) * I0 g* G3 J |3 L# m遗传算法这条路被堵死后我一度陷入俗套,用最直接的贪心搞了一阵子,觉得用贪心算法(即考虑下一步的最优策略)实在是对不起这种比赛。然后我就变得——更贪心一点了。 , V1 V+ k% ~1 z4 m) f* S( b $ }. S5 W7 l# S4 i0 {我试图去寻找接下来K步最优的策略,然后走一步。K=1时算法退化为贪心算法,最终我们设置为K=4(当K>=8时算法速度已经相当缓慢,而4~7的结果大致相同,且K=4的速度基本可以做到2秒内得到结果)。* k% B2 X7 Z' G' ?5 U* _8 ?# g
% @5 [! S3 z( `; D' V G# T值得注意的是我假设RGV在两道工序下只能由第一道工序的CNC到第二道工序的CNC(忽略清洗时间情况下),然后回到第一道工序的CNC,这样往复移动(这里我不说明为什么一定要这样,但是我认为确实应该是这样)。在这个规律的引导下我大大减缩了代码量以及计算复杂度。8 C% ^ _ I) V {/ E5 e* w
' |3 H a* G2 \8 l& d/ _
然后到第四种情况我们已经没有多余时间了,只能延续使用情况三的算法,进行了随机模拟的修改,完成了第四种情况的填表。 7 l& r4 l. i: I" o- D" J# [+ \ + r- x \& o7 B6 `3 q3 D5 f( W以下是第三种情况的代码(第四种类似就不上传了)↓↓↓ ; \( g- b8 a& ?) c# y. N% P) E( I: Q7 [' |$ _
#coding=gbk( M# a/ c2 d' U4 f
import random & x8 h' m3 V5 s9 I' \% d# -*- coding:UTF-8 -*- F! o' P& f& C: V$ b"""' F" P1 |6 ^% s' ~# t
作者:囚生CY" m7 I- N% r+ ?9 V9 m" K& o! `
平台:CSDN 3 H2 I% L' o1 j& Y5 Z- ?1 h7 [ 时间:2018/10/09 0 Z j9 x( G( `! } 转载请注明原作者 , u4 g" A# a% E/ U9 I 创作不易,仅供分享 2 i& H, V7 U9 G: j8 _9 Q"""5 M$ l) m; r2 ]" S r5 U4 l
from tranToXls import * " c6 r8 p+ }2 y* p1 I, G ( F) O' `& k9 h0 v& Z# 第1组 ! y: p W8 k8 g2 ^" _* D"""& i) B' ?9 m: e/ E% E6 T# z3 Y
d1 = 20; I4 R% W0 v/ g# O
d2 = 33- _$ ~6 g8 W( W' S# u
d3 = 466 _$ U' n5 D" v9 E6 E% W
T1 = 400 + b) P9 V3 d( X2 p! }7 g- MT2 = 378# @3 a' L4 x: F }! t) ?
To = 28 8 t) E7 F9 ]9 ]8 v0 QTe = 31# M, ^5 O9 W7 r: G/ O" \
Tc = 255 E# l) S5 B2 ^) K) J, r5 {
""" 4 w+ `' B. v! m: Y- x3 C o# 第2组 3 f9 l" d+ a: p2 E$ z7 d& P( Y5 F) Y$ ]& [' C& g" |" ]% j
d1 = 23 $ |- a" r8 U( v0 A+ s1 g4 Q2 ?d2 = 41$ A# @' q/ J. M C* Q& K
d3 = 59/ Y# [0 C) f6 ? a, b- E5 }) T
T1 = 2807 I# a! r/ G8 p. U
T2 = 500 % {+ @7 [/ Q/ g+ V2 UTo = 30 & q0 P4 A" S) n$ t, b5 x' z& h: lTe = 35& D6 W! H( r" l3 Y$ f
Tc = 30 1 \0 {& S$ w# q; w 7 ^- g; t% W: @3 c" J+ z$ G( R c3 |
# 第3组 : ~; M- y) s X6 | , b& z f! H& C) [8 t""") @3 x7 v6 n- |% \' n+ v
d1 = 180 S. f+ P: B! {, G& }/ @$ P
d2 = 32 * W3 S$ ^0 T( ?d3 = 46 " \* |2 l+ l& N' WT1 = 4553 c; b/ b' T0 `7 U! R
T2 = 1827 R, Z7 U1 I% A4 y2 R
To = 27) W/ n- q- B6 U; m% D
Te = 32$ R5 H) W+ o7 Q6 C( ?
Tc = 25 ; w: s* i4 h# q+ Z"""0 v4 A7 f5 ~+ c$ p; N! M' B# G: u
2 _* [1 W2 R" w+ U9 f
cncT = [To,Te,To,Te,To,Te,To,Te]& ~+ e @, z! ?6 U
tm = [ 6 m! X9 i7 v) ]* k: D; Y7 G [0,0,d1,d1,d2,d2,d3,d3], 5 L8 {- R! z% S- \9 r) Z [0,0,d1,d1,d2,d2,d3,d3],& k0 @1 r& @: d' a* c
[d1,d1,0,0,d1,d1,d2,d2], q/ N; ?! S# L% j3 [ P4 a
[d1,d1,0,0,d1,d1,d2,d2], N b0 O# {% K8 G P4 w" y
[d2,d2,d1,d1,0,0,d1,d1], ! h0 |8 f* l ]5 j3 u2 t- d( o [d2,d2,d1,d1,0,0,d1,d1],# A2 c9 U5 y: A' J1 Y6 d/ ~: ~
[d3,d3,d2,d2,d1,d1,0,0],3 c0 j& I3 t* ~6 U z- D
[d3,d3,d2,d2,d1,d1,0,0], 1 h& ?6 }5 u7 s0 c9 ^]# E9 x1 d4 O8 U4 b! [
Type = [0,1,0,1,1,1,0,1] # CNC刀具分类 1 p* H* u: M6 }. [: d 0 ?* s+ Q; C \A = [] # 储存第一道工序的CNC编号 ( n5 ]$ N& ]8 J* j. O" L+ nB = [] # 储存第二道工序的CNC编号4 e4 }9 w0 d. H7 F
for i in range(len(Type)):( h5 M. k1 O% F+ }( I
if Type: * w5 M$ @4 T1 } B.append(i) 2 Y8 f# ~3 |9 O& d7 J- b' a5 h else:8 w4 k/ n$ Y9 p) |0 U0 k( i
A.append(i): z6 z7 @" L. B/ a4 |- c1 {4 U
8 z- h5 Z3 ]) p
def init_first_round(): # 第一圈初始化(默认把所有第一道CNC按顺序加满再回到当前位置全部加满) $ F) r2 W( l5 f state = [0 for i in range(8)] # 记录CNC状态(还剩多少秒结束,0表示空闲) ! ?( b# U3 f, I/ \, ] isEmpty = [1 for i in range(8)] # CNC是否为空- q! S, I5 D1 I: [; j& c2 r
log = [0 for i in range(8)] # 记录每台CNC正在加工第几件物料2 ]3 C! X3 f0 s2 a: q4 a7 W& a
count1 = 0 ) }4 `8 X, N3 Y9 L$ o1 ] rgv = 0 # rgv状态(0表示空车,1表示载着半成品): [' |0 W1 x9 @0 n! j) [
currP = 0 / d# i# ?& U- N3 G' ~ total = 00 k3 k9 D* M/ \5 t
seq = [] % `& x& c: z' D7 G& r Q* s4 P flag = False 4 s' y. }& e" w! |* f6 e G for i in range(len(Type)):) `5 i4 e- C/ C& m9 R* O, ?
if Type==0: 1 V6 `" _* Z: l' \+ X. a/ w seq.append(i)) @/ _% f' p0 J2 _2 k+ y. ]5 i2 X& S
flag = True 5 G7 X" F6 ^1 c& p# D currP = seq[0] , W) e' U. a! z- a. P seq.append(currP)$ s% l" F3 M: Q: n
count1,rgv,currP,total = simulate(seq,state,isEmpty,log,count1,rgv,currP,total) 3 }4 i, ~' t. C- M return state,isEmpty,log,count1,rgv,currP,total,seq + @) n0 H: t/ I" V; {- ?3 i# Q ' y6 z$ w( e0 R- \( L& Rdef update(state,t):5 ~( e# z1 ]. D) G, X
for i in range(len(state)): ! s" ^2 C+ l! n. G if state < t:# z$ t+ @, B1 Q0 X* ?, B( [/ z4 x% n
state = 0 3 S! |) B2 C! }0 B2 M8 X else: 5 ~6 ]+ {: L) @" I state -= t F7 n) g( l% b, O1 q9 t4 e& H+ L y8 s% V/ ~' v. h
def simulate(seq,state,isEmpty,log,count1,rgv,currP,total,fpath="log.txt"): # 给定了一个序列模拟它的过程以及返回结果(主要用于模拟并记录)0 L9 x+ E- K- L& m
index = 0- `4 m4 ?* o! P9 d
temp = 0" b# S7 J8 `" y2 M
pro1 = {} # 第一道工序的上下料开始时间 8 ^" w( Y3 w$ Y* _ pro2 = {} # 第二道工序的上下料开始时间* _1 a4 m! b( r) e2 [$ R
f = open(fpath,"a"), W5 }0 k$ s% @/ e
while index<len(seq):2 h* A0 h1 |3 Q+ {; w" [
print(isEmpty)9 h/ F& h8 B3 E5 l0 B
nextP = seq[index] # U( R" k \" N0 W; W0 I t = tm[currP][nextP]& b6 a9 V$ s) U6 f# ^
total += t2 i6 V5 ?6 c# l+ o- _! J2 A' `3 V
update(state,t)- T+ ?) X [7 t: y, ]% x6 p" @5 k
if Type[nextP]==0: # 如果下一个位置是第一道工作点# P% |% L P" k C
count1 += 1 ! \* h' t1 ?. r9 F if isEmpty[nextP]: # 如果下一个位置是空的 " B# h' z$ g, |6 c6 \! T H$ R f.write("第{}个物料的工序一上料开始时间为{}\tCNC编号为{}号\n".format(count1,total,nextP+1)) 1 w) C1 D! B- U5 b, r8 t t = cncT[nextP]0 I8 P8 W* ]5 H* r& n
total += t : S' z. [0 p" n update(state,t)1 | V: ]. ^1 K* [: p0 b
state[nextP] = T1 # 更新当前的CNC状态7 U, E) e5 `. }8 u4 k
isEmpty[nextP] = 0 # 就不空闲了& M8 x3 r! T2 K: \- Y* h: x v1 u
else: # 如果没有空闲 ) H% o/ ^* U! H if state[nextP] > 0: # 如果还在工作就等待结束 8 Z3 f; H6 o7 c4 M. V4 ` t = state[nextP]! e( V7 W- i, b; |
total += t / J- t, ~9 O5 u4 p/ I- v7 a; o0 s update(state,t) : E/ q1 F% V0 O' `2 O f.write("第{}个物料的工序一下料开始时间为{}\tCNC编号为{}号\n".format(log[nextP],total,nextP+1))3 x; M/ r1 a" }; G _
f.write("第{}个物料的工序一上料开始时间为{}\tCNC编号为{}号\n".format(count1,total,nextP+1)) % r1 P/ L* O2 l9 ~* |/ w t = cncT[nextP] # 完成一次上下料) R; t `+ D* P7 Y: E
total += t 7 _) |4 C. \4 ~: H. S' u9 }; O; b8 r$ ^ update(state,t) % a3 G/ A9 P1 K. V/ a$ Q4 ~5 j1 u2 E state[nextP] = T1( }1 g+ r9 c7 t( W6 ?
rgv = log[nextP] 1 o$ ]$ K, Y+ c7 j/ ]( L/ I! y log[nextP] = count1; J" K! z6 r5 f! H5 W
else: # 如果下一个位置是第二道工作点 + V, l) ~) M" J: m if isEmpty[nextP]: # 如果下一个位置是空的+ ~6 i. g3 I) @# ?9 v* u
f.write("第{}个物料的工序二上料开始时间为{}\tCNC编号为{}号\n".format(rgv,total,nextP+1))8 R3 L% M! r) {! ]3 y9 g) |
t = cncT[nextP]; `8 C: T8 n2 Q# }/ ]
total += t : G# @9 t. d' l* H4 k0 W update(state,t)3 n5 T7 S2 K6 g, q; y9 J7 u( g
state[nextP] = T2: Q5 e0 u8 J/ V$ j$ r, B8 n6 A, [, F- `
isEmpty[nextP] = 0 - r7 B: W* S+ F else: # 如果没有空闲 2 S5 }& M9 w r+ a, z9 t f.write("第{}个物料的工序二下料开始时间为{}\tCNC编号为{}号\n".format(log[nextP],total,nextP+1)) / z; f( {' z8 K! k$ H f.write("第{}个物料的工序二上料开始时间为{}\tCNC编号为{}号\n".format(rgv,total,nextP+1))% X" H k- p' Y5 f, K) _9 r8 ^
if state[nextP] > 0: # 如果还在工作就等待结束* x1 I1 X( D8 L" R
t = state[nextP]7 M# t' `5 ^* {7 M0 U
total += t ( |- x8 w! y2 Y2 B P( g6 V update(state,t) 5 W( a5 Y2 W; y9 S t = cncT[nextP]+Tc ; u8 k! A% Q+ ^+ d+ x$ v, f total += t( R# [" r* J% k* _4 z$ z
update(state,t) 7 g% K3 m9 q' E0 D l state[nextP] = T24 E. {5 {6 t9 E6 F1 H& i* Z0 a
log[nextP] = rgv 2 U6 t$ Q7 h. c1 V: P- G rgv = 0 3 V3 ^) z- a# V' D! C currP = nextP 9 V( F2 a1 }2 i. P# A2 d# T temp = total & A& r# z9 t# U4 }4 q8 e3 T! z! ]' S
index += 1 ! Q- K( M4 F6 q0 \) W f.close() 9 r6 v$ }7 y6 w total += tm[currP][Type.index(0)] # 最后归到起始点 + q2 R% r/ R; {5 L return count1,rgv,currP,total& A" z( Q) z6 ^6 E' U
& B# i4 ^& I' udef time_calc(seq,state,isEmpty,rgv,currP,total): # 主要用于记录时间 f- Q2 k7 ?+ m3 {& J. G9 {
index = 0 1 p8 l* ~9 r" L/ X, D temp = 0 ; @* N- a% Q, F3 f$ g while index<len(seq):8 h8 R% P2 w( ]# G L: }
nextP = seq[index] " m5 x4 R) V7 {6 N t = tm[currP][nextP] % ~% P8 _1 a0 g total += t , E5 X+ N3 _; O' X' }! f update(state,t) 0 X& F6 Q% y0 A- ?& y2 p: c& B1 y if Type[nextP]==0: # 如果下一个位置是第一道工作点 + N9 N; y1 K( W/ a3 T- t( u8 } l if rgv==1: # 然而载着半成品 1 X# S D v' `) z9 F% m seq.pop(index) # 去掉这个元素并中止当次循环进入下一个循环 ! S3 g ]0 \3 d) ]. @ continue ' N* C+ o6 a6 O3 R0 f2 l, B2 O* ` if isEmpty[nextP]: # 如果下一个位置是空的# f! s* x. p2 I( ^, [
t = cncT[nextP]: E! ]6 J, ~0 H2 h1 g3 x
total += t) t7 k5 h3 i9 c+ ^& T0 u" J
update(state,t) 4 m. g1 A% ^! S- G% x state[nextP] = T1 # 更新当前的CNC状态8 Y3 t s7 @/ p9 K$ ]
isEmpty[nextP] = 0 # 就不空闲了 , L; _6 l8 v7 E else: # 如果没有空闲" |0 A" B" f8 d, H v" _
if state[nextP] > 0: # 如果还在工作就等待结束 ( j ^# @) T" X; h. M' j t = state[nextP] ( I% o1 r: |6 U/ B7 y4 r7 r. [* @5 h total += t* \$ t2 |, \1 Q% N) J7 ?6 S
update(state,t)! \" T i: p @% H8 z# i
t = cncT[nextP] # 完成一次上下料 2 b" E+ e* m2 Q' k; G total += t1 z- l: R4 `' F) Z
update(state,t)4 I4 v0 D; t2 B, y |* B0 h
state[nextP] = T1 " z3 \' a' L4 _) x+ W rgv = 1 : p, _ b& y5 q8 a else: # 如果下一个位置是第二道工作点$ N+ D# ^; b: @ H4 B G [) b
if rgv==0: # 如果是个空车6 @ Q) l& _1 v0 \1 C% P
seq.pop(index) # 删除当前节点 ; X/ t7 }/ W7 I' \8 D continue0 O/ e a0 f5 r. |6 R8 C- [+ ] m! D
if isEmpty[nextP]: # 如果下一个位置是空的; N! H: f v: b8 k
t = cncT[nextP] ! d8 @) X6 B& a/ A, v8 r1 D total += t' S" k/ _4 v9 V, N7 L: C" {
update(state,t)" |7 T4 |: c9 p8 {% V! H5 J
state[nextP] = T2( E6 b, d: J. E
isEmpty[nextP] = 0 4 J) \. h1 k* `" @1 C& ` else: # 如果没有空闲 " m x0 { N3 j0 C9 n9 d0 n! d0 G if state[nextP] > 0: # 如果还在工作就等待结束 - t- k$ O0 x* o: o4 w t = state[nextP] . S" J2 m; w8 \ total += t $ W8 c6 B) D: O. }6 _ update(state,t) ' e7 H+ V- Q- j& u: \" a t = cncT[nextP]+Tc 6 R. h9 Q4 x. d% p4 T5 } total += t 5 g0 A# w1 K3 |/ K9 V update(state,t) : A0 v) F; O H+ o state[nextP] = T2 $ `3 h) {$ V! I rgv = 0 " s( W( S8 v# b! X* D currP = nextP 8 D- I( R) Y5 } temp = total 6 y( b) p Y7 ]; @ index += 1 % C+ o6 g2 a1 e a+ P/ W3 i3 `( X return rgv,currP,total ) _* L6 X4 a2 P' L$ U; O0 E5 i( S/ o3 u: a& z' d
def forward1(state,isEmpty,currP): # 一步最优 Y4 c. ]# @( a' x
lists = []' l2 Z8 O5 ~! D
if currP in A: 3 F1 | k$ P2 _- s& X$ M' D. P rgv = 1% s3 Q0 W" {0 U# v
for e1 in B:# L* p; B% D/ g @0 j( v7 K/ `
lists.append([e1]) * U( b' Y0 V) i* [" |) g ' j# S, ~( Z/ p u1 s( f+ c1 h A else:4 s6 P! S1 `' I: f3 U- T
rgv = 0 2 u) y( ^/ T0 w8 d7 X* W2 o* S( s for e1 in A:! E% V' A: t! c- X* }
lists.append([e1]), X/ _# d& w/ K$ n5 j2 w
5 v% Y+ d+ F4 P- A9 y' R minV = 28800 3 W; ~2 D8 {7 r" N, |$ u for i in range(len(lists)):! M* {2 |3 z+ _" b9 Y8 s
t = time_calc(lists,state[:],isEmpty[:],rgv,currP,0)[-1] , U/ v' T) A9 Z m2 R0 ^ if t<minV:) {4 d; c4 u1 ^ s* v/ G
minV = t & ?! D# x6 V4 y9 I% ?9 v/ g( ? index = i ! S9 ? o- c) E3 @- [8 c return lists[index][0]; | S& o+ v: f j; y
5 }0 A0 A7 j3 L. F* I" zdef forward4(state,isEmpty,currP): # 四步最优 / r: K7 i# v4 o4 z! y: r" u: l lists = [] 9 O- c+ U5 F( m$ P7 N: ~0 O) _$ q/ l """ 遍历所有的可能性 """ ( l' f: U. u7 ]# l0 i2 a! r if currP in A: # 如果当前在第二道工序CNC的位置9 j# S1 ?; N& S+ C* v+ z
rgv = 18 o( Q! r l+ I, N
for e1 in B: / t7 w( U5 Z3 I( _ for e2 in A:4 c% K& C- D8 F! R/ V+ X
for e3 in B: ( S8 ^' q1 K& g* F( [) W. f for e4 in A: 4 P% d2 u0 Q& i2 Z: y1 s lists.append([e1,e2,e3,e4]) $ m5 z; H& ~' ]4 t; T else:7 f+ V3 ?' k1 Y; t
rgv = 01 j6 N( I: s% M" O+ o
for e1 in A: 9 | L8 f. F! W- Q for e2 in B:# V+ Z5 \, \/ S+ a. i& ?) S% T0 o9 V6 W; e
for e3 in A: 9 x! i4 V7 x1 n! @! Z" ? for e4 in B: - U1 T! G2 N; j* f: M; P0 P lists.append([e1,e2,e3,e4]) 5 U' b1 c7 E* ? minV = 28800/ q. z/ f& M8 k, ?$ G' G
for i in range(len(lists)): & N8 n9 Q, y7 N4 L, ? t = time_calc(lists,state[:],isEmpty[:],rgv,currP,0)[-1]4 R; ]2 Y% N D8 e* l& \' U4 \
if t<minV: . W4 H9 L6 y; q" Z minV = t9 l+ ]- i8 c4 a8 w
index = i( T$ H! f, m* \. ]2 [
return lists[index][0] # 给定下一步的4步计算最优& E% l( [/ }6 ?8 U
# o7 l P5 [4 ]: _, @: }+ Adef forward5(state,isEmpty,currP): # 五步最优' ~+ ~, d- \" K( ~2 X# j
lists = []1 x1 d7 `- z* V5 k3 ~6 z+ S
""" 遍历所有的可能性 """ " b6 d" [. ^* o, y: b; n if currP in A: # 如果当前在第二道工序CNC的位置 + v5 v j+ s2 ~8 l6 \' { rgv = 1, D6 S( X6 Y0 D, m
for e1 in B: ; E2 t& K; k9 S" T% ^8 d for e2 in A: |$ v% i1 ^. G/ _+ n
for e3 in B:7 Q# h4 ^0 K* u" e+ R4 F5 a
for e4 in A:7 N( U' O/ d; P2 N5 g h% s
for e5 in B:6 O0 q+ I0 w. {& ^' F' Y8 l+ A
lists.append([e1,e2,e3,e4,e5])6 l; C- g: u: E: ^
else:5 n2 C8 V( V* U& U n2 B& _
rgv = 0; Q) }% f P' `# ~2 g3 l
for e1 in A: * a/ T. N* K8 `6 I, p( J" Y for e2 in B:6 `2 h# g. ^! ?7 H! b5 ?
for e3 in A:9 A' l$ k5 z, W7 }0 G5 i( ^3 ~
for e4 in B: $ N6 H+ {( `' R" C; y for e5 in A: 1 R# \: V( J8 ` lists.append([e1,e2,e3,e4,e5]) 7 p- v7 `! H/ m$ q% o# ^+ m minV = 28800 ( J) Y a3 o8 O# J for i in range(len(lists)): f4 O6 l6 Z* A( @ t = time_calc(lists,state[:],isEmpty[:],rgv,currP,0)[-1] # \: Z$ M5 p6 S if t<minV: ) b* @7 \ X6 g# @ minV = t' \9 ~+ b+ m. [- r( E7 J$ S2 w- z
index = i& v" }' \; I' s" T! Q* f' B: k
return lists[index][0] # 给定下一步的5步计算最优; h3 }, A0 D7 e- s
{6 r, Z6 S3 I3 M+ f
def forward6(state,isEmpty,currP): # 六步最优2 X5 z' D* U0 R3 ^* h
lists = [] ( o6 `+ _0 H# P: `) O3 D """ 遍历所有的可能性 """ $ J% y( l u# |3 ^3 ?7 F( N5 w3 w& M if currP in A: # 如果当前在第二道工序CNC的位置 : G0 O. Z4 ^ D% m" N% ~) n rgv = 18 \; H% v2 @" t0 }& l
for e1 in B:0 ?, q/ g9 K. Q
for e2 in A: 8 o8 P) Z/ x1 `0 \ j for e3 in B: 8 n# y' R' `. e7 L9 B7 _, v for e4 in A:: X9 G: ^; e* [3 B
for e5 in B: * v; z0 K6 ~+ |& I2 [. Q+ \ for e6 in A:" u7 ?# \- q. f" K( F* N
lists.append([e1,e2,e3,e4,e5,e6]) 1 L# m- Y' F, f. j8 T. F else:8 c# W- E; [/ v1 B2 D! c
rgv = 0 5 o2 Q9 ~5 A: M! J8 k4 A+ W0 X! R for e1 in A:, Q7 |: L5 C2 ~
for e2 in B: ! }+ V9 n0 U }$ T! [ for e3 in A: * k3 Z9 D( \2 H6 I for e4 in B:1 f ?. t: V" K$ K
for e5 in A: % Q0 L( r: E( T, f$ f8 \ for e6 in B:5 j2 G4 O* L: p! E% ], {) S7 q
lists.append([e1,e2,e3,e4,e5,e6])# ~) T H/ _+ ]% O+ R7 b9 k! [
minV = 28800 ' O& _5 U8 L4 T: j: v: d for i in range(len(lists)): + y2 n( A; |0 P. B; ^: j% S t = time_calc(lists,state[:],isEmpty[:],rgv,currP,0)[-1]- w$ m$ Z7 J! X. ^/ V. }
if t<minV:$ K' `' e& T S$ o1 W6 o$ b
minV = t2 t; T/ S* M; ^0 g; C
index = i4 z4 o$ m8 h- N
return lists[index][0] # 给定下一步的6步计算最优& \& a& h( V, Q( C0 c. F( z6 U
7 K" @# N0 B; f& B2 Hdef forward7(state,isEmpty,currP): # 七步最优 7 g2 p5 Q% j3 F- p, j! t" k lists = []) @5 X8 X) Z" \, I
""" 遍历所有的可能性 """3 e- Q( V( |0 O$ ~3 ~. ` Y# O
if currP in A: # 如果当前在第二道工序CNC的位置 8 V# q) s+ j; f# h1 y' A# n6 k$ `/ g rgv = 1 % ?) h' L* p; D. m9 G& l) W; Z: ] for e1 in B: & T4 \3 ^% O- C' @. K0 b for e2 in A: 1 [/ f1 t9 c* }' @& Q0 b for e3 in B: 7 p1 T5 ~/ V3 S, x; `' b for e4 in A: , M+ e. Z4 b1 m& c; |! ] ^8 p for e5 in B: ! M6 w7 c: W9 a% g. J' u- ` for e6 in A: 6 q; v% W9 y3 C: \1 b) U for e7 in B: $ \! o7 E' |( R$ {3 Z7 p lists.append([e1,e2,e3,e4,e5,e6,e7]) / m6 p9 ~$ T! G1 @( d, W) E1 |1 ? else:% e& k% x* m, u7 s
rgv = 0 # M/ N5 k8 \& B8 d- ? for e1 in A:: R3 B: k$ V7 Y4 X. Z) X4 T/ F
for e2 in B:/ o4 ?" V' _ M6 X: Z/ b* S) e. [
for e3 in A:0 U7 P! n9 G5 G0 O9 t% c
for e4 in B: 3 S! j; {" d7 |# x/ X n* x for e5 in A:1 d( u3 {. q9 p
for e6 in B: * Q( |& Q' W9 B) v) ] for e7 in A: 1 e5 K$ x& H2 J; d& L lists.append([e1,e2,e3,e4,e5,e6,e7]) # a1 w% R7 n" M) F) c minV = 28800 " ]4 \& U( M( C) }8 w for i in range(len(lists)): 7 v) X" D! e& R ]( t" K" v t = time_calc(lists,state[:],isEmpty[:],rgv,currP,0)[-1]% C% ?$ J) ~* h
if t<minV:3 r$ r) L# @5 G7 i& f7 |6 R
minV = t " E& A' B- W+ E; O index = i8 {; I6 D8 l8 g- \, S2 v
return lists[index][0] # 给定下一步的7步计算最优& R! [0 W, [7 I, m M* C$ R
0 v- f. P7 E; k& ]/ g5 Wdef forward8(state,isEmpty,currP): # 八步最优% e: q2 ^0 r g
lists = [] , q- @; a( f# e. E; n( f1 s; s1 E """ 遍历所有的可能性 """ 7 s: g0 M# U# a8 t8 Q, Q6 G if currP in A: # 如果当前在第二道工序CNC的位置 ( E% W( ]6 R. z( \ rgv = 1 5 t9 v1 V8 L1 W* a) `1 Q2 f for e1 in B:# |4 W- D+ H% X* o D
for e2 in A: ; s4 J e* u9 s X. e- _3 p7 F5 h5 k$ z6 E for e3 in B:( g6 e3 ^# M( R% c
for e4 in A:8 E$ f; Q% L) @0 a8 c1 t( ]
for e5 in B: 3 A/ y* \: P% B) K7 b) ~ for e6 in A:" s9 t% A0 g/ L& u H4 M
for e7 in B: 5 ?) }( A8 {; `& ` for e8 in A:& ^2 x" O. [ n2 @1 o
lists.append([e1,e2,e3,e4,e5,e6,e7,e8]) 2 o% e; M; J/ X2 ` else:" J/ x4 J2 B7 m* s6 |
rgv = 0/ {0 e) I: h* V4 ?, E. @
for e1 in A:3 f5 t, B% T& [0 _
for e2 in B:) P; O0 L* o N7 n( R% B
for e3 in A:+ {: k: W0 k" g8 x
for e4 in B:. r. @4 n6 j2 ^+ s+ F
for e5 in A: ; n0 e$ D$ k5 S2 a) H; x) c for e6 in B: l8 g' K9 X9 Y n) X
for e7 in A:: a$ l, D0 {6 @) g. v, M
for e8 in B: ; r+ \- y1 q; e' k. W# G+ x1 W1 a* n lists.append([e1,e2,e3,e4,e5,e6,e7,e8])" Z0 J. x* |* K$ b) d
minV = 28800( ^" F8 m/ y, k% I1 D# x
for i in range(len(lists)):! c) R. s; M7 B! N3 G
t = time_calc(lists,state[:],isEmpty[:],rgv,currP,0)[-1]9 z; A* ^, n, m/ z; `& H& q" f
if t<minV: ( h) _+ y6 m6 a" a6 {/ }! s( k1 Z minV = t$ b' K6 ~3 @* L$ t. h
index = i5 u# w: r, R- W& S+ j
return lists[index][0] # 给定下一步的8步计算最优3 C3 |1 [: A# R1 c* d
' y, q( D1 \; _2 _& [9 ?+ W1 X
def greedy(state,isEmpty,rgv,currP,total): # 贪婪算法 4 ~- A; r. ~( Z line = [] ' c& R. P) ?5 U: R count = 04 ^1 b7 c# R% h6 D
while True: / G* A9 C2 Q/ o( x #nextP = forward4(state[:],isEmpty[:],currP) + z" B. A3 |1 |$ J! _ D2 f& g
nextP = forward5(state[:],isEmpty[:],currP) ; F2 V" @ ]- O. H" y E/ Y line.append(nextP): Y+ I' X; P' ]# F5 U$ \
rgv,currP,t = time_calc([nextP],state,isEmpty,rgv,currP,0)3 V5 d/ A5 w/ R0 J
total += t: t/ W$ l3 E, h8 i) d! g! H
count += 1 ! i2 i( j* t3 x% E7 V' ], y9 c- K if total>=28800:0 c0 ]% k# j/ B& b: W
break * O; W0 \! E `; Z( _ return line& u( M" y" P: R. q
' m9 u6 _- f* x+ A2 n7 m! P: }: P4 x
if __name__ == "__main__":- t. K* _" x, a
state,isEmpty,log,count1,rgv,currP,total,seq = init_first_round() 4 N4 m! ?6 X- D8 ^' q print(state,isEmpty,log,count1,rgv,currP,total,seq) 7 d3 F" E; u ^8 s line = greedy(state[:],isEmpty[:],rgv,currP,total); i; E7 p! Z; ~ n! N9 Z: ~
simulate(line,state,isEmpty,log,count1,rgv,currP,total)( u0 p$ S4 [: b4 f# d5 ~
2 V6 k }$ C* j write_xlsx() : F$ i1 H9 y: R: N; A% f4 a4 g- S4 r后记0 U- f! h/ w- G' V u3 c7 U; H c0 g
" ~8 }6 @# F7 G8 o2 z+ l! V+ J3 ?# F; t
这次博客有点赶,所以质量有点差,很多点没有具体说清楚。主要最近事情比较多。本来也没想写这篇博客,但是觉得人还是要善始善终,虽然没有人来阅读,但是学习的路上还是要多做小结,另外也是万一有需要的朋友也可以给一些参考。虽然我的水平很差劲,但是我希望能够通过交流学习提高更多人包括我自己的水平。不喜勿喷!* R- a/ d& A( M" L0 g5 N
--------------------- + [9 ^7 ]5 H7 B% Z
( q7 _! ~6 X' B1 H