public void TestGetWarehouseIndex(PositionCodes code, int expectedRow, int expectedCol)
        {
            var state = new ProductionState();
            var res   = state.GetWarehouseIndex(code);

            Assert.AreEqual((expectedRow, expectedCol), res);
        }
Пример #2
0
        private void GenerateWarehouseState(ProductionState state)
        {
            double DistanceFunc(double time, double maxTime) => (1 + (-time / maxTime));
            double UniformFunc(int validCount) => (1.0 / validCount);
            Dictionary <(int row, int col), double> ComputeTimeAdvantageForCells(List <(int row, int col)> validPositions, double maximum) => validPositions.ToDictionary(k => ((k.row, k.col)), t => DistanceFunc(state.TimeMatrix[t.row, t.col], maximum));

            var validPositions = ((PositionCodes[])Enum.GetValues(typeof(PositionCodes)))
                                 .Where(t => t != PositionCodes.Service && t != PositionCodes.Stacker)
                                 .Select(t => state.GetWarehouseIndex(t))
                                 .ToList();

            var timeMatrixMaximum    = state.TimeMatrix.Cast <double>().Max();
            var timeAdvantageForCell = ComputeTimeAdvantageForCells(validPositions, timeMatrixMaximum);
            int numberOfMqbItems     = MaximumOfMqbItems - state.ProductionHistory.Count(t => t == ItemState.MQB);
            int numberOfMebItems     = MaximumOfMebItems - state.ProductionHistory.Count(t => t == ItemState.MEB);
            int numberOfFreeSlots    = MaximumFreeSlotsInWarehouse - numberOfMqbItems - numberOfMebItems;

            var randomPermutationOfItems = Enumerable.Repeat(ItemState.MEB, numberOfMebItems)
                                           .Concat(Enumerable.Repeat(ItemState.MQB, numberOfMqbItems))
                                           .OrderBy(_ => RandomGenerator.Next())
                                           .ToList();

            foreach (var item in randomPermutationOfItems)
            {
                double uniformProb   = UniformFunc(validPositions.Count);
                double weight        = item == ItemState.MEB ? MebDistanceWeight : MqbDistanceWeight;
                var    validProbs    = validPositions.Select(t => UniformProbabilityWeight * uniformProb + timeAdvantageForCell[(t.row, t.col)] * weight).Softmax();
Пример #3
0
        public override bool NextStep()
        {
            if (ProductionState.FutureProductionPlan.Count == 0)
            {
                return(false);
            }

#if HISTORY
            History.Push(ProductionState.Copy());
#endif

            var needed  = ProductionState.FutureProductionPlan.Dequeue();
            var current = ProductionState.ProductionHistory.Dequeue();
            ProductionState.ProductionHistory.Enqueue(needed);

            var nearestFreePosition = GetNearestEmptyPosition(ProductionState);
            (int r, int c) = ProductionState.GetWarehouseIndex(nearestFreePosition);
            ProductionState.WarehouseState[r, c] = current;

            var nearestNeededPosition = GetNearesElementWarehousePosition(ProductionState, needed);
            (r, c) = ProductionState.GetWarehouseIndex(nearestNeededPosition);
            ProductionState.WarehouseState[r, c] = ItemState.Empty;

            var insertTime = ProductionState.TimeMatrix[ProductionState.GetTimeMatrixIndex(PositionCodes.Stacker), ProductionState.GetTimeMatrixIndex(nearestFreePosition)];
            var moveToDifferentCellTime = ProductionState.TimeMatrix[ProductionState.GetTimeMatrixIndex(nearestFreePosition), ProductionState.GetTimeMatrixIndex(nearestNeededPosition)] - 5; // TODO: Validate this calculation
            moveToDifferentCellTime = moveToDifferentCellTime < 0 ? 0 : moveToDifferentCellTime;
            var withdrawTime = ProductionState.TimeMatrix[ProductionState.GetTimeMatrixIndex(nearestNeededPosition), ProductionState.GetTimeMatrixIndex(PositionCodes.Stacker)];
            var totalTime    = insertTime + moveToDifferentCellTime + withdrawTime;
            ProductionState.CurrentStepTime        = totalTime;
            ProductionState.TimeSpentInSimulation += totalTime;

            ProductionState.ProductionStateIsOk = ProductionState.ProductionStateIsOk && totalTime <= TimeLimit;
            RealTime += ClockTime;
            if (totalTime > TimeLimit)
            {
                Delay    += totalTime - TimeLimit;
                RealTime += totalTime - TimeLimit;
            }
            ProductionState.StepCounter++;

            StepLog.Add(new StepModel
            {
                InsertToCell            = nearestFreePosition,
                WithdrawFromCell        = nearestNeededPosition,
                InsertType              = current,
                WithdrawType            = needed,
                InsertTime              = insertTime,
                MoveToDifferentCellTime = moveToDifferentCellTime,
                WithdrawTime            = withdrawTime
            });

            return(true);
        }
        private void WarehouseSwap(ProductionState productionState, Tuple <PositionCodes, PositionCodes> currentSwap, PositionCodes previousPosition, List <BaseStepModel> logger, bool isLastSwap = false)
        {
            (int r, int c) = productionState.GetWarehouseIndex(currentSwap.Item1);
            var    itemType = productionState.WarehouseState[r, c];
            var    swapTime = productionState.SwapWarehouseItems(currentSwap.Item1, currentSwap.Item2);
            double moveToDifferentCellTime;

            moveToDifferentCellTime = productionState.TimeMatrix[
                productionState.GetTimeMatrixIndex(previousPosition),
                productionState.GetTimeMatrixIndex(currentSwap.Item1)
                                      ];

            if (isLastSwap)
            {
                var extraTime = productionState.TimeMatrix[
                    productionState.GetTimeMatrixIndex(currentSwap.Item2),
                    productionState.GetTimeMatrixIndex(PositionCodes.Stacker)
                                ];

                logger.Add(new WarehouseSwapStepModel
                {
                    MoveTime     = moveToDifferentCellTime,
                    SwapFromCell = currentSwap.Item1,
                    SwapTime     = swapTime,
                    SwapToCell   = currentSwap.Item2,
                    SwapElement  = itemType,
                    ExtraTime    = extraTime
                });
            }
            else
            {
                logger.Add(new WarehouseSwapStepModel
                {
                    MoveTime     = moveToDifferentCellTime,
                    SwapFromCell = currentSwap.Item1,
                    SwapTime     = swapTime,
                    SwapToCell   = currentSwap.Item2,
                    SwapElement  = itemType,
                });
            }
        }