Commit 7724b549 authored by ehebrard's avatar ehebrard
Browse files

cactuses

parent 1cfd31cb
......@@ -1404,6 +1404,15 @@ for low values of \numfeat\ and $\mdepth$.
% \numfeat) is low, and for small values of $\mdepth$.
When $\numfeat$ grows, however, it often exceeds the memory limit of 50GB (whereas \budalg does not require more memory than the size of the data set). Finally, \binoct does not produce a single optimality proof and very often exceeds the memory limit.%\footnote{In the experiments in \cite{verwer2019learning} not all datapoints were used.}
\begin{figure}
% \subfloat[depth=3]{\input{src/tables/xscopt3.tex}}
\subfloat[depth=4]{\input{src/tables/xscopt4.tex}}
% \subfloat[depth=5]{\input{src/tables/xscopt5.tex}}
\subfloat[depth=7]{\input{src/tables/xscopt7.tex}}
\subfloat[depth=10]{\input{src/tables/xscopt10.tex}}
\caption{\label{fig:cactus}Proof ratio over time, averaged across all data sets}
\end{figure}
% \clearpage
......@@ -1458,12 +1467,11 @@ We can see in those graphs that \murtree finds an initial tree extremely quickly
\begin{figure}
\subfloat[depth=3]{\input{src/tables/xscerror3.tex}}
% \subfloat[depth=3]{\input{src/tables/xscerror3.tex}}
\subfloat[depth=4]{\input{src/tables/xscerror4.tex}}
% \subfloat[depth=5]{\input{src/tables/xscerror5.tex}}
\subfloat[depth=7]{\input{src/tables/xscerror7.tex}}
\subfloat[depth=10]{\input{src/tables/xscerror10.tex}}
% \subfloat[depth=8]{\input{src/tables/xscerror8.tex}}
% \subfloat[depth=9]{\input{src/tables/xscerror9.tex}}
% \subfloat[depth=10]{\input{src/tables/xscerror10.tex}}
\caption{\label{fig:cactus}Accuracy over time, averaged across all data sets}
\end{figure}
......
#! /usr/bin/env python
from rocknrun import *
import pickle
import copy
# import string
# themurtree = 'murtree_cart'
themurtree = 'murtree_infogain'
# themurtree = 'murtree_full'
# themurtree = 'murtree_default'
thebfs = 'dt_default'
def timeprinter(n, prec, val):
if val >= 3600:
return '$\\mathsmaller{\geq}1$h'
elif val >= 10:
prec = 0
elif val >= 1:
prec = 1
return '%.*f'%(prec, val)
def prodprinter(n, prec, val):
if val >= 10:
prec = 0
if n<0:
return '%s%.*f'%('$\\mathsmaller{\\times}$', prec, val)
else:
return '{\\tiny ${%.2f}$~} %s%.*f'%(n, '$\\mathsmaller{\\times}$', prec, val)
def incprinter(n, prec, val):
if abs(val) >= 10:
prec = 0
elif abs(val) >= 1:
prec = 1
if n<0:
return '%s%.*f'%('$\\mathsmaller{+}$' if val>0 else '', prec, val)
else:
return '{\\tiny ${%.2f}$~} %s%.*f'%(n, '$\\mathsmaller{+}$' if val>0 else '', prec, val)
def percentprinter(n, prec, val):
if val >= 10:
prec = 0
if val >= 1:
prec = 1
if n<0:
return '%s%.*f\\%%'%('$\\mathsmaller{+}$' if val>0 else '', prec, val)
else:
return '{\\tiny ${%.2f}$~} %s%.*f\\%%'%(n, '$\\mathsmaller{+}$' if val>0 else '', prec, val)
def longtablestring(title, fname, sep=6, font='normalsize'):
return "{\\%s\n\\tabcolsep=%ipt\n\\begin{center}\n\\captionof{figure}{%s}\n\\input{%s.tex}\n\\addtocounter{table}{-1}\n\\end{center}\n\\clearpage\n}\n"%(font,sep,title,fname)
def tabularstring(title, fname, sep=6, font='normalsize'):
return "\\begin{table}[htbp]\n\\begin{center}\n\\begin{%s}\n\\tabcolsep=%ipt\n\\input{%s.tex}\n\\end{%s}\n\\end{center}\n\\caption{\\label{tab:%s} %s}\n\\end{table}"%(font,sep,fname,font,fname,title)
def sidewaystablestring(title, fname, sep=6, font='normalsize'):
return "\\begin{sidewaystable}[htbp]\n\\begin{center}\n\\begin{%s}\n\\tabcolsep=%ipt\n\\input{%s.tex}\n\\end{%s}\n\\end{center}\n\\caption{\\label{tab:%s} %s}\n\\end{sidewaystable}"%(font,sep,fname,font,fname,title)
def prettyint(val):
if val < 1000:
return '%s'%val
else:
log10 = 0
val = float(val)
while val >= 10.0:
val /= 10.0
log10 += 1
if val*10 == int(val)*10:
return '\\expnumber{%i}{%i}'%(int(val),log10)
else:
return '\\expnumber{%.1f}{%i}'%(val,log10)
class ITIParser(object):
def __call__(self,output):
data = {}
error = 0
depth = 0
for l in output:
# print l,
if l.startswith('Leaves:'):
row = l[:-1].split(',')
for dt in row:
if dt.find(": ") >= 0 :
p = dt.strip().split(': ')
r = p[1].find('(iti-fast)')
if r >=0 :
p[1] = p[1][:r-1]
r = p[1].find('(dmti-by-leaves)')
if r >=0 :
p[1] = p[1][:r-1]
data[p[0]] = [float(p[1])]
elif len(data) > 0:
lp1 = l.find('(');
lp2 = l.rfind('(');
rp1 = l.find(')');
rp2 = l.rfind(')');
d = (lp1-2)/3
if d > depth :
depth = d
# print (lp1-2)/3
if(lp1 != lp2):
pos = int(l[lp1+1:rp1])
neg = int(l[lp2+1:rp2])
# print pos, neg
error += min(pos,neg)
data['error'] = [error]
data['depth'] = [depth]
if len(data['Leaves']) > 0 :
data['size'] = [2 * data['Leaves'][-1] - 1]
if len(data['cpu']) > 0 :
data['time'] = [data['cpu'][-1]]
if len(data['instances']) > 0 :
data['accuracy'] = [(data['instances'][-1] - data['error'][-1]) / data['instances'][-1]]
# print data
return data
class IParser(object):
def __init__(self):
pass
def __call__(self,output):
res = {}
for line in output:
if line.startswith('iti-tree'):
row = line.split()
res['size'] = [int(row[2])]
res['time'] = [float(row[4])]
break
return res
class CplexParser(object):
def __call__(self,output):
stats = ['time', 'conflicts', 'lb', 'error', 'optimal', 'prooftime', 'solution']
res = {}.fromkeys(stats)
for stat in stats:
res[stat] = []
res['solution'].append(0)
res['optimal'].append(0)
res['prooftime'].append(3600)
stat_set = set(stats)
in_search = False
# numsol = 0
t = 0
conf = 0
lb = 0
ub = sys.maxint
pt = t
pconf = conf
plb = lb
pub = ub
ok = False
for line in output:
# print line
if not ok:
if not line.startswith('num_vars'):
continue
else:
res['num_vars'] = [int(line.split()[1])]
ok = True
if line.startswith('num_rows'):
res['num_rows'] = [int(line.split()[1])]
elif line.startswith('Solution status'):
if line.split()[5] == 'MIP_optimal':
res['optimal'] = [1]
res['prooftime'] = [res['time'][-1]]
elif line.startswith('Presolve time'):
t += float(line.split()[3])
elif line.startswith('Found incumbent of value'):
ub = int(float(line.split()[4]))
# numsol += 1
elif line.startswith('Objective value:'):
ub = int(float(line.split()[2]))
lb = ub
elif line.startswith('Total (root+branch&cut)'):
t = float(line.split()[3])
elif line.startswith('*'):
plus_index = line.find('+')
if plus_index >= 0:
rdata = line[plus_index+1:].split()
offset = 2 if line.find('integral') >= 0 else 0
try:
u = float(rdata[1+offset])
except:
pass
try:
l = float(rdata[2+offset])
except:
pass
try:
c = int(line[1:plus_index].strip())
except:
pass
if c < conf or u < l or u > ub or l < lb:
raise ERROR
lb = l
ub = u
conf = c
else:
rdata = line[1:].split()
offset = 2 if line.find('integral') >= 0 else 0
try:
u = float(rdata[2+offset])
except:
pass
try:
l = float(rdata[3+offset])
except:
pass
try:
c = int(line[0].strip())
except:
pass
# print c, l, u
if c < conf or u < l or u > ub or l < lb:
raise ERROR
lb = l
ub = u
conf = c
elif line.startswith('Elapsed time ='):
t = float(line.split()[3])
# n = int(line.split()[13][:-1])
# if n != numsol:
# raise ERROR
elif line.startswith(' Node Left Objective IInf Best Integer Best Bound ItCnt Gap'):
in_search = True
elif line.startswith('slurm'):
break
elif in_search and line.startswith(' Real time =') or line.startswith('Repeating presolve.'):
in_search = False
elif in_search:
data = line.split()
if len(data) == 8:
l = int(float(data[5]))
if l < lb:
raise ERROR
lb = l
if data[0].endswith('+'):
c = int(data[0][:-1])
else:
c = int(data[0])
if c < conf:
raise ERROR
conf = c
if plb != lb or pub != ub: #or pconf != conf or pt != t:
# print res
res['lb'].append(lb)
res['error'].append(ub)
res['conflicts'].append(conf)
res['time'].append(t)
pt = t
pconf = conf
plb = lb
pub = ub
# if res['lb'][-1] == res['error'][-1]:
# res['optimal'] = [1]
# res['prooftime'] = [res['time'][-1]]
# # print res
if len(res['error']) > 0 and res['error'][-1] != sys.maxint:
res['solution'] = [1]
return res
class DL8Parser(object):
def __call__(self,output):
res = {}
res['optimal'] = [0]
# res['prooftime'] = [3600]
# res['prooftime'] = []
for line in output:
# print line,
if line.startswith("Size:"):
res['size'] = [int(line.split()[1])]
elif line.startswith("Depth:"):
res['depth'] = [int(line.split()[1])]
elif line.startswith("Error:"):
res['error'] = [float(line.split()[1])]
elif line.startswith("Accuracy:"):
res['accuracy'] = [float(line.split()[1])]
elif line.startswith("LatticeSize:"):
res['choices'] = [int(line.split()[1])]
elif line.startswith("Runtime:"):
res['time'] = [float(line.split()[1])]
res['prooftime'] = res['time']
elif line.startswith("Timeout:"):
if line.find('False') >= 0:
res['optimal'] = [1]
# print res
return res
class CPParser(object):
def __call__(self,output):
res = {}
res['optimal'] = [0]
res['prooftime'] = [3600]
for line in output:
if line.startswith("Cost:"):
res['error'] = [int(line.split()[1])]
elif line.startswith("Search time:"):
res['time'] = [float(line.split()[2])/1000]
elif line.startswith("Completed:"):
if line.find("true") >= 0:
res['optimal'] = [1]
res['prooftime'] = res['time']
return res
class CARTParser(object):
def __call__(self,output):
res = {}
for line in output:
if line.startswith("depth"):
res['depth'] = [int(line.split()[1])]
elif line.startswith("error"):
res['error'] = [float(line.split()[1])]
elif line.startswith("accuracy"):
res['accuracy'] = [float(line.split()[1])]
elif line.startswith("time"):
res['time'] = [float(line.split()[1])]
return res
class DTParser(object):
def __init__(self, separator=' ', equal='=', dataflag='d'):
self.equal = equal
self.separator = separator
self.dataflag = dataflag
def store(self, stat, vstr, res):
stat = stat.strip()
if not res.has_key(stat):
res[stat] = []
val = None
try:
val = int(vstr)
except:
val = float(vstr)
# if stat == 'error' and len(res['error'])>0 and val == res['error'][-1]:
# res['optimal'][-1] = 1
res[stat].append(val)
def __call__(self,output):
res = {}
res['optimal'] = [0]
for line in output:
if line.find('optimal') >= 0:
self.store('optimal',1,res)
if line.find('done!') >= 0:
self.store('optimal',1,res)
continue
# break
if line.find('wallclock time') >= 0:
self.store('prooftime',str(res['time'][-1]),res)
if not line.startswith(self.dataflag):
continue
data = line[len(self.dataflag):].split()
for st in data:
stat,val = st.split(self.equal)
self.store(stat,val,res)
if res['optimal'][-1] == 0:
if res.has_key('error'):
if len(res['error'])>1:
if res['error'][-1] == res['error'][-2]:
continue
self.store('sol'+stat,val,res)
else:
self.store('proof'+stat,val,res)
# if res['optimal'][-1] == 0:
# res['prooftime'] = [3600]
return res
def quotient(x,y):
if len(x) == 0 or len(y)==0:
return 0.0
elif y[-1]==0:
return 10.0*float(x[-1])
else:
return float(x[-1])/float(y[-1])
def stop_iter():
"""An easy way to break out of a generator"""
raise StopIteration
def common_start(sa, sb):
return ''.join(a if a == b else stop_iter() for a, b in zip(sa, sb))
where = 'paper'
def catch_errors(e,o):
for elist, etype in zip([o.parse_errors, o.solve_errors, o.kirtania_errors, o.segfaults, o.timeouts, o.asserts, o.memoryouts],['parse', 'solve', 'kirtania', 'segfaults', 'timeouts', 'asserts', 'memoryouts']):
for k in e.keys:
if len(elist[k]):
print
print etype
# subprocess.Popen(['rm', '-rf', etype])
# subprocess.Popen(['mkdir', etype])
kfile = open('slurm_%s'%k, 'r')
rfile = open('rerun_%s_%s'%(etype,k), 'w')
ifile = open('list_%s_%s'%(etype,k), 'w')
for jobid in elist[k] :
alg, bench, seed = e.get_fromjob(k, jobid)
outfile = 'results/%s.out'%e.get_outfile( k, alg, bench, seed )
# subprocess.Popen(['cp', outfile, outfile.replace('results', etype)])
# print o.data[alg][bench]
ifile.write('%s, %s, %s, %s\n'%(k, jobid, outfile, e.cmdline[alg].replace('#BENCHNAME', bench).replace('#BENCHMARK', e.path[bench]).replace('#HINTS', e.annotations[bench])))
print len(elist[k]), '/', e.num_runs_in(k), 'see list_%s_%s'%(etype,k)
rfile.write(kfile.read().replace('1-%i'%e.num_runs_in(k), ','.join([str(jid) for jid in sorted(elist[k])])).replace('--mem=10000','--mem=50000').replace('--mem=3500','--mem=50000'))
rfile.close()
kfile.close()
ifile.close()
if __name__ == '__main__':
# # e = Experiment(['binoct3'])
# # # parsers = {}
# # # for s in e.all_methods:
# # # parsers[s] = CplexParser()
# # #
# # # o = Observation(e, parsers)
# # #
# # # print o.data
# # #
# # # sys.exit(1)
# #
# #
# p = ITIParser();
#
# outp = open('results/itiexp_76.out', 'r').readlines()
#
# # print outp
#
# res = p(outp)
#
# print res
#
# sys.exit(1)
# #