Beispiel #1
0
 private MoveCondition CheckMoveCondition(CraneMove move)
 {
     if (move.EmptyMove)
     {
         return(MoveCondition.Valid); // just a crane relocation
     }
     if (move.SourceId == 0)          // Production -> X
     {
         var block = World.Production.BottomToTop.LastOrDefault();
         if (block == null || block.Id != move.BlockId)
         {
             return(MoveCondition.BlockNotFound);
         }
     }
     else if (move.SourceId <= World.Buffers.Count) // Buffer -> X
     {
         var block = World.Buffers[move.SourceId - 1].BottomToTop.LastOrDefault();
         if (block == null || block.Id != move.BlockId)
         {
             return(MoveCondition.BlockNotFound);
         }
     }
     else
     {
         return(MoveCondition.InvalidSource); // Handover -> X
     }
     if (move.TargetId == 0)
     {
         return(MoveCondition.InvalidTarget);       // X -> Production
     }
     else if (move.TargetId <= World.Buffers.Count) // X -> Buffer
     {
         if (World.Buffers[move.TargetId - 1].BottomToTop.Count >= World.Buffers[move.TargetId - 1].MaxHeight)
         {
             return(MoveCondition.HeightLimitViolated);
         }
     }
     else // X -> Handover
     {
         if (!World.Handover.Ready || World.Handover.Block != null)
         {
             return(MoveCondition.HandoverNotReady);
         }
         Block block;
         if (move.SourceId == World.Production.Id)
         {
             block = World.Production.BottomToTop.LastOrDefault();
         }
         else
         {
             block = World.Buffers[move.SourceId - 1].BottomToTop.LastOrDefault();
         }
         if (!block.Ready)
         {
             return(MoveCondition.BlockNotReady);
         }
     }
     return(MoveCondition.Valid);
 }
Beispiel #2
0
        public RFState Apply(CraneMove move)
        {
            var result = new RFState(this);
            var block  = result.RemoveBlock(move.SourceId);

            result.AddBlock(move.TargetId, block);
            result.Moves.Add(move);
            return(result);
        }
Beispiel #3
0
        public BrpState Apply(CraneMove move)
        {
            var result = new BrpState(this);
            var block  = result.Stacks[move.SourceId].Blocks.Pop();

            if (move.TargetId != HandoverId)
            {
                result.Stacks[move.TargetId].Blocks.Push(block);
            }
            result.Moves.Add(move);
            return(result);
        }
        /// If the top block of the production stack can be put on a buffer schedule this move.
        private static void ClearProductionStack(World world, CraneSchedule schedule)
        {
            var blocks = world.Production.BottomToTop.Count;

            if (blocks > 0)
            {
                var top = world.Production.BottomToTop[blocks - 1];
                foreach (var stack in world.Buffers)
                {
                    if (stack.MaxHeight > stack.BottomToTop.Count)
                    {
                        var move = new CraneMove();
                        move.BlockId  = top.Id;
                        move.SourceId = world.Production.Id;
                        move.TargetId = stack.Id;
                        schedule.Moves.Add(move);
                        return;
                    }
                }
            }
        }
Beispiel #5
0
        void PlanShuffleCrane()
        {
            var dontUse = new List <int>();

            foreach (var mov in plan.Moves)
            {
                dontUse.Add(mov.PickupLocationId);
                dontUse.Add(mov.DropoffLocationId);
            }
            var move_id = plan.Moves.Count;
            var src     = ArrivalStacks().OrderBy(loc => loc.Stack.BottomToTop.Any() ? loc.Stack.BottomToTop.Min(block => block.Sequence) : int.MaxValue).First();

            var amount = Math.Min(SizeOf(src), world.ShuffleCrane.CraneCapacity);

            if (amount == 0)
            {
                return;
            }
            var tgt = BufferStacks().FirstOrDefault(tgt => RemainingCapacity(tgt) >= amount && !dontUse.Contains(tgt.Id));

            if (tgt != null)
            {
                var mov = new CraneMove();
                move_id        += 1;
                mov.Id          = move_id;
                mov.Type        = MoveType.PickupAndDropoff;
                mov.ReleaseTime = new TimeStamp()
                {
                    MilliSeconds = world.Now.MilliSeconds
                };
                mov.PickupLocationId  = src.Id;
                mov.DropoffLocationId = tgt.Id;
                mov.RequiredCraneId   = world.ShuffleCrane.Id;
                mov.Amount            = amount;
                plan.Moves.Add(mov);
                return;
            }
        }
 /// If any block on top of a stack can be moved to the handover schedule this move.
 private static void AnyHandoverMove(World world, CraneSchedule schedule)
 {
     if (!world.Handover.Ready)
     {
         return;
     }
     foreach (var stack in world.Buffers)
     {
         var blocks = stack.BottomToTop.Count;
         if (blocks > 0)
         {
             var top = stack.BottomToTop[blocks - 1];
             if (top.Ready)
             {
                 var move = new CraneMove();
                 move.BlockId  = top.Id;
                 move.SourceId = stack.Id;
                 move.TargetId = world.Handover.Id;
                 schedule.Moves.Add(move);
             }
         }
     }
 }
Beispiel #7
0
        void PlanHandoverCrane()
        {
            var moveId        = plan.Moves.Count;
            var sourceRequest = new List <(Location, int, Block, MoveRequest)>();

            foreach (var req in world.MoveRequests)
            {
                foreach (var src in BufferStacks())
                {
                    var(block, pos) = src.Stack.BottomToTop.Select((slab, idx) => (slab, idx)).FirstOrDefault(x => x.slab.Id == req.BlockId);
                    if (block != null)
                    {
                        sourceRequest.Add((src, pos, block, req));
                        break;
                    }
                }
            }


            sourceRequest.Sort((a, b) => (SizeOf(a.Item1) - a.Item2).CompareTo(SizeOf(a.Item1) - a.Item2));

            foreach (var(src, pos, block, req) in sourceRequest)
            {
                var ty            = block.Type;
                var seq           = block.Sequence;
                var couldTakeTopN = src.Stack.BottomToTop.Reverse().TakeWhile(b => {
                    var isNext = b.Type == ty && b.Sequence == seq;
                    seq       += 1;
                    return(isNext);
                }).Count();

                var mov = new CraneMove();
                moveId         += 1;
                mov.Id          = moveId;
                mov.Type        = MoveType.PickupAndDropoff;
                mov.ReleaseTime = new TimeStamp()
                {
                    MilliSeconds = world.Now.MilliSeconds
                };
                mov.PickupLocationId = src.Id;

                if (couldTakeTopN > 0)
                {
                    var amount = Math.Min(couldTakeTopN, world.HandoverCrane.CraneCapacity);
                    mov.DropoffLocationId = req.TargetLocationId;
                    mov.RequiredCraneId   = world.HandoverCrane.Id;
                    mov.Amount            = amount;
                }
                else
                {
                    // Relocate blocks that are in the way
                    var mustRelocate = SizeOf(src) - pos - 1;
                    var amount       = Math.Min(mustRelocate, world.HandoverCrane.CraneCapacity);
                    var tgt          = BufferStacks().FirstOrDefault(tgt => tgt.Id != src.Id && RemainingCapacity(tgt) >= amount);
                    if (tgt != null)
                    {
                        mov.DropoffLocationId = tgt.Id;
                        mov.RequiredCraneId   = world.HandoverCrane.Id;
                        mov.Amount            = amount;
                    }
                    else
                    {
                        continue;
                    }
                }
                plan.Moves.Add(mov);
                return;
            }
        }
        private IEnumerable <Event> OrderGenerator()
        {
            var moveId = _world.CraneMoves.Count == 0 ? 0 : _world.CraneMoves.Select(x => x.Id).Max();

            while (true)
            {
                var newMoves = false;
                foreach (var b in _world.AllBlocks())
                {
                    var loc = _world.Locations.SingleOrDefault(x => x.Stack.Topmost == b);
                    if (loc == null || _world.CraneMoves.Any(x => x.PickupLocationId == loc.Id || x.DropoffLocationId == loc.Id))
                    {
                        continue;
                    }
                    var freeTargets = (from l in _world.Locations
                                       let lm = _world.CraneMoves.Where(x => x.Type == MoveType.PickupAndDropoff &&
                                                                        (x.PickupLocationId == l.Id || x.DropoffLocationId == l.Id)).ToList()
                                                where l.Id != loc.Id &&
                                                lm.Sum(x => {
                        if (x.PickupLocationId == l.Id)
                        {
                            return(-x.Amount);
                        }
                        if (x.DropoffLocationId == l.Id)
                        {
                            return(x.Amount);
                        }
                        return(0);
                    }) + l.Height < l.MaxHeight &&
                                                l.FreeHeight > 0
                                                select new { Location = l, Moves = lm }).ToList();
                    if (freeTargets.Count == 0)
                    {
                        continue;
                    }

                    var choice = Environment.RandChoice(freeTargets, freeTargets.Select(x => 1.0).ToList());
                    var move   = new CraneMove()
                    {
                        Amount                = 1,
                        DueDate               = new TimeStamp(long.MaxValue),
                        PickupLocationId      = loc.Id,
                        PickupGirderPosition  = loc.GirderPosition,
                        DropoffLocationId     = choice.Location.Id,
                        DropoffGirderPosition = choice.Location.GirderPosition,
                        Id             = ++moveId,
                        PredecessorIds = new HashSet <int>(choice.Moves.Select(x => x.Id)),
                        ReleaseTime    = Now,
                        Type           = MoveType.PickupAndDropoff
                    };
                    _world.CraneMoves.Add(move);
                    _moves.Add(new CraneMoveEvent(Environment, move));
                    newMoves = true;
                }
                if (newMoves)
                {
                    _scheduler.Schedule();
                }
                yield return(new AnyOf(Environment, CraneMoves.Select(x => x.Finished)));

                foreach (var finished in CraneMoves.Where(x => x.Finished.IsProcessed).ToList())
                {
                    for (var i = 0; i < _world.CraneMoves.Count; i++)
                    {
                        if (_world.CraneMoves[i].Id == finished.Id)
                        {
                            _world.CraneMoves.RemoveAt(i); break;
                        }
                    }
                    _moves.Remove(finished);
                }
            }
        }
Beispiel #9
0
 public static string FormatOutput(this CraneMove move)
 {
     return($"Move Block {move.BlockId} from {move.SourceId} to {move.TargetId}");
 }
Beispiel #10
0
        public double CalculateMoveReward(CraneMove move)
        {
            double reward   = 0;
            var    oldState = new RFState(this);
            var    newState = oldState.Apply(move);

            if (move.TargetId == Handover.Id)
            {
                reward += 500;
            }
            else
            {
                if (move.SourceId == Production.Id)
                {
                    reward += 15;
                    var productionFill = oldState.Production.Count / (double)oldState.Production.MaxHeight;

                    if (productionFill >= 1)
                    {
                        reward += 600;
                    }
                    else if (productionFill >= 0.75)
                    {
                        reward += 150;
                    }
                    else if (productionFill > 0.25)
                    {
                        reward += 25;
                    }

                    if (oldState.Buffers.First(stack => stack.Id == move.TargetId).ContainsReady)
                    {
                        if (oldState.Buffers.First(stack => stack.Id == move.TargetId).Top().Ready)
                        {
                            reward -= 100;
                        }
                        else
                        {
                            reward -= 25;
                        }
                    }
                }
                else
                {
                    var oldSourceBuffer = oldState.Buffers.First(stack => stack.Id == move.SourceId);
                    var oldTargetBuffer = oldState.Buffers.First(stack => stack.Id == move.TargetId);
                    var newSourceBuffer = newState.Buffers.First(stack => stack.Id == move.SourceId);
                    var newTargetBuffer = newState.Buffers.First(stack => stack.Id == move.TargetId);

                    if (!oldTargetBuffer.ContainsReady || oldTargetBuffer.IsEmpty)
                    {
                        reward += 20;
                    }
                    else if (oldTargetBuffer.ContainsReady)
                    {
                        if (oldTargetBuffer.Top().Ready)
                        {
                            reward -= 100;
                        }
                        else
                        {
                            reward -= 30;
                        }
                    }

                    if (oldTargetBuffer.ContainsDueBelow(new TimeStamp()
                    {
                        MilliSeconds = 5 * 60000
                    }))
                    {
                        reward -= 10;
                    }

                    if (oldTargetBuffer.BlocksAboveReady() < newTargetBuffer.BlocksAboveReady())
                    {
                        reward -= 20;
                    }

                    if (oldSourceBuffer.BlocksAboveReady() > newSourceBuffer.BlocksAboveReady())
                    {
                        reward += 40;
                    }

                    if (oldSourceBuffer.ContainsReady)
                    {
                        reward += (oldSourceBuffer.MaxHeight - oldSourceBuffer.BlocksAboveReady()) * 10;
                    }

                    if (newSourceBuffer.Top() != null && newSourceBuffer.Top().Ready)
                    {
                        reward += 100;
                    }
                }
            }
            return(reward);
        }