/// <summary> /// Creates new storage container in given location with optionally given name /// </summary> /// <param name="storageLocation">location of storage container</param> /// <param name="containerShortName">container name, optional</param> /// <returns>Error if operation failed, Accepted - when success</returns> public async Task <string> ProvisionContainer(StorageLocations storageLocation, string containerShortName = null) { var uri = $"{_baseProvisioningApiUrl}container"; var containerInput = new ContainerInput { ContainerShortName = containerShortName, MayContainPersonalData = false, StorageLocation = storageLocation.ToString() }; var response = await _httpClient.PostAsync(uri, new StringContent(JsonConvert.SerializeObject(containerInput), Encoding.UTF8, "application/json")); var responseContent = await response.Content.ReadAsStringAsync(); return(response.IsSuccessStatusCode ? response.ReasonPhrase : responseContent); }
private static double[] GetBrainChemicalModifiers(ContainerInput container, double maxWeight) { if (container.BrainChemicalCount == 0) { return null; } int count = StaticRandom.Next(container.BrainChemicalCount); if (count == 0) { return null; } double[] retVal = new double[count]; for (int cntr = 0; cntr < count; cntr++) { retVal[cntr] = Math1D.GetNearZeroValue(maxWeight); } return retVal; }
private static List<NeuralLink> BuildExternalLinksExisting_Prune(List<NeuralLink> links, ContainerInput[] containers, ContainerInput toContainer) { List<NeuralLink> retVal = new List<NeuralLink>(); // Process each from container separately foreach (var group in links.GroupBy(o => o.FromContainer)) { ContainerInput fromContainer = containers.Where(o => o.Container == group.Key).First(); // Find the ratio that talks about this from container var ratio = toContainer.ExternalRatios.Where(o => o.Item1 == fromContainer.ContainerType).FirstOrDefault(); if (ratio == null) { // Links aren't allowed between these types of containers continue; } NeuralLink[] groupLinks = group.ToArray(); // Figure out how many links are supported int maxCount = BuildExternalLinks_Count(ratio.Item2, fromContainer.Container.Neruons_All.Count(), toContainer.Container.Neruons_All.Count(), ratio.Item3); if (groupLinks.Length <= maxCount) { // No need to prune, keep all of these retVal.AddRange(groupLinks); } else { // Prune var pruned = Prune(groupLinks.Select(o => o.Weight).ToArray(), maxCount); // get the largest weights, and normalize them retVal.AddRange(pruned.Select(o => new NeuralLink(groupLinks[o.Item1].FromContainer, groupLinks[o.Item1].ToContainer, groupLinks[o.Item1].From, groupLinks[o.Item1].To, o.Item2, groupLinks[o.Item1].BrainChemicalModifiers))); // copy the referenced links, but use the altered weights } } // Exit Function return retVal; }
/// <summary> /// The containers may not be in the same place that the links think they are. So this method goes through all the container positions /// that all the links point to, and figures out which containers are closest to those positions /// </summary> private static Dictionary<Point3D, ClosestExistingResult[]> BuildExternalLinksExisting_ContainerPoints(ContainerInput[] containers, int maxIntermediateLinks) { Dictionary<Point3D, ClosestExistingResult[]> retVal = new Dictionary<Point3D, ClosestExistingResult[]>(); // can't use SortedList, because point isn't sortable (probably doesn't have IComparable) Point3D[] allPartPoints = containers.Select(o => o.Position).ToArray(); foreach (ContainerInput container in containers.Where(o => o.ExternalLinks != null && o.ExternalLinks.Length > 0)) { // Get a unique list of referenced parts foreach (var exist in container.ExternalLinks) { if (!retVal.ContainsKey(exist.FromContainerPosition)) { retVal.Add(exist.FromContainerPosition, GetClosestExisting(exist.FromContainerPosition, allPartPoints, maxIntermediateLinks)); } } } // Exit Function return retVal; }
private static NeuralLink[] BuildExternalLinksExisting_AcrossParts(NeuralLinkExternalDNA dnaLink, HighestPercentResult[] partLinks, ContainerInput[] containers, Dictionary<ContainerInput, ContainerPoints> nearestNeurons, int maxIntermediateLinks, int maxFinalLinks) { List<NeuralLink> retVal = new List<NeuralLink>(); foreach (HighestPercentResult partLink in partLinks) { #region Get containers ContainerInput fromContainer = containers[partLink.From.Index]; if (!nearestNeurons.ContainsKey(fromContainer)) { nearestNeurons.Add(fromContainer, new ContainerPoints(fromContainer, maxIntermediateLinks)); } ContainerPoints from = nearestNeurons[fromContainer]; ContainerInput toContainer = containers[partLink.To.Index]; if (!nearestNeurons.ContainsKey(toContainer)) { nearestNeurons.Add(toContainer, new ContainerPoints(toContainer, maxIntermediateLinks)); } ContainerPoints to = nearestNeurons[toContainer]; #endregion List<LinkIndexed> links = new List<LinkIndexed>(); // Build links HighestPercentResult[] bestLinks = GetHighestPercent(from.GetNearestPoints(dnaLink.From), to.GetNearestPoints(dnaLink.To), maxIntermediateLinks, false); foreach (HighestPercentResult link in bestLinks) { double[] brainChemicals = null; if (dnaLink.BrainChemicalModifiers != null) { brainChemicals = dnaLink.BrainChemicalModifiers. Take(fromContainer.BrainChemicalCount). // if there are more, just drop them Select(o => o). //Select(o => o * link.Percent). // I decided not to multiply by percent. The weight is already reduced, no point in double reducing ToArray(); } links.Add(new LinkIndexed(link.From.Index, link.To.Index, dnaLink.Weight * link.Percent, brainChemicals)); } // Convert the indices into return links retVal.AddRange(links.Select(o => new NeuralLink(fromContainer.Container, toContainer.Container, from.AllNeurons[o.From], to.AllNeurons[o.To], partLink.Percent * o.Weight, o.BrainChemicalModifiers))); } if (retVal.Count > maxFinalLinks) { // Prune and normalize percents var pruned = Prune(retVal.Select(o => o.Weight).ToArray(), maxFinalLinks); // choose the top X weights, and tell what the new weight should be retVal = pruned.Select(o => new NeuralLink(retVal[o.Item1].FromContainer, retVal[o.Item1].ToContainer, retVal[o.Item1].From, retVal[o.Item1].To, o.Item2, retVal[o.Item1].BrainChemicalModifiers)).ToList(); // copy the referenced retVal items, but with the altered weights } // Exit Function return retVal.ToArray(); }
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; }
/// <summary> /// Gets the readable neurons from the containers of the type requested (and skips the current container) /// </summary> private static List<Tuple<ContainerInput, List<INeuron>>> BuildExternalLinksRandom_Continue_Eligible(NeuronContainerType containerType, int currentIndex, ContainerInput[] containers, List<INeuron>[] readable) { List<Tuple<ContainerInput, List<INeuron>>> retVal = new List<Tuple<ContainerInput, List<INeuron>>>(); for (int cntr = 0; cntr < containers.Length; cntr++) { if (cntr == currentIndex) { continue; } if (containers[cntr].ContainerType != containerType) { continue; } retVal.Add(new Tuple<ContainerInput, List<INeuron>>(containers[cntr], readable[cntr])); } return retVal; }
private static List<NeuralLink> BuildExternalLinksRandom_Continue(ContainerInput[] containers, int currentIndex, Tuple<NeuronContainerType, ExternalLinkRatioCalcType, double> ratio, List<INeuron>[] readable, List<INeuron> writeable, double maxWeight) { List<NeuralLink> retVal = new List<NeuralLink>(); // Find eligible containers var matchingInputs = BuildExternalLinksRandom_Continue_Eligible(ratio.Item1, currentIndex, containers, readable); if (matchingInputs.Count == 0) { return retVal; } // Add up all the eligible neurons int sourceNeuronCount = matchingInputs.Sum(o => o.Item2.Count); // Figure out how many to create (this is the total count. Each feeder container will get a percent of these based on its ratio of // neurons compared to the other feeders) int count = BuildExternalLinks_Count(ratio.Item2, sourceNeuronCount, writeable.Count, ratio.Item3); if (count == 0) { return retVal; } // I don't want to draw so evenly from all the containers. Draw from all containers at once. This will have more clumping, and some containers // could be completely skipped. // // My reasoning for this is manipulators like thrusters don't really make sense to be fed evenly from every single sensor. Also, thruster's count is by // destination neuron, which is very small. So fewer total links will be created by doing just one pass List<Tuple<int, int>> inputLookup = new List<Tuple<int, int>>(); for (int outer = 0; outer < matchingInputs.Count; outer++) { for (int inner = 0; inner < matchingInputs[outer].Item2.Count; inner++) { //Item1 = index into matchingInputs //Item2 = index into neuron inputLookup.Add(new Tuple<int, int>(outer, inner)); } } // For now, just build completely random links Tuple<int, int, double>[] links = GetRandomLinks(inputLookup.Count, writeable.Count, count, Enumerable.Range(0, inputLookup.Count).ToArray(), Enumerable.Range(0, writeable.Count).ToArray(), new SortedList<int, int>(), maxWeight); foreach (var link in links) { // link.Item1 is the from neuron. But all the inputs were put into a single list, so use the inputLookup to figure out which container/neuron // is being referenced var input = matchingInputs[inputLookup[link.Item1].Item1]; int neuronIndex = inputLookup[link.Item1].Item2; double[] brainChemicals = GetBrainChemicalModifiers(input.Item1, maxWeight); // the brain chemicals are always based on the from container (same in NeuralOperation.Tick) retVal.Add(new NeuralLink(input.Item1.Container, containers[currentIndex].Container, input.Item2[neuronIndex], writeable[link.Item2], link.Item3, brainChemicals)); } // Exit Function return retVal; }
private static List<INeuron>[] BuildExternalLinksRandom_FindReadable(ContainerInput[] containers) { return containers. Select(o => o.Container.Neruons_Readonly. Concat(o.Container.Neruons_ReadWrite). ToList()). ToArray(); }
/// <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> /// Gets the readable neurons from the containers of the type requested (and skips the current container) /// </summary> private static List<Tuple<ContainerInput, List<INeuron>, double>> BuildExternalLinksRandom_Continue_Eligible(BotConstruction_PartMap partMap, NeuronContainerType containerType, int currentIndex, ContainerInput[] containers, List<INeuron>[] readable) { var retVal = new List<Tuple<ContainerInput, List<INeuron>, double>>(); for (int cntr = 0; cntr < containers.Length; cntr++) { if (cntr == currentIndex) { continue; } if (containers[cntr].ContainerType != containerType) { continue; } double? weight = null; foreach (var mapped in partMap.Actual) { if ((mapped.Item1.Token == containers[currentIndex].Token && mapped.Item2.Token == containers[cntr].Token) || (mapped.Item2.Token == containers[currentIndex].Token && mapped.Item1.Token == containers[cntr].Token)) { weight = mapped.Item3; break; } } if (weight == null) { // The map doesn't hold a link between these two containers continue; } retVal.Add(Tuple.Create(containers[cntr], readable[cntr], weight.Value)); } 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; }
/// <summary> /// This overload takes a map that tells which parts can link to which /// </summary> public static ContainerOutput[] LinkNeurons(BotConstruction_PartMap partMap, ContainerInput[] containers, double maxWeight) { //TODO: Take these as params (these are used when hooking up existing links) const int MAXINTERMEDIATELINKS = 3; const int MAXFINALLINKS = 3; NeuralLink[][] internalLinks, externalLinks; if (containers.Any(o => o.ExternalLinks != null || o.InternalLinks != null)) { internalLinks = BuildInternalLinksExisting(containers, MAXINTERMEDIATELINKS, MAXFINALLINKS); externalLinks = BuildExternalLinksExisting(containers, MAXINTERMEDIATELINKS, MAXFINALLINKS); //NOTE: The partMap isn't needed for existing links. It is just to help figure out new random links internalLinks = CapWeights(internalLinks, maxWeight); externalLinks = CapWeights(externalLinks, maxWeight); } else { internalLinks = BuildInternalLinksRandom(containers, maxWeight); externalLinks = BuildExternalLinksRandom(partMap, containers, maxWeight); } // Build the return ContainerOutput[] retVal = new ContainerOutput[containers.Length]; for (int cntr = 0; cntr < containers.Length; cntr++) { retVal[cntr] = new ContainerOutput(containers[cntr].Container, internalLinks[cntr], externalLinks[cntr]); } // Exit Function return retVal; }
public ContainerPoints(ContainerInput container, int maxLinks) { this.Container = container; _maxLinks = maxLinks; this.AllNeurons = container.Container.Neruons_All.ToArray(); this.AllNeuronPositions = this.AllNeurons.Select(o => o.Position).ToArray(); //TODO: transform by orientation }