public void TestGetTimeMatrixIndex(PositionCodes code, int expected)
        {
            var state = new ProductionState();
            var res   = state.GetTimeMatrixIndex(code);

            Assert.AreEqual(expected, res);
        }
        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,
                });
            }
        }
예제 #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 List <Tuple <PositionCodes, PositionCodes> > GetBestSwaps(ProductionState productionState, double reservedTime)
        {
            Dictionary <int, List <WarehouseReorganizationRecord> > warehouseReorganizationRecordsDict = new Dictionary <int, List <WarehouseReorganizationRecord> >();

            warehouseReorganizationRecordsDict[0] = new List <WarehouseReorganizationRecord>();
            warehouseReorganizationRecordsDict[0].Add(new WarehouseReorganizationRecord
            {
                ProductionState        = productionState,
                Swap                   = null,
                PreviousRecord         = null,
                RemainingTime          = reservedTime,
                MissingSimulationSteps = SimulateProcessing(productionState, 100)
            });

            if (warehouseReorganizationRecordsDict[0][0].MissingSimulationSteps > 0)
            {
                for (int depthIndex = 0; depthIndex < MaxDepth; depthIndex++)
                {
                    ProgressTriggered?.Invoke(this, new ProgressEventArgs()
                    {
                        State = ProgressState.Update, CurrentValue = depthIndex
                    });
                    warehouseReorganizationRecordsDict[depthIndex + 1] = new List <WarehouseReorganizationRecord>();
                    var warehouseReorganizationRecords = warehouseReorganizationRecordsDict[depthIndex].Where(record => record.RemainingTime > 0).ToList();
                    warehouseReorganizationRecordsDict[depthIndex] = warehouseReorganizationRecords.OrderBy(record => record.MissingSimulationSteps).ThenByDescending(record => record.RemainingTime).Take(SelectBestCnt).ToList();

                    for (int topIndex = 0; topIndex < SelectBestCnt && topIndex < warehouseReorganizationRecordsDict[depthIndex].Count; topIndex++)
                    {
                        var currentRecord  = warehouseReorganizationRecordsDict[depthIndex][topIndex];
                        var availableSwaps = currentRecord.ProductionState.GetAvailableWarehouseSwaps();
                        foreach (var swap in availableSwaps)
                        {
                            ProductionState newProductionState = (ProductionState)currentRecord.ProductionState.Clone();
                            var             swapTimeConsumed   = newProductionState.SwapWarehouseItems(swap.Item1, swap.Item2);
                            PositionCodes   previousPosition;
                            if (currentRecord.PreviousRecord == null)
                            {
                                previousPosition = PositionCodes.Stacker;
                            }
                            else
                            {
                                if (currentRecord.PreviousRecord.Swap == null)
                                {
                                    previousPosition = PositionCodes.Stacker;
                                }
                                else
                                {
                                    previousPosition = currentRecord.PreviousRecord.Swap.Item2;
                                }
                            }
                            var moveTime      = productionState.TimeMatrix[productionState.GetTimeMatrixIndex(previousPosition), productionState.GetTimeMatrixIndex(swap.Item1)];
                            var timeToStacker = productionState.TimeMatrix[productionState.GetTimeMatrixIndex(swap.Item2), productionState.GetTimeMatrixIndex(PositionCodes.Stacker)];
                            var timeRemaining = currentRecord.RemainingTime - moveTime - swapTimeConsumed;

                            if (timeRemaining - timeToStacker > 0)
                            {
                                int numberOfMissingSteps = SimulateProcessing(newProductionState, 100);
                                warehouseReorganizationRecordsDict[depthIndex + 1].Add(new WarehouseReorganizationRecord
                                {
                                    ProductionState        = newProductionState,
                                    Swap                   = swap,
                                    PreviousRecord         = currentRecord,
                                    RemainingTime          = timeRemaining,
                                    MissingSimulationSteps = numberOfMissingSteps
                                });
                            }
                        }
                    }
                }
            }

            var allRecords = warehouseReorganizationRecordsDict.Values.SelectMany(x => x).ToList();
            var bestRecord = allRecords.OrderBy(record => record.MissingSimulationSteps).ThenByDescending(record => record.RemainingTime).ToList()[0];

            return(bestRecord.GetSwapsFromRoot());
        }