import json import random import math from typing import List, Dict, Tuple # ---- Hilfsfunktionen ---- def generate_id(): """Generiert eine eindeutige ID basierend auf Zufallszahlen.""" return random.random() def create_neural_weights(vector_length: int): """Erstellt eine Liste von Gewichten für eine Verbindung.""" return [random.uniform(-0.5, 0.5) for _ in range(vector_length)] # ---- Klassen ---- class Sensor: def __init__(self, name: str, vector_length: int): self.id = generate_id() self.name = name self.vector_length = vector_length self.cx_id = None # Wird später hinzugefügt self.fanout_ids = [] # Verbindungen zu Neuronen def to_dict(self): return { "id": self.id, "name": self.name, "vector_length": self.vector_length, "cx_id": self.cx_id, "fanout_ids": self.fanout_ids, } class Actuator: def __init__(self, name: str, vector_length: int): self.id = generate_id() self.name = name self.vector_length = vector_length self.cx_id = None # Wird später hinzugefügt self.fanin_ids = [] # Verbindungen von Neuronen def to_dict(self): return { "id": self.id, "name": self.name, "vector_length": self.vector_length, "cx_id": self.cx_id, "fanin_ids": self.fanin_ids, } class Neuron: def __init__(self, layer_index: int, input_ids: List[Tuple[float, int]], output_ids: List[float], cx_id: float): self.id = generate_id() self.layer_index = layer_index self.cx_id = cx_id self.activation_function = "tanh" self.input_weights = [ {"input_id": input_id, "weights": create_neural_weights(vector_length)} for input_id, vector_length in input_ids ] self.output_ids = output_ids def to_dict(self): return { "id": self.id, "layer_index": self.layer_index, "cx_id": self.cx_id, "activation_function": self.activation_function, "input_weights": self.input_weights, "output_ids": self.output_ids, } class Cortex: def __init__(self, sensor_ids: List[float], actuator_ids: List[float], neuron_ids: List[float]): self.id = generate_id() self.sensor_ids = sensor_ids self.actuator_ids = actuator_ids self.neuron_ids = neuron_ids def to_dict(self): return { "id": self.id, "sensor_ids": self.sensor_ids, "actuator_ids": self.actuator_ids, "neuron_ids": self.neuron_ids, } # ---- Hauptfunktionen ---- def construct_genotype(sensor_name: str, actuator_name: str, hidden_layer_densities: List[int], file_name: str): """ Konstruktion eines Genotyps und Speicherung in einer JSON-Datei. """ # Sensor erstellen if sensor_name == "rng": sensor = Sensor(name="rng", vector_length=2) else: raise ValueError(f"System does not support a sensor by the name: {sensor_name}") # Aktuator erstellen if actuator_name == "pts": actuator = Actuator(name="pts", vector_length=1) else: raise ValueError(f"System does not support an actuator by the name: {actuator_name}") # Neuronenschichten erstellen output_layer_density = actuator.vector_length layer_densities = hidden_layer_densities + [output_layer_density] cortex_id = generate_id() neurons = create_neuro_layers( cortex_id, sensor, actuator, layer_densities ) # Sensor und Aktuator mit Cortex-Informationen aktualisieren input_layer_neurons = neurons[0] output_layer_neurons = neurons[-1] sensor.cx_id = cortex_id sensor.fanout_ids = [neuron.id for neuron in input_layer_neurons] actuator.cx_id = cortex_id actuator.fanin_ids = [neuron.id for neuron in output_layer_neurons] # Cortex erstellen neuron_ids = [neuron.id for layer in neurons for neuron in layer] cortex = Cortex( sensor_ids=[sensor.id], actuator_ids=[actuator.id], neuron_ids=neuron_ids ) # Genotyp erstellen genotype = { "cortex": cortex.to_dict(), "sensor": sensor.to_dict(), "actuator": actuator.to_dict(), "neurons": [neuron.to_dict() for layer in neurons for neuron in layer] } # Genotyp in Datei speichern with open(file_name, "w") as file: json.dump(genotype, file, indent=4) print(f"Genotype saved to {file_name}") def create_neuro_layers(cortex_id: float, sensor: Sensor, actuator: Actuator, layer_densities: List[int]) -> List[ List[Neuron]]: """ Erstellt alle Neuronen in allen Schichten des Netzwerks. """ neurons = [] input_ids = [(sensor.id, sensor.vector_length)] for layer_index, layer_density in enumerate(layer_densities): output_ids = [] if layer_index < len(layer_densities) - 1: # IDs der nächsten Schicht generieren output_ids = [generate_id() for _ in range(layer_densities[layer_index + 1])] # Neuronen für die aktuelle Schicht erstellen layer_neurons = [ Neuron(layer_index=layer_index, input_ids=input_ids, output_ids=output_ids, cx_id=cortex_id) for _ in range(layer_density) ] neurons.append(layer_neurons) # Aktuelle Schicht wird die Eingabe für die nächste Schicht input_ids = [(neuron.id, 1) for neuron in layer_neurons] # Letzte Schicht mit Verbindung zum Aktuator erstellen final_layer = neurons[-1] for neuron in final_layer: neuron.output_ids = [actuator.id] return neurons # ---- Beispielverwendung ---- if __name__ == "__main__": # Genotyp erstellen und speichern construct_genotype( sensor_name="rng", actuator_name="pts", hidden_layer_densities=[4,3], # Dichten der versteckten Schichten (z. B. 4 Neuronen in der ersten Schicht, 3 in der zweiten) file_name="genotype.json" # Name der Datei, in der der Genotyp gespeichert wird )