同時計画の検討

同時計画 Step1

OptSeq

#rcpsp63.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=3 #プル型同時計画Step1: 作業の場所取りは実績ピンポイント     
iwhich=4  #プル型同時計画Step2: 待機の場所取りは面全体      
if iwhich in [3,4]: 
#=======================================================================
    if iwhich==3 : wplace=[]  #計画上の待機なし
    else: wplace=idata #計画上の待機あり   
#=======================================================================
#[3.1]作業の定義
#=======================================================================
    act={}
    print("*** pull [3,4] ***")
    for i in idata:       
        act[i]=prob.addActivity(data[i][0],duedate=98,backward=True)  
    # print("*** push" ***)        
    # for i in idata:  
    #     act[i]=prob.addActivity(data[i][0])
#=======================================================================
#[3.2]先行制約
#=======================================================================
    for i in  idata:
        for iw in [0,1,2,3,4]:
            if data[i][4][iw] in idata:
                prob.addTemporal(act[i],act[data[i][4][iw]],\
                tempType=CS[data[i][5][iw][0]], delay=int(data[i][5][iw][1]))  
   #-----日程固定
    for i in idata:
   # 0搭載, 2入荷, 6入ブ, 7出ブ, 9合体, 1開始, 3正, 4反, 5出棟, 8運搬,       
        # if data[i][1] in [0,2,9]:
        if data[i][1] in [0,2,6,7,9]:   
        # if data[i][1] in [0,1,2,3,4,5,6,7,8,9]:     
            prob.addTemporal("source",act[i],tempType="SS",delay= data[i][3])   
            prob.addTemporal(act[i],"source",tempType="SS",delay=-data[i][3])     
#=======================================================================
#[3.3]資源制約(配員) 
#=======================================================================    
    mode={}
    wno1=0;wno2=0;wno3=0;wno4=0;wno5=0;wno6=0;wno7=0
    for i in idata:
   #10 F #11 W #12 C #13 CC #15 鉄艤 #16 甲配 #17 機配 #18 内塗 #19 外塗   
        if data[i][1] in [10,12,11,13,15,16,17,18,19]: 
            hours=10
            n=math.ceil(data[i][9]/hours)  #1人で何日かかるか
            mode[i]=Mode("mode["+i+"]",duration=n)
            mode[i].addBreak(0,"inf",maxtime=10)   
            if data[i][1] in [10,12]:      #取付28人
                mode[i].addResource(res1W[1],{(0,n):hours})
                if n>7 : mode[i].addParallel(1,n,8)      
                else:    mode[i].addParallel(1,n,4)                    
                wno1+=1
            elif data[i][1] in [11,13]:    #溶接43人
                mode[i].addResource(res1W[2],{(0,n):hours})
                if n>11 : mode[i].addParallel(1,n,12)      
                else:     mode[i].addParallel(1,n,8)                  
                wno2+=1
            elif data[i][1] in [15]:       #鉄艤装5人
                mode[i].addResource(res1W[4],{(0,n):hours})
                if n>2 : mode[i].addParallel(1,n,5)      
                else:    mode[i].addParallel(1,n,3)   
                wno3+=1
            elif data[i][1] in [16]:       #甲板配管7人
                mode[i].addResource(res1W[5],{(0,n):hours})
                if n>6 : mode[i].addParallel(1,n,7)      
                else:    mode[i].addParallel(1,n,4)          
                wno4+=1
            elif data[i][1] in [17]:       #機関配管5人
                mode[i].addResource(res1W[6],{(0,n):hours})
                if n>14: mode[i].addParallel(1,n,5)      
                else:    mode[i].addParallel(1,n,3)  
                wno5+=1
            elif data[i][1] in [18]:       #塗装12人
                mode[i].addResource(res1W[3], {(0,n):hours})
                if n>8 : mode[i].addParallel(1,n,9)      
                else:    mode[i].addParallel(1,n,8)        
                wno6+=1
            elif data[i][1] in [19]:       #塗装12人
                mode[i].addResource(res1W[3], {(0,n):hours})
                if n>3 : mode[i].addParallel(1,n,8)      
                else:    mode[i].addParallel(1,n,4)        
                wno6+=1                
            act[i].addModes(mode[i])       
   # 0搭載, 1開始, 2入荷, 3正, 4反, 5出棟, 6入ブ, 7出ブ, 8運搬, 9合体; 14ダミー
        else:
            mode[i]=Mode("mode["+i+"]",duration=data[i][2]) 
            act[i].addModes(mode[i])              
    print(wno1,wno2,wno3,wno4,wno5,wno6) 
#=======================================================================
#[3.4]資源制約(作業場所)      
#=======================================================================
   # 0搭載, 1開始, 2入荷, 3正, 4反, 5出棟, 6入ブ, 7出ブ, 8運搬, 9合体, 
    ww={}
    for i in idata:
        if data[i][1] in [1,2,3,4,5,6,7,8,9]:
            for iw in [1,2,3,4]:
                j=data[i][4][iw] #枝iwの後続作業ID
                if j!="0":
                    #シリアルな後続は飛ばす
                    while data[j][8]==0: j=data[j][4][0]
                ww[i,iw]=j 
    #----- 作業場所    
    d_act={} 
    d_mode={}
    for i in idata:
        if data[i][1] in [1,2,3,4,5,6,7,8,9] and data[i][6]!=0:
            d_act[i]=prob.addActivity("場所_for_"+i)       
            for no in range(len(data[i][6])):  
                w=L1L2B1B2lb(R,data,i,6,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_mode[i,no1,j,k]=Mode(\
                        "mode["+i+"]0_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])                    
                prob.addTemporal(act[i],d_act[i],tempType="SS")
                prob.addTemporal(d_act[i],act[i],tempType="SS")
                for iw in [1,2,3,4]:
                    ii=ww[i,iw]
                    if ii!="0":
                        prob.addTemporal(d_act[i],act[ii],tempType="CC")  
                        prob.addTemporal(act[ii],d_act[i],tempType="CC")    
    #----- 待機場所 
    d_act2={}
    d_mode2={}
    for i in wplace:
        if data[i][1] in [1,2,3,4,5,6,7,8,9]:
            data[i][7]=data[i][6]            
            d_act2[i]=prob.addActivity("空置_after_"+i) 
            for no in range(len(data[i][7])):  
                w=L1L2B1B2lb(R,data,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+"]1_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,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])                          
                prob.addTemporal(d_act[i],d_act2[i],tempType="CS")
                prob.addTemporal(d_act2[i],d_act[i],tempType="SC") 
                ii=data[ww[i,1]][4][0]
                prob.addTemporal(act[ii],d_act2[i],tempType="SC")
                prob.addTemporal(d_act2[i],act[ii],tempType="CS")           
#=======================================================================
#[3.5]問題求解 step1
#=======================================================================
    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=Ture
   #prob.Params.Initial=False
   #prob.Params.OutputFlag=False
   #prob.Params.Neighborhood=20
   #prob.Params.RandomSeed=1
    prob.Params.TimeLimit=300  #100 or 300
    prob.optimize()
    filename="rcpsp63.csv"
   #print("writing "+filename) 
    prob.writeExcel(filename) 
#-----------------------------------------------------------------------
#[3.6]計画上の調整期間における場所取り
#-----------------------------------------------------------------------  
    print(" ")
    print("計画上の調整期間における場所取り")  
    jdata=[]; ldata=[]; mdata=[]; ndata=[]
    data1={}
    for i in data:
        data1[i]=data[i].copy()
    for a in prob.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)
            data1[j][3]=a.start
            data1[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])       
            data1[j][6]=[[r,x,x+l,y,y+b]]  
            data1[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:
                data1[i][3]=a.start
                data1[i][2]=a.completion-a.start    
                jdata.append(i)
               #print(len(jdata),i,r,l,b)            
                if   r in [1,2]: data1[i][7]=[R01,R02,R03,P03] 
               #elif r in [5,6]: data[i][7]=[R05,P07]
                else:            data1[i][7]=Q001+Q002+R00            
        elif "S01_" in a.name:
            i=a.name[0:12]  
            ndata.append(i)
            #if i[10:12]=="00": #運搬作業(期間1)
            data1[i][3]=a.start
            data1[i][2]=a.completion-a.start  #不要                
           #data2[i][3]=a.start
           #data2[i][2]=a.completion-a.start          
    print(len(ldata),len(mdata),len(ndata),len(jdata)) 
#sys.exit()

同時計画 Step2

OptSeq

#=======================================================================
#iwhich=4 3プル型同時計画Step2: 待機の場所取りは面全体
if iwhich==4: #rcpsp71_4.csv
#=======================================================================    
    prob2=Model()
#-----------------------------------------------------------------------  
#[4.0]リソースの定義(場所) 
#-----------------------------------------------------------------------    
   #-----未使用のリソース
    for id in R:    
        for i in range(0,R[id][1]):
          for j in range(0,R[id][2]):  
              res3PL[id,i,j] =prob2.addResource(R[id][0]+"[{0:02d}_{1:02d}]".format(i,j),\
                            capacity=res3PL[id,i,j].residual)
#-----------------------------------------------------------------------  
#[4.1]作業の定義
#-----------------------------------------------------------------------  
    act2={}
    for i in jdata:    
        act2[i]=prob2.addActivity("待機_after_"+data[i][0][0:12])
#-----------------------------------------------------------------------  
#[4.2]先行制約
#-----------------------------------------------------------------------  
   #-----日程固定
    for i in jdata:  
        prob2.addTemporal("source",act2[i],tempType="SS",delay= data1[i][3])   
        prob2.addTemporal(act2[i],"source",tempType="SS",delay=-data1[i][3])   
#-----------------------------------------------------------------------  
#[4.4]資源制約(作業場所)      
#-----------------------------------------------------------------------  
    mode2={} 
    for i in jdata:  
       #print(i,data1[i][0])
        for no in range(len(data1[i][7])):      
           #w=L1L2B1B2lb(R,data,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];  
            no1=data1[i][7][no][0];
            L=R[no1][1]; B=R[no1][2];
            L1=data1[i][7][no][1]; L2=data1[i][7][no][2];     
            B1=data1[i][7][no][3]; B2=data1[i][7][no][4];   
            l=math.floor(data1[i][8][0]); b=math.floor(data1[i][8][1]);                
            skipL=1; skipB=1;        
            for j in range(L1,L2-l+1,skipL): 
                for k in range(B1,B2-b+1,skipB):
                    mode2[i,no1,j,k]=Mode(\
                    "mode["+i+"]2_R[{0:03d}][{1:03d}_{2:03d}][{3:03d}_{4:03d}]"\
                    .format(no1,j,k,l,b),duration=data1[i][2])
                    for s in range(0,l):
                        for t in range(0,b):
                            mode2[i,no1,j,k].addResource(res3PL[no1,j+s,k+t],1)            
                    #mode2[i,no1,j,k].addResource(res2S[no1,j,k],l*b)   
                    act2[i].addModes(mode2[i,no1,j,k])
#-----------------------------------------------------------------------  
#[4.5]問題求解
#-----------------------------------------------------------------------  
    A=[]
    for a in prob2.act: A.append(a.name) 
   #print("アクティビティ:",A)  
    N=len(prob2.act)
    print("アクティビティ総数(含待機数):",N)  
    M=[]
    for a in prob2.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)  
#-----
   #prob2.Params.Makespan=True
   #prob2.Params.Initial=False 
   #prob2.Params.OutputFlag=False
   #prob2.Params.RandomSeed=1
    prob2.Params.TimeLimit=300
    prob2.optimize()
    filename="rcpsp64.csv"
   #print("writing "+filename) 
    prob2.writeExcel(filename)
#sys.exit()  
#=======================================================================
#eof