private double GetScore(BuildingProject item, CellType[,] filledCells, MatrixCoordinate inputCoordinate) { if (inputCoordinate.Row + item.Plan.GetLength(0) > filledCells.GetLength(0) || inputCoordinate.Column + item.Plan.GetLength(1) > filledCells.GetLength(1)) { return(int.MinValue); } if (!InMatrix(inputCoordinate.Row + item.Plan.GetLength(0) - 1, inputCoordinate.Column + item.Plan.GetLength(1) - 1)) { return(int.MinValue); } for (int row = 0; row < item.Plan.GetLength(0); row++) { for (int col = 0; col < item.Plan.GetLength(1); col++) { int rowToCheck = inputCoordinate.Row + row; int colToCheck = inputCoordinate.Column + col; if (filledCells[rowToCheck, colToCheck].IsOccupied) { return(int.MinValue); } } } if (item.BuildingType == BuildingType.Residential) { return(1.0 * GetResidntialScore(item, filledCells, inputCoordinate)); } return(1.0 * GetUtilityScore(item, filledCells, inputCoordinate)); }
public Load(int droneId, int warehouseId, int productId, int countOfProducts, int time, int endTime, MatrixCoordinate startPosition) { DroneId = droneId; WarehouseId = warehouseId; ProductId = productId; CountOfProducts = countOfProducts; Time = time; EndTime = endTime; StartPosition = startPosition; }
private MatrixCoordinate AddBestProject(CellType[,] filledCells, MatrixCoordinate first, BuildingProject bestProject) { resId++; for (int row = 0; row < bestProject.Plan.GetLength(0); row++) { for (int col = 0; col < bestProject.Plan.GetLength(1); col++) { if (filledCells[row + first.Row, first.Column + col].IsOccupied) { int n = 0; } filledCells[row + first.Row, first.Column + col].IsOccupied = bestProject.Plan[row, col]; filledCells[row + first.Row, first.Column + col].BuildingType = bestProject.BuildingType; filledCells[row + first.Row, first.Column + col].BuildingIndex = bestProject.Index; filledCells[row + first.Row, first.Column + col].BuildingUniqueIndex = resId; for (int i = -m_Input.MaxDistance; i <= m_Input.MaxDistance; i++) { for (int j = -m_Input.MaxDistance + Math.Abs(i); j <= m_Input.MaxDistance - Math.Abs(i); j++) { int rowToCheck = row + i; int colToCheck = col + i; if (!InMatrix(rowToCheck, colToCheck)) { continue; } var cellToCheck = filledCells[rowToCheck, colToCheck]; if (!cellToCheck.IsOccupied) { continue; } if (cellToCheck.BuildingType == BuildingType.Utility) { filledCells[row + first.Row, first.Column + col].NearUtilities.Add(cellToCheck.UtilityIndex); } else { if (bestProject.BuildingType == BuildingType.Utility) { cellToCheck.NearUtilities.Add(bestProject.UtilityType); } } } } } } return(first); }
private static MatrixCoordinate[] NewMethod(TextReader reader) { int numOfBackbones = int.Parse(reader.ReadLine()); MatrixCoordinate[] coordaintes = new MatrixCoordinate[numOfBackbones]; for (int i = 0; i < numOfBackbones; i++) { string line = reader.ReadLine(); coordaintes[i] = new MatrixCoordinate(line[0], line[1]); } return(coordaintes); }
private static List <MatrixCoordinate> CalculateRouterCoordinates(ProblemInput input, Dictionary <MatrixCoordinate, ScoredCoordinate> scoreDictionary, SortedSet <ScoredCoordinate> set, Cell[,] cells) { int maxRouters = (int)Math.Ceiling((double)input.StartingBudger / input.RouterPrice); List <MatrixCoordinate> coordinates = new List <MatrixCoordinate>(); for (int i = 0; i < maxRouters; i++) { var max = set.Max; if (max.Score != 0) { MatrixCoordinate coordinate = max.Coordinate; coordinates.Add(coordinate); var routerRadius = input.RouterRadius; var notPossible = GetNotPossibleCells(input, cells, coordinate.Row, coordinate.Column, routerRadius); for (int k = 0; k < notPossible.GetLength(0); k++) { for (int l = 0; l < notPossible.GetLength(1); l++) { if (!notPossible[k, l]) { var x = coordinate.Row + k - routerRadius; var y = coordinate.Column + l - routerRadius; if (x >= 0 && x < cells.GetLength(0) && y >= 0 && y < cells.GetLength(1)) { var key = new MatrixCoordinate(x, y); if (scoreDictionary.TryGetValue(key, out var value)) { set.Remove(value); value.Score--; if (value.Score > 0) { set.Add(value); } } } } } } } else { break; } } return(coordinates); }
private int GetUtilityScore(BuildingProject item, CellType[,] filledCells, MatrixCoordinate inputCoordinate) { HashSet <int> nearResidntials = new HashSet <int>(); List <int> nearResidntials2 = new List <int>(); foreach (var currCoordinate in m_AffectedCoordinates[item]) { if (!InMatrix(currCoordinate.Row + inputCoordinate.Row, currCoordinate.Column + inputCoordinate.Column)) { continue; } var cellToCheck = filledCells[currCoordinate.Row + inputCoordinate.Row, currCoordinate.Column + inputCoordinate.Column]; if (!cellToCheck.IsOccupied) { continue; } if (cellToCheck.BuildingType == BuildingType.Utility) { continue; } if (cellToCheck.NearUtilities.Contains(item.UtilityType)) { continue; } if (nearResidntials.Add(cellToCheck.BuildingUniqueIndex)) { nearResidntials2.Add(cellToCheck.BuildingIndex); } } if (nearResidntials2.Any()) { return(nearResidntials2.Sum(_ => m_Input.BuildingProjects[_].Capacity)); } return(1); }
private void TourmenetSolution(ProblemInput input, ProblemOutput output, CellType[,] filledCells) { List <MatrixCoordinate> possiblePoints = new List <MatrixCoordinate> { new MatrixCoordinate(0, 0) }; while (possiblePoints.Count != 0) { MatrixCoordinate first = possiblePoints[0]; if (first.Row == 99) { int n = 0; } possiblePoints.RemoveAt(0); BuildingProject bestProject = GetBestFit(input.BuildingProjects, filledCells, first); if (bestProject == null) { continue; } if (output.Buildings.Count == 1700) { int r = 0; } first = AddBestProject(filledCells, first, bestProject); possiblePoints.Add(new MatrixCoordinate(first.Row + bestProject.Plan.GetLength(0), first.Column)); possiblePoints.Add(new MatrixCoordinate(first.Row, first.Column + bestProject.Plan.GetLength(1))); possiblePoints.Add(new MatrixCoordinate(first.Row + bestProject.Plan.GetLength(0), first.Column + bestProject.Plan.GetLength(1))); output.Buildings.Add(new OutputBuilding() { Coordinate = first, ProjectNumber = bestProject.Index }); } }
public Warehouse(int columnPosition, int rowPosition, int[] numberOfItemsForProduct, int index) : base(index) { Coordinate = new MatrixCoordinate(rowPosition, columnPosition); NumberOfItemsForProduct = numberOfItemsForProduct; }
protected override ProblemOutput Solve(ProblemInput input) { Dictionary <MatrixCoordinate, ScoredCoordinate> scoreDictionary = new Dictionary <MatrixCoordinate, ScoredCoordinate>(); SortedSet <ScoredCoordinate> set = new SortedSet <ScoredCoordinate>(new Shit()); Cell[,] cells = input.Cells; int[,] cellScores = new int[cells.GetLength(0), cells.GetLength(1)]; for (int i = 0; i < cells.GetLength(0); i++) { for (int j = 0; j < cells.GetLength(1); j++) { if (cells[i, j] == Cell.Traget) { InitScoreMatrix(input, cells, cellScores, i, j); } } } for (int i = 0; i < cellScores.GetLength(0); i++) { for (int j = 0; j < cellScores.GetLength(1); j++) { var coordinate = new MatrixCoordinate(i, j); var cellScore = cellScores[i, j]; if (cellScore != 0) { var item = new ScoredCoordinate { Coordinate = coordinate, Score = cellScore }; scoreDictionary.Add(coordinate, item); set.Add(item); } } } int budget = input.StartingBudger; List <MatrixCoordinate> coordinates = CalculateRouterCoordinates(input, scoreDictionary, set, cells); int cost = 0; List <MatrixCoordinate> routerCoordinates = new List <MatrixCoordinate>(); HashSet <MatrixCoordinate> backBoneCoordinates = new HashSet <MatrixCoordinate>(); foreach (var coordinate in coordinates) { MatrixCoordinate startingBackbonePosition = input.StartingBackbonePosition; cost += input.RouterPrice; MatrixCoordinate backboneCoordinate = coordinate; List <Coordinate> coords = new List <Coordinate>(); while (!backboneCoordinate.Equals(startingBackbonePosition) && budget > cost) { if (backBoneCoordinates.Add(backboneCoordinate)) { cost += input.BackBonePrice; } backboneCoordinate = new MatrixCoordinate(backboneCoordinate.Row - Math.Sign(backboneCoordinate.Row - startingBackbonePosition.Row), backboneCoordinate.Column - Math.Sign(backboneCoordinate.Column - startingBackbonePosition.Column)); } if (cost > budget) { break; } routerCoordinates.Add(coordinate); } backBoneCoordinates.Add(input.StartingBackbonePosition); return(new ProblemOutput { BackBoneCoordinates = backBoneCoordinates.ToArray(), RouterCoordinates = routerCoordinates.ToArray() }); }
protected override ProblemOutput Solve(ProblemInput input) { List <Drone> drones = new List <Drone>(); for (int i = 0; i < input.NumberOfDrones; i++) { drones.Add(new Drone(i)); } ProblemOutput output = new ProblemOutput(); foreach (var order in SolverHelper.OrderOrders(input, drones)) { List <Drone> usedDrones = new List <Drone>(); foreach (var product in order.ProductsInOrder) { if (product.Value * input.Products[product.Key].Weight > input.MaxDrownLoad) { // throw new NotSupportedException(); break; } Drone selectedDrone = null; Warehouse selectedWarehouse = null; int minTime = int.MaxValue; foreach (var warehouse in input.Warehouses) { // TODO: Handle drone can't load all items if (warehouse.NumberOfItemsForProduct[product.Key] > product.Value) { foreach (var drone in drones) { var time = drone.CurrentTime + Math.Ceiling(drone.CurrentPosition.CalcEucledianDistance(warehouse.Coordinate)) + 1 + Math.Ceiling(warehouse.Coordinate.CalcEucledianDistance(order.Coordinate)) + 1; if (time < minTime && time < input.NumberOfIterations) { minTime = (int)time; selectedDrone = drone; selectedWarehouse = warehouse; } } } } if (selectedDrone == null) { SolverHelper.CancelOrders(usedDrones, output); break; } else { usedDrones.Add(selectedDrone); var time = selectedDrone.CurrentTime + Math.Ceiling(selectedDrone.CurrentPosition.CalcEucledianDistance(selectedWarehouse.Coordinate)) + 1 + Math.Ceiling(selectedWarehouse.Coordinate.CalcEucledianDistance(order.Coordinate)) + 1; int firstOrderTime = selectedDrone.CurrentTime; MatrixCoordinate firstOrderCoordinate = selectedDrone.CurrentPosition; int lastOrderTime = selectedDrone.CurrentTime - 1 - (int)Math.Ceiling(selectedWarehouse.Coordinate.CalcEucledianDistance(order.Coordinate)); selectedDrone.CurrentTime += (int)time; selectedDrone.CurrentPosition = order.Coordinate; output.Add(new Load(selectedDrone.Index, order.Index, product.Key, product.Value, firstOrderTime, lastOrderTime, firstOrderCoordinate)); output.Add(new Deliver(selectedDrone.Index, order.Index, product.Key, product.Value, lastOrderTime, selectedDrone.CurrentTime)); } } } return(output); }
private int GetResidntialScore(BuildingProject item, CellType[,] filledCells, MatrixCoordinate inputCoordinate) { // return (int)(100.0 * item.Capacity / item.Plan.GetLength(0) / item.Plan.GetLength(1)); HashSet <int> nearUtilities = new HashSet <int>(); foreach (var currCoordinate in m_AffectedCoordinates[item]) { if (!InMatrix(currCoordinate.Row + inputCoordinate.Row, currCoordinate.Column + inputCoordinate.Column)) { continue; } var cellToCheck = filledCells[currCoordinate.Row + inputCoordinate.Row, currCoordinate.Column + inputCoordinate.Column]; if (!cellToCheck.IsOccupied) { continue; } if (cellToCheck.BuildingType == BuildingType.Residential) { continue; } nearUtilities.Add(cellToCheck.UtilityIndex); } if (nearUtilities.Any()) { return(nearUtilities.Count * item.Capacity); } return(1); }
private BuildingProject GetBestFit(IEnumerable <BuildingProject> orderResidntial, CellType[,] filledCells, MatrixCoordinate inputCoordinate) { BuildingProject bestResdintial = null; double bestResidntialScore = int.MinValue; object lockObject = new object(); // Parallel.ForEach(orderResidntial, new ParallelOptions() { MaxDegreeOfParallelism = 5 }, item => foreach (var item in orderResidntial) { double currScore = GetScore(item, filledCells, inputCoordinate); //lock (lockObject) { if (bestResidntialScore < currScore) { bestResdintial = item; bestResidntialScore = currScore; } } } //}); return(bestResdintial); }
public Drone(int index) : base(index) { CurrentPosition = new MatrixCoordinate(0, 0); }