// Sc = type of scores (e.g. Double) sclass TunableParameters> { replace Scrd with GenericallyScored. settable IF1 scoreFunction; gettable Scrd best; new LinkedHashMap parameters; abstract class Parameter { settable S name; settable A defaultValue; abstract A randomValue(); } class IntRangeParameter extends Parameter { settable IntRange range; Int randomValue() { ret random(range); } } class DoubleRangeParameter extends Parameter { settable DoubleRange range; Double randomValue() { ret random(range); } } selfType add(Parameter p) { parameters.put(p.name(), p); this; } MapSO randomInstance() { MapSO map = new LinkedHashMap; for (param : values(parameters)) map.put(param.name(), param.randomValue()); ret map; } Scrd tryARandomCombination() { MapSO instance = randomInstance(); var scored = new GenericallyScored<>(instance, score(instance)); saveInstance(scored); ret scored; } Sc score(MapSO instance) { ret scoreFunction.get(instance); } void saveInstance(Scrd scored) { if (scored == null) ret; if (best == null || cmp(scored.score(), best.score()) > 0) best = scored; } toString { ret "Best: " + best + " (parameters: " + keys(parameters) + ")"; } }