static void ExecuteTurn(ProblemDescription description, List<Drone> drones, List<Command> commands) { foreach (var drone in drones) { drone.ExecuteTurn(description, commands); } }
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; } }
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); }
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; }