From d5983e8d6c22d22819d46774ca35b019832234b9 Mon Sep 17 00:00:00 2001 From: Dawid Pietrykowski Date: Mon, 5 Sep 2022 00:19:55 +0200 Subject: [PATCH] Reworked initial configuration generator --- .../Scripts/InitialConfigurationGenerator.cs | 222 +++++++----------- 1 file changed, 79 insertions(+), 143 deletions(-) diff --git a/Assets/Scripts/InitialConfigurationGenerator.cs b/Assets/Scripts/InitialConfigurationGenerator.cs index cdbb4e8..fbb01f0 100644 --- a/Assets/Scripts/InitialConfigurationGenerator.cs +++ b/Assets/Scripts/InitialConfigurationGenerator.cs @@ -16,25 +16,8 @@ namespace Parking PreProcessCombinations(out var spotCountsPerpendicular, out var spotCountsParallel); var spotsCreated = new int[4, 4]; - - var count = 77; - - var maxCount = count; - - if (PlaceNCars(count, spotCountsPerpendicular, spotCountsParallel, spotsCreated)) - { - count++; - while (PlaceNCars(count, spotCountsPerpendicular, spotCountsParallel, spotsCreated)) count++; - - maxCount = count - 1; - } - else - { - count--; - while (!PlaceNCars(count, spotCountsPerpendicular, spotCountsParallel, spotsCreated)) count--; - - maxCount = count; - } + + var maxCount = TestCombinations(spotCountsPerpendicular, spotCountsParallel, spotsCreated); Debug.Log($"Best solution count {maxCount}"); @@ -54,61 +37,101 @@ namespace Parking return spotsCreated; } - - private bool PlaceNCars(int carsToPlace, int[] spotCountsPerpendicular, int[,] spotCountsParallel, - int[,] spotsCreated) + private int TestCombinations(int[] spotCountsPerpendicular, int[,] spotCountsParallel, int[,] spotsCreated) { int[] counts = {0, 0, 0}; counts[(int) Size.A] += 2; counts[(int) Size.B] += 2; - // counts[(int) Size.D] += 1; var fixedCarSpots = 0; foreach (var c in counts) fixedCarSpots += c; - // Debug.Log($"Fixed car spots: {fixedCarSpots}"); - // Debug.Log("Calculating required spot counts..."); - int maxI = 0; - List driversLowerPrioritySorted = new List(DataImporter.Drivers.Count); - for (var i = 0; i < DataImporter.Drivers.Count && i + fixedCarSpots < carsToPlace; i++) - if (DataImporter.Drivers[i].Priority == 1) { - counts[(int) DataImporter.Drivers[i].Size]++; - maxI = i; - } - - foreach (Driver driver in DataImporter.Drivers) - if(driver.Priority != 1) - driversLowerPrioritySorted.Add(driver); - - for(int i = maxI + 1; counts[(int) Size.C] < 20 && i < DataImporter.Drivers.Count; i++) - if (DataImporter.Drivers[i].Size == Size.C) { - counts[(int) DataImporter.Drivers[i].Size]++; - driversLowerPrioritySorted.Remove(DataImporter.Drivers[i]); - } - - - driversLowerPrioritySorted.Sort(BiggerSizeComparator); - - int singlePriorityCars = counts.Sum(); - for (var i = 0; i < driversLowerPrioritySorted.Count && i + fixedCarSpots + singlePriorityCars < carsToPlace; i++) - counts[(int) driversLowerPrioritySorted[i].Size]++; - - var countsString = $"Małe: {counts[0]} Średnie: {counts[1]} Duże: {counts[2]} " + $"Suma: {counts.Sum() + 1}"; ParkingManager.Instance.UpdateText(countsString); Debug.Log(countsString); + int maxCount = 0; + int[] maxComb = new []{1, 1, 1, 1}; // Debug.Log("Printing top 5 combinations..."); foreach (var comb in Combinations) { - var res = TestCombination(comb.ToArray(), spotCountsPerpendicular, spotCountsParallel, counts, + int res = TryFillCombination(comb.ToArray(), spotCountsPerpendicular, spotCountsParallel, counts, spotsCreated); - if (res) - return true; + if (res > maxCount) { + maxCount = res; + maxComb = comb; + } } - return false; + TryFillCombination(maxComb, spotCountsPerpendicular, spotCountsParallel, counts, + spotsCreated, true); + + return maxCount; + } + + private int TryFillCombination(int[] sizeIds, int[] spotCountsPerpendicularRef, int[,] spotCountsParallelRef, int[] counts, int[,] spotsCreated, bool copyToArray = false) + { + var spotsCreatedTemp = new int[4, 4]; + + for (var i = 0; i < spotsCreatedTemp.GetLength(0); i++) + for (var j = 0; j < spotsCreatedTemp.GetLength(1); j++) + spotsCreatedTemp[i, j] = 0; + + var spotCountsPerpendicular = new int[spotCountsPerpendicularRef.Length]; + spotCountsPerpendicularRef.CopyTo((Span) spotCountsPerpendicular); + + var spotCountsParallel = new int[spotCountsParallelRef.GetLength(0), spotCountsParallelRef.GetLength(1)]; + for (var i = 0; i < spotCountsParallelRef.GetLength(0); i++) + for (var j = 0; j < spotCountsParallelRef.GetLength(1); j++) + spotCountsParallel[i, j] = spotCountsParallelRef[i, j]; + + float[] spotSizes = {4, 4.5f, 5}; + foreach (Driver driver in DataImporter.Drivers) { + List laneIds = new List(){0, 1, 2, 3}; + if (driver.Size == Size.C) + laneIds.Reverse(); + + for (int i = 0; i < 4; i++) { + int laneId = laneIds[i]; + bool freeSpotsAvailable = spotCountsPerpendicular[laneId] != 0; + bool carFits = AvailableSizesCombinations[sizeIds[laneId]] >= spotSizes[(int)driver.Size]; + if (carFits && freeSpotsAvailable) { + spotCountsPerpendicular[laneId]--; + spotsCreatedTemp[laneId, (int)driver.Size]++; + break; + } + } + } + + // for (var laneId = 3; laneId >= 0; laneId--) { + // if (spotCountsPerpendicular[laneId] != 0) { + // if (sizeIds[laneId] == 0) { + // // empty + // } + // else if (sizeIds[laneId] == 1) { + // // parallel only + // } + // else { + // spotsCreatedTemp[laneId, sizeIds[laneId] - 2] += spotCountsPerpendicular[laneId]; + // spotCountsPerpendicular[laneId] = 0; + // } + // } + // } + + int count = 0; + + for (var i = 0; i < spotsCreatedTemp.GetLength(0); i++) + for (var j = 0; j < spotsCreatedTemp.GetLength(1); j++) + count += spotsCreatedTemp[i, j]; + + if(copyToArray) + for (var i = 0; i < spotsCreatedTemp.GetLength(0); i++) + for (var j = 0; j < spotsCreatedTemp.GetLength(1); j++) + spotsCreated[i, j] = spotsCreatedTemp[i, j]; + + + return count; } private void PreProcessCombinations(out int[] spotCountsPerpendicular, out int[,] spotCountsParallel) @@ -143,94 +166,7 @@ namespace Parking Debug.Log("Sorting available combinations..."); Combinations.Sort(UsesMoreSpaceComparator); } - - private bool TestCombination(int[] sizeIds, int[] spotCountsPerpendicularRef, int[,] spotCountsParallelRef, - int[] requiredCountsRef, int[,] spotsCreated) - { - var sizes = sizeIds.Select(x => AvailableSizesCombinations[x]).ToArray(); - // Debug.Log($"Testing: {sizes[0]} {sizes[1]} {sizes[2]} {sizes[3]} sum: {sizes.Sum()}"); - - var spotsCreatedTemp = new int[4, 4]; - - for (var i = 0; i < spotsCreatedTemp.GetLength(0); i++) - for (var j = 0; j < spotsCreatedTemp.GetLength(1); j++) - spotsCreatedTemp[i, j] = 0; - - var requiredCounts = new int[requiredCountsRef.Length]; - requiredCountsRef.CopyTo((Span) requiredCounts); - - var spotCountsPerpendicular = new int[spotCountsPerpendicularRef.Length]; - spotCountsPerpendicularRef.CopyTo((Span) spotCountsPerpendicular); - - var spotCountsParallel = new int[spotCountsParallelRef.GetLength(0), spotCountsParallelRef.GetLength(1)]; - for (var i = 0; i < spotCountsParallelRef.GetLength(0); i++) - for (var j = 0; j < spotCountsParallelRef.GetLength(1); j++) - spotCountsParallel[i, j] = spotCountsParallelRef[i, j]; - - float[] spotSizes = {4, 4.5f, 5}; - - for (var spotSize = 2; spotSize >= 0; spotSize--) - for (var laneId = 3; laneId >= 0; laneId--) - { - if (AvailableSizesCombinations[sizeIds[laneId]] >= spotSizes[spotSize] && - spotCountsPerpendicular[laneId] != 0) - { - // parking perpendicular - var spotsTaken = Math.Min(requiredCounts[spotSize], spotCountsPerpendicular[laneId]); - - spotCountsPerpendicular[laneId] -= spotsTaken; - requiredCounts[spotSize] -= spotsTaken; - - spotsCreatedTemp[laneId, spotSize] += spotsTaken; - - // TODO: Allow mixed configuration - for (var x = 0; x < 3; x++) - spotCountsParallel[laneId, x] = 0; - } - // else if (sizeIds[laneId] == 0 && spotCountsParallel[laneId, spotSize] != 0) { // parking parallel - // int spotsTaken = Math.Min(requiredCounts[spotSize], spotCountsParallel[laneId, spotSize]); - // - // spotCountsParallel[laneId, spotSize] -= spotsTaken; - // requiredCounts[spotSize] -= spotsTaken; - // - // spotsCreatedTemp[laneId, spotSize] += spotsTaken; - // - // // TODO: Allow mixed configuration - // spotCountsPerpendicular[laneId] = 0; - // for(int x = 0; x < 3; x++) - // if(x != spotSize) - // spotCountsParallel[laneId, x] = 0; - // } - if (requiredCounts[spotSize] == 0) - break; - } - - var sum = requiredCounts.Sum(); - if (sum > 0) - return false; - - - for (var laneId = 3; laneId >= 0; laneId--) { - if (spotCountsPerpendicular[laneId] != 0) { - if (sizeIds[laneId] == 0) { - // empty - } - else if (sizeIds[laneId] == 1) { - // parallel only - } - else { - spotsCreatedTemp[laneId, 0] += spotCountsPerpendicular[laneId]; - spotCountsPerpendicular[laneId] = 0; - } - } - } - - for (var i = 0; i < spotsCreatedTemp.GetLength(0); i++) - for (var j = 0; j < spotsCreatedTemp.GetLength(1); j++) - spotsCreated[i, j] = spotsCreatedTemp[i, j]; - return true; - } - + private int UsesMoreSpaceComparator(int[] a1, int[] a2) { float sum1 = 0;