Пример #1
0
 /// <summary>
 /// Allocates the input request.
 /// </summary>
 /// <param name="bundle">The bundle to allocate.</param>
 /// <param name="pod">The pod the bundle shall be stored in.</param>
 /// <param name="station">The station that shall handle the bundle.</param>
 private void Allocate(ItemBundle bundle, Pod pod, InputStation station)
 {
     // Indicate change at instance
     Instance.Changed = true;
     // Check whether decision is possible
     if (station.CapacityInUse + bundle.BundleWeight > station.Capacity)
     {
         throw new InvalidOperationException("Allocating the bundle to the station would exceed its capacity!");
     }
     if (Instance.ControllerConfig.ItemStorageConfig.GetMethodType() != ItemStorageMethodType.Dummy && pod.CapacityInUse + bundle.BundleWeight > pod.Capacity)
     {
         throw new InvalidOperationException("Allocating the bundle to the pod would exceed its capacity!");
     }
     // Remove from ready lists
     _iStationAssignments.Remove(bundle);
     _podAssignments.Remove(bundle);
     // Add the bundle to the station
     station.Add(bundle);
     // Mark the pod at the bundle
     bundle.Pod = pod;
     // Add storage request
     Instance.ResourceManager.NewItemBundleAssignedToStation(bundle, station, pod);
     // Notify item manager
     Instance.ItemManager.NewBundleAssignedToStation(station, bundle);
     // Remove bundle from item manager
     (Instance.ItemManager as ItemManager).TakeAvailableBundle(bundle);
 }
Пример #2
0
 /// <summary>
 /// Notifies the instance that a bundle was allocated.
 /// </summary>
 internal void NotifyBundleAllocated(InputStation iStation, ItemBundle bundle)
 {
     // Store the time the bundle was submitted to the system
     bundle.TimeStampSubmit = Controller.CurrentTime;
     // Raise the event
     BundleAllocated?.Invoke(iStation, bundle);
 }
Пример #3
0
 /// <summary>
 /// Notifies the instance that a bundle was placed in a pod.
 /// </summary>
 /// <param name="pod">The pod the bundle was placed in.</param>
 /// <param name="bot">The corresponding bot.</param>
 /// <param name="bundle">The bundle that was moved from the input-station to the pod.</param>
 /// <param name="station">The station the bundle was distributed from.</param>
 internal void NotifyBundleStored(InputStation station, Bot bot, Pod pod, ItemBundle bundle)
 {
     // Store the number of handled bundles
     pod.StatBundlesHandled++;
     StatOverallBundlesHandled++;
     // Mark every bundle in the history with a timestamp
     _statBundleHandlingTimestamps.Add(new BundleHandledDatapoint(StatTime, bot.ID, pod.ID, station.ID, Controller.CurrentTime - bundle.TimeStamp, Controller.CurrentTime - bundle.TimeStampSubmit));
     // Flush data points in case there are too many already
     if (_statBundleHandlingTimestamps.Count > STAT_MAX_DATA_POINTS)
     {
         StatFlushBundlesHandled();
     }
     // Keep track of the maximal number of handled bundles
     if (StatMaxBundlesHandledByPod < pod.StatBundlesHandled)
     {
         StatMaxBundlesHandledByPod = pod.StatBundlesHandled;
     }
     // Log turnover time
     _statBundleTurnoverTimes.Add(Controller.CurrentTime - bundle.TimeStamp);
     // Log throughput time
     _statBundleThroughputTimes.Add(Controller.CurrentTime - bundle.TimeStampSubmit);
     // Update inventory fill level
     StorageUsage    += bundle.BundleWeight;
     StorageReserved -= bundle.BundleWeight;
     // Raise the event
     BundleStored?.Invoke(station, bot, pod, bundle);
 }
Пример #4
0
        /// <summary>
        /// return the Distance between the bot and the station
        /// </summary>
        /// TODO Change the way to calculate Distance by different Tiers
        private double GetDistance(Bot bot, Object station)
        {
            double distance;

            if (station is InputStation)
            {
                InputStation inStation = station as InputStation;
                //Manhatten Distance
                distance = Math.Abs(inStation.GetInfoCenterX() - bot.GetInfoCenterX()) + Math.Abs(inStation.GetInfoCenterY() - bot.GetInfoCenterY());
                if (inStation.GetInfoCurrentTier().GetInfoZ() != bot.GetInfoCurrentTier().GetInfoZ())
                {
                    distance += bot.GetInfoCurrentTier().GetInfoWidth();
                    distance += Math.Abs(inStation.GetInfoCurrentTier().GetInfoZ() - bot.GetInfoCurrentTier().GetInfoZ());
                }
            }
            else if (station is OutputStation)
            {
                OutputStation outStation = station as OutputStation;
                //Manhatten Distance
                distance = Math.Abs(outStation.GetInfoCenterX() - bot.GetInfoCenterX()) + Math.Abs(outStation.GetInfoCenterY() - bot.GetInfoCenterY());
                if (outStation.GetInfoCurrentTier().GetInfoZ() != bot.GetInfoCurrentTier().GetInfoZ())
                {
                    distance += bot.GetInfoCurrentTier().GetInfoWidth();
                    distance += Math.Abs(outStation.GetInfoCurrentTier().GetInfoZ() - bot.GetInfoCurrentTier().GetInfoZ());
                }
            }
            else
            {
                distance = Int32.MaxValue;
            }
            return(distance);
        }
Пример #5
0
 /// <summary>
 /// This is called to decide about potentially pending bundles.
 /// This method is being timed for statistical purposes and is also ONLY called when <code>SituationInvestigated</code> is <code>false</code>.
 /// Hence, set the field accordingly to react on events not tracked by this outer skeleton.
 /// </summary>
 protected override void DecideAboutPendingBundles()
 {
     foreach (var bundle in _pendingBundles.ToArray())
     {
         InputStation chosenStation = null;
         // Try to reuse the last station for this bundle
         if (_config.Recycle && _lastChosenStation != null && _lastChosenStation.Active && _lastChosenStation.FitsForReservation(bundle))
         {
             // Last chosen station can be used for this bundle too
             chosenStation = _lastChosenStation;
         }
         else
         {
             // Choose a random station
             chosenStation = Instance.InputStations
                             .Where(s => s.Active && s.FitsForReservation(bundle)) // There has to be sufficient capacity left at the station
                             .OrderBy(s => Instance.Randomizer.NextDouble())       // Choose a random one
                             .FirstOrDefault();
             _lastChosenStation = chosenStation;
         }
         // If we found a station, assign the bundle to it
         if (chosenStation != null)
         {
             AddToReadyList(bundle, chosenStation);
         }
     }
 }
Пример #6
0
        /// <summary>
        /// Creates a new input-station.
        /// </summary>
        /// <param name="id">The ID of the input station.</param>
        /// <param name="tier">The position (tier).</param>
        /// <param name="x">The position (x-coordinate).</param>
        /// <param name="y">The position (y-coordinate).</param>
        /// <param name="radius">The radius of the station.</param>
        /// <param name="capacity">The capacity of the station.</param>
        /// <param name="itemBundleTransfertime">The time it takes to handle one bundle at the station.</param>
        /// <param name="activationOrderID">The order ID of the station that defines the sequence in which the stations have to be activated.</param>
        /// <returns>The newly created input station.</returns>
        public InputStation CreateInputStation(int id, Tier tier, double x, double y, double radius, double capacity, double itemBundleTransfertime, int activationOrderID)
        {
            // Consider override values
            if (SettingConfig.OverrideConfig != null && SettingConfig.OverrideConfig.OverrideInputStationCapacity)
            {
                capacity = SettingConfig.OverrideConfig.OverrideInputStationCapacityValue;
            }
            if (SettingConfig.OverrideConfig != null && SettingConfig.OverrideConfig.OverrideInputStationItemBundleTransferTime)
            {
                itemBundleTransfertime = SettingConfig.OverrideConfig.OverrideInputStationItemBundleTransferTimeValue;
            }
            // Init
            InputStation inputStation = new InputStation(this)
            {
                ID = id, Tier = tier, Radius = radius, X = x, Y = y, Capacity = capacity, ItemBundleTransferTime = itemBundleTransfertime, ActivationOrderID = activationOrderID
            };

            inputStation.Queues = new Dictionary <Waypoint, List <Waypoint> >();
            InputStations.Add(inputStation);
            tier.AddInputStation(inputStation);
            _idToInputStations[inputStation.ID] = inputStation;
            // Determine volatile ID
            int volatileID = 0;

            while (_volatileInputStationIDs.Contains(volatileID))
            {
                volatileID++;
            }
            inputStation.VolatileID = volatileID;
            _volatileInputStationIDs.Add(inputStation.VolatileID);
            return(inputStation);
        }
Пример #7
0
 /// <summary>
 /// Gets the number of robots currently assigned to the given station. Does only work for the balanced bot manager. For others it will only return 0.
 /// </summary>
 /// <param name="station">The station to get the number for.</param>
 /// <returns>The number of bots currently assigned to the station or always 0 if the bot manager does not support these assignments.</returns>
 internal int StatGetInfoBalancedBotsPerStation(InputStation station)
 {
     return
         (Controller.BotManager is BalancedBotManager ? (Controller.BotManager as BalancedBotManager).GetAssignedBotCount(station) :
          Controller.BotManager is ConstantRatioBotManager ? (Controller.BotManager as ConstantRatioBotManager).GetAssignedBotCount(station) :
          0);
 }
Пример #8
0
 private void PodHandled(Pod pod, InputStation iStation, OutputStation oStation)
 {
     // If the recycled pod was just handled at an input-station, do not assign any more bundles to it (we do not want to bring it back immediately after replenishing it)
     if (pod == _lastChosenPod && iStation != null)
     {
         _lastChosenPod = null;
     }
 }
Пример #9
0
 private void PodHandled(Pod pod, InputStation iStation, OutputStation oStation)
 {
     // If the recycled pod was just handled at an input-station, do not assign any more bundles to it
     if (pod == _lastChosenPod && iStation != null)
     {
         _lastChosenPod = null;
     }
 }
Пример #10
0
        /// <summary>
        /// Estimates the amount of time it will take before a new item can be picked up from the input-station.
        /// </summary>
        /// <param name="bot">The bot to consider.</param>
        /// <param name="w">The waypoint of the input-station.</param>
        /// <returns>The estimated time.</returns>
        public static double EstimateInputStationWaitTime(Bot bot, Waypoint w)
        {
            InputStation ls = w.InputStation;
            // Assume the wait time is 2 * length of the podbot there plus the time for all bundles
            double waitTime = ((ls.ItemBundleTransferTime + 5 * 2 * bot.Radius) / bot.MaxVelocity) * w.BotCountOverall * w.BotCountOverall; // TODO this estimate cannot hold when transferring many items

            return(waitTime);
        }
Пример #11
0
 private void PodHandled(Pod pod, InputStation iStation, OutputStation oStation)
 {
     // If the recycled pod was just handled at an input-station, do not assign any more bundles to it (we do not want to bring it back immediately after replenishing it)
     if (iStation != null && _lastChosenPodByClassReverse.ContainsKey(pod))
     {
         _lastChosenPodByClass.Remove(_lastChosenPodByClassReverse[pod]);
         _lastChosenPodByClassReverse.Remove(pod);
     }
 }
Пример #12
0
        public void buildReplenishmentStation(int row, int column, directions d, List <Waypoint> bufferPaths, int activationOrderID)
        {
            InputStation iStation = instance.CreateInputStation(
                instance.RegisterInputStationID(), tier, column + 0.5, row + 0.5, lc.StationRadius, lc.IStationCapacity, lc.ItemBundleTransferTime, activationOrderID);

            createTile_ReplenishmentStation(row, column, d, iStation);
            Waypoint wp = tiles[row, column].wp;

            iStation.Queues[wp] = bufferPaths;
        }
Пример #13
0
 /// <summary>
 /// Adds the transaction to the ready list.
 /// </summary>
 /// <param name="bundle">The bundle that is going to be transferred.</param>
 /// <param name="station">The station the bundle is distributed from.</param>
 protected void AddToReadyList(ItemBundle bundle, InputStation station)
 {
     // Update capacity information
     station.RegisterBundle(bundle);
     // Update lists
     _pendingBundles.Remove(bundle);
     // Submit the decision
     Instance.Controller.Allocator.Submit(bundle, station);
     // Notify the instance about the decision
     Instance.NotifyReplenishmentBatchingDecided(station, bundle);
 }
Пример #14
0
 /// <summary>
 /// Creates a new task.
 /// </summary>
 /// <param name="instance">The instance the task belongs to.</param>
 /// <param name="bot">The bot that shall carry out the task.</param>
 /// <param name="reservedPod">The pod to use for the task.</param>
 /// <param name="inputStation">The input station to bring the pod to.</param>
 /// <param name="requests">The requests that shall be finished after successful execution of the task.</param>
 public InsertTask(Instance instance, Bot bot, Pod reservedPod, InputStation inputStation, List <InsertRequest> requests)
     : base(instance, bot)
 {
     InputStation = inputStation;
     Requests     = requests;
     ReservedPod  = reservedPod;
     foreach (var request in requests)
     {
         request.StatInjected = false;
     }
 }
Пример #15
0
        /// <summary>
        /// Enqueues an insertion task.
        /// </summary>
        /// <param name="bot">The bot that shall execute the task.</param>
        /// <param name="station">The station at which the task will be executed.</param>
        /// <param name="pod">The pod to use for this task.</param>
        /// <param name="requests">The requests that will be handled by the task.</param>
        protected void EnqueueInsert(Bot bot, InputStation station, Pod pod, List <InsertRequest> requests)
        {
            InsertTask task = new InsertTask(Instance, bot, pod, station, requests);

            task.Prepare();
            if (_taskQueues[bot] != null)
            {
                _taskQueues[bot].Cancel();
            }
            _taskQueues[bot]       = task;
            _lastTaskEnqueued[bot] = task;
        }
Пример #16
0
 private void SignalBundleStored(InputStation station, Bot bot, Pod pod, ItemBundle bundle)
 {
     // Init, if necessary
     if (_currentActualStock == null)
     {
         InitStockInfo();
     }
     // Update overall load information
     CurrentActualOverallLoad += bundle.BundleWeight;
     // Update actual stock information
     _currentActualStock[bundle.ItemDescription] += bundle.ItemCount;
     // Update available stock information
     _currentAvailableStock[bundle.ItemDescription] += bundle.ItemCount;
 }
Пример #17
0
        /// <summary>
        /// Called whenever a new item has been assigned to an InputStation
        /// </summary>
        /// <param name="item">The assigned item.</param>
        /// <param name="inputStation">The InputStation the item is assigned to.</param>
        /// <param name="pod">The pod to store this item in.</param>
        public void NewItemBundleAssignedToStation(ItemBundle item, InputStation inputStation, Pod pod)
        {
            InsertRequest request = new InsertRequest(item, inputStation, pod);

            _availableStoreRequests.Add(request);
            if (request.Station != null)
            {
                _availableStoreRequestsPerStation[request.Station].Add(request);
                request.Station.StatCurrentlyOpenRequests = _availableStoreRequestsPerStation[request.Station].Count;
            }
            if (request.Pod != null)
            {
                _availableStoreRequestsPerPod[request.Pod].Add(request);
            }
        }
Пример #18
0
        /// <summary>
        /// Creates a new waypoint that serves as the handover point for an input station.
        /// </summary>
        /// <param name="id">The ID of the waypoint.</param>
        /// <param name="tier">The position (tier).</param>
        /// <param name="station">The station.</param>
        /// <param name="isQueueWaypoint">Indicates whether this waypoint is also a queue waypoint.</param>
        /// <returns>The newly created waypoint.</returns>
        public Waypoint CreateWaypoint(int id, Tier tier, InputStation station, bool isQueueWaypoint)
        {
            Waypoint wp = new Waypoint(this)
            {
                ID = id, X = station.X, Y = station.Y, Radius = station.Radius, InputStation = station, IsQueueWaypoint = isQueueWaypoint
            };

            station.Waypoint = wp;
            tier.AddWaypoint(wp);
            Waypoints.Add(wp);
            WaypointGraph.Add(wp);
            _idToWaypoint[wp.ID] = wp;
            // Set volatile ID
            SetVolatileIDForWaypoint(wp);
            // Return
            return(wp);
        }
Пример #19
0
        private void BundleStored(InputStation iStation, Bot bot, Pod pod, ItemBundle bundle)
        {
            // Skip callback, if inactive
            if (!_instance.SettingConfig.MonitorWellSortedness)
            {
                return;
            }
            // Return if not in use yet
            if (_podsContainingItems == null)
            {
                return;
            }
            // --> Add pod to the list of pods containing / offering the respective item
            _podsAvailableItems[bundle.ItemDescription].Add(pod);
            _podsContainingItems[bundle.ItemDescription].Add(pod);
            // --> Update pod utility
            int itemDemand  = _instance.StockInfo.GetCurrentDemand(bundle.ItemDescription);
            int beforeCount = pod.CountContained(bundle.ItemDescription) - bundle.ItemCount;

            // Add either rest of demand that now can be supplied by the pod or simply the content of the bundle
            if (beforeCount < itemDemand)
            {
                _podUtility[pod] += Math.Min(itemDemand - beforeCount, bundle.ItemCount);
                // Update max value
                if (_podUtility[pod] > PodUtilityMax)
                {
                    PodUtilityMax     = _podUtility[pod];
                    _podUtilityMaxPod = pod;
                }
            }
            // --> Update pod speed
            _podSpeed[pod] += bundle.ItemCount * _instance.FrequencyTracker.GetStaticFrequency(bundle.ItemDescription);
            if (_podSpeed[pod] > PodSpeedMax)
            {
                PodSpeedMax     = _podSpeed[pod];
                _podSpeedMaxPod = pod;
            }
        }
Пример #20
0
        /// <summary>
        /// This is called to decide about potentially pending bundles.
        /// This method is being timed for statistical purposes and is also ONLY called when <code>SituationInvestigated</code> is <code>false</code>.
        /// Hence, set the field accordingly to react on events not tracked by this outer skeleton.
        /// </summary>
        protected override void DecideAboutPendingBundles()
        {
            if (_config.BreakBatches)
            {
                // Go through list of not assigned bundles
                for (int i = 0; i < _itemBundles.Count; i++)
                {
                    // Check which pod was used to store the bundle
                    ItemBundle bundle       = _itemBundles[i];
                    Pod        podForBundle = _bundleToPod[bundle];
                    // See whether we already have a station in memory for this pod
                    InputStation chosenStation;
                    if (_lastChosenStations.ContainsKey(podForBundle))
                    {
                        // See whether we can assign the new bundle to that station
                        if (_lastChosenStations[podForBundle].FitsForReservation(bundle))
                        {
                            chosenStation = _lastChosenStations[podForBundle];
                        }
                        else
                        {
                            // The bundle won't fit the station - try a station close by
                            chosenStation = Instance.InputStations
                                            .Where(s => s.Active && s.FitsForReservation(bundle))                                                             // There has to be sufficient capacity left at the station and the station needs to be active
                                            .OrderBy(s => Distances.CalculateEuclid(_lastChosenStations[podForBundle], s, Instance.WrongTierPenaltyDistance)) // Start with the nearest station
                                            .FirstOrDefault();                                                                                                // Return the first one or null if none available
                        }
                    }
                    else
                    {
                        // We don't know this pod - select a new station
                        switch (_config.FirstStationRule)
                        {
                        case SamePodFirstStationRule.Emptiest:
                            chosenStation = Instance.InputStations
                                            .Where(s => s.Active && s.FitsForReservation(bundle))              // There has to be sufficient capacity left at the station and the station needs to be active
                                            .OrderBy(s => (s.CapacityInUse + s.CapacityReserved) / s.Capacity) // Pick the emptiest one
                                            .FirstOrDefault();                                                 // Return the first one or null if none available
                            break;

                        case SamePodFirstStationRule.Fullest:
                            chosenStation = Instance.InputStations
                                            .Where(s => s.Active && s.FitsForReservation(bundle))                        // There has to be sufficient capacity left at the station and the station needs to be active
                                            .OrderByDescending(s => (s.CapacityInUse + s.CapacityReserved) / s.Capacity) // Pick the fullest one
                                            .FirstOrDefault();                                                           // Return the first one or null if none available
                            break;

                        case SamePodFirstStationRule.LeastBusy:
                            chosenStation = Instance.InputStations
                                            .Where(s => s.Active && s.FitsForReservation(bundle)) // There has to be sufficient capacity left at the station and the station needs to be active
                                            .OrderBy(s => s.ItemBundles.Count())                  // Pick the one with the fewest bundles
                                            .FirstOrDefault();                                    // Return the first one or null if none available
                            break;

                        case SamePodFirstStationRule.MostBusy:
                            chosenStation = Instance.InputStations
                                            .Where(s => s.Active && s.FitsForReservation(bundle)) // There has to be sufficient capacity left at the station and the station needs to be active
                                            .OrderByDescending(s => s.ItemBundles.Count())        // Pick the one with the most bundles
                                            .FirstOrDefault();                                    // Return the first one or null if none available
                            break;

                        case SamePodFirstStationRule.Random:
                            chosenStation = Instance.InputStations
                                            .Where(s => s.Active && s.FitsForReservation(bundle)) // There has to be sufficient capacity left at the station and the station needs to be active
                                            .OrderBy(s => Instance.Randomizer.NextDouble())       // Pick a random one
                                            .FirstOrDefault();                                    // Return the first one or null if none available
                            break;

                        case SamePodFirstStationRule.DistanceEuclid:
                            chosenStation = Instance.InputStations
                                            .Where(s => s.Active && s.FitsForReservation(bundle))                                        // There has to be sufficient capacity left at the station and the station needs to be active
                                            .OrderBy(s => Distances.CalculateEuclid(podForBundle, s, Instance.WrongTierPenaltyDistance)) // Pick the nearest one
                                            .FirstOrDefault();                                                                           // Return the first one or null if none available
                            break;

                        default: throw new ArgumentException("Unknown first station rule: " + _config.FirstStationRule);
                        }
                    }
                    // If we found a station, assign the bundle to it
                    if (chosenStation != null)
                    {
                        AddToReadyList(bundle, chosenStation);
                        _bundleToPod.Remove(bundle);
                        _itemBundles.RemoveAt(0);
                        i--;
                        _lastChosenStations[podForBundle] = chosenStation;
                    }
                }
            }
            else
            {
                // Assign batches in the order they arrive in
                List <Pod> removedBatches = null;
                foreach (var batch in _podBundles.OrderBy(p => _waitingTime[p.Key]))
                {
                    double batchSize = batch.Value.Sum(b => b.BundleWeight);
                    // Choose a suitable station
                    InputStation chosenStation = Instance.InputStations
                                                 // Only active stations where the complete bundle fits
                                                 .Where(s => s.Active && batchSize <= s.RemainingCapacity)
                                                 // Only stations that are located on the same tier as the pod (if desired)
                                                 .Where(s => s.Tier == batch.Key.Tier)
                                                 // Find the best station according to the chosen rule
                                                 .ArgMin(s =>
                    {
                        switch (_config.FirstStationRule)
                        {
                        case SamePodFirstStationRule.Emptiest: return((s.CapacityInUse + s.CapacityReserved) / s.Capacity);

                        case SamePodFirstStationRule.Fullest: return(1 - ((s.CapacityInUse + s.CapacityReserved) / s.Capacity));

                        case SamePodFirstStationRule.LeastBusy: return(s.ItemBundles.Count());

                        case SamePodFirstStationRule.MostBusy: return(-s.ItemBundles.Count());

                        case SamePodFirstStationRule.Random: return(Instance.Randomizer.NextDouble());

                        case SamePodFirstStationRule.DistanceEuclid: return(Distances.CalculateEuclid(batch.Key, s, Instance.WrongTierPenaltyDistance));

                        default: throw new ArgumentException("Unknown rule: " + _config.FirstStationRule);
                        }
                    });
                    // Check whether there was a suitable station at all
                    if (chosenStation != null)
                    {
                        // Submit the decision
                        foreach (var bundle in batch.Value)
                        {
                            AddToReadyList(bundle, chosenStation);
                        }
                        // Clean up
                        _lastChosenStations[batch.Key] = chosenStation;
                        if (removedBatches == null)
                        {
                            removedBatches = new List <Pod>();
                        }
                        removedBatches.Add(batch.Key);
                    }
                    else
                    {
                        // If FCFS applies, we cannot assign further batches until this one gets assigned
                        if (_config.FCFS)
                        {
                            break;
                        }
                    }
                }
                // Actually remove the batches
                if (removedBatches != null)
                {
                    foreach (var batch in removedBatches)
                    {
                        _podBundles.Remove(batch);
                    }
                }
            }
        }
Пример #21
0
 /// <summary>
 /// Creates a new insertion request.
 /// </summary>
 /// <param name="bundle">The bundle.</param>
 /// <param name="station">The station.</param>
 /// <param name="pod">The pod.</param>
 public InsertRequest(ItemBundle bundle, InputStation station, Pod pod)
 {
     Bundle = bundle; Station = station; Pod = pod; State = RequestState.Unfinished;
 }
Пример #22
0
 /// <summary>
 /// Returns all requests belonging to the specified station.
 /// </summary>
 /// <param name="station">The station which requests are desired.</param>
 /// <returns>The requests of the given station.</returns>
 public IEnumerable <InsertRequest> GetStoreRequestsOfStation(InputStation station)
 {
     return(_availableStoreRequestsPerStation[station]);
 }
Пример #23
0
        /// <summary>
        /// Based on the current situation, the bot needs to get an item, but doesn't have it.
        /// This function reserves the item the pod should pick up. Returns the pod that should be used, null if it's carying a pod and the current pod won't work (too full).
        /// </summary>
        /// <param name="bot">The bot to consider.</param>
        /// <param name="bestRequest">The best request to use for the best pickup task.</param>
        /// <param name="bestStation">The station to use for the best pickup task.</param>
        /// <param name="bestPod">The pod to use for the best pickup task.</param>
        public void ReserveBestItemToPickUp(Bot bot, out InsertRequest bestRequest, out Pod bestPod, out InputStation bestStation)
        {
            bestPod     = null;
            bestStation = null;
            bestRequest = null;

            // If have a pod currently
            if (bot.Pod != null)
            {
                Pod pod = bot.Pod;

                // Current pod works, so find closest input station and best task
                double closestInputStationTime = double.PositiveInfinity;

                // Check all tasks
                foreach (var storeTask in Instance.ResourceManager.AvailableStoreRequests)
                {
                    // See how long it would take to get to this input station
                    // Choose the worst of delivering or waiting
                    Waypoint sw   = storeTask.Station.Waypoint;
                    double   time = Math.Max(Estimators.EstimateTravelTimeEuclid(bot, bot.CurrentWaypoint, sw), Estimators.EstimateInputStationWaitTime(bot, sw));

                    // If it's the best and it fits the current pod, then use it
                    if (time < closestInputStationTime && pod.CapacityInUse + storeTask.Bundle.BundleWeight <= pod.Capacity)
                    {
                        bestRequest             = storeTask;
                        closestInputStationTime = time;
                    }
                }

                // If no pickup suits the pod, get rid of it
                if (bestRequest == null)
                {
                    return;
                }

                // Allocate task!
                bestStation = bestRequest.Station;
                bestPod     = pod;
            }

            // Don't have a pod
            double bestPickupTime = double.PositiveInfinity;

            bestRequest = null;
            bestPod     = null;

            foreach (var pod in Instance.ResourceManager.UnusedPods)
            {
                // Find time to pick up the bundle
                double pickupTime = Estimators.EstimateTravelTimeEuclid(bot, pod.Waypoint);

                // Check all tasks
                foreach (var storeTask in Instance.ResourceManager.AvailableStoreRequests)
                {
                    // If it has room
                    if (pod.CapacityInUse + storeTask.Bundle.BundleWeight <= pod.Capacity)
                    {
                        // See how long it would take to get to this input station
                        // Choose the worst of delivering or waiting
                        Waypoint sw          = storeTask.Station.Waypoint;
                        double   deliverTime = Math.Max(Estimators.EstimateTravelTimeEuclid(bot, pod.Waypoint, sw), Estimators.EstimateInputStationWaitTime(bot, sw));

                        //if it's the best, then use it
                        if (pickupTime + deliverTime < bestPickupTime)
                        {
                            bestRequest    = storeTask;
                            bestPickupTime = pickupTime + deliverTime;
                            bestPod        = pod;
                        }
                    }
                }
            }

            // No pickup request available
            if (bestRequest == null)
            {
                return;
            }

            // Pickup available - set it
            bestStation = bestRequest.Station;
        }
Пример #24
0
        public void createTile_ReplenishmentStation(int row, int column, directions d, InputStation iStation)
        {
            Waypoint wp = instance.CreateWaypoint(instance.RegisterWaypointID(), tier, iStation, true);

            if (tiles[row, column] != null)
            {
                throw new ArgumentException("trying to overwrite an existing waypoint!! At createTile_ReplenishmentStation: tiles[row, column] != null");
            }
            tiles[row, column] = new Tile(d, wp, waypointTypes.ReplenishmentStation);
        }
Пример #25
0
 private double GetOrderValue(InputStation iStation, Bot bot)
 {
     return(_config.PreferSameTier && iStation.Tier == bot.Tier ? -Instance.Randomizer.NextDouble() : Instance.Randomizer.NextDouble());
 }
Пример #26
0
 /// <summary>
 /// Signals the manager that a station that was previously not in use can now be assigned bundles.
 /// </summary>
 /// <param name="station">The newly activated station.</param>
 public void SignalStationActivated(InputStation station)
 {
     SituationInvestigated = false;
 }
Пример #27
0
 /// <summary>
 /// Notifies the instance that a station was chosen for a bundle.
 /// </summary>
 /// <param name="station">The chosen station.</param>
 /// <param name="bundle">The corresponding bundle.</param>
 internal void NotifyReplenishmentBatchingDecided(InputStation station, ItemBundle bundle)
 {
     // Raise the event
     ReplenishmentBatchingDecided?.Invoke(station, bundle);
 }
Пример #28
0
 /// <summary>
 /// Notifies the instance that a pod was used at a station.
 /// </summary>
 /// <param name="pod">The pod that was used.</param>
 /// <param name="iStation">The input station at which the pod was used or <code>null</code> if it was used at an output station.</param>
 /// <param name="oStation">The output station at which the pod was used or <code>null</code> if it was used at an input station.</param>
 internal void NotifyPodHandled(Pod pod, InputStation iStation, OutputStation oStation)
 {
     // Raise the event
     PodHandled?.Invoke(pod, iStation, oStation);
 }
 /// <summary>
 /// Used to keep track of the decisions done by replenishment batching.
 /// </summary>
 /// <param name="station">The chosen station.</param>
 /// <param name="bundle">The corresponding bundle.</param>
 private void ReplenishmentBatchingDecided(InputStation station, ItemBundle bundle)
 {
     _bundleToStation[bundle] = station; SituationInvestigated = false;
 }
Пример #30
0
 /// <summary>
 /// Submits a new replenishment assignment decision to the allocator.
 /// </summary>
 /// <param name="bundle">The bundle that is being assigned to an input station.</param>
 /// <param name="station">The input station that shall be used to store the bundle.</param>
 public void Submit(ItemBundle bundle, InputStation station)
 {
     // Store assignment until the next allocation update
     _iStationAssignments[bundle] = station;
 }