-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathevaluators.py
85 lines (68 loc) · 2.68 KB
/
evaluators.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import numpy as np
from abc import abstractmethod
class Evaluator:
"""
Abstract class for evaluators.
This class also mantains the registry for the evaluators.
"""
registry = {}
def __init_subclass__(cls, **kwargs):
"""When initializing a subclass, add it to the registry."""
Evaluator.registry[cls.__name__] = cls
@classmethod
def get_class(cls, name):
return Evaluator.registry[name]
def __call__(self, program):
"""Evaluate the program and return its loss."""
return self.evaluate(program)
def evaluate(self, program):
"""Evaluate the program and return its loss."""
try:
print(f"Testing {program}")
exec(program, globals(), locals())
heuristic = locals()['solution']
return self._execute_and_return_loss(heuristic)
except:
# Malformed solution
return float("inf")
@abstractmethod
def _execute_and_return_loss(self, heuristic):
pass
class OneMaxEvaluator(Evaluator):
"""
Trivial problem, just for testing.
The goal of this problem is to maximize the number of ones in an array.
"""
def __init__(self, dim):
self._dim = dim
def _execute_and_return_loss(self, heuristic):
cur_solution = []
for _ in range(self._dim):
# Evaluate the possible choices at each step and choose greedily
choices = [0, 1]
scores = []
for choice in choices:
scores.append(heuristic(cur_solution + [choice]))
best = np.argmax(scores)
cur_solution.append(choices[best])
# The goal of this problem is to maximize the number of ones, but we're minimizing, so I return the opposite
return -sum(cur_solution)
class OddMaxEvaluator(Evaluator):
"""
Trivial problem, just for testing.
The goal of this problem is to maximize the number of ones in the odd positions of an array, while minimizing the number of ones in the even positions.
"""
def __init__(self, dim):
self._dim = dim
def _execute_and_return_loss(self, heuristic):
cur_solution = []
for _ in range(self._dim):
# Evaluate the possible choices at each step and choose greedily
choices = [0, 1]
scores = []
for choice in choices:
scores.append(heuristic(cur_solution + [choice]))
best = np.argmax(scores)
cur_solution.append(choices[best])
# The goal of this problem is to maximize the number of ones, but we're minimizing, so I return the opposite
return -sum(cur_solution[1::2]) + sum(cur_solution[::2])