Makrus hat nen kleinen Pimmel
This commit is contained in:
@ -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
|
||||
|
||||
# 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))
|
||||
|
||||
|
||||
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:
|
||||
|
||||
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