static void ExecuteTurn(ProblemDescription description, List<Drone> drones, List<Command> commands)
 {
     foreach (var drone in drones)
     {
         drone.ExecuteTurn(description, commands);
     }
 }
Beispiel #2
0
 static void ExecuteTurn(ProblemDescription description, List <Drone> drones, List <Command> commands)
 {
     foreach (var drone in drones)
     {
         drone.ExecuteTurn(description, commands);
     }
 }
        public int?GetBestOrder(ProblemDescription description, Position nextPosition)
        {
            var orders = description.Orders
                         .Select((order, orderId) => new { order, orderId })
                         .OrderBy(item =>
            {
                double score = 0;
                Position pos = nextPosition;
                var path     = FindBestPath(item.order, description);
                if (path == null)
                {
                    return(int.MaxValue);
                }
                foreach (var a in path)
                {
                    score += 0.8 * DistanceCalculator.CalculateDistance(pos, description.Warehouses[a].position);
                    score += 0.2 * description.Orders.Where(order => order.RealId == item.order.RealId).Sum(order => order.orderedProducts.Sum(orderx => orderx.Value));
                    pos    = description.Warehouses[a].position;
                }
                score += DistanceCalculator.CalculateDistance(pos, item.order.position);
                return(score);
            }).ToList();

            return(orders.FirstOrDefault()?.orderId);
        }
        public void ExecuteOrder(ProblemDescription description, int i, List <Command> commands)
        {
            var order = description.Orders[i];

            description.Orders.RemoveAt(i);
            var orderProductsAux = new Dictionary <int, int>(order.orderedProducts);

            var warehouseList = FindBestPath(order, description);

            foreach (int idWarehouse in warehouseList)
            {
                foreach (int idProd in order.orderedProducts.Keys.ToList())
                {
                    if (order.orderedProducts[idProd] == 0)
                    {
                        continue;
                    }

                    if (idProd >= description.Warehouses[idWarehouse].heldProducts.Count)
                    {
                        continue;
                    }
                    if (description.Warehouses[idWarehouse].heldProducts[idProd] > 0)
                    {
                        int ammountToRetrieve = Math.Min(order.orderedProducts[idProd], description.Warehouses[idWarehouse].heldProducts[idProd]);

                        description.Warehouses[idWarehouse].heldProducts[idProd] -= ammountToRetrieve; //remove from available on wh
                        order.orderedProducts[idProd] -= ammountToRetrieve;                            //remove from order

                        LoadCommand command = new LoadCommand();
                        command.DroneId       = Id;
                        command.WarehouseId   = idWarehouse;
                        command.ProductId     = idProd;
                        command.ProductAmount = ammountToRetrieve;
                        commands.Add(command);
                    }
                    TurnsToNextAction += DistanceCalculator.CalculateDistance(NextPosition, description.Warehouses[idWarehouse].position) + 1;
                    NextPosition       = description.Warehouses[idWarehouse].position;
                }
            }
            foreach (int idProd in orderProductsAux.Keys)
            {
                if (orderProductsAux[idProd] == 0)
                {
                    continue;
                }
                var command = new DeliverCommand();
                command.DroneId       = Id;
                command.CustomerId    = order.RealId;
                command.ProductId     = idProd;
                command.ProductAmount = orderProductsAux[idProd];
                commands.Add(command);
                TurnsToNextAction += DistanceCalculator.CalculateDistance(NextPosition, order.position) + 1;
                NextPosition       = order.position;
            }
        }
Beispiel #5
0
 static void Main(string[] args)
 {
     string[] inputs = { "busy_day.in", "mother_of_all_warehouses.in", "redundancy.in" };
     Parallel.ForEach(inputs, input =>
     {
         var description = ProblemDescription.LoadFromFile(input);
         var commands    = Solver.Execute(description);
         SolutionWriter.WriteToFile(commands, input + ".out");
     });
 }
        private static int GetOrderLoad(ProblemDescription description, Order order)
        {
            int total = 0;

            foreach (var item in order.orderedProducts)
            {
                var type     = item.Key;
                var quantity = item.Value;
                total += description.ProductWeights[type] * quantity;
            }

            return(total);
        }
        internal void ExecuteTurn(ProblemDescription description, List <Command> commands)
        {
            if (TurnsToNextAction > 0)
            {
                --TurnsToNextAction;
            }
            else
            {
                var bestOrder = GetBestOrder(description, NextPosition);

                if (bestOrder != null)
                {
                    ExecuteOrder(description, bestOrder.Value, commands);
                }
            }
        }
        public static List<Command> Execute(ProblemDescription description)
        {
            var commands = new List<Command>();
            var drones = new List<Drone>();
            for (int i = 0; i < description.NumDrones; ++i)
            {
                drones.Add(new Drone(i, description.Warehouses[0].position));
            }

            for (int turnId = 0; turnId < description.Deadline; ++turnId)
            {
                ExecuteTurn(description, drones, commands);
            }

            return commands;
        }
        private static void BreakAndAddOrder(ProblemDescription description, Order order)
        {
            int maxPayload = description.MaximumLoad;

            while (GetOrderLoad(description, order) > maxPayload)
            {
                var newOrder = new Order();
                newOrder.RealId   = order.RealId;
                newOrder.position = order.position;
                int newLoad = 0;

                for (;;)
                {
                    int heaviestItemSoFar = -1;
                    int bestWeight        = int.MinValue;
                    foreach (var item in order.orderedProducts)
                    {
                        if (item.Value == 0)
                        {
                            continue;
                        }

                        int weight = description.ProductWeights[item.Key];
                        if (newLoad + weight < maxPayload && weight > bestWeight)
                        {
                            heaviestItemSoFar = item.Key;
                            bestWeight        = weight;
                        }
                    }

                    if (heaviestItemSoFar < 0)
                    {
                        break;
                    }

                    int numItems = (maxPayload - newLoad) / bestWeight;
                    numItems = Math.Min(numItems, order.orderedProducts[heaviestItemSoFar]);
                    order.orderedProducts[heaviestItemSoFar]   -= numItems;
                    newOrder.orderedProducts[heaviestItemSoFar] = numItems;
                    newLoad += numItems * bestWeight;
                }

                description.Orders.Add(newOrder);
            }
            description.Orders.Add(order);
        }
Beispiel #10
0
        public static List <Command> Execute(ProblemDescription description)
        {
            var commands = new List <Command>();
            var drones   = new List <Drone>();

            for (int i = 0; i < description.NumDrones; ++i)
            {
                drones.Add(new Drone(i, description.Warehouses[0].position));
            }

            for (int turnId = 0; turnId < description.Deadline; ++turnId)
            {
                ExecuteTurn(description, drones, commands);
            }

            return(commands);
        }
        public void ExecuteOrder(ProblemDescription description, int i, List<Command> commands)
        {
            var order = description.Orders[i];
            description.Orders.RemoveAt(i);
            var orderProductsAux = new Dictionary<int,int>(order.orderedProducts);

            var warehouseList = FindBestPath(order, description);

            foreach (int idWarehouse in warehouseList)
            {
                foreach(int idProd in order.orderedProducts.Keys.ToList()) {
                    if (order.orderedProducts[idProd] == 0) continue;

                    if (idProd >= description.Warehouses[idWarehouse].heldProducts.Count) continue;
                    if (description.Warehouses[idWarehouse].heldProducts[idProd] > 0)
                    {
                        int ammountToRetrieve = Math.Min(order.orderedProducts[idProd], description.Warehouses[idWarehouse].heldProducts[idProd]);

                        description.Warehouses[idWarehouse].heldProducts[idProd] -= ammountToRetrieve; //remove from available on wh
                        order.orderedProducts[idProd] -= ammountToRetrieve; //remove from order

                        LoadCommand command = new LoadCommand();
                        command.DroneId = Id;
                        command.WarehouseId = idWarehouse;
                        command.ProductId = idProd;
                        command.ProductAmount = ammountToRetrieve;
                        commands.Add(command);
                    }
                    TurnsToNextAction += DistanceCalculator.CalculateDistance(NextPosition, description.Warehouses[idWarehouse].position) + 1;
                    NextPosition = description.Warehouses[idWarehouse].position;
                }
            }
            foreach(int idProd in orderProductsAux.Keys)
            {
                if (orderProductsAux[idProd] == 0) continue;
                var command = new DeliverCommand();
                command.DroneId = Id;
                command.CustomerId = order.RealId;
                command.ProductId = idProd;
                command.ProductAmount = orderProductsAux[idProd];
                commands.Add(command);
                TurnsToNextAction += DistanceCalculator.CalculateDistance(NextPosition, order.position) + 1;
                NextPosition = order.position;
            }
        }
 public int? GetBestOrder(ProblemDescription description, Position nextPosition)
 {
     var orders = description.Orders
         .Select((order, orderId) => new { order, orderId })
         .OrderBy(item =>
     {
         double score = 0;
         Position pos = nextPosition;
         var path = FindBestPath(item.order, description);
         if (path == null) return int.MaxValue;
         foreach (var a in path)
         {
             score += 0.8 * DistanceCalculator.CalculateDistance(pos, description.Warehouses[a].position);
             score += 0.2 * description.Orders.Where(order => order.RealId == item.order.RealId).Sum(order => order.orderedProducts.Sum(orderx => orderx.Value));
             pos = description.Warehouses[a].position;
         }
         score += DistanceCalculator.CalculateDistance(pos, item.order.position);
         return score;
     }).ToList();
     return orders.FirstOrDefault()?.orderId;
 }
        private List <int> FindBestPath(Order order, ProblemDescription description)
        {
            List <int> warehouseList = new List <int>();

            // FIXME: Do this better.
            // We may be able to find a single warehouse with everything.
            // So maybe try multiple alternatives

            Dictionary <int, int> missingItems = new Dictionary <int, int>(order.orderedProducts);

            List <Tuple <Warehouse, int> > warehouses = description.Warehouses
                                                        .Select((warehouse, warehouseId) => Tuple.Create(warehouse, warehouseId))
                                                        .ToList();

            var activePosition = NextPosition;

            for (;;)
            {
                int maxValue = int.MaxValue;
                int minIndex = -1;
                for (int i = 0; i < warehouses.Count; ++i)
                {
                    var warehouse = warehouses[i];
                    var distance  = DistanceCalculator.CalculateSquareDistance(activePosition, warehouse.Item1.position);
                    if (distance < maxValue)
                    {
                        maxValue = distance;
                        minIndex = i;
                    }
                }

                var tuple = warehouses[minIndex];

                var  heldProducts = tuple.Item1.heldProducts;
                bool anyMatch     = false;

                foreach (var itemType in missingItems.Keys.ToList())
                {
                    if (missingItems[itemType] == 0)
                    {
                        continue;
                    }

                    if (itemType < heldProducts.Count && heldProducts[itemType] > 0)
                    {
                        var numProducts = Math.Min(heldProducts[itemType], missingItems[itemType]);

                        anyMatch = true;
                        missingItems[itemType] -= numProducts;
                        if (missingItems[itemType] == 0)
                        {
                            missingItems.Remove(itemType);
                        }
                    }
                }

                if (anyMatch)
                {
                    warehouseList.Add(tuple.Item2);
                    warehouses.Remove(tuple);
                    activePosition = tuple.Item1.position;
                    break;
                }

                if (missingItems.Count == 0)
                {
                    break;
                }

                return(null);
            }

            return(warehouseList);
        }
        public static ProblemDescription LoadFromFile(string path)
        {
            var description = new ProblemDescription();

            using (var reader = File.OpenText(path))
            {
                var parametersLine = reader.ReadLine();

                var parameters = parametersLine.Split(' ');

                description.NumRows = int.Parse(parameters[0]);
                description.NumCols = int.Parse(parameters[1]);

                description.NumDrones = int.Parse(parameters[2]);
                description.Deadline = int.Parse(parameters[3]);
                description.MaximumLoad = int.Parse(parameters[4]);

                var numProducts = int.Parse(reader.ReadLine());

                description.ProductWeights = reader.ReadLine()
                    .Split(' ')
                    .Select(int.Parse)
                    .ToList();

                int numWarehouses = int.Parse(reader.ReadLine());
                for (int i = 0; i < numWarehouses; ++i)
                {
                    var locationLine = reader.ReadLine();
                    var location = locationLine.Split(' ');

                    var warehouse = new Warehouse();
                    warehouse.position = new Position(int.Parse(location[0]),
                        int.Parse(location[1]));
                    warehouse.heldProducts = reader.ReadLine()
                        .Split(' ')
                        .Select(int.Parse)
                        .ToList();

                    description.Warehouses.Add(warehouse);
                }

                int numOrders = int.Parse(reader.ReadLine());
                int orderId = 0;
                for (int i = 0; i < numOrders; ++i)
                {
                    var locationLine = reader.ReadLine();
                    var location = locationLine.Split(' ');

                    var order = new Order();
                    order.RealId = orderId++;
                    order.position = new Position(int.Parse(location[0]),
                        int.Parse(location[1]));

                    int numProductTypes = int.Parse(reader.ReadLine());
                    var orderInfoLine = reader.ReadLine();
                    var orderInfoItems = orderInfoLine.Split(' ');
                    for (int j = 0; j < numProductTypes; ++j)
                    {
                        var productType = int.Parse(orderInfoItems[j]);

                        if (order.orderedProducts.ContainsKey(productType))
                        {
                            order.orderedProducts[productType]++;
                        } else
                        {
                            order.orderedProducts[productType] = 1;
                        }
                    }

                    BreakAndAddOrder(description, order);
                }
            }

            return description;
        }
        private static int GetOrderLoad(ProblemDescription description, Order order)
        {
            int total = 0;
            foreach (var item in order.orderedProducts)
            {
                var type = item.Key;
                var quantity = item.Value;
                total += description.ProductWeights[type] * quantity;
            }

            return total;
        }
        internal void ExecuteTurn(ProblemDescription description, List<Command> commands)
        {
            if (TurnsToNextAction > 0)
            {
                --TurnsToNextAction;
            } else
            {
                var bestOrder = GetBestOrder(description, NextPosition);

                if (bestOrder != null)
                {
                    ExecuteOrder(description, bestOrder.Value, commands);
                }
            }
        }
        public static ProblemDescription LoadFromFile(string path)
        {
            var description = new ProblemDescription();

            using (var reader = File.OpenText(path))
            {
                var parametersLine = reader.ReadLine();

                var parameters = parametersLine.Split(' ');

                description.NumRows = int.Parse(parameters[0]);
                description.NumCols = int.Parse(parameters[1]);

                description.NumDrones   = int.Parse(parameters[2]);
                description.Deadline    = int.Parse(parameters[3]);
                description.MaximumLoad = int.Parse(parameters[4]);

                var numProducts = int.Parse(reader.ReadLine());

                description.ProductWeights = reader.ReadLine()
                                             .Split(' ')
                                             .Select(int.Parse)
                                             .ToList();

                int numWarehouses = int.Parse(reader.ReadLine());
                for (int i = 0; i < numWarehouses; ++i)
                {
                    var locationLine = reader.ReadLine();
                    var location     = locationLine.Split(' ');

                    var warehouse = new Warehouse();
                    warehouse.position = new Position(int.Parse(location[0]),
                                                      int.Parse(location[1]));
                    warehouse.heldProducts = reader.ReadLine()
                                             .Split(' ')
                                             .Select(int.Parse)
                                             .ToList();

                    description.Warehouses.Add(warehouse);
                }

                int numOrders = int.Parse(reader.ReadLine());
                int orderId   = 0;
                for (int i = 0; i < numOrders; ++i)
                {
                    var locationLine = reader.ReadLine();
                    var location     = locationLine.Split(' ');

                    var order = new Order();
                    order.RealId   = orderId++;
                    order.position = new Position(int.Parse(location[0]),
                                                  int.Parse(location[1]));

                    int numProductTypes = int.Parse(reader.ReadLine());
                    var orderInfoLine   = reader.ReadLine();
                    var orderInfoItems  = orderInfoLine.Split(' ');
                    for (int j = 0; j < numProductTypes; ++j)
                    {
                        var productType = int.Parse(orderInfoItems[j]);

                        if (order.orderedProducts.ContainsKey(productType))
                        {
                            order.orderedProducts[productType]++;
                        }
                        else
                        {
                            order.orderedProducts[productType] = 1;
                        }
                    }

                    BreakAndAddOrder(description, order);
                }
            }

            return(description);
        }
        private static void BreakAndAddOrder(ProblemDescription description, Order order)
        {
            int maxPayload = description.MaximumLoad;

            while (GetOrderLoad(description, order) > maxPayload)
            {
                var newOrder = new Order();
                newOrder.RealId = order.RealId;
                newOrder.position = order.position;
                int newLoad = 0;

                for (;;)
                {
                    int heaviestItemSoFar = -1;
                    int bestWeight = int.MinValue;
                    foreach (var item in order.orderedProducts)
                    {
                        if (item.Value == 0) continue;

                        int weight = description.ProductWeights[item.Key];
                        if (newLoad + weight < maxPayload && weight > bestWeight)
                        {
                            heaviestItemSoFar = item.Key;
                            bestWeight = weight;
                        }
                    }

                    if (heaviestItemSoFar < 0)
                    {
                        break;
                    }

                    int numItems = (maxPayload - newLoad) / bestWeight;
                    numItems = Math.Min(numItems, order.orderedProducts[heaviestItemSoFar]);
                    order.orderedProducts[heaviestItemSoFar] -= numItems;
                    newOrder.orderedProducts[heaviestItemSoFar] = numItems;
                    newLoad += numItems * bestWeight;
                }

                description.Orders.Add(newOrder);
            }
            description.Orders.Add(order);
        }
        private List<int> FindBestPath(Order order, ProblemDescription description)
        {
            List<int> warehouseList = new List<int>();

            // FIXME: Do this better.
            // We may be able to find a single warehouse with everything.
            // So maybe try multiple alternatives

            Dictionary<int, int> missingItems = new Dictionary<int, int>(order.orderedProducts);

            List<Tuple<Warehouse, int>> warehouses = description.Warehouses
                .Select((warehouse, warehouseId) => Tuple.Create(warehouse, warehouseId))
                .ToList();

            var activePosition = NextPosition;
            for (;;)
            {
                int maxValue = int.MaxValue;
                int minIndex = -1;
                for (int i = 0; i < warehouses.Count; ++i)
                {
                    var warehouse = warehouses[i];
                    var distance = DistanceCalculator.CalculateSquareDistance(activePosition, warehouse.Item1.position);
                    if (distance < maxValue)
                    {
                        maxValue = distance;
                        minIndex = i;
                    }
                }

                var tuple = warehouses[minIndex];

                var heldProducts = tuple.Item1.heldProducts;
                bool anyMatch = false;

                foreach (var itemType in missingItems.Keys.ToList())
                {
                    if (missingItems[itemType] == 0)
                    {
                        continue;
                    }

                    if (itemType < heldProducts.Count && heldProducts[itemType] > 0)
                    {
                        var numProducts = Math.Min(heldProducts[itemType], missingItems[itemType]);

                        anyMatch = true;
                        missingItems[itemType] -= numProducts;
                        if (missingItems[itemType] == 0)
                        {
                            missingItems.Remove(itemType);
                        }
                    }
                }

                if (anyMatch)
                {
                    warehouseList.Add(tuple.Item2);
                    warehouses.Remove(tuple);
                    activePosition = tuple.Item1.position;
                    break;
                }

                if (missingItems.Count == 0)
                {
                    break;
                }

                return null;
            }

            return warehouseList;
        }