OptSeq |
#rcpsp71.py プッシュ型逐次計画
from optseq import *
import math
#=======================================================================
prob=Model()
CS=["CS","CC","SS","SC"]
#=======================================================================
#リソースの定義(RCPSP計画用)
file_path = 'RCPSP_u.res.txt'
with open(file_path, 'r', encoding='utf-8') as file:
prog=file.read()
exec(prog)
#=======================================================================
#データセットの定義(RCPSP計画用)
# data_BC1, data_BC2, data_BC3, data_BC4, data_BC5, data_BC6, data_BC7
file_path = 'RCPSP6_data_all.txt'
with open(file_path, 'r', encoding='utf-8') as file:
prog=file.read()
exec(prog)
#=======================================================================
data={}
data.update(data_BC1);
data.update(data_BC2);
data.update(data_BC3);
data.update(data_BC4);
data.update(data_BC5);
data.update(data_BC6);
data.update(data_BC7);
#-----
def extact(data):
w=[]
for i in data.keys():
if data[i][1]>=0: w.append(i)
return w
#-----
idata_BC1=extact(data_BC1)
idata_BC2=extact(data_BC2)
idata_BC3=extact(data_BC3)
idata_BC4=extact(data_BC4)
idata_BC5=extact(data_BC5)
idata_BC6=extact(data_BC6)
idata_BC7=extact(data_BC7)
idata=idata_BC1+idata_BC2+idata_BC3+idata_BC4+idata_BC5+idata_BC6+idata_BC7
#print(len(idata))
#=======================================================================
def L1L2B1B2lb(R,data,i,j,no):
no1=data[i][j][no][0]; #j=6,7
L=R[no1][1]; B=R[no1][2];
l=math.floor(data[i][8][0]); b=math.floor(data[i][8][1]);
L1=data[i][j][no][1]; L2=data[i][j][no][2];
if L1<0: l=l-abs(L1); L1=0;
if L2>L: l=l-abs(L2-L); L2=L;
B1=data[i][j][no][3]; B2=data[i][j][no][4];
if B1<0: b=b-abs(B1); B1=0
if B2>B: b=b-abs(B2-B); B2=B;
ll=L2-L1; bb=B2-B1;
if L2-L1>l: ll=l
if B2-B1>b: bb=b
return [no1,L1,L2,B1,B2,ll,bb]
#=======================================================================
#iwhich=5 #プッシュ型逐次計画Step1: 作業の場所取りは面全体(前後船含む)
iwhich=6 #プッシュ型逐次計画Step2: 待機の場所取りは面全体(前後船含む)
if iwhich in [5,6]: #rcpsp7_5.csv
#=======================================================================
data2={}
for i in data:
data2[i]=data[i].copy()
prob3=Model()
#-----------------------------------------------------------------------
#[5.0a]リソースの定義(場所)
#-----------------------------------------------------------------------
res3PL,S=res3(prob3,R)
res2S=res2(prob3,R,S)
#-----------------------------------------------------------------------
#[5.0b]リソースの定義(作業員)
#-----------------------------------------------------------------------
H={
1:["H[1]", 28*10, 1], #取付
2:["H[2]", 43*10, 1], #溶接
3:["H[3]", 12*10, 1], #塗装
4:["H[4]", 5*10, 1], #鉄艤
5:["H[5]", 7*10, 1], #甲配
6:["H[6]", 5*10, 1], #機配
}
res1W=res1(prob3,H)
#-----------------------------------------------------------------------
#[5.0c]作業の定義G2
#-----------------------------------------------------------------------
d1=26; d2=50;
# w1=[]; w2=[]; w3=[]; w4=[]; w5=[];
# for i in data:
# start=data2[i][3]
# stop=data2[i][3]+data2[i][2]
# if stop7 : mode3[i].addParallel(1,n,8)
else: mode3[i].addParallel(1,n,4)
wno1+=1
elif data2[i][1] in [11,13]: #溶接43人
mode3[i].addResource(res1W[2],{(0,n):hours})
if n>11 : mode3[i].addParallel(1,n,12)
#if n>11 : mode3[i].addParallel(1,n,8)
else: mode3[i].addParallel(1,n,8)
wno2+=1
elif data2[i][1] in [15]: #鉄艤装5人
mode3[i].addResource(res1W[4],{(0,n):hours})
if n>2 : mode3[i].addParallel(1,n,5)
else: mode3[i].addParallel(1,n,3)
wno3+=1
elif data2[i][1] in [16]: #甲板配管7人
mode3[i].addResource(res1W[5],{(0,n):hours})
if n>6 : mode3[i].addParallel(1,n,7)
else: mode3[i].addParallel(1,n,4)
wno4+=1
elif data2[i][1] in [17]: #機関配管5人
mode3[i].addResource(res1W[6],{(0,n):hours})
if n>14: mode3[i].addParallel(1,n,5)
else: mode3[i].addParallel(1,n,3)
wno5+=1
elif data2[i][1] in [18]: #塗装12人
mode3[i].addResource(res1W[3], {(0,n):hours})
if n>8 : mode3[i].addParallel(1,n,9)
else: mode3[i].addParallel(1,n,8)
wno6+=1
elif data2[i][1] in [19]: #塗装12人
mode3[i].addResource(res1W[3], {(0,n):hours})
if n>3 : mode3[i].addParallel(1,n,8)
else: mode3[i].addParallel(1,n,4)
wno6+=1
act3[i].addModes(mode3[i])
# 0搭載, 1開始, 2入荷, 3正, 4反, 5出棟, 6入ブ, 7出ブ, 8運搬, 9合体; 14ダミー
elif data2[i][1]!=-1:
if data2[i][1]==14: mode3[i]=Mode("mode["+i+"]",duration=data2[i][2])
else: mode3[i]=Mode("mode["+i+"]",duration=1)
act3[i].addModes(mode3[i])
wno7+=1
#-----------------------------------------------------------------------
#[5.4]資源制約(作業場所)...G2+G3
#-----------------------------------------------------------------------
# 0搭載, 1開始, 2入荷, 3正, 4反, 5出棟, 6入ブ, 7出ブ, 8運搬, 9合体,
ww={}
for i in idata2:
if data2[i][1] in [1,2,3,4,5,6,7,8,9]:
for iw in [1,2,3,4]:
j=data2[i][4][iw] #枝iwの後続作業ID
if j!="0":
#シリアルな後続は飛ばす
while data2[j][8]==0: j=data2[j][4][0]
ww[i,iw]=j
#----- 作業場所
d_act={}
d_mode={}
for i in idata2:
if data2[i][1] in [1,2,3,4,5,6,7,8,9] and data2[i][6]!=0:
d_act[i]=prob3.addActivity("場所_for_"+i)
#print(i)
for no in range(len(data2[i][6])):
w=L1L2B1B2lb(R,data2,i,6,no)
no1,L1,L2,B1,B2,l,b=w[0],w[1],w[2],w[3],w[4],w[5],w[6]
#if i in idata2b: L1=0; L2=R[no1][1]; B1=0; B2=R[no1][2];
skipL=1; skipB=1;
for j in range(L1,L2-l+1,skipL):
for k in range(B1,B2-b+1,skipB):
d_mode[i,no1,j,k]=Mode(\
"mode["+i+"]3_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):
d_mode[i,no1,j,k].addBreak(0,'inf')
d_mode[i,no1,j,k].addResource(res3PL[no1,j+s,k+t],1,"break")
d_mode[i,no1,j,k].addResource(res2S[no1],l*b,"break")
d_act[i].addModes(d_mode[i,no1,j,k])
prob3.addTemporal(act3[i],d_act[i],tempType="SS")
prob3.addTemporal(d_act[i],act3[i],tempType="SS")
for iw in [1,2,3,4]:
ii=ww[i,iw]
if ii!="0" and ii in idata2:
prob3.addTemporal(d_act[i],act3[ii],tempType="CC")
prob3.addTemporal(act3[ii],d_act[i],tempType="CC")
#----- 待機場所
d_act2={}
d_mode2={}
for i in wplace:
if data2[i][1] in [1,2,3,4,5,6,7,8,9]:
data2[i][7]=data2[i][6]
d_act2[i]=prob3.addActivity("空置_after_"+i)
for no in range(len(data2[i][7])):
w=L1L2B1B2lb(R,data2,i,7,no)
no1,L1,L2,B1,B2,l,b=w[0],w[1],w[2],w[3],w[4],w[5],w[6]
#L1=0; L2=R[no1][1]; B1=0; B2=R[no1][2];
skipL=1; skipB=1;
for j in range(L1,L2-l+1,skipL):
for k in range(B1,B2-b+1,skipB):
d_mode2[i,no1,j,k]=Mode(\
"mode["+i+"]4_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):
d_mode2[i,no1,j,k].addBreak(0,'inf')
d_mode2[i,no1,j,k].addResource(res3PL[no1,j+s,k+t],0,"break")
#d_mode2[i,no1,j,k].addResource(res2S[no1],0,"break")
d_act2[i].addModes(d_mode2[i,no1,j,k])
prob3.addTemporal(d_act[i],d_act2[i],tempType="CS")
prob3.addTemporal(d_act2[i],d_act[i],tempType="SC")
ii=data2[ww[i,1]][4][0]
if ii in wplace:
prob3.addTemporal(act3[ii],d_act2[i],tempType="SC")
prob3.addTemporal(d_act2[i],act3[ii],tempType="CS")
#-----------------------------------------------------------------------
#[5.5]問題求解... G2+G3
#-----------------------------------------------------------------------
A=[]
for a in prob3.act: A.append(a.name)
#print("アクティビティ:",A)
N=len(prob3.act)
print("アクティビティ総数(含待機数):",N)
M=[]
for a in prob3.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)
#-----------------------------------------------------------------------
#prob3.Params.Makespan=True
#prob3.Params.Initial=False
#prob3.Params.OutputFlag=False
#prob3.Params.Neighborhood=20
#prob3.Params.RandomSeed=1
prob3.Params.TimeLimit=300
prob3.optimize()
filename="rcpsp71.csv"
#print("writing "+filename)
prob3.writeExcel(filename)
print("アクティビティ総数(含待機数):",N)
print("平均モード数:",round(sum(M)/N))
print("問題の規模: 10**",P)
#sys.exit()
#-----------------------------------------------------------------------
#[5.6]計画上の調整期間における場所取り
#-----------------------------------------------------------------------
print(" ")
print("計画上の調整期間における場所取り in G2+G3")
jdata=[]; ldata=[]; mdata=[]; ndata=[]
data3={}
for i in data2:
data3[i]=data2[i].copy()
for a in prob3.act:
if len(a.modes)==1: mode_nam=a.selected.name
else: mode_nam=a.selected
#print("__"+a.name,len(a.modes),mode_nam,a.start,a.completion)
if "場所_for_" in a.name:
i=a.name[7:] #運搬作業(期間1)
j=i[0:11]+"1"
ldata.append(j)
data3[j][3]=a.start
data3[j][2]=a.completion-a.start
r=int(mode_nam[16+6:19+6])
x=int(mode_nam[21+6:24+6])
y=int(mode_nam[25+6:28+6])
l=int(mode_nam[30+6:33+6])
b=int(mode_nam[34+6:37+6])
data3[j][6]=[[r,x,x+l,y,y+b]]
data3[j][8]=[l,b,0]
elif "空置_after_" in a.name:
i=a.name[9:]
#j=i[0:11]+"W"
mdata.append(i)
if a.completion-a.start>0:
data3[i][3]=a.start
data3[i][2]=a.completion-a.start
jdata.append(i)
#print(len(jdata),i,r,l,b)
if r in [1,2]: data3[i][7]=[R01,R02,R03,P03]
#elif r in [5,6]: data3[i][7]=[R05,P07]
else: data3[i][7]=Q001+Q002+R00
elif "S01_" in a.name:
i=a.name[0:12]
ndata.append(i)
#if i[10:12]=="00": #運搬作業(期間1)
data3[i][3]=a.start
data3[i][2]=a.completion-a.start #不要
#data3[i][3]=a.start
#data3[i][2]=a.completion-a.start
print(len(ldata),len(mdata),len(ndata),len(jdata))
#sys.exit()
|