Makrus hat nen kleinen Pimmel

This commit is contained in:
Kai Koellemann
2023-07-16 20:00:15 +02:00
parent eaf2e7e111
commit 0fd332a6e5
3 changed files with 99 additions and 42 deletions

View File

@ -2,9 +2,11 @@ from __future__ import annotations
from dataclasses import dataclass
from enum import Enum
from random import choice, random
import networkx as nx
from random import choice
import numpy as np
from graphs import creates_cycle
rng = np.random.default_rng()
class NodeType(Enum):
INPUT = 1
@ -90,8 +92,8 @@ class Genome:
def mutate(genome: Genome) -> None:
mutation = choice([MutationType.ADD_CONNECTION])
mutation = choice([MutationType.ADD_NODE, MutationType.ADD_CONNECTION])
print(mutation)
if mutation is MutationType.ADD_CONNECTION:
_mutate_add_connection(genome)
elif mutation is MutationType.ADD_NODE:
@ -104,22 +106,18 @@ def _mutate_add_connection(genome: Genome) -> None:
is added connecting two previously unconnected nodes.
"""
from_node = choice([node for node in genome.nodes if not node.type != NodeType.OUTPUT])
from_node = choice([node for node in genome.nodes.values() if not node.type != NodeType.OUTPUT])
to_node = choice([node for node in genome.nodes.values() if node.type != NodeType.INPUT])
inputs = [node.id for node in genome.nodes.values() if node.type == NodeType.INPUT]
distance_to_input = _distance_to_input(genome, from_node, inputs)
to_node = choice([node for node in genome.nodes if _distance_to_input(genome, node, inputs) < distance_to_input and tuple[from_node, node] not in genome.connections])
# Checking if connection already exists
if (from_node, to_node) in genome.connections:
return
genome.add_connection(from_node, to_node, weight=random.uniform(0,1))
# Checking for cycles
if creates_cycle(genome.connections.keys(), (from_node.id, to_node.id)):
return
def _distance_to_input(g: Genome, node, inputs) -> int:
paths = []
for input_node in inputs:
paths += list(nx.all_simple_paths(g, input_node, node))
path_lengths = [len(path) for path in paths]
return max(path_lengths)
genome.add_connection(from_node, to_node, weight=rng.uniform(0,1))
def _mutate_add_node(genome: Genome) -> None:

View File

@ -0,0 +1,28 @@
def creates_cycle(connections: list[tuple[int, int]], test: tuple[int, int]) -> bool:
"""
Returns true if the addition of the 'test' connection would create a cycle,
assuming that no cycle already exists in the graph represented by 'connections'.
https://github.com/CodeReclaimers/neat-python/blob/4928381317213ee3285204ae1f2a086286aa3a10/neat/graphs.py#L4
"""
i, o = test
if i == o:
return True
visited = {o}
while True:
num_added = 0
for a, b in connections:
if a in visited and b not in visited:
if b == i:
return True
visited.add(b)
num_added += 1
if num_added == 0:
return False

File diff suppressed because one or more lines are too long