Beispiel #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;
            }
        }
Beispiel #2
0
        private static SOMResult ProcessNewItemBatch(SOMItem[] newItemBatch, bool discardDupes, double dupeDistSquared, SOMResult existing)
        {
            const int TOTALMAX = BATCHMAX * 10;

            // Items only make it here when they aren't too similar to the som nodes, but items within this list may be dupes
            if (discardDupes)
            {
                newItemBatch = DedupeItems(newItemBatch, dupeDistSquared);
            }

            if (newItemBatch.Length > BATCHMAX)
            {
                // There are too many, just take a sample
                newItemBatch = UtilityCore.RandomRange(0, newItemBatch.Length, BATCHMAX).
                               Select(o => newItemBatch[o]).
                               ToArray();
            }

            SOMItem[] existingItems = null;
            if (existing != null)
            {
                existingItems = existing.InputsByNode.
                                SelectMany(o => o).
                                Select(o => ((SOMInput <SOMItem>)o).Source).
                                ToArray();
            }

            SOMItem[] allItems = UtilityCore.ArrayAdd(existingItems, newItemBatch);



            //TODO: This is too simplistic.  See if existingItems + newItemBatch > total.  If so, try to draw down the existing nodes evenly.  Try
            //to preserve previous images better.  Maybe even throw in a timestamp to get a good spread of times
            //
            //or get a SOM of the new, independent of the old.  Then merge the two pulling representatives to keep the most diversity.  Finally,
            //take a SOM of the combined
            if (allItems.Length > TOTALMAX)
            {
                allItems = UtilityCore.RandomRange(0, allItems.Length, TOTALMAX).
                           Select(o => allItems[o]).
                           ToArray();
            }



            SOMInput <SOMItem>[] inputs = allItems.
                                          Select(o => new SOMInput <SOMItem>()
            {
                Source = o, Weights = o.Weights,
            }).
                                          ToArray();

            //TODO: May want rules to persist from run to run
            SOMRules rules = GetSOMRules_Rand();

            return(SelfOrganizingMaps.TrainSOM(inputs, rules, true));
        }
Beispiel #3
0
        /// <summary>
        /// This will move the types in transfer from the from array to the to array.  The arrays passed in won't be affected,
        /// but the return will be the new from and to
        /// </summary>
        private static Tuple <Type[], Tuple <Type, int>[]> TransferTypes(Type[] existingFrom, Tuple <Type, int>[] existingTo, Tuple <Type, int>[] transfer)
        {
            // Only keep the types that aren't in transfer
            Type[] newFrom = existingFrom.Where(o => !transfer.Any(p => p.Item1.Equals(o))).ToArray();
            if (newFrom.Length == 0)
            {
                newFrom = null;
            }

            // Add transfer to existing
            Tuple <Type, int>[] newTo = UtilityCore.ArrayAdd(existingTo, transfer);

            return(Tuple.Create(newFrom, newTo));
        }
Beispiel #4
0
        /// <summary>
        /// This allows items to be updated that aren't added to the map
        /// </summary>
        public void AddNonMapItem(IPartUpdatable item, long token)
        {
            if (item.IntervalSkips_MainThread != null)
            {
                _nonmapItemsMain.Add(Tuple.Create(item.IntervalSkips_MainThread.Value, item, token));
            }

            lock (_lockTypesAny)
            {
                if (item.IntervalSkips_AnyThread != null)
                {
                    _nonmapItemsAny = UtilityCore.ArrayAdd(_nonmapItemsAny, Tuple.Create(item.IntervalSkips_AnyThread.Value, item, token));
                }
            }
        }