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