public NeuronBackPointer(INeuron neuron, INeuronContainer container, NeuralLink[] links) { this.Neuron = neuron; this.Container = container; this.Links = links; }
private static NeuralLink[][] BuildExternalLinksExisting(ContainerInput[] containers, int maxIntermediateLinks, int maxFinalLinks) { NeuralLink[][] retVal = new NeuralLink[containers.Length][]; // Figure out which containers (parts) are closest to the containers[].ExternalLinks[].FromContainerPosition var partBreakdown = BuildExternalLinksExisting_ContainerPoints(containers, maxIntermediateLinks); // This gets added to as needed (avoids recalculating best matching neurons by position) Dictionary<ContainerInput, ContainerPoints> nearestNeurons = new Dictionary<ContainerInput, ContainerPoints>(); for (int cntr = 0; cntr < containers.Length; cntr++) { ContainerInput container = containers[cntr]; if (container.ExternalLinks == null || container.ExternalLinks.Length == 0) { // There are no existing external links retVal[cntr] = null; continue; } List<NeuralLink> containerLinks = new List<NeuralLink>(); // The external links are from shifting from containers, but the to container is always known (this container), so the to container // is always an array of one ClosestExistingResult[] toPart = new ClosestExistingResult[] { new ClosestExistingResult(true, cntr, 1d) }; // Link part to part foreach (var exist in container.ExternalLinks) { // Figure out which parts to draw from HighestPercentResult[] partLinks = GetHighestPercent(partBreakdown[exist.FromContainerPosition], toPart, maxIntermediateLinks, true); // Get links between neurons in between the matching parts containerLinks.AddRange(BuildExternalLinksExisting_AcrossParts(exist, partLinks, containers, nearestNeurons, maxIntermediateLinks, maxFinalLinks)); } // Prune containerLinks = BuildExternalLinksExisting_Prune(containerLinks, containers, container); retVal[cntr] = containerLinks.ToArray(); } // Exit Function return retVal; }
private static NeuralLink[][] CapWeights(NeuralLink[][] links, double maxWeight) { if (links == null) { return null; } NeuralLink[][] retVal = new NeuralLink[links.Length][]; for (int outer = 0; outer < links.Length; outer++) { if (links[outer] == null) { retVal[outer] = null; continue; } retVal[outer] = links[outer].Select(o => new NeuralLink(o.FromContainer, o.ToContainer, o.From, o.To, CapWeights_Weight(o.Weight, maxWeight), o.BrainChemicalModifiers == null ? null : o.BrainChemicalModifiers.Select(p => CapWeights_Weight(p, maxWeight)).ToArray())).ToArray(); } return retVal; }
/// <summary> /// This builds links between neurons across containers /// </summary> private static NeuralLink[][] BuildExternalLinksRandom(ContainerInput[] containers, double maxWeight) { NeuralLink[][] retVal = new NeuralLink[containers.Length][]; // Pull out the readable nodes from each container List<INeuron>[] readable = BuildExternalLinksRandom_FindReadable(containers); // Shoot through each container, and create links that feed it for (int cntr = 0; cntr < containers.Length; cntr++) { ContainerInput container = containers[cntr]; if (container.ExternalRatios == null || container.ExternalRatios.Length == 0) { // This container shouldn't be fed by other containers (it's probably a sensor) retVal[cntr] = null; continue; } // Find writable nodes List<INeuron> writeable = new List<INeuron>(); writeable.AddRange(container.Container.Neruons_ReadWrite); writeable.AddRange(container.Container.Neruons_Writeonly); if (writeable.Count == 0) { // There are no nodes that can be written retVal[cntr] = null; continue; } List<NeuralLink> links = new List<NeuralLink>(); foreach (var ratio in container.ExternalRatios) { // Link to this container type links.AddRange(BuildExternalLinksRandom_Continue(containers, cntr, ratio, readable, writeable, maxWeight)); } // Add links to the return jagged array if (links.Count == 0) { retVal[cntr] = null; } else { retVal[cntr] = links.ToArray(); } } // Exit Function return retVal; }
/// <summary> /// This builds links between neurons that are all in the same container, based on exising links /// </summary> private static NeuralLink[][] BuildInternalLinksExisting(ContainerInput[] containers, int maxIntermediateLinks, int maxFinalLinks) { NeuralLink[][] retVal = new NeuralLink[containers.Length][]; for (int cntr = 0; cntr < containers.Length; cntr++) { ContainerInput container = containers[cntr]; if (container.InternalLinks == null || container.InternalLinks.Length == 0) { // There are no existing internal links retVal[cntr] = null; continue; } //TODO: May want to use readable/writable instead of all (doing this first because it's easier). Also, the ratios are good suggestions //for creating a good random brain, but from there, maybe the rules should be relaxed? INeuron[] allNeurons = container.Container.Neruons_All.ToArray(); int count = Convert.ToInt32(Math.Round(container.InternalRatio.Value * allNeurons.Length)); if (count == 0) { retVal[cntr] = null; continue; } // All the real work is done in this method LinkIndexed[] links = BuildInternalLinksExisting_Continue(allNeurons, count, container.InternalLinks, container.BrainChemicalCount, maxIntermediateLinks, maxFinalLinks); // Exit Function retVal[cntr] = links.Select(o => new NeuralLink(container.Container, container.Container, allNeurons[o.From], allNeurons[o.To], o.Weight, o.BrainChemicalModifiers)).ToArray(); } // Exit Function return retVal; }
/// <summary> /// This builds random links between neurons that are all in the same container /// </summary> private static NeuralLink[][] BuildInternalLinksRandom(ContainerInput[] containers, double maxWeight) { NeuralLink[][] retVal = new NeuralLink[containers.Length][]; for (int cntr = 0; cntr < containers.Length; cntr++) { ContainerInput container = containers[cntr]; if (container.InternalRatio == null) { // If ratio is null, that means to not build any links retVal[cntr] = null; continue; } #region Separate into buckets // Separate into readable and writeable buckets List<INeuron> readable = new List<INeuron>(); readable.AddRange(container.Container.Neruons_Readonly); int[] readonlyIndices = Enumerable.Range(0, readable.Count).ToArray(); List<INeuron> writeable = new List<INeuron>(); writeable.AddRange(container.Container.Neruons_Writeonly); int[] writeonlyIndices = Enumerable.Range(0, writeable.Count).ToArray(); SortedList<int, int> readwritePairs = new SortedList<int, int>(); // storing illegal pairs so that neurons can't link to themselves (I don't know if they can in real life. That's a tough term to search for, google gave far too generic answers) foreach (INeuron neuron in container.Container.Neruons_ReadWrite) { readwritePairs.Add(readable.Count, writeable.Count); readable.Add(neuron); writeable.Add(neuron); } #endregion // Figure out how many to make int smallerNeuronCount = Math.Min(readable.Count, writeable.Count); int count = Convert.ToInt32(Math.Round(container.InternalRatio.Value * smallerNeuronCount)); if (count == 0) { // There are no links to create retVal[cntr] = null; } // Create Random LinkIndexed[] links = GetRandomLinks(readable.Count, writeable.Count, count, readonlyIndices, writeonlyIndices, readwritePairs, maxWeight). // get links Select(o => new LinkIndexed(o.Item1, o.Item2, o.Item3, GetBrainChemicalModifiers(container, maxWeight))). // tack on the brain chemical receptors ToArray(); // Exit Function retVal[cntr] = links. Select(o => new NeuralLink(container.Container, container.Container, readable[o.From], writeable[o.To], o.Weight, o.BrainChemicalModifiers)). ToArray(); } // Exit Function return retVal; }
public ContainerOutput(INeuronContainer container, NeuralLink[] internalLinks, NeuralLink[] externalLinks) { this.Container = container; this.InternalLinks = internalLinks; this.ExternalLinks = externalLinks; }
public NeuralBucket(NeuralLink[] links) { // Group the links up by the output neuron, and feeder neurons _neurons = links .GroupBy(o => o.To) .Select(o => new NeuronBackPointer(o.Key, o.First().ToContainer, o.ToArray())) .ToArray(); // Just create it. It will be populated each tick _indices = new int[_neurons.Length]; this.Count = _neurons.Length; }