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 HighestPercentResult[] GetHighestPercent(ClosestExistingResult[] from, ClosestExistingResult[] to, int maxReturn, bool isFromSameList) { // Find the combinations that have the highest percentage List<Tuple<int, int, double>> products = new List<Tuple<int, int, double>>(); for (int fromCntr = 0; fromCntr < from.Length; fromCntr++) { for (int toCntr = 0; toCntr < to.Length; toCntr++) { if (isFromSameList && from[fromCntr].Index == to[toCntr].Index) { continue; } products.Add(new Tuple<int, int, double>(fromCntr, toCntr, from[fromCntr].Percent * to[toCntr].Percent)); } } // Don't return too many IEnumerable<Tuple<int, int, double>> topProducts = null; if (products.Count <= maxReturn) { topProducts = products; // no need to sort or limit } else { topProducts = products.OrderByDescending(o => o.Item3).Take(maxReturn).ToArray(); } // Normalize double totalPercent = topProducts.Sum(o => o.Item3); HighestPercentResult[] retVal = topProducts.Select(o => new HighestPercentResult(from[o.Item1], to[o.Item2], o.Item3 / totalPercent)).ToArray(); return retVal; }
public HighestPercentResult(ClosestExistingResult from, ClosestExistingResult to, double percent) { this.From = from; this.To = to; this.Percent = percent; }