OptSeq |
#rcpsp51.py
from optseq import *
import math
prob=Model()
CS=["CS","CC","SS","SC"]
#=======================================================================
#リソースの定義(場所)
#=======================================================================
#場所の名前と矩形サイズ [name,L=L2-L1+1,B=B2-B1+1]
R={
1:["P01", 58, 13],\
2:["P02", 58, 13],\
3:["P03", 42, 16],\
5:["P05", 52, 12],\
6:["P06", 52, 13],\
}
#-----各場所の長さ方向線分[L1,L2]・幅方向線分[B1,B2]
P01=[ 1,0, R[1][1],0, R[1][2]]
P02=[ 2,0, R[2][1],0, R[2][2]]
P03=[ 3,0, R[3][1],0, R[3][2]]
P05=[ 5,0, R[5][1],0, R[5][2]]
P06=[ 6,0, R[6][1],0, R[6][2]]
#-----メッシュの使用可否
resPL={}
S={}
for id in R:
resPL[id]=0
S[id]=0
#if not id in [2,3,4,5,6,11,13,14,15,16,17,18,19,20]:
#if not id in [2,3,4,5,6,7,13]:
if not id in [2,3,5,6]:
for i in range(0,R[id][1]):
for j in range(0,R[id][2]):
resPL[id,i,j] =prob.addResource(R[id][0]+"[{0:02d}_{1:02d}]".format(i,j), capacity={(0,"inf"):1})
S[id]+=1
if id==2:
for i in range(0,R[id][1]):
for j in range(0,R[id][2]):
if i in range(0,15) and j in range(0,13):
resPL[id,i,j] =prob.addResource(R[id][0]+"[{0:02d}_{1:02d}]".format(i,j), capacity={(0,"inf"):0})
else:
resPL[id,i,j] =prob.addResource(R[id][0]+"[{0:02d}_{1:02d}]".format(i,j), capacity={(0,"inf"):1})
S[id]+=1
if id==3:
for i in range(0,R[id][1]):
for j in range(0,R[id][2]):
if i in range(0,28) and j in range(0,2):
resPL[id,i,j] =prob.addResource(R[id][0]+"[{0:02d}_{1:02d}]".format(i,j), capacity={(0,"inf"):0})
elif i in range(0,4) and j in range(2,15):
resPL[id,i,j] =prob.addResource(R[id][0]+"[{0:02d}_{1:02d}]".format(i,j), capacity={(0,"inf"):1})
elif i in range(0,46) and j in range(15,16):
resPL[id,i,j] =prob.addResource(R[id][0]+"[{0:02d}_{1:02d}]".format(i,j), capacity={(0,"inf"):1})
else:
resPL[id,i,j] =prob.addResource(R[id][0]+"[{0:02d}_{1:02d}]".format(i,j), capacity={(0,"inf"):1})
S[id]+=1
if id==5:
for i in range(0,R[id][1]):
for j in range(0,R[id][2]):
if i in range(0,13) and j in range(0,12):
resPL[id,i,j] =prob.addResource(R[id][0]+"[{0:02d}_{1:02d}]".format(i,j), capacity={(0,"inf"):0})
else:
resPL[id,i,j] =prob.addResource(R[id][0]+"[{0:02d}_{1:02d}]".format(i,j), capacity={(0,"inf"):1})
S[id]+=1
if id==6:
for i in range(0,R[id][1]):
for j in range(0,R[id][2]):
if i in range(0,3) and j in range(0,13):
resPL[id,i,j] =prob.addResource(R[id][0]+"[{0:02d}_{1:02d}]".format(i,j), capacity={(0,"inf"):0})
else:
resPL[id,i,j] =prob.addResource(R[id][0]+"[{0:02d}_{1:02d}]".format(i,j), capacity={(0,"inf"):1})
S[id]+=1
#=======================================================================
#データセット
#=======================================================================
data_P12={
#id:["activity",[1:定盤],2:期間,3:開始,[4:L,4:B]],
1:["S01_B041S_FWFW",[P01,P02],11,45,[14,13]],
2:["S01_B041P_FWFW",[P01,P02],10,47,[11,12]],
3:["S01_B051S_FWFW",[P01,P02],11,48,[14,13]],
4:["S01_B051P_FWFW",[P01,P02],10,50,[11,13]],
5:["S01_B061S_FWFW",[P01,P02],11,51,[14,13]],
6:["S01_B061P_FWFW",[P01,P02],10,53,[11,13]],
7:["S01_B071S_FWFW",[P01,P02],11,56,[11,13]],
8:["S01_B071P_FWFW",[P01,P02],10,58,[10,11]],
9:["S01_B091S_FWFW",[P01,P02],11,59,[14,13]],
10:["S01_B091P_FWFW",[P01,P02],10,61,[11,13]],
11:["S01_B101S_FWFW",[P01,P02],11,62,[14,12]],
12:["S01_B101P_FWFW",[P01,P02],10,65,[14,9]],
13:["S01_B123C_FWFW",[[1,42,57,0,12]],13,58,[15,12]],
14:["S01_B184C_FW",[P01,P02],8,73,[17,9]],
15:["S01_B184H_FW",[P01,P02],6,68,[11,12]],
16:["S01_B392P_FWFW",[[1,46,58,0,13]],10,71,[12,13]],
17:["S01_B392S_FWFW",[[1,34,46,0,13]],10,73,[12,13]],
18:["S01_B432S_FWFW",[[2,45,55,0,13]],10,75,[10,13]],
19:["S01_B432P_FWFW",[[2,33,43,0,13]],10,77,[10,13]],
20:["S01_B444S_FW",[P01,P02],9,88,[10,12]],
21:["S01_B462P_FCW",[P01,P02],10,79,[9,13]],
22:["S01_B462S_FCW",[P01,P02],10,81,[9,13]],
23:["S01_B472P_FWFW",[P01,P02],10,82,[14,13]],
24:["S01_B472S_FWFW",[P01,P02],10,84,[14,13]],
25:["S01_B502P_FWFW",[P01,P02],9,85,[14,13]],
26:["S01_B502S_FWFW",[P01,P02],9,88,[14,13]],
27:["S01_B534S_FW",[P01,P02],8,92,[12,13]],
28:["S01_B544P_FW",[P01,P02],8,95,[12,13]],
29:["S01_B563H_FW",[P01,P02],3,75,[8,9]],
}
data_P03={
#id:["activity",[1:定盤],2:期間,3:開始,[4:L,4:B]],
30:["S01_B114C_FWFW",[P03],14,60,[12,13]],
31:["S01_B114H_FW",[P03],5,57,[14,6]],
32:["S01_B223D_FW",[P03],9,65,[9,13]],
33:["S01_B223C_FW",[P03],9,65,[14,9]],
34:["S01_B223C_W",[P03],3,75,[14,9]],
35:["S01_B384C_FWFW",[P03],16,75,[17,10]],
36:["S01_B563C_FW",[P03],6,77,[7,10]],
37:["S01_B573C_F",[P03],3,92,[15,11]],
38:["S01_B573C_FW",[P03],8,96,[15,11]],
}
data_P05={
#id:["activity",[1:定盤],2:期間,3:開始,[4:L,4:B]],
39:["S01_B153H_FW",[P05],5,60,[10,12]],
40:["S01_B223H_FW",[P05],4,62,[11,12]],
41:["S01_B293D_FW",[P05],8,68,[15,10]],
42:["S01_B293C_FW",[P05],6,70,[7,8]],
43:["S01_B293C_W",[P05],2,77,[7,8]],
44:["S01_B422P_FFW",[P05],9,75,[5,12]],
45:["S01_B422S_FFW",[P05],9,77,[5,12]],
46:["S01_B454P_FW",[P05],9,90,[10,12]],
47:["S01_B594C_FW",[P05],9,98,[21,7]],
48:["S01_B594H_FW",[P05],4,95,[8,8]],
49:["S01_B707D_FW",[P05],9,86,[24,12]],
}
data_P06={
#id:["activity",[1:定盤],2:期間,3:開始,[4:L,4:B]],
50:["S01_B165C_FWF",[P06],7,64,[13,12]],
51:["S01_B175C_FWF",[P06],7,66,[13,11]],
52:["S01_B195C_FWF",[P06],7,68,[13,13]],
53:["S01_B235C_FWF",[P06],7,71,[13,13]],
54:["S01_B245C_FWF",[P06],7,73,[13,13]],
55:["S01_B265C_FWF",[P06],7,75,[13,12]],
56:["S01_B275C_FWF",[P06],7,78,[13,11]],
57:["S01_B345C_FWF",[P06],7,80,[13,9]],
58:["S01_B375C_FWF",[P06],7,82,[14,12]],
59:["S01_B496P_FW",[P06],5,90,[20,11]],
60:["S01_B496S_FW",[P06],5,92,[20,11]],
61:["S01_B586P_FW",[P06],5,96,[20,12]],
62:["S01_B586S_FW",[P06],5,98,[20,12]],
63:["S01_B626P_FW",[P06],5,102,[20,12]],
64:["S01_B626S_FW",[P06],5,104,[20,12]],
65:["S01_B636P_FW",[P06],5,108,[20,12]],
66:["S01_B636S_FW",[P06],5,110,[20,12]],
67:["S01_B646P_FW",[P06],5,113,[20,12]],
68:["S01_B646S_FW",[P06],5,115,[20,12]],
}
data={}
data.update(data_P12)
data.update(data_P03)
data.update(data_P05)
data.update(data_P06)
# idata=data_P12.keys()
# idata=data_P03.keys()
# idata=data_P05.keys()
# idata=data_P06.keys()
#-----
idata_P12=data_P12.keys()
idata_P03=data_P03.keys()
idata_P05=data_P05.keys()
idata_P06=data_P06.keys()
idata=idata_P12|idata_P03|idata_P05|idata_P06
#=======================================================================
#作業の定義
#=======================================================================
act={}
for i in idata:
act[i]=prob.addActivity(data[i][0])
#=======================================================================
#先行制約
#=======================================================================
#-----日程固定
for i in idata:
prob.addTemporal("source",act[i],tempType="SS",delay= data[i][3])
prob.addTemporal(act[i],"source",tempType="SS",delay=-data[i][3])
# sys.exit()
#=======================================================================
#資源制約(作業場所)
#=======================================================================
mode={}
for i in idata:
for no in range(len(data[i][1])):
no1=data[i][1][no][0];
L=R[no1][1]; B=R[no1][2];
L1=data[i][1][no][1]; L2=data[i][1][no][2];
B1=data[i][1][no][3]; B2=data[i][1][no][4];
l=math.floor(data[i][4][0]); b=math.floor(data[i][4][1]);
skipL=1; skipB=1;
for j in range(L1,L2-l+1,skipL):
for k in range(B1,B2-b+1,skipB):
mode[i,no1,j,k]=Mode(\
"mode[{0:02d}]_[{1:03d}][{2:03d}_{3:03d}][{4:03d}_{5:03d}]"\
.format(i,no1,j,k,l,b),duration=data[i][2])
for s in range(0,l):
for t in range(0,b):
mode[i,no1,j,k].addResource(resPL[no1,j+s,k+t],1)
act[i].addModes(mode[i,no1,j,k])
#=====モード制約
con={}
for i in idata:
if i in [33,37,42]:
no1=data[i][1][no][0];
L=R[no1][1]; B=R[no1][2];
L1=data[i][1][no][1]; L2=data[i][1][no][2];
B1=data[i][1][no][3]; B2=data[i][1][no][4];
l=math.floor(data[i][4][0]); b=math.floor(data[i][4][1]);
skipL=1; skipB=1;
for j in range(L1,L2-l+1,skipL):
for k in range(B1,B2-b+1,skipB):
con[i,no1,j,k]=prob.addResource("constraint["+str(i)+"]_\
[{0:03d}][{1:03d}_{2:03d}][{3:03d}_{4:03d}]"\
.format(no1,j,k,l,b),rhs=0,direction="=")
con[i,no1,j,k].addTerms(1,act[i],mode[i,no1,j,k])
con[i,no1,j,k].addTerms(-1,act[i+1],mode[i+1,no1,j,k])
#=======================================================================
#組立工程計画 問題の規模
#=======================================================================
A=[]
for a in prob.act: A.append(a.name)
#print("アクティビティ:",A)
N=len(prob.act)
print("アクティビティ総数(含待機数):",N)
M=[]
for a in prob.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)
#=======================================================================
#組立工程計画 問題求解
#=======================================================================
# prob.Params.Makespan=True
# prob.Params.Initial=False
prob.Params.TimeLimit=30
# prob.Params.Neighborhood=20
# prob.Params.RandomSeed=1
# prob.Params.OutputFlag=False
prob.optimize()
filename="rcpsp51.csv"
prob.writeExcel(filename)
#=======================================================================
sys.exit()
#eof
|