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 void TurkishAirportSolution(ProblemInput input, ProblemOutput output, CellType[,] filledCells) { var Size1Building = input.BuildingProjects.FirstOrDefault(_ => _.Plan.Length == 1 && _.BuildingType == BuildingType.Residential); for (int i = 0; i < filledCells.GetLength(0); i++) { for (int j = 0; j < filledCells.GetLength(1); j++) { if (filledCells[i, j].IsOccupied) { continue; } BuildingProject bestProject = GetBestFit(input.BuildingProjects, filledCells, new MatrixCoordinate(i, j)); if (bestProject == null) { continue; } AddBestProject(filledCells, new MatrixCoordinate(i, j), bestProject); output.Buildings.Add(new OutputBuilding() { Coordinate = new MatrixCoordinate(i, j), ProjectNumber = bestProject.Index }); } } }
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)); }
private static void PrintToFile(ProblemInput input, ProblemOutput output) { try { File.Delete(@"C:\temp\f.txt"); } catch { } using (var writer = new StreamWriter(@"C:\temp\f.txt")) { CellState[,] state = new CellState[input.Rows, input.Columns]; foreach (var item in output.Buildings) { BuildingProject buildingProject1 = input.BuildingProjects[item.ProjectNumber]; for (int i = 0; i < buildingProject1.Plan.GetLength(0); i++) { for (int j = 0; j < buildingProject1.Plan.GetLength(1); j++) { if (!buildingProject1.Plan[i, j]) { continue; } if (buildingProject1.BuildingType == BuildingType.Residential) { state[item.Coordinate.Row + i, item.Coordinate.Column + j] = CellState.Res; } else { state[item.Coordinate.Row + i, item.Coordinate.Column + j] = CellState.Util; } } } } for (int i = 0; i < state.GetLength(0); i++) { for (int j = 0; j < state.GetLength(1); j++) { if (state[i, j] == CellState.Empty) { writer.Write("E"); } else if (state[i, j] == CellState.Res) { writer.Write("R"); } else if (state[i, j] == CellState.Util) { writer.Write("U"); } else { throw new Exception(); } } writer.WriteLine(); } } }
private static void DataAnalyze() { string[] data = new string[] { Properties.Resources.a_example, Properties.Resources.b_short_walk, Properties.Resources.c_going_green, Properties.Resources.d_wide_selection, Properties.Resources.e_precise_fit, Properties.Resources.f_different_footprints, }; for (int i = 0; i < data.Length; i++) { ProblemInput prob = new Parser().ParseFromData(data[i]); var residtianls = prob.BuildingProjects.Where(_ => _.BuildingType == BuildingType.Residential).ToList(); var utility = prob.BuildingProjects.Where(_ => _.BuildingType == BuildingType.Utility).ToList(); bool anyTwiceUtil = false; for (int j = 0; j < utility.Count; j++) { for (int n = 0; n < utility.Count; n++) { if (j != n && utility[j].UtilityType == utility[n].UtilityType) { anyTwiceUtil = true; break; } } } bool canPutInside = CanPutInside(prob); var bestRes = residtianls.Max(_ => 1.0 * _.Capacity / _.Plan.GetLength(0) / _.Plan.GetLength(1)); BuildingProject bestBuilding = null; foreach (var item in residtianls) { var _ = item; if (1.0 * _.Capacity / _.Plan.GetLength(0) / _.Plan.GetLength(1) == bestRes) { bestBuilding = item; } } Console.WriteLine($"case {i}:"); Console.WriteLine($"insert case data Rows: {prob.Rows}, Columns:{prob.Columns}, MaxDistance: {prob.MaxDistance}"); Console.WriteLine($"Are two util same type : { anyTwiceUtil}"); Console.WriteLine($"Can put inside: {canPutInside}"); Console.WriteLine($"Best res: {bestRes}, size: {bestBuilding.Plan.GetLength(0)}, {bestBuilding.Plan.GetLength(1)}"); Console.WriteLine($"different utilities :{utility.Select(project => project.UtilityType).Distinct().Count()}"); Console.WriteLine($"Num res :{residtianls.Count}"); bool anySize1Res = prob.BuildingProjects.Any(_ => _.Plan.Length == 1 && _.BuildingType == BuildingType.Residential); Console.WriteLine("Size 1 res: " + anySize1Res); Console.WriteLine($"Min res: " + prob.BuildingProjects.Min(_ => _.Plan.Length)); Console.WriteLine($"Any spcial: " + prob.BuildingProjects.Any(_ => _.Plan.Length != 1 && _.Plan.Cast <bool>().Count(__ => __) == 1)); // Console.WriteLine($"Num res :{residtianls.Count}"); } }
protected override ProblemOutput Solve(ProblemInput input) { ProblemOutput output = new ProblemOutput(); output.Buildings = new List <OutputBuilding>(); BuildingProject utiliy = GetBestUtility(input); // List<OutputBuilding> residntialis = GetBestResidentials(input); List <OutputBuilding> residntialis = new List <OutputBuilding>(); bool[,] filles = new bool[input.Rows, input.Columns]; for (int row = 0; row < input.Rows; row += input.MaxDistance + utiliy.Plan.GetLength(0)) { for (int col = 0; col < input.Columns; col += input.MaxDistance + utiliy.Plan.GetLength(1) + 1) { output.Buildings.Add(new OutputBuilding() { Coordinate = new MatrixCoordinate(row, col), ProjectNumber = utiliy.Index }); for (int i = 0; i < utiliy.Plan.GetLength(0); i++) { for (int j = 0; j < utiliy.Plan.GetLength(1); j++) { filles[row + i, col + j] = utiliy.Plan[i, j]; } } foreach (var item in residntialis) { output.Buildings.Add(new OutputBuilding() { Coordinate = new MatrixCoordinate(item.Coordinate.Row, item.Coordinate.Column), ProjectNumber = item.ProjectNumber }); } } } var Size1Building = input.BuildingProjects.FirstOrDefault(_ => _.Plan.Length == 1 && _.BuildingType == BuildingType.Residential); if (Size1Building != null) { for (int i = 0; i < filles.GetLength(0); i++) { for (int j = 0; j < filles.GetLength(1); j++) { if (filles[i, j]) { continue; } output.Buildings.Add(new OutputBuilding() { Coordinate = new MatrixCoordinate(i, j), ProjectNumber = Size1Building.Index }); } } } return(output); }
protected override ProblemInput ParseFromStream(TextReader reader) { int[] firstLine = ReadLineAsIntArray(reader); ProblemInput input = new ProblemInput { Columns = firstLine[1], Rows = firstLine[0], MaxDistance = firstLine[2], BuildingProjects = new BuildingProject[firstLine[3]] }; for (int i = 0; i < input.BuildingProjects.Length; i++) { string[] buildingLine = reader.GetStringList(); BuildingType type = buildingLine[0] == "R" ? BuildingType.Residential : BuildingType.Utility; int rows = int.Parse(buildingLine[1]); int columns = int.Parse(buildingLine[2]); int number = int.Parse(buildingLine[3]); BuildingProject project = new BuildingProject(i) { BuildingType = type, Capacity = number, UtilityType = number, Plan = new bool[rows, columns] }; for (int j = 0; j < rows; j++) { var row = reader.ReadLine(); for (int k = 0; k < columns; k++) { project.Plan[j, k] = row[k] == '#'; } } input.BuildingProjects[i] = project; } return(input); }
private BuildingProject GetBestUtility(ProblemInput input) { double bestRatio = -1; BuildingProject bestProject = null; foreach (var item in input.BuildingProjects) { if (item.BuildingType == BuildingType.Residential) { continue; } double currRatio = 1.0 * item.Plan.GetLength(0) * item.Plan.GetLength(1) / item.Plan.Cast <bool>().Count(_ => _); if (currRatio > bestRatio) { bestProject = item; bestRatio = currRatio; } } return(bestProject); }
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 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); }
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 }); } }
private object OrderByResidintialMethod(BuildingProject arg) { return(1.0 * arg.Capacity / arg.Plan.GetLength(0) / arg.Plan.GetLength(1)); }
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 double GetUtilityHeuristic(BuildingProject project1) { // return 1.0 / project1.Plan.Cast<bool>().Count(b => b); return(1.0 / project1.Plan.Length); }
private double GetResidntialHeuristic(BuildingProject project1) { // return project1.Capacity / (double)project1.Plan.Cast<bool>().Count(b => b); return(project1.Capacity / (double)project1.Plan.Length); }
private static HashSet <int> GetUtilities(ProblemInput input, int[,] utilityGrid, OutputBuilding building, BuildingProject buildingProject, Dictionary <BuildingProject, MatrixCoordinate[]> dic) { HashSet <int> utilities = new HashSet <int>(); bool[,] plan = buildingProject.Plan; var coordinates = dic[buildingProject]; foreach (var item in coordinates) { int gridRow = item.Row + building.Coordinate.Row; int gridCol = item.Column + building.Coordinate.Column; if (IsWithinGrid(utilityGrid, gridRow, gridCol) && utilityGrid[gridRow, gridCol] != 0) { utilities.Add(utilityGrid[gridRow, gridCol]); } } return(utilities); }