コード例 #1
0
ファイル: Neural.cs プロジェクト: charlierix/AsteroidMiner
        /// <summary>
        /// This does a fuzzy match to find the best links it can
        /// </summary>
        /// <remarks>
        /// The existing links passed in point to where neurons used to be.  This method compares those positions with where
        /// neurons are now, and tries to match up with the closest it can
        /// 
        /// NOTE: Both neurons and links could have been mutated independent of each other.  This method doesn't care how
        /// they got the way they are, it just goes by position
        /// </remarks>
        private static LinkIndexed[] BuildInternalLinksExisting_Continue(IEnumerable<INeuron> neurons, int count, NeuralLinkDNA[] existing, int maxBrainChemicals, int maxIntermediateLinks, int maxFinalLinks)
        {
            NeuralLinkDNA[] existingPruned = existing;
            if (existing.Length > count)
            {
                // Prune without distributing weight (if this isn't done here, then the prune at the bottom of this method will
                // artificially inflate weights with the links that this step is removing)
                existingPruned = existing.OrderByDescending(o => Math.Abs(o.Weight)).Take(count).ToArray();
            }

            Point3D[] allPoints = neurons.Select(o => o.Position).ToArray();

            #region Find closest points

            // Get a unique list of points
            Dictionary<Point3D, ClosestExistingResult[]> resultsByPoint = new Dictionary<Point3D, ClosestExistingResult[]>();		// can't use SortedList, because point isn't sortable (probably doesn't have IComparable)
            foreach (var exist in existingPruned)
            {
                if (!resultsByPoint.ContainsKey(exist.From))
                {
                    resultsByPoint.Add(exist.From, GetClosestExisting(exist.From, allPoints, maxIntermediateLinks));
                }

                if (!resultsByPoint.ContainsKey(exist.To))
                {
                    resultsByPoint.Add(exist.To, GetClosestExisting(exist.To, allPoints, maxIntermediateLinks));
                }
            }

            #endregion

            List<LinkIndexed> retVal = new List<LinkIndexed>();

            #region Build links

            foreach (var exist in existingPruned)
            {
                HighestPercentResult[] links = GetHighestPercent(resultsByPoint[exist.From], resultsByPoint[exist.To], maxFinalLinks, true);

                foreach (HighestPercentResult link in links)
                {
                    double[] brainChemicals = null;
                    if (exist.BrainChemicalModifiers != null)
                    {
                        brainChemicals = exist.BrainChemicalModifiers.
                            Take(maxBrainChemicals).		// 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();
                    }

                    retVal.Add(new LinkIndexed(link.From.Index, link.To.Index, exist.Weight * link.Percent, brainChemicals));
                }
            }

            #endregion

            // Exit Function
            if (retVal.Count > count)
            {
                #region Prune

                // Prune the weakest links
                // Need to redistribute the lost weight (since this method divided links into smaller ones).  If I don't, then over many generations,
                // the links will tend toward zero

                retVal = retVal.OrderByDescending(o => Math.Abs(o.Weight)).ToList();

                LinkIndexed[] kept = retVal.Take(count).ToArray();
                LinkIndexed[] removed = retVal.Skip(count).ToArray();

                double keptSum = kept.Sum(o => Math.Abs(o.Weight));
                double removedSum = removed.Sum(o => Math.Abs(o.Weight));

                double ratio = keptSum / (keptSum + removedSum);
                ratio = 1d / ratio;

                return kept.Select(o => new LinkIndexed(o.From, o.To, o.Weight * ratio, o.BrainChemicalModifiers)).ToArray();

                #endregion
            }
            else
            {
                return retVal.ToArray();
            }
        }
コード例 #2
0
ファイル: Neural.cs プロジェクト: charlierix/AsteroidMiner
 public ContainerInput(long token, INeuronContainer container, NeuronContainerType containerType, Point3D position, Quaternion orientation, double? internalRatio, Tuple<NeuronContainerType, ExternalLinkRatioCalcType, double>[] externalRatios, int brainChemicalCount, NeuralLinkDNA[] internalLinks, NeuralLinkExternalDNA[] externalLinks)
 {
     this.Token = token;
     this.Container = container;
     this.ContainerType = containerType;
     this.Position = position;
     this.Orientation = orientation;
     this.InternalRatio = internalRatio;
     this.ExternalRatios = externalRatios;
     this.BrainChemicalCount = brainChemicalCount;
     this.InternalLinks = internalLinks;
     this.ExternalLinks = externalLinks;
 }