diff --git a/MonteCarlo.png b/MonteCarlo.png new file mode 100644 index 0000000..11b7a04 Binary files /dev/null and b/MonteCarlo.png differ diff --git a/Popis_Algoritmu.md b/Popis_Algoritmu.md new file mode 100644 index 0000000..aa458a4 --- /dev/null +++ b/Popis_Algoritmu.md @@ -0,0 +1,54 @@ +# **Popis algoritmu** + +--- + +## 1. Verze dokumentu + +| Verze | Datum | Autor | Komentář | +| ----- | -------- | ------------ | ----------------------- | +| 0.1 | 2.3.2025 | Filip Kohout | První šablona dokumentu | + +## 2. Obsah + +- [**Popis algoritmu**](#popis-algoritmu) + - [1. Verze dokumentu](#1-verze-dokumentu) + - [2. Obsah](#2-obsah) + - [3.Algoritmus simulace](#3algoritmus-simulace) + - [3.1 Inicializace](#31-inicializace) + - [3.2 Simulace](#32-simulace) + - [3.3 Optimalizace](#33-optimalizace) + - [3.4 Vyhodnocení](#34-vyhodnocení) + - [4. Struktura](#4-struktura) + +## 3.Algoritmus simulace + +### 3.1 Inicializace + +- Nastaví se celkový počet zákazníků na **250**. +- Rozdělí se do jednotlivých hodin dle procentuálního podílu. +- Každému zákazníkovi se přiřadí náhodný čas příchodu (**1**-**60**) a doba odbavení (5-15 minut) pomocí pseudonáhodného generátoru Random. + +### 3.2 Simulace + +- Banka otevírá každou hodinu určitý počet přepážek, (není stanoven maximální počet přepážek, takže v kodu uvažuji možnost neomezeného počtu přepážek (nebo stanovení maximálního počtu přepážek ve vstupních parametrech třídy)). +- Proběhne simulace pro jednotlivé hodiny během dne s různými počty otevřených přepážek ale stejnými náhodně vygenerovanými příchody zákazníků. +- Pokud jsou všechny přepážky obsazené, další zákazníci čekají ve frontě. + +### 3.3 Optimalizace + +- Pro každou iteraci se sleduje aktuální stav fronty a vypočítá se čekací doba jednotlivých zákazníků. +- Pokud je čekací doba delší než maximální přípustná, zákazník odchází nespokojen. +- Celkový počet spokojených zákazníků se převede na relativní podíl (**0**-**1**). +- Vybere se nejmenší počet přepážek s největší spokojeností. + +> [!IMPORTANT] +> V případě že zákazník přijde ke konci simulační hodiny a doba jeho obsluhy i čekání by přesáhla 60 minut hodiny, pro zjednodušení, poběží program přes čas dokud zákazníka/y neobslouží. + +### 3.4 Vyhodnocení + +- Nejlepší počet přepážek v každé hodině se uloží do výstupu. +- Generuje se souhrnná zpráva o efektivitě provozu a procentu spokojených zákazníků. + +## 4. Struktura + +![Code Structure](./MonteCarlo.png) \ No newline at end of file diff --git a/Popis_Simulačního_Přístupu.md b/Popis_Simulačního_Přístupu.md new file mode 100644 index 0000000..398b37a --- /dev/null +++ b/Popis_Simulačního_Přístupu.md @@ -0,0 +1,76 @@ +# **Popis simulačního přístupu** + +--- + +## 1. Verze dokumentu + +| Verze | Datum | Autor | Komentář | +| ----- | -------- | ------------ | ----------------------- | +| 0.1 | 2.3.2025 | Filip Kohout | První šablona dokumentu | + +--- + +## 2. Obsah + +- [**Popis simulačního přístupu**](#popis-simulačního-přístupu) + - [1. Verze dokumentu](#1-verze-dokumentu) + - [2. Obsah](#2-obsah) + - [2. Cíl simulace](#2-cíl-simulace) + - [3. Vstupní data](#3-vstupní-data) + - [4. Metodika simulace](#4-metodika-simulace) + - [5. Závěr](#5-závěr) + +## 2. Cíl simulace + +Cílem simulace je určit optimální počet otevřených přepážek v bance pro různé časy dne tak, aby doba čekání na obsloužení nepřekročila 15 minut. Použitá metoda je Monte Carlo simulace, která generuje náhodné příchody zákazníků a jejich dobu strávenou v bance. + +## 3. Vstupní data + +- Celkový počet zákazníků za den: **250** + +- Rozložení zákazníků dle hodin (relativní podíl z celku): + - 8-9h: 0,04 + - 9-10h: 0,10 + - 10-11h: 0,15 + - 11-12h: 0,08 + - 12-13h: 0,10 + - 13-14h: 0,06 + - 14-15h: 0,09 + - 15-16h: 0,14 + - 16-17h: 0,10 + - 17-18h: 0,12 + - 18-19h: 0,02 + +- Doba odbavení jednoho zákazníka: **5**-**15** minut (rovnoměrné rozložení) + +Maximální doba čekání: 15 minut + +## 4. Metodika simulace + +![Code Graph](./MonteCarlo.png) + +1. Generování příchodů zákazníků + +- Počet zákazníků v dané hodině je určen koeficientem a celkovým počtem 250. +- Každému zákazníkovi je přiřazen náhodný čas příchodu a náhodně vygenerovaná doba odbavení. + +2. Simulace průběhu dne + +- Banka postupně zpracovává zákazníky v závislosti na počtu otevřených přepážek. +- Počet přepážek se postupně zvyšuje a hledá se optimální počet, při kterém všichni zákazníci čekají maximálně 15 minut. + +3. Vyhodnocení simulace + +- Pro každou hodinu dne se určí nejmenší počet přepážek, při kterém je splněn požadavek maximální doby čekání. +- Pokud počet přepážek splňující podmínku existuje, je zvolen nejmenší možný. +- Na základě simulace se sestaví plán otevřených přepážek pro každou hodinu. + +4. Očekávané výstupy + +- Počet otevřených přepážek pro každou hodinu dne. +- Statistika čekacích dob a procentuální spokojenosti zákazníků. +- Analýza vytíženosti přepážek. + +## 5. Závěr + +Tento simulační model poskytuje přesný odhad potřebného personálu v bance a pomáhá efektivně řídit provoz tak, aby byl zajištěn plynulý chod a minimální doba čekání. diff --git a/Program.cs b/Program.cs index 5cc3e2a..6aca532 100644 --- a/Program.cs +++ b/Program.cs @@ -15,7 +15,7 @@ * uint MaxNumOfCounters is optional - Maximal number of opened counters * uint float[11] TimeCoef is optional - Coefficients for number of customers for each hour */ - _ = new BankSim(250, 15, 15, 5); + _ = new BankSim(250, 15, 15, 5, MaxNumOfCounters: 6); } } @@ -27,7 +27,7 @@ public uint MinServiceTime; public uint MaxNumOfCounters; - private float[] NumOfCustomersCoef = new float[] { 0.04f, 0.1f, 0.15f, 0.08f, 0.1f, 0.6f, 0.09f, 0.14f, 0.1f, 0.12f, 0.02f }; + private float[] NumOfCustomersCoef = new float[] { 0.04f, 0.1f, 0.15f, 0.08f, 0.1f, 0.06f, 0.09f, 0.14f, 0.1f, 0.12f, 0.02f }; private uint NumOfCustomers; private static Random random = new Random(); @@ -54,7 +54,7 @@ Console.WriteLine($"Maximal Customer Waiting Time To Tolerate: {this.MaxWaitTime} min."); Console.WriteLine($"Maximal Service Time Of One Customer: {this.MaxServiceTime} min."); Console.WriteLine($"Minimal Service Time Of One Customer: {this.MinServiceTime} min."); - Console.WriteLine($"Maximal Number Of Opened Counters: {this.MaxNumOfCounters} min."); + Console.WriteLine($"Maximal Number Of Opened Counters: {this.MaxNumOfCounters}"); Console.WriteLine(); // Generate the number of customers for each hour and run simulation for each hour @@ -69,19 +69,19 @@ List satisfied_coefficient = new List(); for (int i = 1; i <= MaxNumOfCounters; ++i) { - //Console.WriteLine($"Number of counters: {i}"); + Console.WriteLine($"Number of counters: {i}"); List waiting_time_per_customer = RunSimulationHour(i); satisfied_coefficient.Add(SatisfiedCustomers(waiting_time_per_customer)); - //Console.WriteLine(); + Console.WriteLine(); } // Select number of counter with the satisfied coefficient int best_counter = satisfied_coefficient.IndexOf(satisfied_coefficient.Max()) + 1; - Console.WriteLine($"Best number of counters: {best_counter}, satisfied customers {satisfied_coefficient.Max() * 100}%"); + //Console.WriteLine($"Best number of counters: {best_counter}, satisfied customers {satisfied_coefficient.Max() * 100}%"); //! LOG result[day_hour] = new KeyValuePair((uint)best_counter, satisfied_coefficient.Max()); Customers.Clear(); - Console.WriteLine(); + //Console.WriteLine(); //! LOG day_hour++; } @@ -120,7 +120,7 @@ List<(uint endTime, uint arrivalTime, uint waitingTime)> activeCounters = new List<(uint, uint, uint)>(); List waiting_time = new List(); - for (uint i = 0; i < 10000; ++i) //! Optimize this number somehow maybe + for (uint i = 0; i < 1000; ++i) //! Optimize this number somehow maybe { // Add new arriving customers to waiting queue foreach (var customer in Customers.FindAll(x => x.Key == i)) @@ -139,7 +139,7 @@ uint endTime = startTime + serviceTime; activeCounters.Add((endTime, arrivalTime, waitingTime)); - //Console.WriteLine($"customer {arrivalTime}-{endTime} | served at {startTime} min. for {serviceTime} min. | waiting {waitingTime}"); + //Console.WriteLine($"customer {arrivalTime}-{endTime} | served at {startTime} min. for {serviceTime} min. | waiting {waitingTime}"); //!LOG waiting_time.Add(waitingTime); } @@ -172,5 +172,10 @@ // Return the percentage of satisfied customers as a value between 0 and 1 return (double)satisfied / waiting_times.Count(); } + + public Dictionary> GetResult() + { + return result; + } } } \ No newline at end of file diff --git a/README.md b/README.md index 8236ad6..95ab795 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,7 @@ # Bank Calc -- počet otevřených přepážek nikdy nemůže být vyšší než počet zákazníků za dannou hodinu -- čekací doba musí zároveň odpovídat max 15 minutám pro každého zákazníka -- počet přepážek musí být co nejnižší +## Structure -## Postup - -- generace počtu zákazníků za dannou hodinu -- náhodná generace času příchodu zákazníků -- výpočet dob čekání jednotlivých zákazníků pro počty otevřených přepážek (od maximálního počtu zákazníků až po 1 přepážku) -- přepočet počtu zákazníků kteří nebyli uspokojeni a odešli na procenta (90% zákazníků bylo uspokojeno) -- filtrace pouze přepážek které splňují požadavek na co nejvyšší spokojenost zákazníků (není menší než 80% třeba) +- [Popis Simulačního Přístupu](./Popis_Simulačního_Přístupu.md) +- [Popis Algoritmu](./Popis_Algoritmu.md) +- [Analýza potřebného počtu přepážek](./)