Added spot orientation, refactored code
This commit is contained in:
parent
60ec303402
commit
a038117d95
@ -336,6 +336,90 @@ SpriteRenderer:
|
||||
m_WasSpriteAssigned: 1
|
||||
m_MaskInteraction: 0
|
||||
m_SpriteSortPoint: 0
|
||||
--- !u!1 &1698470686
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1698470687}
|
||||
- component: {fileID: 1698470688}
|
||||
m_Layer: 0
|
||||
m_Name: Isometric Diamond
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &1698470687
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1698470686}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0.391, z: 0}
|
||||
m_LocalScale: {x: 0.29000002, y: 0.13049999, z: 0.6524999}
|
||||
m_ConstrainProportionsScale: 1
|
||||
m_Children: []
|
||||
m_Father: {fileID: 13560301962479320}
|
||||
m_RootOrder: 4
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!212 &1698470688
|
||||
SpriteRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1698470686}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 0
|
||||
m_ReceiveShadows: 0
|
||||
m_DynamicOccludee: 1
|
||||
m_StaticShadowCaster: 0
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_ReceiveGI: 1
|
||||
m_PreserveUVs: 0
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 1
|
||||
m_SelectedEditorRenderState: 0
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_Sprite: {fileID: -2413806693520163455, guid: a86470a33a6bf42c4b3595704624658b, type: 3}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_FlipX: 0
|
||||
m_FlipY: 0
|
||||
m_DrawMode: 0
|
||||
m_Size: {x: 1, y: 0.5}
|
||||
m_AdaptiveModeThreshold: 0.5
|
||||
m_SpriteTileMode: 0
|
||||
m_WasSpriteAssigned: 1
|
||||
m_MaskInteraction: 0
|
||||
m_SpriteSortPoint: 0
|
||||
--- !u!1 &13560301962479332
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -371,6 +455,7 @@ Transform:
|
||||
- {fileID: 378070325}
|
||||
- {fileID: 44517024}
|
||||
- {fileID: 1120243406}
|
||||
- {fileID: 1698470687}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
|
@ -168,6 +168,90 @@ SpriteRenderer:
|
||||
m_WasSpriteAssigned: 1
|
||||
m_MaskInteraction: 0
|
||||
m_SpriteSortPoint: 0
|
||||
--- !u!1 &1240076081
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1240076082}
|
||||
- component: {fileID: 1240076083}
|
||||
m_Layer: 0
|
||||
m_Name: Isometric Diamond (1)
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &1240076082
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1240076081}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0.365, z: 0}
|
||||
m_LocalScale: {x: 0.29000002, y: 0.145, z: 0.6524999}
|
||||
m_ConstrainProportionsScale: 1
|
||||
m_Children: []
|
||||
m_Father: {fileID: 13560301962479320}
|
||||
m_RootOrder: 4
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!212 &1240076083
|
||||
SpriteRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1240076081}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 0
|
||||
m_ReceiveShadows: 0
|
||||
m_DynamicOccludee: 1
|
||||
m_StaticShadowCaster: 0
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_ReceiveGI: 1
|
||||
m_PreserveUVs: 0
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 1
|
||||
m_SelectedEditorRenderState: 0
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_Sprite: {fileID: -2413806693520163455, guid: a86470a33a6bf42c4b3595704624658b, type: 3}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_FlipX: 0
|
||||
m_FlipY: 0
|
||||
m_DrawMode: 0
|
||||
m_Size: {x: 1, y: 0.5}
|
||||
m_AdaptiveModeThreshold: 0.5
|
||||
m_SpriteTileMode: 0
|
||||
m_WasSpriteAssigned: 1
|
||||
m_MaskInteraction: 0
|
||||
m_SpriteSortPoint: 0
|
||||
--- !u!1 &1413974509
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -371,6 +455,7 @@ Transform:
|
||||
- {fileID: 1413974510}
|
||||
- {fileID: 1859742736}
|
||||
- {fileID: 54299844}
|
||||
- {fileID: 1240076082}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
|
@ -252,6 +252,90 @@ SpriteRenderer:
|
||||
m_WasSpriteAssigned: 1
|
||||
m_MaskInteraction: 0
|
||||
m_SpriteSortPoint: 0
|
||||
--- !u!1 &584568173
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 584568174}
|
||||
- component: {fileID: 584568175}
|
||||
m_Layer: 0
|
||||
m_Name: Isometric Diamond (2)
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &584568174
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 584568173}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0.36000013, z: 0}
|
||||
m_LocalScale: {x: 0.29000002, y: 0.16312498, z: 0.6524999}
|
||||
m_ConstrainProportionsScale: 1
|
||||
m_Children: []
|
||||
m_Father: {fileID: 13560301962479320}
|
||||
m_RootOrder: 4
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!212 &584568175
|
||||
SpriteRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 584568173}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 0
|
||||
m_ReceiveShadows: 0
|
||||
m_DynamicOccludee: 1
|
||||
m_StaticShadowCaster: 0
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_ReceiveGI: 1
|
||||
m_PreserveUVs: 0
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 1
|
||||
m_SelectedEditorRenderState: 0
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_Sprite: {fileID: -2413806693520163455, guid: a86470a33a6bf42c4b3595704624658b, type: 3}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_FlipX: 0
|
||||
m_FlipY: 0
|
||||
m_DrawMode: 0
|
||||
m_Size: {x: 1, y: 0.5}
|
||||
m_AdaptiveModeThreshold: 0.5
|
||||
m_SpriteTileMode: 0
|
||||
m_WasSpriteAssigned: 1
|
||||
m_MaskInteraction: 0
|
||||
m_SpriteSortPoint: 0
|
||||
--- !u!1 &1661884534
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -371,6 +455,7 @@ Transform:
|
||||
- {fileID: 92791926}
|
||||
- {fileID: 504262852}
|
||||
- {fileID: 1661884535}
|
||||
- {fileID: 584568174}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
|
@ -956,8 +956,6 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: af24978eff1b496b78bcc0aeccf046ed, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
width: 68
|
||||
height: 29
|
||||
stepTime: 15
|
||||
timeText: {fileID: 861769593}
|
||||
countsText: {fileID: 489742541}
|
||||
|
@ -1,27 +1,31 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using System.IO;
|
||||
|
||||
public class DataImporter
|
||||
namespace Parking
|
||||
{
|
||||
public static List<Driver> Drivers = new List<Driver>();
|
||||
public class DataImporter
|
||||
{
|
||||
public static List<Driver> Drivers = new();
|
||||
|
||||
public static void ReadFile(string path)
|
||||
{
|
||||
string fileData = System.IO.File.ReadAllText(path);
|
||||
String[] lines = fileData.Split("\n"[0]);
|
||||
int counter = 0;
|
||||
foreach (string line in lines)
|
||||
var fileData = File.ReadAllText(path);
|
||||
var lines = fileData.Split("\n"[0]);
|
||||
var counter = 0;
|
||||
foreach (var line in lines)
|
||||
{
|
||||
if (counter == 0)
|
||||
{
|
||||
counter++;
|
||||
continue;
|
||||
}
|
||||
String[] lineData = (line.Trim()).Split(',');
|
||||
ParkingPreference preference = (lineData[0] == "" ? ParkingPreference.Any : (lineData[0] == "P" ? ParkingPreference.Front : ParkingPreference.Back));
|
||||
|
||||
var lineData = line.Trim().Split(',');
|
||||
var preference = lineData[0] == ""
|
||||
? ParkingPreference.Any
|
||||
: lineData[0] == "P"
|
||||
? ParkingPreference.Front
|
||||
: ParkingPreference.Back;
|
||||
Size size;
|
||||
switch (lineData[1])
|
||||
{
|
||||
@ -41,9 +45,10 @@ public class DataImporter
|
||||
size = Size.A;
|
||||
break;
|
||||
}
|
||||
Drivers.Add(new(size, counter, preference));
|
||||
// float.TryParse(lineData[0], x);
|
||||
|
||||
Drivers.Add(new Driver(size, counter, preference));
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,31 +1,54 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using Unity.Burst.Intrinsics;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
|
||||
public class Driver
|
||||
namespace Parking
|
||||
{
|
||||
public Size Size = Size.A;
|
||||
public int Priority = 0;
|
||||
public class Driver
|
||||
{
|
||||
public ParkingPreference ParkingPreference = ParkingPreference.Any;
|
||||
public int Priority;
|
||||
public readonly Size Size = Size.A;
|
||||
|
||||
public Driver(Size size, int priority, ParkingPreference parkingPreference)
|
||||
{
|
||||
this.Size = size;
|
||||
this.Priority = priority;
|
||||
this.ParkingPreference = parkingPreference;
|
||||
Size = size;
|
||||
Priority = priority;
|
||||
ParkingPreference = parkingPreference;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum Size {
|
||||
public class Spot : IComparable<Spot>
|
||||
{
|
||||
public Size Size;
|
||||
public bool Flipped;
|
||||
public GameObject GameObject;
|
||||
|
||||
public Spot(Size size, bool flipped)
|
||||
{
|
||||
Size = size;
|
||||
Flipped = flipped;
|
||||
}
|
||||
|
||||
public int CompareTo(Spot obj)
|
||||
{
|
||||
return Size.CompareTo(obj.Size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public enum Size
|
||||
{
|
||||
A = 0,
|
||||
B = 1,
|
||||
C = 2,
|
||||
D = 3
|
||||
}
|
||||
}
|
||||
|
||||
public enum ParkingPreference {
|
||||
public enum ParkingPreference
|
||||
{
|
||||
Any = 0,
|
||||
Front = 1,
|
||||
Back = 2,
|
||||
Back = 2
|
||||
}
|
||||
}
|
221
Assets/Scripts/InitialConfigurationGenerator.cs
Normal file
221
Assets/Scripts/InitialConfigurationGenerator.cs
Normal file
@ -0,0 +1,221 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Parking
|
||||
{
|
||||
public class InitialConfigurationGenerator
|
||||
{
|
||||
private static readonly List<int[]> Combinations = new(3000);
|
||||
private static readonly float[] AvailableSizesCombinations = {0, 2.5f, 4, 4.5f, 5}; //, 7.5f};
|
||||
private readonly float _spotWidth = 2.25f;
|
||||
|
||||
public int[,] FindSolution()
|
||||
{
|
||||
PreProcessCombinations(out var spotCountsPerpendicular, out var spotCountsParallel);
|
||||
|
||||
var spotsCreated = new int[4, 4];
|
||||
|
||||
var start = 80;
|
||||
var count = start;
|
||||
|
||||
var maxCount = 0;
|
||||
|
||||
if (PlaceNCars(30, spotCountsPerpendicular, spotCountsParallel, spotsCreated))
|
||||
{
|
||||
count++;
|
||||
while (PlaceNCars(count, spotCountsPerpendicular, spotCountsParallel, spotsCreated)) count++;
|
||||
|
||||
maxCount = count--;
|
||||
}
|
||||
else
|
||||
{
|
||||
count--;
|
||||
while (!PlaceNCars(count, spotCountsPerpendicular, spotCountsParallel, spotsCreated)) count--;
|
||||
|
||||
maxCount = count;
|
||||
}
|
||||
|
||||
Debug.Log($"Best solution count {maxCount}");
|
||||
|
||||
return spotsCreated;
|
||||
}
|
||||
|
||||
|
||||
private bool PlaceNCars(int carsToPlace, 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...");
|
||||
for (var i = 0; i < DataImporter.Drivers.Count && i + fixedCarSpots < carsToPlace; i++)
|
||||
counts[(int) DataImporter.Drivers[i].Size]++;
|
||||
|
||||
var countsString = $"A: {counts[0]} B: {counts[1]} C: {counts[2]} " +
|
||||
$"Suma: {counts.Sum()}";
|
||||
ParkingManager.Instance.UpdateText(countsString);
|
||||
Debug.Log(countsString);
|
||||
|
||||
|
||||
Debug.Log("Printing top 5 combinations...");
|
||||
foreach (var comb in Combinations)
|
||||
{
|
||||
var res = TestCombination(comb.ToArray(), spotCountsPerpendicular, spotCountsParallel, counts,
|
||||
spotsCreated);
|
||||
if (res)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void PreProcessCombinations(out int[] spotCountsPerpendicular, out int[,] spotCountsParallel)
|
||||
{
|
||||
Debug.Log("Calculating spot counts...");
|
||||
float[] spotLengthsParallel = {4f, 4.5f, 5f}; //, 7.5f};
|
||||
spotCountsPerpendicular = new[] {0, 0, 0, 0};
|
||||
spotCountsPerpendicular[0] = Mathf.FloorToInt((ParkingManager.Width - 5.5f) / _spotWidth);
|
||||
spotCountsPerpendicular[1] = Mathf.FloorToInt((ParkingManager.Width - 5.5f - 2.5f) / _spotWidth);
|
||||
spotCountsPerpendicular[2] = Mathf.FloorToInt((ParkingManager.Width - 5.5f - 2.5f) / _spotWidth);
|
||||
spotCountsPerpendicular[3] =
|
||||
Mathf.FloorToInt((ParkingManager.Width - 5.5f - 3.6f * 2 - 2.5f * 4) / _spotWidth);
|
||||
spotCountsParallel = new int[4, 4];
|
||||
for (var i = 0; i < 3; i++)
|
||||
for (var j = 0; j < spotLengthsParallel.Length; j++)
|
||||
spotCountsParallel[i, j] = Mathf.FloorToInt((ParkingManager.Width - 5.5f) / spotLengthsParallel[j]);
|
||||
for (var j = 0; j < spotLengthsParallel.Length; j++)
|
||||
spotCountsParallel[3, j] =
|
||||
Mathf.FloorToInt((ParkingManager.Width - 5.5f - 3.6f * 2 - 2.5f * 4) / spotLengthsParallel[j]);
|
||||
Debug.Log("" +
|
||||
$"P1: {spotCountsPerpendicular[0]}/ P2: {spotCountsPerpendicular[1]} " +
|
||||
$"P3: {spotCountsPerpendicular[2]} P4: {spotCountsPerpendicular[3]} " +
|
||||
$"Sum: {spotCountsPerpendicular.Sum()}");
|
||||
|
||||
Debug.Log("Generating combinations...");
|
||||
int[] arr = {0, 1, 2, 3, 4};
|
||||
var n = arr.Length;
|
||||
var r = 4;
|
||||
CombinationRepetition(arr, n, r);
|
||||
Debug.Log($"Found {Combinations.Count} available combinations");
|
||||
|
||||
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()}");
|
||||
|
||||
for (var i = 0; i < spotsCreated.GetLength(0); i++)
|
||||
for (var j = 0; j < spotsCreated.GetLength(1); j++)
|
||||
spotsCreated[i, j] = 0;
|
||||
|
||||
var requiredCounts = new int[requiredCountsRef.Length];
|
||||
requiredCountsRef.CopyTo((Span<int>) requiredCounts);
|
||||
|
||||
var spotCountsPerpendicular = new int[spotCountsPerpendicularRef.Length];
|
||||
spotCountsPerpendicularRef.CopyTo((Span<int>) 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;
|
||||
|
||||
spotsCreated[laneId, spotSize] += spotsTaken;
|
||||
|
||||
// TODO: Allow modified 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;
|
||||
//
|
||||
// spotsCreated[laneId, spotSize] += spotsTaken;
|
||||
//
|
||||
// // TODO: Allow modified 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;
|
||||
return true;
|
||||
}
|
||||
|
||||
private int UsesMoreSpaceComparator(int[] a1, int[] a2)
|
||||
{
|
||||
float sum1 = 0;
|
||||
float sum2 = 0;
|
||||
foreach (float val in a1) sum1 += val;
|
||||
|
||||
foreach (float val in a2) sum2 += val;
|
||||
|
||||
return -1 * sum1.CompareTo(sum2);
|
||||
}
|
||||
|
||||
private void CombinationRepetitionUtil(int[] chosen, int[] arr,
|
||||
int index, int r, int start, int end)
|
||||
{
|
||||
if (index == r)
|
||||
{
|
||||
// combinations.Add(new[] {arr[chosen[0]]});
|
||||
var tempArr = new List<int>(r);
|
||||
for (var i = 0; i < r; i++) tempArr.Add(arr[chosen[i]]);
|
||||
var hasEnoughSpace = tempArr.Select(x => AvailableSizesCombinations[x]).Sum() <
|
||||
ParkingManager.Height - 11;
|
||||
var contains5 = tempArr.Contains(4);
|
||||
tempArr.Sort();
|
||||
if (hasEnoughSpace && contains5)
|
||||
Combinations.Add(tempArr.ToArray());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = start; i <= end; i++)
|
||||
{
|
||||
chosen[index] = i;
|
||||
CombinationRepetitionUtil(chosen, arr, index + 1,
|
||||
r, i, end);
|
||||
}
|
||||
}
|
||||
|
||||
private void CombinationRepetition(int[] arr, int n, int r)
|
||||
{
|
||||
var chosen = new int[r + 1];
|
||||
CombinationRepetitionUtil(chosen, arr, 0, r, 0, n - 1);
|
||||
}
|
||||
}
|
||||
}
|
3
Assets/Scripts/InitialConfigurationGenerator.cs.meta
Normal file
3
Assets/Scripts/InitialConfigurationGenerator.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3de3cc3a61864323b1208796de3acdc5
|
||||
timeCreated: 1661969778
|
@ -1,36 +1,42 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TMPro;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
|
||||
public class ParkingManager : MonoBehaviour
|
||||
namespace Parking
|
||||
{
|
||||
private static readonly float[] AvailableSizesCombinations = {0, 2.5f, 4, 4.5f, 5};//, 7.5f};
|
||||
public class ParkingManager : MonoBehaviour
|
||||
{
|
||||
public const float Width = 68;
|
||||
public const float Height = 29;
|
||||
|
||||
public static ParkingManager Instance;
|
||||
|
||||
private static readonly List<int[]> combinations = new(3000);
|
||||
[SerializeField] private float width = 68;
|
||||
[SerializeField] private float height = 29;
|
||||
[SerializeField] private int stepTime = 15;
|
||||
[SerializeField] private TextMeshProUGUI timeText;
|
||||
[SerializeField] private TextMeshProUGUI countsText;
|
||||
[SerializeField] private GameObject spotPrefabA;
|
||||
[SerializeField] private GameObject spotPrefabB;
|
||||
[SerializeField] private GameObject spotPrefabC;
|
||||
[SerializeField] public TextMeshProUGUI countsText;
|
||||
[SerializeField] public GameObject spotPrefabA;
|
||||
[SerializeField] public GameObject spotPrefabB;
|
||||
[SerializeField] public GameObject spotPrefabC;
|
||||
|
||||
private readonly float[] _spotHeights = {3.5f, 4f, 5f, 7.5f};
|
||||
|
||||
public readonly List<List<Spot>> SpotMap = new() {new(), new(), new(), new()};
|
||||
private TimeSpan _currentTime = TimeSpan.FromHours(8);
|
||||
private float[] _spotHeights = {3.5f, 4f, 5f, 7.5f};
|
||||
|
||||
private float _spotWidth = 2.25f;
|
||||
private void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
timeText.text = _currentTime.ToString();
|
||||
DataImporter.ReadFile("Assets/Data/v1.csv");
|
||||
Debug.Log(DataImporter.Drivers);
|
||||
FindSolution();
|
||||
InitialConfigurationGenerator generator = new();
|
||||
ArrangeSpots(generator.FindSolution());
|
||||
}
|
||||
|
||||
public void AdvanceTime()
|
||||
@ -39,282 +45,93 @@ public class ParkingManager : MonoBehaviour
|
||||
timeText.text = _currentTime.ToString();
|
||||
}
|
||||
|
||||
private void FindSolution()
|
||||
public void UpdateText(string text)
|
||||
{
|
||||
PreProcessCombinations(out var spotCountsPerpendicular, out var spotCountsParallel);
|
||||
|
||||
int[,] spotsCreated = new int[4, 4];
|
||||
|
||||
int start = 80;
|
||||
int count = start;
|
||||
|
||||
int maxCount = 0;
|
||||
|
||||
if (PlaceNCars(30, spotCountsPerpendicular, spotCountsParallel, spotsCreated))
|
||||
{
|
||||
count++;
|
||||
while (PlaceNCars(count, spotCountsPerpendicular, spotCountsParallel, spotsCreated))
|
||||
{
|
||||
count++;
|
||||
countsText.text = text;
|
||||
}
|
||||
|
||||
maxCount = count--;
|
||||
}
|
||||
else
|
||||
private void ArrangeSpots(int[,] spotsCreated)
|
||||
{
|
||||
count--;
|
||||
while (!PlaceNCars(count, spotCountsPerpendicular, spotCountsParallel, spotsCreated))
|
||||
{
|
||||
count--;
|
||||
}
|
||||
var spotMap = GenerateSpotMap(spotsCreated);
|
||||
|
||||
maxCount = count;
|
||||
}
|
||||
Debug.Log($"Best solution count {maxCount}");
|
||||
var maxP3 = _spotHeights[(int) spotMap[2].Max().Size];
|
||||
var maxP2 = _spotHeights[(int) spotMap[1].Max().Size];
|
||||
|
||||
VisualiseSpots(spotsCreated);
|
||||
}
|
||||
|
||||
private void VisualiseSpots(int[,] spotsCreated)
|
||||
{
|
||||
List<List<Size>> spotMap = new List<List<Size>>() {new(), new(), new(), new()};
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
for (int j = 0; j < spotsCreated.GetLength(1); j++)
|
||||
{
|
||||
for (int k = 0; k < spotsCreated[i, j]; k++)
|
||||
{
|
||||
spotMap[i].Add((Size) j);
|
||||
}
|
||||
}
|
||||
}
|
||||
spotMap[0].Sort((a, b) => a.CompareTo(b)); // ascending sort
|
||||
spotMap[1].Sort((a, b) => b.CompareTo(a)); // descending sort
|
||||
spotMap[2].Sort((a, b) => b.CompareTo(a)); // descending sort
|
||||
spotMap[3].Sort((a, b) => a.CompareTo(b)); // ascending sort
|
||||
|
||||
float maxP3 = _spotHeights[(int)spotMap[2].Max()];
|
||||
float maxP2 = _spotHeights[(int)spotMap[1].Max()];
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (var i = 0; i < 4; i++)
|
||||
{
|
||||
float currentY;
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
currentY = -height / 2.0f + 2f;
|
||||
currentY = -Height / 2.0f + 2f;
|
||||
break;
|
||||
case 1:
|
||||
currentY = height/2 - 5.5f - 5f - maxP3 / 2.0f - maxP2;
|
||||
currentY = Height / 2 - 5.5f - 5f - maxP3 / 2.0f - maxP2;
|
||||
break;
|
||||
case 2:
|
||||
currentY = height/2 - 5.5f - 5f - maxP3 / 2.0f;
|
||||
currentY = Height / 2 - 5.5f - 5f - maxP3 / 2.0f;
|
||||
break;
|
||||
case 3:
|
||||
currentY = height / 2.0f - 2f;
|
||||
currentY = Height / 2.0f - 2f;
|
||||
break;
|
||||
default:
|
||||
currentY = -10;
|
||||
break;
|
||||
}
|
||||
|
||||
float currentX;
|
||||
if (i != 0) currentX = -width / 2f - 2.25f / 2f + 2.25f;
|
||||
else currentX = -width / 2f + 5.5f - 2.25f / 2f + 2.25f + 1.75f;
|
||||
for (int j = 0; j < spotMap[i].Count; j++)
|
||||
if (i != 0) currentX = -Width / 2f - 2.25f / 2f + 2.25f;
|
||||
else currentX = -Width / 2f + 5.5f - 2.25f / 2f + 2.25f + 1.75f;
|
||||
|
||||
var flipped = false;
|
||||
|
||||
for (var j = 0; j < spotMap[i].Count; j++)
|
||||
{
|
||||
GameObject spot;
|
||||
bool alignTop = i % 2 != 0;
|
||||
switch (spotMap[i][j])
|
||||
spotMap[i][j].Flipped = flipped;
|
||||
var alignTop = i % 2 != 0;
|
||||
switch (spotMap[i][j].Size)
|
||||
{
|
||||
case Size.A:
|
||||
spot = Instantiate(spotPrefabA);
|
||||
spot.transform.position = new Vector3(currentX, currentY, 0);
|
||||
spotMap[i][j].GameObject = Instantiate(Instance.spotPrefabA);
|
||||
spotMap[i][j].GameObject.transform.position = new Vector3(currentX, currentY, 0);
|
||||
spotMap[i][j].GameObject.transform.rotation =
|
||||
Quaternion.Euler(new Vector3(0, 0, spotMap[i][j].Flipped ? 180 : 0));
|
||||
break;
|
||||
case Size.B:
|
||||
spot = Instantiate(spotPrefabB);
|
||||
spot.transform.position = new Vector3(currentX, currentY + (alignTop ? -1 : 1) * 0.25f, 0);
|
||||
spotMap[i][j].GameObject = Instantiate(Instance.spotPrefabB);
|
||||
spotMap[i][j].GameObject.transform.position =
|
||||
new Vector3(currentX, currentY + (alignTop ? -1 : 1) * 0.25f, 0);
|
||||
spotMap[i][j].GameObject.transform.rotation =
|
||||
Quaternion.Euler(new Vector3(0, 0, spotMap[i][j].Flipped ? 180 : 0));
|
||||
break;
|
||||
case Size.C:
|
||||
spot = Instantiate(spotPrefabC);
|
||||
spot.transform.position = new Vector3(currentX, currentY + (alignTop ? -1 : 1) * 0.5f, 0);
|
||||
break;
|
||||
default:
|
||||
spotMap[i][j].GameObject = Instantiate(Instance.spotPrefabC);
|
||||
spotMap[i][j].GameObject.transform.position =
|
||||
new Vector3(currentX, currentY + (alignTop ? -1 : 1) * 0.5f, 0);
|
||||
spotMap[i][j].GameObject.transform.rotation =
|
||||
Quaternion.Euler(new Vector3(0, 0, spotMap[i][j].Flipped ? 180 : 0));
|
||||
break;
|
||||
}
|
||||
|
||||
currentX += 2.25f;
|
||||
|
||||
flipped = !flipped;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool PlaceNCars(int carsToPlace, int[] spotCountsPerpendicular, int[,] spotCountsParallel, int[,] spotsCreated)
|
||||
private List<List<Spot>> GenerateSpotMap(int[,] spotsCreated)
|
||||
{
|
||||
for (var i = 0; i < 4; i++)
|
||||
for (var j = 0; j < spotsCreated.GetLength(1); j++)
|
||||
for (var k = 0; k < spotsCreated[i, j]; k++)
|
||||
SpotMap[i].Add(new Spot((Size) j, false));
|
||||
|
||||
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...");
|
||||
for (int i = 0; i < DataImporter.Drivers.Count && i + fixedCarSpots < carsToPlace; i++)
|
||||
{
|
||||
counts[(int) DataImporter.Drivers[i].Size]++;
|
||||
SpotMap[0].Sort((a, b) => a.Size.CompareTo(b.Size)); // ascending sort
|
||||
SpotMap[1].Sort((a, b) => b.Size.CompareTo(a.Size)); // descending sort
|
||||
SpotMap[2].Sort((a, b) => b.Size.CompareTo(a.Size)); // descending sort
|
||||
SpotMap[3].Sort((a, b) => a.Size.CompareTo(b.Size)); // ascending sort
|
||||
return SpotMap;
|
||||
}
|
||||
|
||||
string countsString = $"A: {counts[0]} B: {counts[1]} C: {counts[2]} " +
|
||||
$"Suma: {counts.Sum()}";
|
||||
countsText.text = countsString;
|
||||
Debug.Log(countsString);
|
||||
|
||||
|
||||
Debug.Log("Printing top 5 combinations...");
|
||||
foreach (var comb in combinations)
|
||||
{
|
||||
bool res = TestCombination(comb.ToArray(), spotCountsPerpendicular, spotCountsParallel, counts, spotsCreated);
|
||||
if (res)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void PreProcessCombinations(out int[] spotCountsPerpendicular, out int[,] spotCountsParallel)
|
||||
{
|
||||
Debug.Log("Calculating spot counts...");
|
||||
float[] spotLengthsParallel = {4f, 4.5f, 5f};//, 7.5f};
|
||||
spotCountsPerpendicular = new[] {0, 0, 0, 0};
|
||||
spotCountsPerpendicular[0] = Mathf.FloorToInt((width - 5.5f) / _spotWidth);
|
||||
spotCountsPerpendicular[1] = Mathf.FloorToInt((width - 5.5f - 2.5f) / _spotWidth);
|
||||
spotCountsPerpendicular[2] = Mathf.FloorToInt((width - 5.5f - 2.5f) / _spotWidth);
|
||||
spotCountsPerpendicular[3] = Mathf.FloorToInt((width - 5.5f - (3.6f * 2) - (2.5f * 4)) / _spotWidth);
|
||||
spotCountsParallel = new int[4, 4];
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int j = 0; j < spotLengthsParallel.Length; j++)
|
||||
spotCountsParallel[i, j] = Mathf.FloorToInt((width - 5.5f) / spotLengthsParallel[j]);
|
||||
for (int j = 0; j < spotLengthsParallel.Length; j++)
|
||||
spotCountsParallel[3, j] = Mathf.FloorToInt((width - 5.5f - (3.6f * 2) - (2.5f * 4)) / spotLengthsParallel[j]);
|
||||
Debug.Log($"" +
|
||||
$"P1: {spotCountsPerpendicular[0]}/ P2: {spotCountsPerpendicular[1]} " +
|
||||
$"P3: {spotCountsPerpendicular[2]} P4: {spotCountsPerpendicular[3]} " +
|
||||
$"Sum: {spotCountsPerpendicular.Sum()}");
|
||||
|
||||
Debug.Log("Generating combinations...");
|
||||
int[] arr = {0, 1, 2, 3, 4};
|
||||
var n = arr.Length;
|
||||
var r = 4;
|
||||
CombinationRepetition(arr, n, r);
|
||||
Debug.Log($"Found {combinations.Count} available combinations");
|
||||
|
||||
Debug.Log("Sorting available combinations...");
|
||||
combinations.Sort(UsesMoreSpaceComparator);
|
||||
}
|
||||
|
||||
private bool TestCombination(int[] sizeIds, int[] spotCountsPerpendicularRef, int[,] spotCountsParallelRef, int[] requiredCountsRef, int[,] spotsCreated)
|
||||
{
|
||||
float[] sizes = sizeIds.Select(x => AvailableSizesCombinations[x]).ToArray();
|
||||
Debug.Log($"Testing: {sizes[0]} {sizes[1]} {sizes[2]} {sizes[3]} sum: {sizes.Sum()}");
|
||||
|
||||
for(int i = 0; i < spotsCreated.GetLength(0); i++)
|
||||
for (int j = 0; j < spotsCreated.GetLength(1); j++)
|
||||
spotsCreated[i, j] = 0;
|
||||
|
||||
int[] requiredCounts = new int[requiredCountsRef.Length];
|
||||
requiredCountsRef.CopyTo((Span<int>) requiredCounts);
|
||||
|
||||
int[] spotCountsPerpendicular = new int[spotCountsPerpendicularRef.Length];
|
||||
spotCountsPerpendicularRef.CopyTo((Span<int>) spotCountsPerpendicular);
|
||||
|
||||
int[,] spotCountsParallel = new int[spotCountsParallelRef.GetLength(0), spotCountsParallelRef.GetLength(1)];
|
||||
for(int i = 0; i < spotCountsParallelRef.GetLength(0); i++)
|
||||
for(int j = 0; j < spotCountsParallelRef.GetLength(1); j++)
|
||||
spotCountsParallel[i,j] = spotCountsParallelRef[i, j];
|
||||
|
||||
float[] spotSizes = {4, 4.5f, 5};
|
||||
|
||||
for (int spotSize = 2; spotSize >= 0; spotSize--)
|
||||
{
|
||||
for (int laneId = 3; laneId >= 0; laneId--)
|
||||
{
|
||||
if (AvailableSizesCombinations[sizeIds[laneId]] <= spotSizes[spotSize] && spotCountsPerpendicular[laneId] != 0) { // parking perpendicular
|
||||
int spotsTaken = Math.Min(requiredCounts[spotSize], spotCountsPerpendicular[laneId]);
|
||||
|
||||
spotCountsPerpendicular[laneId] -= spotsTaken;
|
||||
requiredCounts[spotSize] -= spotsTaken;
|
||||
|
||||
spotsCreated[laneId, spotSize] += spotsTaken;
|
||||
|
||||
// TODO: Allow modified configuration
|
||||
for(int 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;
|
||||
//
|
||||
// spotsCreated[laneId, spotSize] += spotsTaken;
|
||||
//
|
||||
// // TODO: Allow modified configuration
|
||||
// spotCountsPerpendicular[laneId] = 0;
|
||||
// for(int x = 0; x < 3; x++)
|
||||
// if(x != spotSize)
|
||||
// spotCountsParallel[laneId, x] = 0;
|
||||
// }
|
||||
if(requiredCounts[spotSize] == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int sum = requiredCounts.Sum();
|
||||
if(sum > 0)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
private int UsesMoreSpaceComparator(int[] a1, int[] a2)
|
||||
{
|
||||
float sum1 = 0;
|
||||
float sum2 = 0;
|
||||
foreach (float val in a1) sum1 += val;
|
||||
|
||||
foreach (float val in a2) sum2 += val;
|
||||
|
||||
return -1 * sum1.CompareTo(sum2);
|
||||
}
|
||||
|
||||
private void CombinationRepetitionUtil(int[] chosen, int[] arr,
|
||||
int index, int r, int start, int end)
|
||||
{
|
||||
if (index == r)
|
||||
{
|
||||
// combinations.Add(new[] {arr[chosen[0]]});
|
||||
var tempArr = new List<int>(r);
|
||||
for (var i = 0; i < r; i++) tempArr.Add(arr[chosen[i]]);
|
||||
bool hasEnoughSpace = tempArr.Select(x => AvailableSizesCombinations[x]).Sum() < height - 11;
|
||||
bool contains5 = tempArr.Contains(4);
|
||||
tempArr.Sort();
|
||||
if (hasEnoughSpace && contains5)
|
||||
combinations.Add(tempArr.ToArray());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = start; i <= end; i++)
|
||||
{
|
||||
chosen[index] = i;
|
||||
CombinationRepetitionUtil(chosen, arr, index + 1,
|
||||
r, i, end);
|
||||
}
|
||||
}
|
||||
|
||||
private void CombinationRepetition(int[] arr, int n, int r)
|
||||
{
|
||||
var chosen = new int[r + 1];
|
||||
CombinationRepetitionUtil(chosen, arr, 0, r, 0, n - 1);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user