public BulkLoader()
        {
            var itemValidator = new ItemValidator();
            var itemLinker    = new ItemLinker();

            OnItemProcessing = new Chain <IItemProcessor>
            {
                new ItemBucketer(),
                new ItemVersionEnsurer(),
                itemValidator,
                new ItemLinker()
            };

            OnStagedDataValidating = new Chain <IValidateStagedData>
            {
                itemValidator,
                new ValidateNoDuplicates()
            };

            OnTempDataValidating = new Chain <IValidateStagedData>
            {
                new ValidateDataIntegrity()
            };

            OnTransactionCommitting = new Chain <ISyncInTransaction>
            {
                new SyncHistoryTable(),
                new SyncPublishQueue()
            };

            OnItemsLoading = new Chain <IChangeProcessor>
            {
                new ChangeCacheClearer()
            };

            OnItemsLoaded = new Chain <IChangeProcessor>
            {
                new ChangeLogger(),
                itemLinker,
                new ChangeIndexer()
            };
        }
Exemplo n.º 2
0
        private static NeuronMapping[] MapNeurons(Point3D[] externalPoints, Point3D[] internalPoints)
        {
            // FuzzyLink wasn't designed for from and to points to be sitting on top of each other, so need to pull them apart
            //
            // external is pulled to -Z, internal is +Z.  These offset coordinates don't have any meaning outside this function, they are just
            // a hack to allow FuzzyLink to work properly

            // Figure out how far to separate them to ensure they are fully separated
            var    aabb       = Math3D.GetAABB(externalPoints.Concat(internalPoints));
            double offsetDist = Math1D.Max(aabb.Item2.X - aabb.Item1.X, aabb.Item2.Y - aabb.Item1.Y, aabb.Item2.Z - aabb.Item1.Z);

            offsetDist *= 3;
            Vector3D offset = new Vector3D(0, 0, offsetDist);

            // Create seed links.  The easiest approach is just to create one per internal point and then let the fuzzy linker find the best
            // external point
            //
            // I could see the argument for remembering the links across generations so that if the external points drift around too much,
            // the original linking will better persist.  But if the bot is mutating that much over generations, the neat NN should be retrained
            // from time to time.  Also, if a mismapping causes the bot to perform bad, then it won't be making children (and a mismapping
            // might end up causing better performance)
            Tuple <Point3D, Point3D, double>[] initialLinks = internalPoints.
                                                              Select(o => Tuple.Create(o - offset, o + offset, 1d)).
                                                              ToArray();

            Point3D[] pointsForFuzzy = externalPoints.Select(o => o - offset).
                                       Concat(internalPoints.Select(o => o + offset)).
                                       ToArray();

            // Allow a few more links than points.  If the external and internal points are aligned well, then the extra link allowance won't
            // be used
            int numLinks = (internalPoints.Length * 1.1).ToInt_Ceiling();

            var finalLinks = ItemLinker.FuzzyLink(initialLinks, pointsForFuzzy, numLinks, 6);


            const double THICKNESS = .005;
            const double DOT       = THICKNESS * 3;

            Debug3DWindow window = new Debug3DWindow();

            window.AddDots(externalPoints, DOT, Colors.IndianRed);
            window.AddDots(internalPoints, DOT, Colors.DodgerBlue);

            window.AddDots(pointsForFuzzy, DOT, Colors.Silver);
            window.AddLines(initialLinks.Select(o => (o.Item1, o.Item2)), THICKNESS, Colors.Orchid);


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

            foreach (var link in finalLinks)
            {
                int?externalIndex = null;
                int?internalIndex = null;

                foreach (int index in new[] { link.Item1, link.Item2 })
                {
                    if (index < externalPoints.Length)
                    {
                        externalIndex = index;
                    }
                    else
                    {
                        internalIndex = index - externalPoints.Length;
                    }
                }

                if (externalIndex == null || internalIndex == null)
                {
                    // This should never happen in practice, the internal and external sets are pulled too far apart to accidentally be linked together.
                    // Just ignore this link
                    continue;
                }

                retVal.Add(new NeuronMapping()
                {
                    Index_External = externalIndex.Value,
                    Index_NEAT     = internalIndex.Value,
                    Weight         = link.Item3,
                });
            }


            foreach (var link in finalLinks)
            {
                window.AddLine(pointsForFuzzy[link.Item1], pointsForFuzzy[link.Item2], THICKNESS * link.Item3, Colors.GhostWhite);
            }
            foreach (var link in retVal)
            {
                window.AddLine(externalPoints[link.Index_External], internalPoints[link.Index_NEAT], THICKNESS * link.Weight, Colors.Coral);
            }

            window.Show();

            return(retVal.ToArray());
        }