-
Notifications
You must be signed in to change notification settings - Fork 0
/
brains.py
51 lines (35 loc) · 1.52 KB
/
brains.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
import random
import numpy as np
from utils import logistic
from tree import Tree, TreeBrain, TreeNode
class NoBrain(TreeBrain):
def __init__(self):
self.happy = True
def describe(self):
return 'NoBrain(olEeoleoleoleeee)'
def mutate(self, lr: float = 0.01) -> 'TreeBrain':
return NoBrain()
def wants_to_grow(self, here: TreeNode) -> float:
return random.random()
def angle(self, here: TreeNode) -> int:
angle = np.random.randint(0, TreeNode.angles)
return angle
def ratio(self, here: TreeNode) -> float:
return random.random()
class SimpleBrain(TreeBrain):
def __init__(self, weights: np.ndarray = None):
self.happy = True
self.weights = np.zeros((TreeNode.features_shape + 2, 3)) if weights is None else weights
def feed_features(self, x: np.ndarray, row: int):
return logistic(self.weights[-1, row] * np.dot(x, self.weights[:-2, row]) + self.weights[-2, row])
def describe(self):
return f'SimpleBrain({self.weights.shape})'
def wants_to_grow(self, here: TreeNode) -> float:
return self.feed_features(here.features(), 0)
def angle(self, here: TreeNode) -> int:
return int((TreeNode.angles - 1) * self.feed_features(here.features(), 1))
def ratio(self, here: TreeNode) -> float:
return self.feed_features(here.features(), 2)
def mutate(self, lr: float = 0.01):
weights = self.weights + (np.random.random(self.weights.shape) - 0.5) * lr
return SimpleBrain(weights)