abstract loop body into Runner class
This commit is contained in:
parent
3c7b41b562
commit
953f522360
2 changed files with 86 additions and 50 deletions
|
@ -153,6 +153,73 @@ for problem_list in GO_BENCHMARKS.values():
|
||||||
), "please use Infinity instead; it's basically equivalent"
|
), "please use Infinity instead; it's basically equivalent"
|
||||||
|
|
||||||
|
|
||||||
|
class Runner:
|
||||||
|
def __init__(self, multiple=2, run_anyway=3, always_run_anyway=True, quiet=False):
|
||||||
|
self.multiple = multiple
|
||||||
|
self.run_anyway = run_anyway
|
||||||
|
self.always_run_anyway = always_run_anyway
|
||||||
|
self.quiet = quiet
|
||||||
|
self._wrapped = None
|
||||||
|
|
||||||
|
def run(
|
||||||
|
self, optimizer, objective, size, budget, frugal_percent=1.0, greedy_percent=2.0
|
||||||
|
):
|
||||||
|
note = (lambda s: None) if self.quiet else m36
|
||||||
|
warn = m33
|
||||||
|
|
||||||
|
opt_name = optimizer.__name__
|
||||||
|
obj_name = objective.__name__
|
||||||
|
obj_realname = getattr(objective, "__realname__", obj_name)
|
||||||
|
|
||||||
|
wrapped_kwargs = dict(
|
||||||
|
objective=objective,
|
||||||
|
optimizer=optimizer,
|
||||||
|
budget=budget,
|
||||||
|
size=size,
|
||||||
|
frugal_percent=frugal_percent,
|
||||||
|
greedy_percent=greedy_percent,
|
||||||
|
)
|
||||||
|
if self._wrapped is None:
|
||||||
|
wrapped = COWrap(**wrapped_kwargs)
|
||||||
|
else:
|
||||||
|
# this can be 10+ times faster.
|
||||||
|
wrapped = self._wrapped.attempt_reuse(**wrapped_kwargs)
|
||||||
|
self._wrapped = wrapped
|
||||||
|
|
||||||
|
results = []
|
||||||
|
|
||||||
|
run = 1
|
||||||
|
while (cache := wrapped.cached(run)) is not None:
|
||||||
|
run += 1
|
||||||
|
fopt, xopt, history = cache
|
||||||
|
results.append((fopt, opt_name, history))
|
||||||
|
|
||||||
|
once = False
|
||||||
|
while (
|
||||||
|
run <= self.multiple
|
||||||
|
or (self.always_run_anyway or not once)
|
||||||
|
and self.run_anyway
|
||||||
|
and run <= self.run_anyway
|
||||||
|
):
|
||||||
|
# assert run == wrapped._run, (run, wrapped._run)
|
||||||
|
if run != (_run := wrapped._run):
|
||||||
|
warn(f"Note: updating local run count from {run} to {_run}.")
|
||||||
|
run = _run
|
||||||
|
continue # check conditions again
|
||||||
|
|
||||||
|
note(
|
||||||
|
f"Using {opt_name} to optimize {obj_realname} ({obj_name}) [{run}] ..."
|
||||||
|
)
|
||||||
|
_ = optimizer(wrapped, size=size, budget=budget)
|
||||||
|
fopt, xopt = wrapped.finish()
|
||||||
|
result = (fopt, opt_name, wrapped.history)
|
||||||
|
results.append(result)
|
||||||
|
once = True
|
||||||
|
run += 1
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
def main(argv, display=True):
|
def main(argv, display=True):
|
||||||
from .utilities import fib
|
from .utilities import fib
|
||||||
from .utilities import prune_results, perform_another_experimental_scoring_method
|
from .utilities import prune_results, perform_another_experimental_scoring_method
|
||||||
|
@ -199,7 +266,7 @@ def main(argv, display=True):
|
||||||
if type(score) is float:
|
if type(score) is float:
|
||||||
assert type(price) is float, "type mismatch"
|
assert type(price) is float, "type mismatch"
|
||||||
# unweight = 10 # len(optimizers) # sum(place_scores)
|
# unweight = 10 # len(optimizers) # sum(place_scores)
|
||||||
unweight = multiple * np.sqrt(len(optimizers))
|
unweight = runner.multiple * np.sqrt(len(optimizers))
|
||||||
stats = f"(score:{score * unweight:4.0f}, price:{price * unweight:4.0f})"
|
stats = f"(score:{score * unweight:4.0f}, price:{price * unweight:4.0f})"
|
||||||
else:
|
else:
|
||||||
stats = f"(score:{score:4}, price:{price:4})"
|
stats = f"(score:{score:4}, price:{price:4})"
|
||||||
|
@ -253,9 +320,7 @@ def main(argv, display=True):
|
||||||
old_summary = True
|
old_summary = True
|
||||||
note = (lambda s: None) if quieter else m36
|
note = (lambda s: None) if quieter else m36
|
||||||
|
|
||||||
multiple = 2
|
runner = Runner()
|
||||||
run_anyway = 3
|
|
||||||
always_run_anyway = True
|
|
||||||
|
|
||||||
percents = dict(frugal_percent=1.0, greedy_percent=2.0)
|
percents = dict(frugal_percent=1.0, greedy_percent=2.0)
|
||||||
|
|
||||||
|
@ -270,7 +335,11 @@ def main(argv, display=True):
|
||||||
size = abs(size)
|
size = abs(size)
|
||||||
objectives = GO_BENCHMARKS[size] # * multiple
|
objectives = GO_BENCHMARKS[size] # * multiple
|
||||||
optimizers = list(which) # copy
|
optimizers = list(which) # copy
|
||||||
ms = f" ({multiple}+{run_anyway-multiple} times)" if multiple != 1 else ""
|
ms = (
|
||||||
|
f" ({runner.multiple}+{runner.run_anyway - runner.multiple} times)"
|
||||||
|
if runner.multiple != 1
|
||||||
|
else ""
|
||||||
|
)
|
||||||
n_obj = len(objectives)
|
n_obj = len(objectives)
|
||||||
n_opt = len(optimizers)
|
n_opt = len(optimizers)
|
||||||
print(f"Optimizing {n_obj} objectives{ms} with {n_opt} optimizers...")
|
print(f"Optimizing {n_obj} objectives{ms} with {n_opt} optimizers...")
|
||||||
|
@ -281,54 +350,12 @@ def main(argv, display=True):
|
||||||
|
|
||||||
results = {}
|
results = {}
|
||||||
for optimizer in prog(pseudo_shuffled(optimizers), pref="m"):
|
for optimizer in prog(pseudo_shuffled(optimizers), pref="m"):
|
||||||
opt_name = optimizer.__name__
|
|
||||||
wrapped = None
|
|
||||||
for objective in prog(pseudo_shuffled(objectives), pref="s"):
|
for objective in prog(pseudo_shuffled(objectives), pref="s"):
|
||||||
obj_name = objective.__name__
|
new_results = runner.run(optimizer, objective, size, budget)
|
||||||
obj_realname = getattr(objective, "__realname__", obj_name)
|
results.setdefault(objective.__name__, []).extend(new_results)
|
||||||
|
|
||||||
if wrapped is None:
|
|
||||||
wrapped = COWrap(
|
|
||||||
objective,
|
|
||||||
optimizer=optimizer,
|
|
||||||
budget=budget,
|
|
||||||
size=size,
|
|
||||||
**percents,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
wrapped.objective = objective # 10+ times faster
|
|
||||||
|
|
||||||
run = 1
|
|
||||||
while (cache := wrapped.cached(run)) is not None:
|
|
||||||
run += 1
|
|
||||||
fopt, xopt, history = cache
|
|
||||||
results.setdefault(obj_name, []).append((fopt, opt_name, history))
|
|
||||||
|
|
||||||
once = False
|
|
||||||
while (
|
|
||||||
run <= multiple
|
|
||||||
or (always_run_anyway or not once)
|
|
||||||
and run_anyway
|
|
||||||
and run <= run_anyway
|
|
||||||
):
|
|
||||||
# assert run == wrapped._run, (run, wrapped._run)
|
|
||||||
if run != (_run := wrapped._run):
|
|
||||||
m33(f"Note: updating local run count from {run} to {_run}.")
|
|
||||||
run = _run
|
|
||||||
continue # check conditions again
|
|
||||||
|
|
||||||
note(
|
|
||||||
f"Using {opt_name} to optimize {obj_realname} ({obj_name}) [{run}] ..."
|
|
||||||
)
|
|
||||||
_ = optimizer(wrapped, size=size, budget=budget)
|
|
||||||
fopt, xopt = wrapped.finish()
|
|
||||||
result = (fopt, opt_name, wrapped.history)
|
|
||||||
results.setdefault(obj_name, []).append(result)
|
|
||||||
once = True
|
|
||||||
run += 1
|
|
||||||
|
|
||||||
all_results = results
|
all_results = results
|
||||||
results = prune_results(results, multiple, _check=old_summary)
|
results = prune_results(results, runner.multiple, _check=old_summary)
|
||||||
|
|
||||||
scores, prices = {}, {}
|
scores, prices = {}, {}
|
||||||
all_opt_names = set()
|
all_opt_names = set()
|
||||||
|
|
|
@ -162,6 +162,15 @@ class COWrap:
|
||||||
self._cached_summaries = None
|
self._cached_summaries = None
|
||||||
self.reset_objective()
|
self.reset_objective()
|
||||||
|
|
||||||
|
# this should always have the same arguments as __init__.
|
||||||
|
def attempt_reuse(self, objective, *, optimizer, size, budget, **kwargs):
|
||||||
|
if self.optimizer != optimizer or self.size != size or self.budget != budget:
|
||||||
|
return type(self)(
|
||||||
|
objective, optimizer=optimizer, size=size, budget=budget, **kwargs
|
||||||
|
)
|
||||||
|
self.objective = objective
|
||||||
|
return self
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return (
|
return (
|
||||||
"<COWrap on "
|
"<COWrap on "
|
||||||
|
|
Loading…
Add table
Reference in a new issue