Exemplo n.º 1
0
        /// <summary>
        /// This fires in an arbitrary thread.  It looks at what's in the map, and builds instructions that will be run in the main thread
        /// (adds/removes)
        /// </summary>
        public void Update_AnyThread(double elapsedTime)
        {
            MapOctree snapshot = _map.LatestSnapshot;

            if (snapshot == null)
            {
                return;
            }

            IEnumerable <MapObjectInfo> allItems = snapshot.GetItems();

            //_map.GetAllItems(true)        //TODO: May want to use this to get disposed items

            // Look for too few/many
            ChangeInstruction[] asteroids = ExamineAsteroids(allItems, _boundry);
            ChangeInstruction[] minerals  = ExamineMinerals(allItems, _boundry, _mineralTypesByValue);

            // Store these instructions for the main thread to do
            if (asteroids != null || minerals != null)
            {
                ChangeInstruction[] instructions = UtilityCore.ArrayAdd(asteroids, minerals);

                if (instructions.Length > MAXCHANGES)
                {
                    instructions = UtilityCore.RandomOrder(instructions, MAXCHANGES).ToArray();
                }

                _instructions = instructions;
            }
        }
Exemplo n.º 2
0
        private static SOMResult TrainSOM(SOMNode[] nodes, ISOMInput[] inputs, SOMRules rules, bool returnEmptyNodes = false)
        {
            double mapRadius = MathND.GetRadius(MathND.GetAABB(nodes.Select(o => o.Weights)));

            SOMNode[] returnNodes = nodes.
                                    Select(o => o.Clone()).
                                    ToArray();

            double timeConstant = rules.NumIterations / Math.Log(mapRadius);

            int iteration           = 0;
            int remainingIterations = rules.NumIterations;

            while (remainingIterations > 0)
            {
                foreach (ISOMInput input in UtilityCore.RandomOrder(inputs, Math.Min(remainingIterations, inputs.Length)))
                {
                    // Find closest node
                    SOMNode closest = GetClosest(returnNodes, input).Item1;

                    // Find other affected nodes (a node and distance squared)
                    double searchRadius = mapRadius * rules.InitialRadiusPercent * Math.Exp(-iteration / timeConstant);
                    Tuple <SOMNode, double>[] neigbors = GetNeighbors(returnNodes, closest, searchRadius);

                    double learningRate = rules.LearningRate * Math.Exp(-(double)iteration / (double)rules.NumIterations);

                    // Adjust the matched node (full learning rate)
                    AdjustNodeWeights(closest, input.Weights, learningRate);

                    foreach (var node in neigbors)
                    {
                        double influence = GetInfluence(rules.AttractionFunction, node.Item2, searchRadius);

                        // Adjust a neighbor
                        AdjustNodeWeights(node.Item1, input.Weights, learningRate * influence);
                    }

                    iteration++;
                }

                remainingIterations -= inputs.Length;
            }

            // See which images go with which nodes
            ISOMInput[][] inputsByNode = GetInputsByNode(returnNodes, inputs);

            SOMResult retVal = new SOMResult(returnNodes, inputsByNode, true);

            if (!returnEmptyNodes)
            {
                retVal = RemoveZeroNodes(retVal);
            }

            return(retVal);
        }