예제 #1
0
        private void ItemExtracted(Pod pod, ItemDescription item)
        {
            // Skip callback, if inactive
            if (!_instance.SettingConfig.MonitorWellSortedness)
            {
                return;
            }
            // Return if not in use yet
            if (_podsContainingItems == null)
            {
                return;
            }
            // --> Update pod utility
            int  itemDemand       = _instance.StockInfo.GetCurrentDemand(item);
            bool updateUtilityMax = false;

            // Update demand by new content of pod (pod lost one of these items)
            if (itemDemand >= pod.CountContained(item))
            {
                // The demand for this item is still high, but we can now supply one item less (because the content is low in comparison to the demand)
                _podUtility[pod]--;
                // Check whether utility max has to be updated
                if (pod == _podUtilityMaxPod)
                {
                    updateUtilityMax = true;
                }
            }
            // Update to new demand (demand for the given item sunk by one)
            foreach (var itemPod in _podsContainingItems[item])
            {
                // If the demand for the item is less then the pod content, we need to update to the new demand by decreasing the utility by one
                if (itemDemand < itemPod.CountContained(item))
                {
                    _podUtility[itemPod]--;
                    // Check whether utility max has to be updated
                    if (itemPod == _podUtilityMaxPod)
                    {
                        updateUtilityMax = true;
                    }
                }
            }
            // Refresh new max
            if (updateUtilityMax)
            {
                VolatileKeyValuePair <Pod, double> bestUtility = _podUtility.ArgMax(pu => pu.Value);
                _podUtilityMaxPod = bestUtility.Key;
                PodUtilityMax     = bestUtility.Value;
            }
            // --> Remove pod from list of pods containing / offering the item, if it was the last one
            if (!pod.IsAvailable(item))
            {
                _podsAvailableItems[item].Remove(pod);
            }
            if (!pod.IsContained(item))
            {
                _podsContainingItems[item].Remove(pod);
            }
            // --> Update pod speed
            _podSpeed[pod] -= _instance.FrequencyTracker.GetStaticFrequency(item);
            if (pod == _podSpeedMaxPod)
            {
                // Refresh max value
                VolatileKeyValuePair <Pod, double> bestSpeed = _podSpeed.ArgMax(ps => ps.Value);
                _podSpeedMaxPod = bestSpeed.Key;
                PodSpeedMax     = bestSpeed.Value;
            }
        }
예제 #2
0
 /// <summary>
 /// Initializes this tracker.
 /// </summary>
 private void EnsureInit()
 {
     if (_podsContainingItems == null)
     {
         // --> Init storage location info
         _storageLocationProminence = new VolatileIDDictionary <Waypoint, double>(_instance.Waypoints
                                                                                  .Where(w => w.PodStorageLocation)
                                                                                  // Determine pod prominence score
                                                                                  .Select(w => new VolatileKeyValuePair <Waypoint, double>(w, _instance.OutputStations.Min(s => { return(Distances.CalculateShortestTimePathPodSafe(w, s.Waypoint, _instance)); })))
                                                                                  .ToList());
         StorageLocationsOrdered = _storageLocationProminence
                                   // Order storage locations by their prominence
                                   .OrderBy(kvp => kvp.Value)
                                   // Break ties randomly
                                   .ThenBy(kvp => _instance.Randomizer.NextDouble())
                                   // Select the actual locations and build a list
                                   .Select(kvp => kvp.Key).ToList();
         // Store prominence index
         _storageLocationIndeces = new VolatileIDDictionary <Waypoint, int>(StorageLocationsOrdered.Select(w => new VolatileKeyValuePair <Waypoint, int>(w, 0)).ToList());
         for (int i = 0; i < StorageLocationsOrdered.Count; i++)
         {
             _storageLocationIndeces[StorageLocationsOrdered[i]] = i;
         }
         // Determine prominence ranks
         _storageLocationRanks = new VolatileIDDictionary <Waypoint, int>(StorageLocationsOrdered.Select(w => new VolatileKeyValuePair <Waypoint, int>(w, 0)).ToList());
         int currentRank = 1; double currentProminenceValue = _storageLocationProminence[StorageLocationsOrdered.First()];
         foreach (var storageLocation in StorageLocationsOrdered)
         {
             // Update rank, if required
             if (_storageLocationProminence[storageLocation] > currentProminenceValue)
             {
                 currentRank++;
                 currentProminenceValue = _storageLocationProminence[storageLocation];
             }
             // Set rank of storage location
             _storageLocationRanks[storageLocation] = currentRank;
         }
         _storageLocationsPerRank = _storageLocationRanks.GroupBy(kvp => kvp.Value).ToDictionary(k => k.Key, v => v.Select(kvp => kvp.Key).OrderBy(kvp => _instance.Randomizer.NextDouble()).ToList());
         StorageLocationRankMax   = _storageLocationRanks.Values.Max();
         // Store prominence ranks for statistics tracking
         foreach (var w in StorageLocationsOrdered)
         {
             w.InfoTagProminence = 1.0 - ((_storageLocationRanks[w] - 1.0) / (StorageLocationRankMax - 1.0));
         }
         // --> Init pod score values
         _podsContainingItems = new VolatileIDDictionary <ItemDescription, HashSet <Pod> >(
             _instance.ItemDescriptions.Select(i => new VolatileKeyValuePair <ItemDescription, HashSet <Pod> >(i, _instance.Pods.Where(p => p.IsContained(i)).ToHashSet())).ToList());
         _podsAvailableItems = new VolatileIDDictionary <ItemDescription, HashSet <Pod> >(
             _instance.ItemDescriptions.Select(i => new VolatileKeyValuePair <ItemDescription, HashSet <Pod> >(i, _instance.Pods.Where(p => p.IsAvailable(i)).ToHashSet())).ToList());
         // Determine initial pod utility
         _podUtility = new VolatileIDDictionary <Pod, double>(
             _instance.Pods.Select(p => new VolatileKeyValuePair <Pod, double>(p, p.ItemDescriptionsContained.Sum(i => Math.Min(p.CountContained(i), _instance.StockInfo.GetCurrentDemand(i)))))
             .ToList());
         VolatileKeyValuePair <Pod, double> bestUtility = _podUtility.ArgMax(pu => pu.Value);
         _podUtilityMaxPod = bestUtility.Key;
         PodUtilityMax     = bestUtility.Value;
         // Determine initial pod speed
         _podSpeed = new VolatileIDDictionary <Pod, double>(
             _instance.Pods.Select(p => new VolatileKeyValuePair <Pod, double>(p, p.ItemDescriptionsContained.Sum(i => p.CountContained(i) * _instance.FrequencyTracker.GetStaticFrequency(i))))
             .ToList());
         VolatileKeyValuePair <Pod, double> bestSpeed = _podSpeed.ArgMax(ps => ps.Value);
         _podSpeedMaxPod = bestSpeed.Key;
         PodSpeedMax     = bestSpeed.Value;
     }
 }