private Evolver() { var parameters = new RandomParameters( new EdgeParameters(new Parameter(-1, 1, .005)), new NodeParameters( new Parameter(-1, 1, .005), new FunctionParameters(.005, new Parameter(-1, 1, .005)) ) ); Func <Network, double> fitnessFunction = network => { return(-Enumerable.Range(-5, 11).Select(i => (Math.Abs(network.Evaluate(new double[] { i })[0] - Math.Abs(i)))) .Sum()); }; var random = new Random(); var evolution = new Evolution(random, parameters, fitnessFunction) { Size = Size = new Size(700, 600), Anchor = AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom | AnchorStyles.Left }; Controls.Add(evolution); var layerSizes = new int[] { 1, 1, 1 }; evolution.SetNetworks(Enumerable.Range(0, 16).Select(i => CreateLayered(random, parameters, layerSizes)) .ToList()); evolution.Start(); }
public Evolution(Random randomGenerator, RandomParameters parameters, Func <Network, double> fitnessFunction) { SetStyle(ControlStyles.DoubleBuffer, true); _randomGenerator = randomGenerator; _parameters = parameters; _fitnessFunction = fitnessFunction; Controls.Add(interfaceContainer = new FlowLayoutPanel() { Anchor = AnchorStyles.Bottom | AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right }); interfaceContainer.FlowDirection = FlowDirection.TopDown; interfaceContainer.Controls.Add(_iterationLabel = new Label()); interfaceContainer.Controls.Add(_fitnessLabel = new Label()); interfaceContainer.Controls.Add(_outputLabel = new Label() { AutoSize = true, Font = new Font(FontFamily.GenericMonospace, 8) }); interfaceContainer.Controls.Add(_networkLabel = new Label() { AutoSize = true, Font = new Font(FontFamily.GenericMonospace, 8) }); }
private static Network CreateLayered(Random random, RandomParameters randomParameters, IList <int> layerSizes) { var result = new Network(); var layers = layerSizes.Count; var innovationNumber = 0; var layerNodes = Enumerable.Range(0, layers) .Select(i => Enumerable.Range(0, layerSizes[i]) .Select(a => result.AddNode(new Node(innovationNumber++, randomParameters.Node.Bias.GetNew(random)))) .ToArray()) .ToArray(); layerNodes[layers - 1].ToList() .ForEach(node => node.ActivationFunction = new ActivationFunctions.LeakyRelu(1, 1)); result.InNodes = layerNodes[0]; result.OutNodes = layerNodes[layers - 1]; Enumerable.Range(0, layers - 1).ToList() .ForEach(i => layerNodes[i + 1].ToList() .ForEach(outNode => layerNodes[i].ToList() .ForEach(inNode => result.AddEdge( new Edge(innovationNumber++, randomParameters.Edge.Weight.GetNew(random), inNode, outNode) )))); return(result); }
public void Mutate(Random random, Func <long> innovationNumberGenerator, RandomParameters parameters) { _nodes.Values.ToList().ForEach(node => { node.Mutate(random, parameters.Node); if (random.NextDouble() < parameters.Node.RemoveRate) { _nodes.Remove(node.InnovationNumber); return; } // TODO: Add S new edges (in which S follows a binomial distribution with parameters n = _nodes.Count * _nodes.Count and p = parameters.Edge.AddRate; }); _edges.Values.ToList().ForEach(edge => { edge.Mutate(random, parameters.Edge); if (random.NextDouble() < parameters.Edge.RemoveRate || !_nodes.ContainsKey(edge.InNode.InnovationNumber) || !_nodes.ContainsKey(edge.OutNode.InnovationNumber)) { _edges.Remove(edge.InnovationNumber); return; } if (random.NextDouble() < parameters.Node.AddRate) { Func <Random, double> newWeight = parameters.Edge.Weight.GetNew; Func <Random, double> newBias = parameters.Node.Bias.GetNew; edge.OutNode.IncomingEdges.Remove(edge); _edges.Remove(edge.InnovationNumber); var newNode = AddNode(new Node(innovationNumberGenerator(), newBias(random))); AddEdge(new Edge(innovationNumberGenerator(), newWeight(random), edge.InNode, newNode)); AddEdge(new Edge(innovationNumberGenerator(), newWeight(random), newNode, edge.OutNode)); } }); }