組立計画
これを得るプログラムを、本資料では次のように分割して示しています。
プログラムII ************************ 組立工程計画 ************************
・プログラムII-1 リソース(場所・メッシュ)の定義
・プログラムII-2 リソース(作業員)の定義
・プログラムII-3 組立工程計画アクティビティの定義(一部艤装工程追加)
先行制約の設定
・プログラムII-4 モードの設定
組立工程計画 資源制約(配員)
組立工程計画 資源制約(作業場所)
・プログラムII-5 RCPSP求解
・プログラムII-6 データセットの更新
#プログラムII-1.0
#========================================================================
print("")
print(' ************************ 組立工程計画 *************************')
print("")
#========================================================================
# import dill
# dill.load_session('usukiR040510a.pkl')
#=====
usuki2=Model()
プログラムII-1
#プログラムII-1.1
#=======================================================================
#リソースの定義(場所)
#=======================================================================
#-----メッシュの使用可否
for id in R:
if not id in [4,5,6,13]:
for i in range(0,R[id][1]):
for j in range(0,R[id][2]):
resPL[id,i,j] =usuki2.addResource(R[id][0]+"[{0:02d}_{1:02d}]".\
format(i,j), capacity=resPL[id,i,j].residual)
if id==4:
for i in range(0,R[id][1]):
for j in range(0,R[id][2]):
if i in range(0,11) and j in range(0,12):
resPL[id,i,j] =usuki2.addResource(R[id][0]+"[{0:02d}_{1:02d}]".\
format(i,j), capacity={(0,"inf"):0})
else:
resPL[id,i,j] =usuki2.addResource(R[id][0]+"[{0:02d}_{1:02d}]".\
format(i,j), capacity=resPL[id,i,j].residual)
if id==5:
for i in range(0,R[id][1]):
for j in range(0,R[id][2]):
if i in range(0,7) and j in range(0,10):
resPL[id,i,j] =usuki2.addResource(R[id][0]+"[{0:02d}_{1:02d}]".\
format(i,j), capacity={(0,"inf"):0})
else:
resPL[id,i,j] =usuki2.addResource(R[id][0]+"[{0:02d}_{1:02d}]".\
format(i,j), capacity=resPL[id,i,j].residual)
if id==6:
for i in range(0,R[id][1]):
for j in range(0,R[id][2]):
if i in [0,22,23,24,25,26,27,28,29,30,31,32,33,34,35] and \
j in range(0,13):
resPL[id,i,j] =usuki2.addResource(R[id][0]+"[{0:02d}_{1:02d}]".\
format(i,j), capacity={(0,"inf"):0})
elif i in range(1,17) and j in range(0,1):
resPL[id,i,j] =usuki2.addResource(R[id][0]+"[{0:02d}_{1:02d}]".\
format(i,j), capacity={(0,"inf"):0})
else:
resPL[id,i,j] =usuki2.addResource(R[id][0]+"[{0:02d}_{1:02d}]".\
format(i,j), capacity=resPL[id,i,j].residual)
if id==13:
for i in range(0,R[id][1]):
for j in range(0,R[id][2]):
if i in [31,32,33,34,35,36,37,63,64,65,66,67,68,69,70,71] and \
j in range(0,24):
resPL[id,i,j] =usuki2.addResource(R[id][0]+"[{0:02d}_{1:02d}]".\
format(i,j), capacity={(0,"inf"):0})
else:
resPL[id,i,j] =usuki2.addResource(R[id][0]+"[{0:02d}_{1:02d}]".\
format(i,j), capacity=resPL[id,i,j].residual)
プログラムII-2
#プログラムII-2
#=======================================================================
#リソースの定義(作業員)
#=======================================================================
resWH =usuki2.addResource("R[WH]", capacity=resWH.residual)
resWW =usuki2.addResource("R[WW]", capacity=resWW.residua)
resWF1=usuki2.addResource("R[WF1]", capacity=resWF1.residual)
resWF2=usuki2.addResource("R[WF2]", capacity=resWF2.residual)
resWF3=usuki2.addResource("R[WF3]", capacity=resWF3.residual)
resWP =usuki2.addResource("R[WP]", capacity=resWP.residual)
resWP2=usuki2.addResource("R[WP2]", capacity=resWP2.residual)
プログラムII-3
#プログラムII-3
#=======================================================================
#組立工程計画アクティビティ idata2
#=======================================================================
w=[]
for i in data:
if data[i][1] in ACT_kumitate+PL_kumitate and data[i][11] in BLK_all and data[i][12] in [0]:
w.append(i)
idata2=w&data.keys()
if 3 in BLK_all:
idata2.add("A09320") #組立中ブラスト(運ブ)
idata2.add("A09321") #組立中ブラスト(ブラスト棟)
idata2.add("A09322") #組立中ブラスト(ブラスト作業)
idata2.add("A09330") #組立中ブラスト(運ブ2)
if 7 in BLK_all:
idata2=idata2-{
'A11700','A11701','A11702','A11703','A11704','A11705','A11706',\
'A11710','A11711','A11712','A11713','A11714','A11715','A11716',\
'A11720','A11721','A11722','A11723','A11724','A11725','A11726','A11727','A11728','A11729'} #総組は場所だけ残して作業は除く
print(idata2)
プログラムII-4.1
#プログラムII-4.1a
#=======================================================================
#組立工程計画 作業の定義
#=======================================================================
act2={}
for i in idata2:
j=i
while data[j][1]!=16:
j=data[j][4][0]
act2[i]=usuki2.addActivity(data[i][0], duedate=data[j][3]+data[j][2], backward=True)
#プログラムII-4.1b
#=======================================================================
#組立工程計画 先行制約
#=======================================================================
for i in idata2:
if data[i][1] in ACT_kumitate:
for iw in[0,1,2,3,4]:
if data[i][4][iw] in idata2:
usuki2.addTemporal(act2[i],act2[data[i][4][iw]],tempType=CS[data[i][5][iw][0]], delay= int(data[i][5][iw][1]*2))
if data[i][1] in ["A02010","A02610","A03010","A03210","A04310","A09210",] and data[i][5][iw][0]==0: #外板
usuki2.addTemporal(act2[data[i][4][iw]],act2[i],tempType=CS[3], delay=-int(data[i][5][iw][1]*2))
#-----
for i in idata2:
if data[i][1] in PL_kumitate:
for iw in[0]:
if data[i][4][iw] in idata2:
ii=data[i][4][iw]
usuki2.addTemporal(act2[i],act2[ii],tempType="CS")
usuki2.addTemporal(act2[ii],act2[i],tempType="SC")
for jj in idata2:
for iw in[0]:
if data[i][4][iw] in idata2:
if data[jj][4][iw]==i:
usuki2.addTemporal(act2[jj],act2[i],tempType="CS")
usuki2.addTemporal(act2[i],act2[jj],tempType="SC")
#-----開始日の制約
for i in idata2:
if data[i][1] in [11]:
usuki2.addTemporal("source",act2[i],tempType="SS",delay= 80)
#-----運搬日の制約
for i in idata2:
if data[i][1] in [16]:
usuki2.addTemporal("source",act2[i],tempType="SS",delay= int(data[i][3]-10))
プログラムII-4.2
#プログラムII-4.2a
#=======================================================================
#組立工程計画 資源制約(配員)
#=======================================================================
mode2={}
for i in idata2:
if data[i][1] in ACT_kumitate+ACT_gisou:
#-----
#1F #2W #3C #4CC #20ブラスト #31鉄艤 #32甲配 #33機配 #34PA #39_甲配 #40_機配
if data[i][1] in [1,2,3,4,20,31,32,33,34,39,40]:
n=math.ceil(data[i][9][0][0]/5) #1人で何日かかるか
if data[i][1] in [1,3]: #取付
mode2[i]=Mode("mode2["+i+"]",duration=n)
mode2[i].addBreak(0,0)
mode2[i].addResource(resWH,{(0,n):5})
mode2[i].addParallel(1,n,28)
if data[i][1] in [2,4]: #溶接
mode2[i]=Mode("mode2["+i+"]",duration=n)
mode2[i].addBreak(0,0)
mode2[i].addResource(resWW,{(0,n):5})
mode2[i].addParallel(1,n,43)
if data[i][1] in [31]: #鉄組立
mode2[i]=Mode("mode0["+i+"]",duration=n)
mode2[i].addBreak(0,0)
mode2[i].addResource(resWF1,{(0,n):5})
mode2[i].addParallel(1,n,5)
if data[i][1] in [32,39]: #甲板配管
mode2[i]=Mode("mode0["+i+"]",duration=n)
mode2[i].addBreak(0,0)
mode2[i].addResource(resWF2,{(0,n):5})
mode2[i].addParallel(1,n,7)
if data[i][1] in [33,40]: #機関配管
mode2[i]=Mode("mode0["+i+"]",duration=n)
mode2[i].addBreak(0,0)
mode2[i].addResource(resWF3,{(0,n):5})
mode2[i].addParallel(1,n,10)
if data[i][1]==20: #塗装内
mode2[i]=Mode("mode0["+i+"]",duration=n)
mode2[i].addBreak(0,0)
mode2[i].addResource(resWP, {(0,n):5})
mode2[i].addParallel(1,n,8)
if data[i][1]==34: #塗装外
mode2[i]=Mode("mode0["+i+"]",duration=n)
mode2[i].addBreak(0,0)
mode2[i].addResource(resWP2,{(0,n):5})
mode2[i].addParallel(1,n,8)
act2[i].addModes(mode2[i])
#-----
#10:入荷 #7:社0 #8:検0 #9:W0 #16:運 #17:運0 #18:運2 #19:合体 #21:運ブ #25:運ブ2 #35:AT #0:搭載
elif data[i][1] in [10,7,8,9,16,17,18,19,21,25,35,0]:
mode2[i]=Mode("mode2["+i+"]",duration=data[i][2]) #組立工程運搬作業時数未定のため期間だけ確保
act2[i].addModes(mode2[i])
#-----
#11:開始 #5:社 #6:検 #12:正 #13:反 #14:積み #15:一体 #36:磨き #37:O/P #38:_鉄艤 #16:運
elif data[i][1] in [11,5,6,12,13,14,15,36,37,38,16]:
mode2[i]=Mode("mode2["+i+"]",duration=data[i][2]) #組立工程運搬作業時数未定のため期間だけ確保
act2[i].addModes(mode2[i])
#プログラムII-4.2b
#=======================================================================
#組立工程計画 資源制約(作業場所)
#=======================================================================
for i in idata2:
if data[i][1] in PL_kumitate+PL_gisou:
#-----
if data[i][1] in [22,23,24,70,71,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87]: #PL_gisou.remove(72): #72:D5_AH
if data[i][1] in [22,23,24]: data[i][6]=AB
for no in range(len(data[i][6])):
no1=data[i][6][no][0];
L=R[no1][1]; B=R[no1][2];
L1=data[i][6][no][1]; L2=data[i][6][no][2];
B1=data[i][6][no][3]; B2=data[i][6][no][4];
skipL=math.floor(L/8); skipL=1
skipB=math.floor(B/2);
l=math.floor(data[i][8][0]); b=math.floor(data[i][8][1]);
if data[i][1] in [22,23,24]: l=19; b=16;
for j in range(L1,L2-l+1,skipL):
for k in range(B1,B2-b+1,skipB):
mode2[i]=Mode("mode2["+i+"]_R[{0:03d}][{1:03d}_{2:03d}][{3:03d}_{4:03d}]".format(no1,j,k,l,b))
for s in range(0,l):
for t in range(0,b):
mode2[i].addBreak(0,0)
mode2[i].addResource(resPL[no1,j+s,k+t],1,"break")
act2[i].addModes(mode2[i])
#-----
elif data[i][1] in [51,53,54,55,56,57,58,59,60,61,62,63,64]: #PL_kumitate.remove(65): #65:K4_1AS1
for no in range(len(data[i][6])):
no1=data[i][6][no][0];
L=R[no1][1]; B=R[no1][2];
L1=data[i][6][no][1]; L2=data[i][6][no][2];
B1=data[i][6][no][3]; B2=data[i][6][no][4];
skipL=math.floor(L/8); skipL=1
skipB=math.floor(B/2);
l=math.floor(data[i][8][0]); b=math.floor(data[i][8][1]);
if data[i][1] in [22,23,24]: l=19; b=16;
for j in range(L1,L2-l+1,skipL):
for k in range(B1,B2-b+1,skipB):
mode2[i,no1,j,k]=Mode("mode2["+i+"]_R[{0:03d}][{1:03d}_{2:03d}][{3:03d}_{4:03d}]".format(no1,j,k,l,b))
for s in range(0,l):
for t in range(0,b):
mode2[i].addBreak(0,0)
mode2[i].addResource(resPL[no1,j+s,k+t],1,"break")
act2[i].addModes(mode2[i])
#-----
elif i in {"A01431","A11701","A11711","A11721"}: #場所と期間が固定されている場合
if data[i][6]!=0:
for no in range(len(data[i][6])):
no1=data[i][6][no][0];
L=R[no1][1]; B=R[no1][2];
L1=data[i][6][no][1]; L2=data[i][6][no][2];
B1=data[i][6][no][3]; B2=data[i][6][no][4];
skipL=math.floor(L/4); skipL=2;
skipB=math.floor(B/2); # skipB=1;
l=math.floor(data[i][8][0]); b=math.floor(data[i][8][1]);
for j in range(L1,L2-l+1,skipL):
for k in range(B1,B2-b+1,skipB):
mode2[i]=Mode("mode2["+i+"]_R[{0:03d}][{1:03d}_{2:03d}][{3:03d}_{4:03d}]".format(no1,j,k,l,b),duration=int(data[i][2]))
for s in range(0,l):
for t in range(0,b):
mode2[i].addResource(resPL[no1,j+s,k+t],1)
act2[i].addModes(mode2[i])
プログラムII-5
#プログラムII-5
#=======================================================================
#組立工程計画 問題の規模
#=======================================================================
N=len(usuki2.act)
print("アクティビティ総数(含待機数):",N)
M=[]
for a in usuki2.act: M.append(len(a.modes))
print("モード数:",M)
print("平均モード数:",round(sum(M)/N))
P=math.ceil(math.log10(round(sum(M)/N)**N))
print("問題の規模: 10**",P)
#=======================================================================
#組立工程計画 問題求解
#=======================================================================
#usuki2.Params.Makespan=True
usuki2.Params.Initial=False
usuki2.Params.TimeLimit=3600
usuki2.Params.Neighborhood=20
usuki2.Params.OutputFlag=False
usuki2.optimize()
●プログラムII-6
#プログラムII-6
#=======================================================================
#データセットの更新
#=======================================================================
print("")
for a in usuki2.act:
for i in idata2:
if a.name==data[i][0]:
if len(a.modes)==1: nam=a.selected.name
else: nam=a.selected
#print("_"+a.name,len(a.modes),nam,a.start,a.completion)
data[i][3]=a.start
data[i][2]=a.completion-a.start
if len(nam)>15:
r=int(nam[16:19])
x=int(nam[21:24])
y=int(nam[25:28])
l=int(nam[30:33])
b=int(nam[34:37])
place=[[ r, x, x+l, y, y+b]]
data[i][6]=place
print(data[i][0:8])
#========================================================================
filename="usu_S1777_kumitate_R040510b.csv"
print("writing "+filename)
usuki2.writeExcel(filename)
import dill
dill.dump_session('usukiR040510b.pkl')
#------
#eof