ベンチマーク問題例の解き方
最適化の研究では,ベンチマーク問題例というのを読み込んで実験する必要が出てくる.
通常は,決められたテキストファイルであるが,これがまちまちでコツをしらないと苦労する.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()
この記事が気に入ったらサポートをしてみませんか?