Makrus hat nen kleinen Pimmel
This commit is contained in:
@ -2,9 +2,11 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from random import choice, random
|
from random import choice
|
||||||
import networkx as nx
|
import numpy as np
|
||||||
|
from graphs import creates_cycle
|
||||||
|
|
||||||
|
rng = np.random.default_rng()
|
||||||
|
|
||||||
class NodeType(Enum):
|
class NodeType(Enum):
|
||||||
INPUT = 1
|
INPUT = 1
|
||||||
@ -90,8 +92,8 @@ class Genome:
|
|||||||
|
|
||||||
|
|
||||||
def mutate(genome: Genome) -> None:
|
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:
|
if mutation is MutationType.ADD_CONNECTION:
|
||||||
_mutate_add_connection(genome)
|
_mutate_add_connection(genome)
|
||||||
elif mutation is MutationType.ADD_NODE:
|
elif mutation is MutationType.ADD_NODE:
|
||||||
@ -104,22 +106,18 @@ def _mutate_add_connection(genome: Genome) -> None:
|
|||||||
is added connecting two previously unconnected nodes.
|
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]
|
# Checking if connection already exists
|
||||||
distance_to_input = _distance_to_input(genome, from_node, inputs)
|
if (from_node, to_node) in genome.connections:
|
||||||
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])
|
return
|
||||||
|
|
||||||
|
# Checking for cycles
|
||||||
|
if creates_cycle(genome.connections.keys(), (from_node.id, to_node.id)):
|
||||||
|
return
|
||||||
|
|
||||||
genome.add_connection(from_node, to_node, weight=random.uniform(0,1))
|
genome.add_connection(from_node, to_node, weight=rng.uniform(0,1))
|
||||||
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
def _mutate_add_node(genome: Genome) -> None:
|
def _mutate_add_node(genome: Genome) -> None:
|
||||||
|
|||||||
28
Abschlussprojekt/graphs.py
Normal file
28
Abschlussprojekt/graphs.py
Normal 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
Reference in New Issue
Block a user