ベンチマーク問題例の解き方

最適化の研究では,ベンチマーク問題例というのを読み込んで実験する必要が出てくる.

通常は,決められたテキストファイルであるが,これがまちまちでコツをしらないと苦労する.Pythonで読み込む際のテクニックを例を用いて説明する.

例題として使うのは,PSBPLibというプロジェクトスケジューリング問題の中のMulti-modeの問題集だ.こちらでメンテされている.

こんなテキストファイルを読む必要がある.

************************************************************************
file with basedata            : c154_.bas
initial value random generator: 802306808
************************************************************************
projects                      :  1
jobs (incl. supersource/sink ):  18
horizon                       :  122
RESOURCES
 - renewable                 :  2   R
 - nonrenewable              :  2   N
 - doubly constrained        :  0   D
************************************************************************
PROJECT INFORMATION:
pronr.  #jobs rel.date duedate tardcost  MPM-Time
   1     16      0       22        2       22
************************************************************************
PRECEDENCE RELATIONS:
jobnr.    #modes  #successors   successors
  1        1          3           2   3   4
  2        3          2           5  10
  3        3          3           8   9  16
  4        3          3           5   7  11
  5        3          2           6  14
  6        3          1          12
  7        3          1           9
  8        3          1          10
  9        3          2          15  17
 10        3          2          11  13
 11        3          1          15
 12        3          1          16
 13        3          1          17
 14        3          1          16
 15        3          1          18
 16        3          1          18
 17        3          1          18
 18        1          0        
************************************************************************
REQUESTS/DURATIONS:
jobnr. mode duration  R 1  R 2  N 1  N 2
------------------------------------------------------------------------
 1      1     0       0    0    0    0
 2      1     1       6    0    0    1
        2     1       0   10    8    0
        3     9       0    8    8    0
 3      1     4       6    0    0    5
        2     5       0   10    5    0
        3     7       0   10    0    4
 4      1     1       3    0    0    7
        2     3       3    0    8    0
        3     4       3    0    0    3
 5      1     3       0    1    0    9
        2     6      10    0    6    0
        3     7       8    0    2    0
 6      1     2       9    0    0    8
        2     6       6    0    0    5
        3    10       0    2    0    5
 7      1     2       1    0    0    6
        2     4       0    8    0    6
        3     7       0    7    0    6
 8      1     3       8    0    0    6
        2     5       0    8    0    4
        3     6       5    0    3    0
 9      1     1       2    0    0    7
        2     3       0    4    0    6
        3     6       2    0    0    6
10      1     8       0   10    0    5
        2     8       0    9    1    0
        3     9       0    9    0    6
11      1     1       2    0    8    0
        2     3       0    5    8    0
        3     8       0    3    6    0
12      1     4       0    8    3    0
        2     9       0    8    0    6
        3    10       0    6    2    0
13      1     5       2    0    0    5
        2     6       0    9    0    4
        3    10       0    7    0    2
14      1     5       0    6    0    5
        2     7       3    0    6    0
        3    10       3    0    5    0
15      1     3       8    0   10    0
        2     4       0    7    7    0
        3     9       6    0    0    5
16      1     4       0    7   10    0
        2     6       0    7    0    8
        3     7       5    0    0    1
17      1     2       0    4    0    4
        2     2       0    5    5    0
        3     3       0    2    5    0
18      1     0       0    0    0    0
************************************************************************
RESOURCEAVAILABILITIES:
 R 1  R 2  N 1  N 2
  20   26   23   36
************************************************************************

説明の文が途中にはいっていたり,人間が読みやすいように整形してあるので,プログラムで読むのは面倒くさい.ただ,定形なので,何行目に何が入っているかを直打ちしても大丈夫なので,こんな感じでコーディングする.綺麗ではないが動けばいいのだ.

まずはファイルを開いて,行ごとのリストとして保管する.

f = open("c154_3.mm")
data = f.readlines()
f.close()

5行目はジョブ数とか決め打ちで基本データを読み込む.

n_jobs = int(data[5].split()[-1])
print("jobs",n_jobs)
n_res = int(data[8].split()[-2])
n_non = int(data[9].split()[-2])
print("res=",n_res, n_non)
n_modes, n_succs, succs = {},{},{}
for i in range(n_jobs):
   row = list(map(int,data[18+i].split())) 
   #print(row)
   idx = row[0]
   n_modes[idx] = row[1]
   n_succs[idx] = row[2]
   succs[idx] = row[3:]

作業時間,モード,資源,時間制約なども読むこむ.

count=0
duration, usage = {},{}
for i in n_modes:
   for m in range(n_modes[i]):
       row = list(map(int, data[18+4+n_jobs+count].split()))
       if m==0:
           duration[i,row[1]] = row[2]
           usage[i,row[1]] = row[3:]
       else:
           duration[i,row[0]] = row[1]
           usage[i,row[0]] = row[2:]
       count+=1
res_ub = list(map(int, data[18+4+3+n_jobs+count].split()))

読み込んだデータをOptSeqで解いてみる.これでベンチマーク問題の実験ができる.ちゃんと回せば,幾つかは世界記録を更新できるだろう.

model = Model()
act, mode, res = {},{},{}
#resource
for r in range(n_res):
   res[r] = model.addResource(name=f"resource[{r}]",capacity=res_ub[r])
for r in range(n_res,n_res+n_non):
   res[r] = model.addResource(name=f"resource[{r}]",rhs=res_ub[r], direction="<=")
#activity
for a in range(1,n_jobs+1):
   act[a] = model.addActivity(name=f"activity[{a}]")
#mode
for a,m in duration:
   mode[a,m] = Mode(name=f"mode[{a},{m}]", duration=duration[a,m])
   for r, req in enumerate(usage[a,m]):
       if r<n_res:
           if req>0:
               mode[a,m].addResource(res[r],requirement=req)
       else:
           #non-renewable constraint
           if req>0:
               res[r].addTerms(req, act[a], mode[a,m])
   act[a].addModes(mode[a,m])
#temporal
for i in succs:
   for j in succs[i]:
       model.addTemporal(act[i], act[j])
print(model) 
model.optimize()


この記事が気に入ったらサポートをしてみませんか?