-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpoints.py
More file actions
80 lines (67 loc) · 2.53 KB
/
points.py
File metadata and controls
80 lines (67 loc) · 2.53 KB
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
import numpy as np
from PIL import Image, ImageDraw
class Points:
def __init__(
self, rs: np.ndarray = None, thetas: np.ndarray = None, num_points: int = 23
):
self.num_points = num_points
if rs is None:
self.rs = np.random.uniform(0.0, 1.0, self.num_points)
else:
self.rs = rs
if thetas is None:
self.thetas = np.sort(np.random.uniform(0.0, 2 * np.pi, self.num_points))
else:
self.thetas = thetas
self._sort()
def mutate(self, mutation_rate: float = 0.1):
for i in range(self.num_points):
if np.random.rand() < mutation_rate:
self.rs[i] = np.random.uniform(0.0, 1.0)
if np.random.rand() < mutation_rate:
self.thetas[i] = np.random.uniform(0.0, 2 * np.pi)
# 角度でソート
self._sort()
def to_image(self, image_size: int = 256) -> Image.Image:
"""256x256の画像として可視化する関数."""
img = Image.new("L", (image_size, image_size), 255)
draw = ImageDraw.Draw(img)
center = image_size // 2
# 点が存在しうる範囲を白色の円で描画
draw.ellipse(
(
center - (image_size // 2),
center - (image_size // 2),
center + (image_size // 2),
center + (image_size // 2),
),
outline=0,
)
for r, theta in zip(self.rs, self.thetas):
x = center + r * (image_size // 2) * np.cos(theta)
y = center + r * (image_size // 2) * np.sin(theta)
draw.ellipse((x - 2, y - 2, x + 2, y + 2), fill=0)
return img
def _sort(self):
indices = np.argsort(self.thetas)
self.rs = self.rs[indices]
self.thetas = self.thetas[indices]
def crossover(points1: Points, points2: Points) -> Points:
"""GAにおける交叉操作を行う関数."""
num_points = points1.num_points
crossover_point = np.random.randint(5, num_points - 6)
new_rs = np.concatenate(
(points1.rs[:crossover_point], points2.rs[crossover_point:])
)
new_thetas = np.concatenate(
(points1.thetas[:crossover_point], points2.thetas[crossover_point:])
)
new_points = Points(rs=new_rs, thetas=new_thetas)
return new_points
if __name__ == "__main__":
p1 = Points()
p2 = Points()
p1.to_image().save("points1.png")
p2.to_image().save("points2.png")
child = crossover(p1, p2)
child.to_image().save("child.png")