OptSeqによる平準化

OptSeqによる平準化

以下では、「工程’s」による平準化で扱った同じ問題を考えます。

●まず山積みを行うプログラムは次のようになります。 

#prob11.py
from optseq import *
#=====リソース
prob11=Model()
res1=ex.addResource("Resource",capacity={(0,"inf"):20}) #10
#-----データセット
#i:[期間、後続、納期]
data={\
1:[3,[4,5],3],\
2:[4,[6,7],1],\
3:[6,[9]  ,1],\
4:[4,[6,7],4],\
5:[5,[8]  ,4],\
6:[4,[10] ,5],\
7:[5,[9],  4],\
8:[2,[10] ,5],\
9:[2,[10] ,2],\
10:[5,[0] ,3],\
}
#=====アクティビティ
act={}
for i in data:
  act[i]=prob11.addActivity("Act[{0}]".format(i))
#=====先行制約
for i in data:
  for j in data[i][1]:
    if j>0: prob11.addTemporal(act[i],act[j])  
#====資源制約  
mode={}  
for i in data:
  mode[i]=Mode("Mode[{0:02d}]".format(i),data[i][0])
  mode[i].addResource(res1,requirement=data[i][2])
  act[i].addModes(mode[i])
#=====最適化
prob11.Params.Makespan=True
prob11.Params.TimeLimit=1
#prob11.Params.OutputFlag=True
prob11.optimize()
prob11.write("prob11.txt")
prob11.writeExcel("prob11.csv")
#=====prob11.txt
#  activity    mode   duration  1 2 3 4 5 6 7 8 910111213141516171819
#---------------------------------------------------------------------
#  Act[1]   Mode[01]     3     ======                                
#  Act[2]   Mode[02]     4     ========                              
#  Act[3]   Mode[03]     6     ============                          
#  Act[4]   Mode[04]     4           ========                        
#  Act[5]   Mode[05]     5           ==========                      
#  Act[6]   Mode[06]     4                   ========                
#  Act[7]   Mode[07]     5                   ==========              
#  Act[8]   Mode[08]     2                     ====                  
#  Act[9]   Mode[09]     2                             ====          
# Act[10]   Mode[10]     5                                 ==========
#---------------------------------------------------------------------
#   resource usage/capacity     
#---------------------------------------------------------------------
#           Resource            5 5 510 9 9 8131414 9 4 2 2 3 3 3 3 3
#                              20202020202020202020202020202020202020
#--------------------------------------------------------------------- 

このプログラムを実行して、次の結果を得ます。

この結果は「工程’s」では次のように得られていました。


●これに対してOptSeqでは、次のような平準化が可能です。

これを行うプログラムを次に示します。データセットでは、各作業を1人で行う場合の作業期間が登録されています。これを小作業の並列化という手法を用いて平準化しています。

#prob12.py
from optseq import *
#=====リソース
prob12=Model()
res1=ex.addResource("Resource",capacity={(0,"inf"):10})
#-----データセット
#i:[期間、後続、納期]
data={\
1:[9,[4,5] ,1],\
2:[4,[6,7] ,1],\
3:[6,[9]   ,1],\
4:[16,[6,7],1],\
5:[20,[8]  ,1],\
6:[20,[10] ,1],\
7:[20,[9]  ,1],\
8:[10,[10] ,1],\
9:[4,[10]  ,1],\
10:[15,[0] ,1],\
}
#=====アクティビティ
act={}
for i in data:
  act[i]=prob12.addActivity("Act[{0}]".format(i))
#=====先行制約
for i in data:
  for j in data[i][1]:
    if j>0: prob12.addTemporal(act[i],act[j])  
#====資源制約  
mode={}  
for i in data:
  mode[i]=Mode("Mode[{0:02d}]".format(i),data[i][0])
  mode[i].addResource(res1,requirement=data[i][2])
  mode[i].addParallel(1,data[i][0],10)     
  act[i].addModes(mode[i])
#=====最適化
prob12.Params.Makespan=True
prob12.Params.TimeLimit=1
#prob11.Params.OutputFlag=True
prob12.optimize()
prob12.write("prob12.txt")
prob12.writeExcel("prob12.csv")
#=====prob12.txt
#  activity    mode   duration  1 2 3 4 5 6 7 8 910111213
#---------------------------------------------------------
#  Act[1]   Mode[01]     9     *6*3                      
#  Act[2]   Mode[02]     4     *4                        
#  Act[3]   Mode[03]     6       *6                      
#  Act[4]   Mode[04]     16        *10*6                  
#  Act[5]   Mode[05]     20          *4*10*6              
#  Act[6]   Mode[06]     20                  *4*10*6      
#  Act[7]   Mode[07]     20              *4*10*6          
#  Act[8]   Mode[08]     10                      *4*6    
#  Act[9]   Mode[09]     4                         *4    
#  Act[10]   Mode[10]     15                          *10*5 
#---------------------------------------------------------
#   resource usage/capacity     
#---------------------------------------------------------
#           Resource           10 910101010101010101010 5
#                              10101010101010101010101010
#---------------------------------------------------------

このプログラムを実行して、次の結果を得ます。

●上の例は配員計画を基に作業期間を定めており、日程計画と配員計画の同時計画を達成しています。次の例は、作業期間が未知の仮想作業を定義し、作業設備の確保も併せて達成しようとしています。

##prob13.py
from optseq import *
#=====リソース
prob13=Model()
res1=prob13.addResource("Resource1",capacity={(0,"inf"):10}) #10
res2=prob13.addResource("Resource2",capacity={(0,"inf"):10})  #10
#-----データセット
#i:[期間、後続、納期]
data={\
1:[9,[4,5] ,1],\
2:[4,[6,7] ,1],\
3:[6,[9]   ,1],\
4:[16,[6,7],1],\
5:[20,[8]  ,1],\
6:[20,[10] ,1],\
7:[20,[9]  ,1],\
8:[10,[10] ,1],\
9:[4,[10]  ,1],\
10:[15,[0] ,1],\
}
#=====アクティビティ
act={}
for i in data:
  act[i]=prob13.addActivity("Act[{0}]".format(i))
#=====先行制約
for i in data:
  for j in data[i][1]:
    if j>0: prob13.addTemporal(act[i],act[j])  
#====資源制約  
mode={}  
for i in data:
  mode[i]=Mode("Mode[{0:02d}]".format(i),data[i][0])
  mode[i].addResource(res1,requirement=data[i][2])
  mode[i].addParallel(1,data[i][0],10)     
  act[i].addModes(mode[i])
#====仮想作業    
dact={}
for i in data:
  dact[i]=prob13.addActivity("DAct[{0:02d}]".format(i))
  prob13.addTemporal(act[i],dact[i],tempType="SS") 
  prob13.addTemporal(act[i],dact[i],tempType="CC")
dmode={}
for i in data:
  dmode[i]=Mode("DMode[{0:02d}]".format(i))
  dmode[i].addBreak(0,0)
  dmode[i].addResource(res2,{(0,"inf"):1},"break")
  dact[i].addModes(dmode[i])
#=====最適化
prob13.Params.Makespan=True
prob13.Params.TimeLimit=1
#prob13.Params.OutputFlag=True
prob13.optimize()
prob13.write("prob13.txt")
prob13.writeExcel("prob13.csv")
#=====prob13.txt
#  activity    mode   duration  1 2 3 4 5 6 7 8 910111213
#---------------------------------------------------------
#  Act[1]   Mode[01]     9     *4*5                      
#  Act[2]   Mode[02]     4       *4                      
#  Act[3]   Mode[03]     6     *6                        
#  Act[4]   Mode[04]     16            *10*6              
#  Act[5]   Mode[05]     20        *10*10                  
#  Act[6]   Mode[06]     20                    *4*10*6    
#  Act[7]   Mode[07]     20                *4*10*6        
#  Act[8]   Mode[08]     10              *4*6            
#  Act[9]   Mode[09]     4                         *4    
# Act[10]   Mode[10]     15                          *10*5
# DAct[01] DMode[01]     0     ....                      
# DAct[02] DMode[02]     0       ..                      
# DAct[03] DMode[03]     0     ..                        
# DAct[04] DMode[04]     0             ....              
# DAct[05] DMode[05]     0         ....                  
# DAct[06] DMode[06]     0                     ......    
# DAct[07] DMode[07]     0                 ......        
# DAct[08] DMode[08]     0               ....            
# DAct[09] DMode[09]     0                         ..    
# DAct[10] DMode[10]     0                           ....
#---------------------------------------------------------
#   resource usage/capacity     
#---------------------------------------------------------
#          Resource1           10 910101010101010101010 5
#                              10101010101010101010101010
#---------------------------------------------------------
#          Resource2            2 2 1 1 1 2 2 1 2 1 2 1 1
#                               2 2 2 2 2 2 2 2 2 2 2 2 2

このプログラムを実行して、次の結果を得ます。

RCPSP

RCPSP

RCPSP (Resource Constraint Project Scheduling Problem, 資源制約プロジェクトスケジューリング問題)とは、先行制約(Precedence Constraints)と資源制約(Resource Constraints)のもとで、決定変数を各作業の開始日とし、目的関数を最小化する組合せ最適化問題で、次のように定式化(またはモデル化)表されます。

    \[\displaystyle{\boxed{\begin{array}{cl} {\bf min}&\ Objective\ Function\\ {start\ times}&\\ {\bf subject\ to}&1^\circ\ Precedence\ Constraints\\ &2^\circ\ Resource\ Constraints \end{array}}}\]

これを拡張した問題に対する商用ソルバーとして、OptSeqがあります。そこで使用可能なクラス、インスタンス、メソッドを以下に示します。

●クラス「モデル」
model=Model()

●クラス「作業」
act=model.addActivity(name=””,duedate=”inf”,backward=False,weight=1,autoselect=False,quadratic=False)
act.addModes(mode1,mode2,…)

●クラス「モード」
mode=Mode(name,duration=0)
mode.addResource(resource,requirement={(start,finish):req},rtype=None)
mode.addBreak(start=0,finish=0,maxtime=’inf’)
mode.addBreak(start=0,{(start,finish):req},’break’)
mode.addParallel(start=1,finish=1,maxparallel=’inf’)
mode.addState(state,fromValue=0,toValue=0)

●クラス「資源」
res=model.addResource(name,capacity,rhs=0,direction=’<=',weight='inf')
res.addCapacity(start,finish,amount)
res.addTerms(coeffs,vars,values)

●クラス「時間制約」
model.addTemporal(pred,succ,tempType=’CS’,delay=0,pred_mode=None,succ_mode=None)

●クラス「状態」
model.addState(name)

基本的例題

例1(プッシュ型とプル型) ある作業の納期と作業期間が与えられるとき、納期までどれくらい余裕があるのか(prob1a)、または納期にジャストインするためにはいつから作業に取りかかればよいか(prob1b)という問題を考えます。そのために作業をどう前詰めするか、納期に後詰めするかが問われ、それぞれプッシュ型とプル型に対応します。

#prob1a.py
from optseq import *
#=====リソース
prob1=Model()
res=prob1.addResource("worker",1)
#=====データセット
#i:[期間、後続、納期]
data={
1:[5,2,'inf'],\
2:[1,0,10]\
}
#=====アクティビティ
act={}
for i in data:
  act[i]=prob1.addActivity("Act[{0}]".format(i))
#=====先行制約
for i in data:
  if data[i][1]!=0:
    prob1.addTemporal(act[i],act[data[i][1]])    
#-----納期日
for i in data:
  if data[i][1]==0:
    prob1.addTemporal("source",act[i],"SS",delay= data[i][2]-1)
    prob1.addTemporal(act[i],"source","SS",delay=-data[i][2]+1) 
#====資源制約  
mode={}  
for i in data:
  mode[i]=Mode("Mode[{0}]".format(i),duration=data[i][0])
  mode[i].addResource(res,requirement=1)
  act[i].addModes(mode[i])
#=====最適化
prob1.Params.Makespan=True
prob1.Params.TimeLimit=1
#prob1.Params.OutputFlag=True
prob1.optimize()
prob1.write("prob1a.txt")
prob1.writeExcel("prob1a.csv")
#=====prob1a.txt
#  activity    mode   duration  1 2 3 4 5 6 7 8 910
#---------------------------------------------------
#  Act[1]   Mode[1]      5     ==========          
#  Act[2]   Mode[2]      1                       ==
#---------------------------------------------------
#   resource usage/capacity     
#---------------------------------------------------
#            worker             1 1 1 1 1 0 0 0 0 1
#                               1 1 1 1 1 1 1 1 1 1
#---------------------------------------------------

OptSeqは指定がなければ前詰めが実行されます。納入作業は10日目に行うと考えて、開始のタイミングを9日目終了に合わせています。

#prob1b.py
from optseq import *
#=====リソース
prob1=Model()
res=prob1.addResource("worker",1)
#=====データセット
#i:[期間、後続、納期]
data={
1:[5,2,10],\
2:[1,0,10]\
}
#=====アクティビティ
act={}
for i in data:
  act[i]=prob1.addActivity("Act[{0}]".format(i),duedate=data[i][2],backward=True)  
#=====先行制約
for i in data:
  if data[i][1]!=0:
    prob1.addTemporal(act[i],act[data[i][1]])    
#-----納期日
for i in data:
  if data[i][1]==0:
    prob1.addTemporal("source",act[i],"SS",delay= data[i][2]-1)
    prob1.addTemporal(act[i],"source","SS",delay=-data[i][2]+1)    
#====資源制約  
mode={}  
for i in data:
  mode[i]=Mode("Mode[{0}]".format(i),duration=data[i][0])
  mode[i].addResource(res,requirement=1)
  act[i].addModes(mode[i])
#=====最適化
prob1.Params.Makespan=True
prob1.Params.TimeLimit=1
#prob1.Params.OutputFlag=True
prob1.optimize()
prob1.write("prob1b.txt")
prob1.writeExcel("prob1b.csv")
#=====prob1a.txt
#  activity    mode   duration  1 2 3 4 5 6 7 8 910
#---------------------------------------------------
#  Act[1]   Mode[1]      5             ==========  
#  Act[2]   Mode[2]      1                       ==
#---------------------------------------------------
#   resource usage/capacity     
#---------------------------------------------------
#            worker             0 0 0 0 1 1 1 1 1 1
#                               1 1 1 1 1 1 1 1 1 1
#---------------------------------------------------

作業の定義において、納期の指定(duedate)と後詰めの指定(backward=True)を行っています。そのためにデータセットで主作業(Act[1])にも納期を指定する必要があることに注意してください(後続作業として納品作業があるので本来は不要であるように思われますが)。

例2(その場待機と置き場待機) 種々の制約があると待機期間が生じます。リソース(作業員、作業機械、作業場所)によっては待機中も確保が必要になります。たとえば、リソースが作業場所の場合、その作業場所で待機をするその場待機と、どこか待機場所を確保する置き場待機が考えられます。

#prob2a.py
from optseq import *
#=====リソース
prob2=Model()
res=prob2.addResource("place",1)
#=====データセット
#i:[期間、後続、納期]
data={
1:[5,2,'inf'],\
2:[1,0,10]\
}
#=====アクティビティ
act={}
for i in data:
  act[i]=prob2.addActivity("Act[{0}]".format(i))
#=====先行制約
for i in data:
  if data[i][1]!=0:
    prob2.addTemporal(act[i],act[data[i][1]],tempType="CS",delay=0)
    prob2.addTemporal(act[data[i][1]],act[i],tempType="SC",delay=0)  
#-----納期日
for i in data:
  if data[i][1]==0:
    prob2.addTemporal("source",act[i],"SS",delay= data[i][2]-1)
    prob2.addTemporal(act[i],"source","SS",delay=-data[i][2]+1)  
#====資源制約  
mode={}  
for i in data:
  mode[i]=Mode("Mode[{0}]".format(i),duration=data[i][0])
  mode[i].addResource(res,requirement=1)
  mode[i].addBreak(0,'inf') 
 #mode[i].addBreak(0,'inf',maxtime=2)
 #mode[i].addBreak(0,0)  
  mode[i].addResource(res,{(0,'inf'):1},'break')
  act[i].addModes(mode[i])
#=====最適化  
prob2.Params.Makespan=True
prob2.Params.TimeLimit=1
#prob2.Params.OutputFlag=True
prob2.optimize()
prob2.write("prob2a.txt")
prob2.writeExcel("prob2a.csv")
#=====prob2a.txt: mode[i].addBreak(0,'inf') 
#  activity    mode   duration  1 2 3 4 5 6 7 8 910
#---------------------------------------------------
#  Act[1]   Mode[1]      5     ==========........  
#  Act[2]   Mode[2]      1                       ==
#---------------------------------------------------
#   resource usage/capacity     
#---------------------------------------------------
#            place              1 1 1 1 1 1 1 1 1 1
#                               1 1 1 1 1 1 1 1 1 1
#---------------------------------------------------
#=====prob2a.txt: mode[i].addBreak(0,'inf',maxtime=2) 
#  activity    mode   duration  1 2 3 4 5 6 7 8 910
#---------------------------------------------------
#  Act[1]   Mode[1]      5     ========....==....  
#  Act[2]   Mode[2]      1                       ==
#---------------------------------------------------
#   resource usage/capacity     
#---------------------------------------------------
#            place              1 1 1 1 1 1 1 1 1 1
#                               1 1 1 1 1 1 1 1 1 1
#---------------------------------------------------
#=====prob2a.txt: mode[i].addBreak(0,0) 
#  activity    mode   duration  1 2 3 4 5 6 7 8 910
#---------------------------------------------------
#  Act[1]   Mode[1]      5     ........==========  
#  Act[2]   Mode[2]      1                       ==
#---------------------------------------------------
#   resource usage/capacity     
#---------------------------------------------------
#            place              1 1 1 1 1 1 1 1 1 1
#                               1 1 1 1 1 1 1 1 1 1
#---------------------------------------------------

ここでは、待機期間の取り方を3種類考えて、その場待機を実現しています。

#prob2b.py
from optseq import *
#=====リソース
prob2=Model()
res0=prob2.addResource("place",1)
res1=prob2.addResource("stock",1)
#=====データセット
#i:[期間、後続、納期]
data={
1:[5,-2,"inf"],\
2:[1,0,10]\
}
#=====アクティビティ
act={}
for i in data:
  act[i]=prob2.addActivity("Act[{0}]".format(i))
#=====先行制約
for i in data:
  if data[i][1]!=0:
    prob2.addTemporal(act[i],act[data[i][1]],tempType="CS",delay=0)  
#-----納期日
for i in data:
  if data[i][1]==0:
    prob2.addTemporal("source",act[i],"SS",delay= data[i][2]-1)
    prob2.addTemporal(act[i],"source","SS",delay=-data[i][2]+1)  
#====資源制約  
mode={}  
for i in data:
  mode[i]=Mode("Mode[{0}]".format(i),duration=data[i][0])
  mode[i].addResource(res0,1)
  act[i].addModes(mode[i])
#=====仮想作業
d_act={}
for i in data:
  if data[i][1]<0:
    d_act[i]=prob2.addActivity("Wait[{0}]".format(i))
    prob2.addTemporal(act[i],d_act[i],tempType="CS")
    prob2.addTemporal(d_act[i],act[i],tempType="SC")
    prob2.addTemporal(d_act[i],act[abs(data[i][1])],tempType="CS")
    prob2.addTemporal(act[abs(data[i][1])],d_act[i],tempType="SC")
d_mode={}
for i in data:
  if data[i][1]<0:
    d_mode[i]=Mode("d_Mode[{0}]".format(i))
    d_mode[i].addBreak(0,0)
    d_mode[i].addResource(res1,{(0,"inf"):1},"break")
    d_act[i].addModes(d_mode[i])
#=====最適化      
prob2.Params.Makespan=True
prob2.Params.TimeLimit=1
#prob2.Params.OutputFlag=True
prob2.optimize()
prob2.write("prob2b.txt")
prob2.writeExcel("prob2b.csv")
#=====prob2b.txt 
#  activity    mode   duration  1 2 3 4 5 6 7 8 910
#---------------------------------------------------
#  Act[1]   Mode[1]      5     ==========          
#  Act[2]   Mode[2]      1                       ==
# Wait[1]  d_Mode[1]     0               ........  
#---------------------------------------------------
#   resource usage/capacity     
#---------------------------------------------------
#            place              1 1 1 1 1 0 0 0 0 1
#                               1 1 1 1 1 1 1 1 1 1
#---------------------------------------------------
#            stock              0 0 0 0 0 1 1 1 1 0
#                               1 1 1 1 1 1 1 1 1 1
#---------------------------------------------------

ここでは、待機場所を別に確保して、待機中はそこを使うようにしています。この置き場待機を実施するかどうかは、データセットにおける後続作業の番号が負であるかどうかで判断しています。

エクスポート

エクスポート

●「工程’s」のファイルにエクスポートを行うと、次のような13種類のTSVファイルが得られます。

ここで、次の3つのファイルに注目します。
・koutei.tsv ⇒作業の定義
・requirement.tsv ⇒要求リソース
・constraint.tsv ⇒先行制約
これらから、データセットを作成するのに必要な項目(以下の赤太字)を抽出します。

koutei.tsvのレコードを構成するフィールド(129個)

第1階層グループID 第1階層グループ名称 第1階層グループ備考1 第1階層グループ備考2 第1階層グループ備考3 第1階層グループ備考4 第1階層グループ備考5 第1階層グループ備考6 第1階層グループ備考7 第1階層グループ備考8 第1階層グループ備考9 第1階層グループ備考10 第2階層グループID 第2階層グループ名称 第3階層グループID 第3階層グループ名称 第4階層グループID 第4階層グループ名称 第5階層グループID 第5階層グループ名称 第6階層グループID 第6階層グループ名称 第7階層グループID 第7階層グループ名称 第8階層グループID 第8階層グループ名称 第9階層グループID 第9階層グループ名称 第10階層グループID 第10階層グループ名称 行番号 工程ID 工程名称 初期工程開始日 初期工程終了日 工程開始日 工程終了日 工程期間 カレンダID 進捗度 数量 備考1 備考2 備考3 備考4 備考5 備考6 備考7 備考8 備考9 備考10 バーを移動しない 後続に影響しない範囲で遅く開始する 編集不可 左シンボル形状 中シンボル形状 右シンボル形状 左シンボル色 中シンボル色 右シンボル色 テキストの表示位置 URL表示名1 URL1 URL表示名2 URL2 URL表示名3 URL3 URL表示名4 URL4 URL表示名5 URL5 第1階層グループ非表示 第1階層グループバー非表示 第1階層グループ折りたたみ(バーチャート) 第1階層グループ折りたたみ(ツリービュー) 第1階層グループ名称の書き方 第2階層グループ非表示 第2階層グループバー非表示 第2階層グループ折りたたみ(バーチャート) 第2階層グループ折りたたみ(ツリービュー) 第2階層グループ名称の書き方 第3階層グループ非表示 第3階層グループバー非表示 第3階層グループ折りたたみ(バーチャート) 第3階層グループ折りたたみ(ツリービュー) 第3階層グループ名称の書き方 第4階層グループ非表示 第4階層グループバー非表示 第4階層グループ折りたたみ(バーチャート) 第4階層グループ折りたたみ(ツリービュー) 第4階層グループ名称の書き方 第5階層グループ非表示 第5階層グループバー非表示 第5階層グループ折りたたみ(バーチャート) 第5階層グループ折りたたみ(ツリービュー) 第5階層グループ名称の書き方 第6階層グループ非表示 第6階層グループバー非表示 第6階層グループ折りたたみ(バーチャート) 第6階層グループ折りたたみ(ツリービュー) 第6階層グループ名称の書き方 第7階層グループ非表示 第7階層グループバー非表示 第7階層グループ折りたたみ(バーチャート) 第7階層グループ折りたたみ(ツリービュー) 第7階層グループ名称の書き方 第8階層グループ非表示 第8階層グループバー非表示 第8階層グループ折りたたみ(バーチャート) 第8階層グループ折りたたみ(ツリービュー) 第8階層グループ名称の書き方 第9階層グループ非表示 第9階層グループバー非表示 第9階層グループ折りたたみ(バーチャート) 第9階層グループ折りたたみ(ツリービュー) 第9階層グループ名称の書き方 第10階層グループ非表示 第10階層グループバー非表示 第10階層グループ折りたたみ(バーチャート) 第10階層グループ折りたたみ(ツリービュー) 第10階層グループ名称の書き方 初期計画左シンボル形状 初期計画中シンボル形状 初期計画右シンボル形状 初期計画左シンボル色 初期計画中シンボル色 初期計画右シンボル色 拡張設定1 EOR

PERTの例題について赤太字の項目を抜き出すと次のようになります。

requirement.tsvのレコードを構成するフィールド(5個)

工程ID 資源ID 必要量 タイプ EOR

PERTの例題について赤太字の項目を抜き出すと次のようになります。

constraint.tsvのレコードを構成するフィールド(26個)

先行工程ID 後続工程ID タイプ 作業間隔 カレンダID 備考 非表示 描画順序1 描画オフセット右1 描画オフセット下1 描画順序2 描画オフセット右2 描画オフセット下2 描画順序3 描画オフセット右3 描画オフセット下3 描画順序4 描画オフセット右4 描画オフセット下4 描画順序5 描画オフセット右5 描画オフセット下5 描画順序6 描画オフセット右6 描画オフセット下6 EOR

PERTの例題について赤太字の項目を抜き出すと次のようになります。

データセットの作成

「工程’s」による平準化

「工程’s」による平準化…Homework

●作業情報が次表のように与えられる例を考えます。

# 作業名 作業時間 先行関係 作業員
1 A1 3 4 5 3
2 A2 4 6 7 1
3 A3 6 8 1
4 A4 4 6 7 4
5 A5 5 9 4
6 A6 4 10 5
7 A7 5 8 4
8 A8 2 10 5
9 A9 2 10 2
10 A10 5 0 3

山積みを行った結果を次に示します。毎日10名まで配員可能とすると、これをオーバーしていることが分かります。

ここで、赤い作業の列がCPを表しています。通常は、CP以外の作業を前後させて平準化(山均し)を行います。

●「工程’s」の「オシカ」を用いて平準化を行った結果を次に示します。

●以上は、各作業を作業期間中は毎日一定の配員で行う場合です。しかし日ごとに配員数を変えてよい場合を検討するために、次の山積みを行います。

●これを平準化して、次の結果を得ます。

本来は、作業81が始まるまでに作業A74を終わらせたいところですが、「工程’s」でそれが可能かどうかは現在検討中です。

●参考までに、別の方法で日ごとの配員数を変えながら(したがって作業期間を変えながら)、平準化を行った結果を次に示します。

ここで、10名の作業員はどの作業も担当できることを仮定しています。

基本操作

アクティティビティの定義と先行関係の付与…Homework

●操作1:編集期間の設定

●操作2:通し日の設定

●操作3:グループ名の定義(行の追加、行番号の定義)

●操作4:アクティビティの定義(名称の設定)

●操作5:シンボルの変更

●操作5:後続作業の定義、先行関係の付与

先行関係には、CS関係(完了⇒開始)、SC関係(開始⇒完了)、SS関係(開始⇒開始)、CC関係(完了⇒完了)の4種類がある。

●操作6:グループバーを非表示
●操作7:操作の取り消し

リソースの付与…Homework

●操作8:資源マスターの定義

●操作9:必要資源の付与

●操作10:バーレイアウトの変更

●操作11:キャパ(提供可能資源量)の付与