求解プログラム

rcpsp51a.py


001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071

#rcpsp51a.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    

072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
111
112
113
114
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
        
#=======================================================================
#データセット 
#=======================================================================
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)

161
162
163
164

idata=data_P12.keys()
# idata=data_P03.keys()
# idata=data_P05.keys()
# idata=data_P06.keys() 

165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
211
212
213
214
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245

#=======================================================================
#作業の定義
#=======================================================================
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

rcpsp51b.py




161
162
163
164

#rcpsp51b.py
 :
# idata=data_P12.keys()
idata=data_P03.keys()
# idata=data_P05.keys()
# idata=data_P06.keys() 
 :

rcpsp51c.py




161
162
163
164

#rcpsp51c.py
 :
# idata=data_P12.keys()
# idata=data_P03.keys()
idata=data_P05.keys()
# idata=data_P06.keys() 
 :

rcpsp51d.py




161
162
163
164

#rcpsp51d.py
 :
# idata=data_P12.keys()
# idata=data_P03.keys()
# idata=data_P05.keys()
idata=data_P06.keys() 
 :

rcpsp51.py




161
162
163
164

#rcpsp51.py
 :
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
 :

準備

作業場所

P01:58Lx13B Q01:40Lx18B R01:4Lx14B
P02:58Lx13B Q02:50Lx18B R02:11Lx14B
P03:42Lx16B Q03:70Lx22B R03:4Lx14B
P04:26Lx43B Q04:40Lx14B R04:51Lx13B
P05:52Lx12B Q05:35Lx17B R05:26Lx18B
P06:52Lx13B Q06:40Lx15B R06:5Lx10B
P07:61Lx29B Q07:30Lx12B R07:6Lx29B
Q08:32Lx12B
B01:16Lx19B Q09:35Lx15B DOC:136Lx24B
B02:16Lx19B Q10:30Lx12B
B03:16Lx19B Q11:30Lx12B

ブロックリスト

B014C*:4Lx8B B184H : 11Lx12B B384C : 17Lx10B B552P*: 14Lx13B
B021S*:14Lx13B B195C : 13Lx13B B392P : 12Lx14B B552S*: 14Lx13B
B021P*:11Lx13B B208P : 7Lx13B B392S : 12Lx14B B563C : 7Lx10B
B031S*:14Lx13B B208S : 7Lx13B B408P : 7Lx13B B563H : 8Lx9B
B031P*:11Lx13B B218P : 7Lx13B B408S : 7Lx13B B573C : 15Lx11B
B041S :14Lx13B B218S : 7Lx13B B414P*: 12Lx12B B573H : 10Lx10B
B041P :11Lx12B B223C : 11Lx12B B414S*: 12Lx12B B586P : 20Lx12B
B051S :14Lx13B B223H : 11Lx12B B422P : 5Lx13B B586S : 20Lx12B
B051P :11Lx13B B223D : 9Lx13B B422S : 5Lx13B B594C : 21Lx7B
B061S :14Lx13B B235C : 13Lx13B B432S : 10Lx13B B594H : 19Lx4B
B061P :11Lx13B B245C : 13Lx13B B432P : 10Lx13B B602P*: 14Lx13B
B071S :13Lx11B B258P : 7Lx13B B444S : 10Lx12B B602S*: 14Lx13B
B071P :10Lx11B B258S : 7Lx13B B444H : 5Lx11B B613C*: 21Lx13B
B084P*:8Lx11B B265C : 13Lx11B B454P : 10Lx12B B626P : 20Lx12B
B084S*:8Lx8B B275C : 13Lx11B B454H : 5Lx11B B626S : 20Lx12B
B084C :19Lx9B B288P : 7Lx13B B462P : 13Lx9B B636P : 20Lx12B
B091S :14Lx13B B288S : 7Lx13B B462S : 13Lx9B B636S : 20Lx12B
B091P :11Lx13B B293C : 8Lx7B B472P : 14Lx13B B646P : 20Lx12B
B101S :14Lx12B B293D : 15Lx10B B472S : 14Lx13B B646S : 20Lx12B
B101P :14Lx9B B308P : 7Lx13B B484C*: 21Lx10B B657C*: 6Lx6B
B114C :13Lx13B B308S : 7Lx13B B496P : 20Lx11B B667C*: 6Lx10B
B114H :29Lx3B B318P : 7Lx13B B496S : 20Lx11B B677P*: 18Lx12B
B123C :15Lx12B B318S : 7Lx13B B502P : 14Lx13B B677S*: 18Lx12B
B134P*:12Lx11B B324P : 11Lx12B B502S : 14Lx13B B687C*: 3Lx7B
B134S*:11Lx12B B324S : 11Lx12B B514P*: 12Lx13B B697C*: 16Lx9B
B143C*:14Lx8B B333C*: 17Lx10B B514S*: 12Lx13B B707C*: 24Lx12B
B153C :7Lx10B B345C : 13Lx9B B522P*: 14Lx13B B707D : 24Lx14B
B153H :10Lx12B B358P : 7Lx13B B522S*: 14Lx13B B707E*: 15Lx9B
B153D :8Lx10B B358S : 7Lx13B B534S : 12Lx13B B717P*: 3Lx6B
B165C :13Lx12B B364P*: 10Lx11B B534H : 4Lx13B B717S*: 5Lx7B
B175C :13Lx11B B364S*: 10Lx11B B544P : 12Lx13B B727P*: 3Lx7B
B184C :17Lx9B B375C : 14Lx12B B544H : 4Lx13B B727S*: 3Lx7B

補遺4


001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051

Sub Waritsuke()
  Worksheets("waritsuke").Activate
  ActiveSheet.DrawingObjects.Delete
  Dim Sheet1 As Variant
  Sheet1 = "rcpsp42"
  Dim time1 As Integer, time2 As Integer, sp As Integer
  time1 = 2: time2 = 10: sp = 7:
  Dim act As Variant, mode As Variant, ID As Integer, no As Integer
  Dim joban As Integer, sx As Integer, sy As Integer, tx As Integer
  Dim ty As Integer, start As Integer, completion As Integer
  Dim S As Range, Q As Shape
  For i = 2 To 14
    act = Worksheets(Sheet1).Cells(i, 1) 'MsgBox (act)
    act = Mid(act, 8, 3)
    mode = Worksheets(Sheet1).Cells(i, 2)
    ID = Len(mode)
    If ID = 21 Then
      sx = Val(Mid(mode, 9, 2))
      sy = Val(Mid(mode, 12, 2))
      tx = Val(Mid(mode, 16, 2))
      ty = Val(Mid(mode, 19, 2))
      start = Worksheets(Sheet1).Cells(i, 3) + 1
      completion = Worksheets(Sheet1).Cells(i, 5)
      For j = start - time1 To completion - time1
        Set S = Range(Cells(3 + sp * j + sx, 4 + 1 + sy), _
        Cells(2 + sp * j + sx + tx, 3 + 1 + sy + ty))
        Set Q = ActiveSheet.Shapes.AddShape(1, S.Left, S.Top, _
        S.Width, S.Height)
        Q.Select
        ic = i Mod 6
        Selection.Font.ColorIndex = 1
        If ic = 0 Then
          Q.Fill.ForeColor.RGB = RGB(255, 0, 0)  '赤
        ElseIf ic = 1 Then
          Q.Fill.ForeColor.RGB = RGB(0, 255, 0)  '緑
        ElseIf ic = 2 Then
          Q.Fill.ForeColor.RGB = RGB(0, 0, 255)  '青
          Selection.Font.ColorIndex = 2
        ElseIf ic = 3 Then
          Q.Fill.ForeColor.RGB = RGB(255, 255, 0) '黄
        ElseIf ic = 4 Then
          Q.Fill.ForeColor.RGB = RGB(0, 255, 255) 'シアン
        ElseIf ic = 5 Then
          Q.Fill.ForeColor.RGB = RGB(255, 0, 255) 'マジェンダ
        End If
        Selection.Text = act
        Selection.Font.Size = 7
      Next j
    End If
  Next i
End Sub

逐次計画の基礎

rcpsp43a.py


001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031

032
033
034
035
036
037
038
039
040

#rcpsp43a.py
from optseq import *
import math
#====データセット
#Key:["",期間,[後続]、員数,開始,完了],\
data={
"A01":["A01_3人",3,["A04","A06"],3,0,0],
"A02":["A02_1人",4,["A05","A07"],1,0,0],
"A03":["A03_1人",6,["A08","0"],1,0,0],
"A04":["A04_4人",4,["A05","A07"],4,0,0],
"A05":["A05_4人",5,["A08","0"],4,0,0],
"A06":["A06_4人",5,["A09","0"],4,0,0],
"A07":["A07_5人",4,["A10","0"],5,0,0],
"A08":["A08_2人",2,["A10","0"],2,0,0],
"A09":["A09_5人",2,["A10","0"],5,0,0],
"A10":["A10_3人",4,["0","0"],3,0,0],\
}
#====アクティビティ
prob=Model()
act={}
for i in data:
    act[i]=prob.addActivity(data[i][0])
#====先行制約
for i in data:
    for j in data[i][2]:
        if j!="0": prob.addTemporal(act[i],act[j])  
#====資源制約  
res=prob.addResource("Resource",capacity={(0,"inf"):10}) 
mode={}  
for i in data:
    mode[i]=Mode("M["+i+"][{0:02d}]".format(data[i][3]),
                                    duration=data[i][1])
    mode[i].addResource(res,requirement=data[i][3])
    act[i].addModes(mode[i])
#====求解
prob.Params.Makespan=True
prob.Params.TimeLimit=1
prob.Params.OutputFlag=True
prob.optimize()
prob.write("rcpsp43a.txt")
prob.writeExcel("rcpsp43a.csv")  

041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061

#=======================================================================
print("") 
for a in prob.act:
  mode_nam=a.selected.name
  i=a.name[0:3]
  data[i][4]=a.start
  data[i][5]=a.completion  
#-----
w1=[]; w2=[]; w3=[]; w4=[]; w5=[];
d1=5; d2=20; 
for i in data:
  start=data[i][4]
  stop=data[i][5]
  if stop < d1: w1.append(i)                  # 完了
  if start+1 <= d1 and d1 <= stop: w2.append(i) #仕掛
  if d1 < start+1  and stop < d2:  w3.append(i) #自由
  if start+1 <= d2 and d2 < stop: w4.append(i) #次のリスケにおける仕掛
  if d2 < start+1: w5.append(i)               #未着手
idata2a=w2;   #仕掛かり中のアクティビティ
idata2b=w3;   #仕掛かっていないアクティビティ 
idata2=w2+w3; #リスケすべきアクティビティ日

062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091

#====アクティビティ
prob2=Model()
act2={}
for i in idata2b:
    act2[i]=prob2.addActivity(data[i][0])
#====先行制約
for i in idata2b:
    for j in data[i][2]:
        if j!="0": prob2.addTemporal(act2[i],act2[j])
#----リスケ日以降
    prob2.addTemporal("source",act[i],tempType="SS",delay=d1) 
#====資源制約  
w={(0,3):5,(3,4):0,(4,6):1,(6,7):2,(7,8):6,(8,30):10} #Case1
#w={(0,3):5,(3,4):0,(4,6):1,(6,7):2,(7,8):6,(8,30):8}  #Case2
res2=prob2.addResource("Resource2",capacity=w) 
mode2={}  
for i in idata2b:
    mode2[i]=Mode("M["+i+"][{0:02d}]".format(data[i][3]),
                                    duration=data[i][1])
    mode2[i].addResource(res2,requirement=data[i][3])
    act2[i].addModes(mode2[i])
#====求解
prob2.Params.Makespan=True
prob2.Params.TimeLimit=1
prob2.Params.OutputFlag=True
prob2.optimize()
prob2.write("rcpsp43b.txt")
prob2.writeExcel("rcpsp43b.csv")  
#=======================================================================
#eof

rcpsp43b.py





074
075
 
#rcpsp43b.py
 :
#====資源制約  
#w={(0,3):5,(3,4):0,(4,6):1,(6,7):2,(7,8):6,(8,30):10} #Case1
w={(0,3):5,(3,4):0,(4,6):1,(6,7):2,(7,8):6,(8,30):8}  #Case2
 :

同時計画の基礎

rcpsp42.py


001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033

#rcpsp42.py
from optseq import *
import math
#====データセット
#i:[期間,納期,[l,b]]
data={
#key:["名前",ID,[後続],[B,L],時数]
"A11":["A11_BLK1_開始" ,1, ["A12"],[1,2],0],
"A12":["A12_BLK1_作業1",11,["A13"],[1,2],10],
"A13":["A13_BLK1_作業2",12,["A31"],[1,2],20],
"A21":["A21_BLK2_開始" ,1, ["A22"],[2,1],0],
"A22":["A22_BLK2_作業1",11,["A23"],[2,1],20],
"A23":["A23_BLK2_作業2",12,["A31"],[2,1],30],
"A31":["A31_BLK3_合体" ,2, ["A32","A33"],[2,2],0],
"A32":["A32_BLK3_作業3",13,["A41"],[2,2],5],
"A33":["A33_BLK3_作業4",14,["A41"],[2,2],5],
"A41":["A41_BLK3_納品" ,0, ["0"  ],[2,2],0],
}    
#=====アクティビティ
prob=Model()
act={}
for i in data:
   #act[i]=prob.addActivity(data[i][0])
    act[i]=prob.addActivity(name=data[i][0],duedate=10,backward=True)    
#====先行制約
for i in data:
    for j in data[i][2]:
        if j!="0": prob.addTemporal(act[i],act[j])      
#----納期日の固定
for i in data:
    if data[i][2][0]=="0":
        prob.addTemporal("source",act[i],tempType="CC",delay= 10)   
        prob.addTemporal(act[i],"source",tempType="CC",delay=-10)  

034
035
003
036
037
038
039
040
041
042
043
044
045
    
#====資源制約         
res1=prob.addResource("worker",capacity={(0,"inf"):5}) 
mode={}  
for i in data:
    if data[i][1] in [11,12,13,14]:
        period=math.ceil(data[i][4]/8) #1人で何日かかるか
        mode[i]=Mode("M["+i+"]_[{0:02d}]".format(period),duration=period)
        mode[i].addResource(res1,requirement=1)
        mode[i].addParallel(start=1,finish=period,maxparallel=2)
        act[i].addModes(mode[i])
    else:
        mode[i]=Mode("M["+i+"]",duration=1)
        act[i].addModes(mode[i])   

014
015
016
017
018
019


020
021


022
023
024
025
026
027
028
029
030
031
032
033


034
035
036
037
038
039
040
041
042
043
  
#----場所取り
res={}
for i in range(0,4):
    for j in range(0,4):  
        if i==1 and j==2 :
            res[i,j]=prob.addResource(\
                "place[{0:02d}_{1:02d}]".format(i,j),\
                capacity={(0,"inf"):0})            
        else:     
            res[i,j]=prob.addResource(\
                "place[{0:02d}_{1:02d}]".format(i,j),\
                capacity={(0,"inf"):1})   
#----
d_act={}
d_mode={}
ww={'A11':'A13', 'A21':'A23', 'A31':'A33'} 
L=5; B=5; L1=0; L2=4; B1=0; B2=4; skipL=1; skipB=1; 
for i in data:  
    if data[i][1] in [1,2]:
        d_act[i]=prob.addActivity("場所_for_"+i)  
        l=data[i][3][0]; b=data[i][3][1];    
        for j in range(L1,L2-l+1,skipL): 
            for k in range(B1,B2-b+1,skipB):
                d_mode[i,j,k]=Mode(\
                    "M["+i+"]_[{0:02d}_{1:02d}][{2:02d}_{3:02d}]"\
                    .format(j,k,l,b))
                d_mode[i,j,k].addBreak(0,'inf')
                for s in range(0,l):
                    for t in range(0,b):
                        d_mode[i,j,k].addResource(res[j+s,k+t],1,"break")
                d_act[i].addModes(d_mode[i,j,k])
        prob.addTemporal(act[i],d_act[i],tempType="SS")
        prob.addTemporal(d_act[i],act[i],tempType="SS")
        ii=ww[i]              
        prob.addTemporal(d_act[i],act[ii],tempType="CC")
        prob.addTemporal(act[ii],d_act[i],tempType="CC")

044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
062

#====問題の規模:      
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.TimeLimit=1
prob.Params.OutputFlag=True
prob.optimize()
prob.write("rcpsp42.txt")
prob.writeExcel("rcpsp42.csv")
sys.exit()   

【rcpsp42.csv】

定盤計画の基礎

rcpsp41.py


001
002
003
004
005
006
007
008
009
010
011
012
013
014
015

#rcpsp41.py
from optseq import *
import math
#====データセット
#i:[名前,期間,[l,b]]
data={
1:["BLK1",1,[2,2]],
2:["BLK2",1,[1,2]],
3:["BLK3",1,[2,1]]
}    
#=====アクティビティ
prob=Model()
act={}
for i in data.keys():
    act[i]=prob.addActivity(data[i][0])

016
017
018
019
020
021


022
023

#====資源制約  
res={}
for i in range(0,4):
    for j in range(0,4):  
        if i==1 and j==2 :
            res[i,j]=prob.addResource(\
                "place[{0:02d}_{1:02d}]".format(i,j),\
                capacity={(0,"inf"):0})            
        else:     
            res[i,j]=prob.addResource(\
                "place[{0:02d}_{1:02d}]".format(i,j),\
                capacity={(0,"inf"):1})  

024
025
026
027
028
029
030
031


032
033
034
035

#-----
mode={}  
L=5; B=5; L1=0; L2=4; B1=0; B2=4;
for i in data:
    l=data[i][2][0]; b=data[i][2][1];
    for j in range(L1,L2-l+1):
        for k in range(B1,B2-b+1):         
             mode[i,j,k]=Mode(\
                 "mode[{0:02d}]_[{1:02d}_{2:02d}][{3:02d}_{4:02d}]"\
                 .format(i,j,k,l,b),duration=data[i][1])
             for s in range(0,l):
                 for t in range(0,b):
                     mode[i,j,k].addResource(res[j+s,k+t],1)         
             act[i].addModes(mode[i,j,k])    

036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054

#====問題の規模:      
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.TimeLimit=1
prob.Params.OutputFlag=True
prob.optimize()
prob.write("rcpsp41.txt")
prob.writeExcel("rcpsp41.csv")

【rcpsp41.csv】

補遺3


001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102

    def writeExcel(self, filename="optseq_chart.csv", scale=1):
        """
        Output the gantt's chart as a csv file for printing using Excel.

            - Argument:
                - filename: Output file name. Default="optseq_chart.csv."

            - Example usage:

            >>> model.writeExcel("sample.csv")

        """
        f = open(filename, "w")
        horizon = 0
        actList = []
        for a in self.activities:
            actList.append(a)
            act = self.activities[a]
            horizon = max(act.completion, horizon)
        # print("planning horizon=",horizon)
        if scale <= 0:
            print("optseq write scale error")
            exit(0)
        original_horizon = horizon
        horizon = int(horizon/scale)+1
        actList.sort()
        title = " activity ,   mode,".center(20)+" duration,"
        width = len(str(horizon))  # period width =largest index of time
        for t in range(horizon):
            num = str(t+1)
            title += num.rjust(width)+","
        f.write(title+"\n")
        for a in actList:  # sorted order
            act = self.activities[a]  # act: activity object
            actstring = act.name.center(10)[:10]+","
            if len(act.modes) >= 2:
                actstring += str(act.selected.name).center(10)+","
                actstring += str(self.modes[act.selected.name].duration).center(10)+","
            else:
                actstring += str(act.modes[0].name).center(10)[:10]+","
                actstring += str(act.modes[0].duration).center(10)+","
            execute = [0 for t in range(horizon)]
            for (s, c) in act.execute:
                para = act.execute[s, c]
                for t in range(s, c):
                    t2 = int(t/scale)
                    execute[t2] = int(para)
            for t in range(horizon):
                if execute[t] >= 2:
                    actstring += "*"+str(execute[t]).rjust(width-1)+","
                elif execute[t] == 1:
                    actstring += ""+"="*(width)+","
                elif t >= int(act.start/scale) and t < int(act.completion/scale):
                    actstring += ""+"."*(width)+","
                else:
                    actstring += ""+" "*width+","
            f.write(actstring+"\n")
        resList = []
        for r in self.resources:
            resList.append(r)
        resList.sort()

        for r in resList:
            res = self.resources[r]
            if len(res.terms) == 0:  # output residual and capacity
                rstring = res.name.center(30)+", , ,"
                cap = [0 for t in range(horizon)]
                residual = [0 for t in range(horizon)]
                for (s, c) in res.residual:
                    amount = res.residual[(s, c)]
                    if c == "inf":
                        c = horizon
                    s = min(s, original_horizon)
                    c = min(c, original_horizon)
                    s2 = int(s/scale)
                    c2 = int(c/scale)
                    for t in range(s2, c2):
                        residual[t] += amount

                for (s, c) in res.capacity:
                    amount = res.capacity[(s, c)]
                    if c == "inf":
                        c = horizon
                    s = min(s, original_horizon)
                    c = min(c, original_horizon)
                    s2 = int(s/scale)
                    c2 = int(c/scale)
                    for t in range(s2, c2):
                        cap[t] += amount

                for t in range(horizon):
                    # num=str(cap[t]-residual[t])
                    rstring += str(residual[t]) + ","
                f.write(rstring+"\n")

                # rstring= str(" ").center(30)+", , ,"
                #
                # for t in range(horizon):
                #    num=str(cap[t])
                #    rstring+=""+num.rjust(width) +","
                # f.write(rstring+"\n")
        f.close()


027

#       title = " activity ,   mode,".center(20)+" duration,"
        title=" activity,"+" mode,"+" start,"+" duration,"+" completion,"        








035
036
037
038
038a
038b
039
040
041
041a
041b

#           actstring = act.name.center(10)[:10]+","
#           if len(act.modes) >= 2:
#               actstring += str(act.selected).center(10)+","
#               actstring += str(self.modes[act.selected].duration).center(10)+","
#           else:
#               actstring += str(act.modes[0].name).center(10)[:10]+","
#               actstring += str(act.modes[0].duration).center(10)+","
            actstring = act.name + ","
            if len(act.modes)>=2:
                actstring+=str(act.selected)+","
                actstring+=str(act.start)+","
                actstring+=str(self.modes[act.selected].duration)+","
                actstring+=str(act.completion)+","                
            else:
                actstring += str(act.modes[0].name) + ","
                actstring += str(act.start) + ","
                actstring += str(act.modes[0].duration)+","  
                actstring+=str(act.completion)+","                  


066

#               rstring = res.name.center(30)+", , ,"
                rstring = ", , , ,"+res.name+","                

仮想アクティビティ

rcpsp34.py
cace 1


001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043

#rcpsp34.py
from optseq import *
#====データセット 
#i:[名前,期間,後続,資源]
data={
 1:["A01",5,[2],1],
 2:["A02",1,[0],0]
}
date10=10 #納期日
#====アクティビティ
prob=Model()
act={}
for i in data:
    act[i]=prob.addActivity(name=data[i][0])    
#====先行制約
for i in data.keys():
    for j in data[i][2]:
        if j>0: 
            prob.addTemporal(act[i],act[j],tempType="CS",delay=0)            
            prob.addTemporal(act[j],act[i],tempType="SC",delay=0) #重要             
#----A02固定
i==2
prob.addTemporal("source",act[i],tempType="CC",delay= date10)   
prob.addTemporal(act[i],"source",tempType="CC",delay=-date10)  
#====資源制約  
res=prob.addResource("place",capacity={(0,"inf"):1}) 
mode={}  
for i in data:
    mode[i]=Mode("M{0:02d}".format(i),duration=data[i][1])
    mode[i].addResource(res,requirement=data[i][3])
    if i==1:
        mode[i].addBreak(0,'inf')           #Case1
       #mode[i].addBreak(0,'inf',maxtime=2) #Case2
       #mode[i].addBreak(0,0)               #Case3
        mode[i].addResource(res,1,'break')
    act[i].addModes(mode[i])
#====求解
prob.Params.Makespan=True
prob.Params.TimeLimit=1
#prob.Params.OutputFlag=True
prob.optimize()
prob.write("rcpsp34.txt")
prob.writeExcel("rcpsp34.csv")

【rcpsp34.txt】


001
002
003
004
005
006
007
008
009
010

  activity    mode   duration  1 2 3 4 5 6 7 8 910
------------------------------------------------------------
   A01       M01        5     ==========........  
   A02       M02        1                       ==
------------------------------------------------------------
   resource usage/capacity     
------------------------------------------------------------
            place              1 1 1 1 1 1 1 1 1 0
                               1 1 1 1 1 1 1 1 1 1
------------------------------------------------------------

cace 2


001
002
003
004

       #mode[i].addBreak(0,'inf')           #Case1
        mode[i].addBreak(0,'inf',maxtime=2) #Case2
       #mode[i].addBreak(0,0)               #Case3
        mode[i].addResource(res,1,'break')  

【rcpsp34.txt】


001
002
003
004
005
006
007
008
009
010

  activity    mode   duration  1 2 3 4 5 6 7 8 910
------------------------------------------------------------
   A01       M01        5     ========....==....  
   A02       M02        1                       ==
------------------------------------------------------------
   resource usage/capacity     
------------------------------------------------------------
            place              1 1 1 1 1 1 1 1 1 0
                               1 1 1 1 1 1 1 1 1 1
------------------------------------------------------------

cace 3


001
002
003
004

       #mode[i].addBreak(0,'inf')           #Case1
       #mode[i].addBreak(0,'inf',maxtime=2) #Case2
        mode[i].addBreak(0,0)               #Case3
        mode[i].addResource(res,1,'break')  

【rcpsp34.txt】


001
002
003
004
005
006
007
008
009
010

  activity    mode   duration  1 2 3 4 5 6 7 8 910
------------------------------------------------------------
   A01       M01        5             ==========  
   A02       M02        1                       ==
------------------------------------------------------------
   resource usage/capacity     
------------------------------------------------------------
            place              0 0 0 0 1 1 1 1 1 0
                               1 1 1 1 1 1 1 1 1 1
------------------------------------------------------------

rcpsp35.py


001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057

#rcpsp35.py
from optseq import *
import math
#====データセット 
#i:[名前、後続、時数]
data={
 1:["搬入", [2],1],
 2:["作業1",[3],10],
 3:["作業2",[4],20],
 4:["搬出", [0],1],
}
#====アクティビティ
prob=Model()
act={}
for i in data:
    act[i]=prob.addActivity(name=data[i][0])
#====先行制約
for i in data:
    for j in data[i][1]:
        if j>0: prob.addTemporal(act[i],act[j])  
#----搬入日・搬出日の固定
prob.addTemporal("source",act[1],tempType="CC",delay= 1)   
prob.addTemporal(act[1],"source",tempType="CC",delay=-1)   
# prob.addTemporal("source",act[4],tempType="CC",delay= 10)   
# prob.addTemporal(act[4],"source",tempType="CC",delay=-10)      
#====資源制約  
res=prob.addResource("worker",capacity={(0,"inf"):5}) 
mode={}  
for i in data:
  if i in [2,3]:
    period=math.ceil(data[i][2]/8) #1人で何日かかるか
    mode[i]=Mode("M{0:02d}_{1:02d}".format(i,period),duration=period)
    mode[i].addResource(res,requirement=1)
    mode[i].addParallel(start=1,finish=period,maxparallel=2)
    act[i].addModes(mode[i])
  else:
    mode[i]=Mode("M{0:02d}".format(i),duration=1)
    act[i].addModes(mode[i])
#----場所取り
d_act={}
d_act=prob.addActivity("場所取り")
place=prob.addResource("place",capacity={(0,"inf"):1}) 
d_mode={}      
d_mode=Mode("M01_")
d_mode.addBreak(0,'inf')
d_mode.addResource(place,1,"break")
d_act.addModes(d_mode)                    
prob.addTemporal(act[1],d_act,tempType="CS")
prob.addTemporal(d_act,act[1],tempType="SC") 
prob.addTemporal(d_act,act[4],tempType="CS")
prob.addTemporal(act[4],d_act,tempType="SC") 
#====求解
prob.Params.Makespan=True
prob.Params.TimeLimit=1
#prob.Params.OutputFlag=True
prob.optimize()
prob.write("rcpsp35.txt")
prob.writeExcel("rcpsp35.csv")

【rcpsp35.txt】


001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016

  activity    mode   duration 12345
------------------------------------
   作業1     M02_02     2     *2   
   作業2     M03_03     3     *2= 
   場所取り   M01_       0      ... 
   搬入       M01        1     =    
   搬出       M04        1         =
------------------------------------
   resource usage/capacity     
------------------------------------
            place             01110
                              11111
------------------------------------
            worker            02210
                              55555
------------------------------------

小作業の並列化

rcpsp33.py




026
027
028
029
030
031
032

#rcpsp32.py 
 :
#====資源制約  
res=prob.addResource("Resource",capacity={(0,"inf"):10}) 
mode={}  
for i in data:
    mode[i]=Mode("M{0:02d}_{1:02d}".format(i,data[i][3]),duration=data[i][1])                    
    mode[i].addResource(res,requirement=data[i][3])
    act[i].addModes(mode[i])



026
027
028
029
029a
030
031
031a
032

#rcpsp33.py 
 :
#====資源制約  
res=prob.addResource("Resource",capacity={(0,"inf"):10}) 
mode={}  
for i in data:
    period=data[i][1]*data[i][3] #1人で何日かかるか
    mode[i]=Mode("M{0:02d}_{1:02d}".format(i,period),duration=period)
    mode[i].addResource(res,requirement=1)
    mode[i].addParallel(start=1,finish=period,maxparallel=10)
    act[i].addModes(mode[i])  

【rcpsp33.txt】


001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018

  activity    mode   duration  1 2 3 4 5 6 7 8 910111213
---------------------------------------------------------------------
   A01      M01_09      9     *6*3                      
   A02      M02_04      4     *4                        
   A03      M03_06      6       *6                      
   A04      M04_16      16        *10*6                  
   A05      M05_20      20                  *4*10*6      
   A06      M06_20      20          *4*10*6              
   A07      M07_20      20              *4*10*6          
   A08      M08_04      4                         *4    
   A09      M09_10      10                      *4*6    
   A10      M10_15      15                          *10*5
---------------------------------------------------------------------
   resource usage/capacity     
---------------------------------------------------------------------
           Resource           10 910101010101010101010 5
                              10101010101010101010101010
---------------------------------------------------------------------