2020年4月23日木曜日

ログ整形スクリプト

NEOS-ServerのGurobiデータとSC3のデータを拾うスクリプトを書きました。
下がGurobi用です。
import re
import csv
f = open('120w4gurobi.txt', 'r')
line = f.readline()
mode=0
map={ }
read_enable=False
constant=1480 #Constant objective value
while line:
 #print(line.strip())
 if 'Gap' in line:
  read_enable=True
 if 'ERROR' in line:
  read_enable=False
 if read_enable:
  print(line)
  l = line.split()
  count=0;
  second=''
  for s in reversed(l):
  
   if count==0 and 's' in s:
    second=s.replace('s','')
    print(second)
   if count==4:
    print(s)
    if second !='':
     map[int(second)]=float(s)+constant
   count+=1
 line = f.readline()
f.close()
#print(map)
map=sorted(map.items())
print(map)
f = open('result.csv', 'w')

for s in map:
 print(s[0])
 s1=str(s[0])+','+str(s[1])
 s1+='\n'
 f.write(s1) 
f.close()
 
SC3用が下です。
import re
import csv
f = open('result.txt', 'r')
line = f.readline()
mode=0
map={ }
read_enable=False
constant_time=213.809 #Algorithm1 Solving Process Started time
once=False
while line:
 #print(line.strip())
 if 'Algorithm 1 Solving Process Started.' in line and once==False:
  read_enable=True
  once=True
 if '*********UB=' in line:
  read_enable=False
 if read_enable:
  #print(line)
  l = line.split()
  count=0;
  second=''
  for s in reversed(l):
  
   if count==0 and '(sec)' in s:
    second=s.replace('(sec)','')
    print(second)
   if count==1:
    print(s)
    if second !='':
     sec=float(second)+constant_time
     map[sec]=float(s)
   count+=1
 line = f.readline()
f.close()
#print(map)
map=sorted(map.items())
print(map)
f = open('result.csv', 'w')

for s in map:
 print(s[0])
 s1=str(s[0])+','+str(s[1])
 s1+='\n'
 f.write(s1) 
f.close()
 
で、グラフが下です。
これだと、良く判らないので、横(時間)、縦(目的関数値)で拡大してみます。
さらに縦を拡大します。
グラフから、■Algorithm1は、計測直後から実行可能解が出力されます。遅れて、Algorithm4は、200秒、Gurobiは、767sec後から実行可能解が出力されます。
■Algorithm4は、330secで打ち切っていますが、それでも8時間後のGurobiよりも良い目的関数値になっています。

ナーススケジューリング解の設計目標として、良い解を出来る限り早く出力すること、がありますが、どちらかというと学術分野では、速さよりも時間をかけたときの目的関数値の優劣を競う面があります。その意味で、Algorithm4が、最終的な目的関数値が最小ですので優秀なのですが、実務的には、

■数分内に実用的な目的関数値を出力する

ことの方がより重要です。仮に8時間後に厳密解が判ったとしても、その差が数%内ならば、数分内に出力される方を選ぶでしょう。なぜならナーススケジューリングは、一回で解を得ておしまいではなく、何回もの試行を経て決定されることが一般的だからです。その意味で、解の有無が直ぐに判るAlgorithm1が最も実務的です。

が、ソフトエラーが多数に渡る場合、GAP(下界と上界の差)が、今回のように50%程度になることもあります。そのAlgorith1のこうした弱点を補うことが今回のAlgorithm4の目的でした。狙い通り、
INRCⅡの殆ど全てのインスタンス及びSchedulingBenchmarkのBestKnown値の更新、いくつかの成果はありました。残念ながら、実用的には、今だ道が遠いのですが、作業予定時間を大幅に超過してしまいました。これまでの成果をまとめて一区切りとしたいと思います。

■厳密解が確定
その後、テストを続けた結果厳密解が確定しました。16000sec後にAlgorithm4が確定(2050)させました。120W4というのは、スタッフ120人のWeeksが4です。確定できたのは、僅か数インスタンスしかないのですが、必ずしもインスタンス的に小さいものでないことが興味深いです。




0 件のコメント:

コメントを投稿