most-queue 1.62__tar.gz → 1.63__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {most_queue-1.62 → most_queue-1.63}/PKG-INFO +5 -6
- {most_queue-1.62 → most_queue-1.63}/README.md +4 -5
- most_queue-1.63/doctest-output/QS.gv +18 -0
- most_queue-1.63/most_queue/general/distribution_fitting.py +340 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/general/distribution_params.py +10 -1
- {most_queue-1.62 → most_queue-1.63}/most_queue/general/interfaces.py +3 -1
- {most_queue-1.62 → most_queue-1.63}/most_queue/general/plots.py +19 -11
- most_queue-1.63/most_queue/general/tables.py +361 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/misc/approx_cdf_make.py +13 -12
- {most_queue-1.62 → most_queue-1.63}/most_queue/misc/calc_v_pls.py +67 -46
- {most_queue-1.62 → most_queue-1.63}/most_queue/misc/compare_fj_calc.py +5 -4
- {most_queue-1.62 → most_queue-1.63}/most_queue/misc/flow_sum.py +33 -15
- {most_queue-1.62 → most_queue-1.63}/most_queue/misc/run_mgn_with_h2_delay_cold_warm.py +204 -89
- {most_queue-1.62/tests → most_queue-1.63/most_queue/misc}/test_fj_delta.py +23 -23
- most_queue-1.63/most_queue/misc/test_network_opt_approx.py +53 -0
- most_queue-1.63/most_queue/misc/test_network_opt_plus.py +63 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/misc/vacations_paper_utils.py +20 -37
- {most_queue-1.62 → most_queue-1.63}/most_queue/rand_distribution.py +104 -298
- {most_queue-1.62 → most_queue-1.63}/most_queue/sim/base.py +52 -38
- {most_queue-1.62 → most_queue-1.63}/most_queue/sim/batch.py +36 -35
- {most_queue-1.62 → most_queue-1.63}/most_queue/sim/finite_source.py +18 -13
- {most_queue-1.62 → most_queue-1.63}/most_queue/sim/flow_sum.py +49 -29
- {most_queue-1.62 → most_queue-1.63}/most_queue/sim/fork_join.py +88 -57
- {most_queue-1.62 → most_queue-1.63}/most_queue/sim/fork_join_delta.py +63 -57
- {most_queue-1.62 → most_queue-1.63}/most_queue/sim/impatient.py +10 -10
- {most_queue-1.62 → most_queue-1.63}/most_queue/sim/negative.py +49 -39
- {most_queue-1.62 → most_queue-1.63}/most_queue/sim/networks/network.py +26 -24
- {most_queue-1.62 → most_queue-1.63}/most_queue/sim/networks/priority_network.py +35 -26
- {most_queue-1.62 → most_queue-1.63}/most_queue/sim/priority.py +122 -120
- {most_queue-1.62 → most_queue-1.63}/most_queue/sim/utils/distribution_utils.py +61 -45
- most_queue-1.63/most_queue/sim/utils/distributions.yaml +24 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/sim/utils/exceptions.py +2 -2
- {most_queue-1.62 → most_queue-1.63}/most_queue/sim/utils/phase.py +2 -2
- {most_queue-1.62 → most_queue-1.63}/most_queue/sim/utils/qs_queue.py +6 -6
- {most_queue-1.62 → most_queue-1.63}/most_queue/sim/utils/servers.py +34 -37
- {most_queue-1.62 → most_queue-1.63}/most_queue/sim/utils/stats_update.py +5 -2
- {most_queue-1.62 → most_queue-1.63}/most_queue/sim/utils/tasks.py +22 -14
- {most_queue-1.62 → most_queue-1.63}/most_queue/sim/vacations.py +29 -16
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/batch/mm1.py +4 -4
- most_queue-1.63/most_queue/theory/calc_params.py +33 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/closed/engset.py +3 -2
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/fifo/ek_d_n.py +27 -22
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/fifo/gi_m_1.py +38 -24
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/fifo/gi_m_n.py +50 -28
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/fifo/m_d_n.py +11 -8
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/fifo/mg1.py +16 -17
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/fifo/mgn_takahasi.py +47 -35
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/fifo/mmnr.py +8 -9
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/fork_join/m_m_n.py +31 -18
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/fork_join/split_join.py +55 -44
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/impatience/mm1.py +10 -4
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/negative/mg1_disasters.py +12 -13
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/negative/mg1_rcs.py +21 -15
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/negative/mgn_disaster.py +41 -41
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/negative/mgn_rcs.py +45 -44
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/negative/structs.py +12 -3
- most_queue-1.63/most_queue/theory/networks/network_viewer.py +98 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/networks/open_network.py +21 -21
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/networks/open_network_prty.py +36 -26
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/networks/opt/transition.py +81 -70
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/networks/opt/transition_approx.py +48 -40
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/networks/opt/transition_plus.py +40 -27
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/priority/mgn_invar_approx.py +13 -11
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/priority/non_preemptive/mg1.py +4 -5
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/priority/preemptive/m_ph_n_busy_approx.py +62 -47
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/priority/preemptive/mg1.py +37 -64
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/priority/preemptive/mmn_2cls_pr_busy_approx.py +90 -73
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/priority/preemptive/mmn_3cls_busy_approx.py +98 -53
- most_queue-1.63/most_queue/theory/utils/binom_probs.py +23 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/utils/busy_periods.py +22 -20
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/utils/conditional.py +16 -12
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/utils/conv.py +5 -4
- most_queue-1.63/most_queue/theory/utils/diff5dots.py +39 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/utils/flow_sum.py +41 -29
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/utils/passage_time.py +246 -154
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/utils/q_poisson_arrival_calc.py +18 -9
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/utils/residual.py +8 -4
- most_queue-1.63/most_queue/theory/utils/student_stat.py +172 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/utils/transforms.py +5 -5
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/utils/utilization_approx.py +14 -11
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/vacations/m_h2_h2warm.py +105 -85
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/vacations/mg1_warm_calc.py +7 -8
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/vacations/mgn_with_h2_delay_cold_warm.py +108 -81
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/vacations/mmn_with_h2_cold_and_h2_warmup.py +87 -63
- {most_queue-1.62 → most_queue-1.63}/pyproject.toml +18 -1
- {most_queue-1.62 → most_queue-1.63}/requirements.txt +1 -1
- {most_queue-1.62 → most_queue-1.63}/setup.py +1 -1
- {most_queue-1.62 → most_queue-1.63}/tests/default_params.yaml +1 -1
- {most_queue-1.62 → most_queue-1.63}/tests/test_base_qs_sim.py +19 -20
- {most_queue-1.62 → most_queue-1.63}/tests/test_batch.py +15 -15
- {most_queue-1.62 → most_queue-1.63}/tests/test_ek_d_n.py +15 -14
- {most_queue-1.62 → most_queue-1.63}/tests/test_engset.py +22 -25
- {most_queue-1.62 → most_queue-1.63}/tests/test_fj_sim.py +27 -27
- {most_queue-1.62 → most_queue-1.63}/tests/test_gi_m_1_calc.py +17 -18
- {most_queue-1.62 → most_queue-1.63}/tests/test_gi_m_n_calc.py +16 -18
- {most_queue-1.62 → most_queue-1.63}/tests/test_impatience.py +13 -13
- {most_queue-1.62 → most_queue-1.63}/tests/test_m_d_n_calc.py +14 -14
- most_queue-1.63/tests/test_m_h2_h2warm.py +97 -0
- {most_queue-1.62 → most_queue-1.63}/tests/test_m_ph_n_prty.py +42 -36
- {most_queue-1.62 → most_queue-1.63}/tests/test_mg1_calc.py +17 -15
- {most_queue-1.62 → most_queue-1.63}/tests/test_mg1_disaster.py +29 -31
- most_queue-1.63/tests/test_mg1_rcs.py +75 -0
- {most_queue-1.62 → most_queue-1.63}/tests/test_mg1_warmup.py +19 -28
- most_queue-1.63/tests/test_mgn_disaster.py +94 -0
- most_queue-1.63/tests/test_mgn_rcs.py +97 -0
- {most_queue-1.62 → most_queue-1.63}/tests/test_mgn_tt.py +26 -32
- {most_queue-1.62 → most_queue-1.63}/tests/test_mgn_with_h2_delay_cold_warm.py +75 -70
- most_queue-1.63/tests/test_mmn_h2cold_h2warm.py +142 -0
- {most_queue-1.62 → most_queue-1.63}/tests/test_mmn_prty_pnz_approx.py +23 -26
- {most_queue-1.62 → most_queue-1.63}/tests/test_network_im_prty.py +75 -65
- most_queue-1.63/tests/test_network_no_prty.py +94 -0
- {most_queue-1.62 → most_queue-1.63}/tests/test_network_opt.py +24 -14
- most_queue-1.63/tests/test_qs_sim.py +79 -0
- {most_queue-1.62 → most_queue-1.63}/tests/test_qs_sim_prty.py +49 -26
- {most_queue-1.62 → most_queue-1.63}/tests/units/test_busy_moments_calc.py +18 -12
- {most_queue-1.62 → most_queue-1.63}/tests/units/test_conditionals.py +47 -53
- {most_queue-1.62 → most_queue-1.63}/tests/units/test_h2_params_cv.py +21 -28
- {most_queue-1.62 → most_queue-1.63}/tests/units/test_queue_types.py +15 -18
- {most_queue-1.62 → most_queue-1.63}/tests/units/test_tt_up_probs.py +9 -12
- {most_queue-1.62 → most_queue-1.63}/tests/units/test_v1_on_channels.py +32 -20
- {most_queue-1.62 → most_queue-1.63}/tests/units/test_v1_utlization_approx.py +2 -2
- {most_queue-1.62 → most_queue-1.63}/tests/units/test_weibull.py +5 -5
- most_queue-1.63/tutorials/m_h2_h2warm.ipynb +334 -0
- most_queue-1.63/tutorials/mgn_takahasi_takami.ipynb +300 -0
- most_queue-1.63/tutorials/network_with_priorities.ipynb +374 -0
- {most_queue-1.62 → most_queue-1.63}/tutorials/priority_queue.ipynb +23 -17
- most_queue-1.63/tutorials/queue_sim.ipynb +378 -0
- {most_queue-1.62 → most_queue-1.63}/works/negative_queues/work_mgn_negatives.py +163 -105
- {most_queue-1.62 → most_queue-1.63}/works/vacations/utils.py +4 -21
- most_queue-1.62/most_queue/general/tables.py +0 -324
- most_queue-1.62/most_queue/theory/networks/network_viewer.py +0 -90
- most_queue-1.62/most_queue/theory/utils/binom_probs.py +0 -14
- most_queue-1.62/most_queue/theory/utils/diff5dots.py +0 -30
- most_queue-1.62/most_queue/theory/utils/student_stat.py +0 -184
- most_queue-1.62/tests/cold_warm_delay_params.yaml +0 -51
- most_queue-1.62/tests/test_m_h2_h2warm.py +0 -108
- most_queue-1.62/tests/test_mg1_rcs.py +0 -85
- most_queue-1.62/tests/test_mgn_disaster.py +0 -98
- most_queue-1.62/tests/test_mgn_rcs.py +0 -101
- most_queue-1.62/tests/test_mmn_h2cold_h2warm.py +0 -144
- most_queue-1.62/tests/test_network_no_prty.py +0 -77
- most_queue-1.62/tests/test_network_opt_approx.py +0 -42
- most_queue-1.62/tests/test_network_opt_plus.py +0 -49
- most_queue-1.62/tests/test_qs_sim.py +0 -75
- most_queue-1.62/tutorials/m_h2_h2warm.ipynb +0 -338
- most_queue-1.62/tutorials/mgn_takahasi_takami.ipynb +0 -302
- most_queue-1.62/tutorials/network_with_priorities.ipynb +0 -371
- most_queue-1.62/tutorials/queue_sim.ipynb +0 -378
- {most_queue-1.62 → most_queue-1.63}/.gitignore +0 -0
- {most_queue-1.62 → most_queue-1.63}/LICENSE +0 -0
- {most_queue-1.62 → most_queue-1.63}/assets/1.gif +0 -0
- {most_queue-1.62 → most_queue-1.63}/assets/2.gif +0 -0
- {most_queue-1.62 → most_queue-1.63}/assets/3.gif +0 -0
- {most_queue-1.62 → most_queue-1.63}/assets/queue_long.png +0 -0
- {most_queue-1.62 → most_queue-1.63}/deploy.txt +0 -0
- {most_queue-1.62 → most_queue-1.63}/docs/Makefile +0 -0
- {most_queue-1.62 → most_queue-1.63}/docs/make.bat +0 -0
- {most_queue-1.62 → most_queue-1.63}/docs/source/conf.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/docs/source/index.rst +0 -0
- {most_queue-1.62 → most_queue-1.63}/docs/source/modules.rst +0 -0
- {most_queue-1.62 → most_queue-1.63}/docs/source/most_queue.rst +0 -0
- {most_queue-1.62 → most_queue-1.63}/docs/source/most_queue.sim.rst +0 -0
- {most_queue-1.62 → most_queue-1.63}/docs/source/most_queue.theory.rst +0 -0
- {most_queue-1.62 → most_queue-1.63}/googleb31d3dccb40f969f.html +0 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/__init__.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/general/__init__.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/sim/__init__.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/sim/networks/__init__.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/sim/utils/__init__.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/__init__.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/batch/__init__.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/closed/__init__.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/fifo/__init__.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/fork_join/__init__.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/impatience/__init__.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/networks/__init__.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/networks/opt/__init__.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/priority/__init__.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/priority/non_preemptive/__init__.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/priority/preemptive/__init__.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/r_example.gexf +0 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/utils/__init__.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/most_queue/theory/vacations/__init__.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/tests/__init__.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/tests/units/h2_params_cv_greater_than_exp.png +0 -0
- {most_queue-1.62 → most_queue-1.63}/tests/units/h2_params_cv_less_than_exp.png +0 -0
- {most_queue-1.62 → most_queue-1.63}/tests/units/v1_on_channels.png +0 -0
- {most_queue-1.62 → most_queue-1.63}/tests/units/v1_on_utilization_approx.png +0 -0
- {most_queue-1.62 → most_queue-1.63}/works/__init__.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/works/negative_queues/__init__.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/works/negative_queues/base_parameters.yaml +0 -0
- {most_queue-1.62 → most_queue-1.63}/works/vacations/__init__.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/works/vacations/base_parameters.yaml +0 -0
- {most_queue-1.62 → most_queue-1.63}/works/vacations/channels.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/works/vacations/cooling.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/works/vacations/cooling_delay.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/works/vacations/main.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/works/vacations/run_one_calc_vs_sim.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/works/vacations/service.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/works/vacations/utilization.py +0 -0
- {most_queue-1.62 → most_queue-1.63}/works/vacations/warmup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: most_queue
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.63
|
|
4
4
|
Summary: Software package for calculation and simulation of queuing systems
|
|
5
5
|
Project-URL: Homepage, https://github.com/xabarov/most-queue
|
|
6
6
|
Author-email: Xabarov Roman <xabarov1985@gmail.com>
|
|
@@ -104,15 +104,14 @@ Most_queue consists of two main parts:
|
|
|
104
104
|
|-----|-------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------|-------------------|
|
|
105
105
|
| 1. | M/Ph/c/PR | Numerical calculation of QS M/Ph/c with 2 classes and PR - priority. Based on the approximation of busy periods | [link](https://github.com/xabarov/most-queue/blob/main/tests/test_m_ph_n_prty.py) | |
|
|
106
106
|
| 2. | M/M/c/PR | Numerical calculation of QS M/M/c with 2 classes, PR - priority by the Takahashi-Takami numerical method based on the approximation of the busy period by the Cox distribution | [link](https://github.com/xabarov/most-queue/blob/main/tests/test_mmn_prty_pnz_approx.py) | |
|
|
107
|
-
| 3. | M/
|
|
108
|
-
| 4. | M/G/1/
|
|
109
|
-
| 5. | M/G/
|
|
110
|
-
| 6. | M/G/c/Priority | Calculating QS with NP and PR (multi-channel) by method of relation | [link](https://github.com/xabarov/most-queue/blob/main/tests/test_qs_sim_prty.py) |[link](https://github.com/xabarov/most-queue/blob/main/tutorials/priority_queue.ipynb) |
|
|
107
|
+
| 3. | M/G/1/PR | Calculating QS with preemtive priorities (single-channel). | [link](https://github.com/xabarov/most-queue/blob/main/tests/test_qs_sim_prty.py) |[link](https://github.com/xabarov/most-queue/blob/main/tutorials/priority_queue.ipynb) |
|
|
108
|
+
| 4. | M/G/1/NP | Calculating QS with non-preemtive priorities (single-channel). | [link](https://github.com/xabarov/most-queue/blob/main/tests/test_qs_sim_prty.py) |[link](https://github.com/xabarov/most-queue/blob/main/tutorials/priority_queue.ipynb) |
|
|
109
|
+
| 5. | M/G/c/Priority | Calculating QS with NP and PR (multi-channel) by method of relation | [link](https://github.com/xabarov/most-queue/blob/main/tests/test_qs_sim_prty.py) |[link](https://github.com/xabarov/most-queue/blob/main/tutorials/priority_queue.ipynb) |
|
|
111
110
|
|
|
112
111
|
### Queueing Systems with Vacations
|
|
113
112
|
| # | Kendall Notations | Description | Example | Tutorial |
|
|
114
113
|
|-----|-------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------|-------------------|
|
|
115
|
-
| 1. | M/H<SUB>2</SUB>/c | Numerical calculation of the M/H<SUB>2</SUB>/c system with H<SUB>2</SUB>-warming using the
|
|
114
|
+
| 1. | M/H<SUB>2</SUB>/c | Numerical calculation of the M/H<SUB>2</SUB>/c system with H<SUB>2</SUB>-warming using the Takahashi-Takami method. | [link](https://github.com/xabarov/most-queue/blob/main/tests/test_m_h2_h2warm.py) | [link](https://github.com/xabarov/most-queue/blob/main/tutorials/m_h2_h2warm.ipynb)| |
|
|
116
115
|
| 2. | M/G/1 | Solving for QS M/G/1 with warm-up | | |
|
|
117
116
|
| 3. | M/Ph/c | Multichannel queuing system with H<SUB>2</SUB>-serving time, H<SUB>2</SUB>-warm-up, H<SUB>2</SUB>-cold delay and H<SUB>2</SUB>-cold (vacations). The system uses complex parameters, which allows you to calculate systems with arbitrary serving, warm-up, cold-delay and cold variation coefficients | [link](https://github.com/xabarov/most-queue/blob/main/tests/test_mgn_with_h2_delay_cold_warm.py) | |
|
|
118
117
|
| 4. | M/M/c | Multichannel queuing system with exp serving time, H<SUB>2</SUB>-warm-up and H<SUB>2</SUB>-cold (vacations). The system uses complex parameters, which allows to calculate systems with arbitrary warm-up and cold variation coefficients | [link](https://github.com/xabarov/most-queue/blob/main/tests/test_mmn_h2cold_h2warm.py) | |
|
|
@@ -63,15 +63,14 @@ Most_queue consists of two main parts:
|
|
|
63
63
|
|-----|-------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------|-------------------|
|
|
64
64
|
| 1. | M/Ph/c/PR | Numerical calculation of QS M/Ph/c with 2 classes and PR - priority. Based on the approximation of busy periods | [link](https://github.com/xabarov/most-queue/blob/main/tests/test_m_ph_n_prty.py) | |
|
|
65
65
|
| 2. | M/M/c/PR | Numerical calculation of QS M/M/c with 2 classes, PR - priority by the Takahashi-Takami numerical method based on the approximation of the busy period by the Cox distribution | [link](https://github.com/xabarov/most-queue/blob/main/tests/test_mmn_prty_pnz_approx.py) | |
|
|
66
|
-
| 3. | M/
|
|
67
|
-
| 4. | M/G/1/
|
|
68
|
-
| 5. | M/G/
|
|
69
|
-
| 6. | M/G/c/Priority | Calculating QS with NP and PR (multi-channel) by method of relation | [link](https://github.com/xabarov/most-queue/blob/main/tests/test_qs_sim_prty.py) |[link](https://github.com/xabarov/most-queue/blob/main/tutorials/priority_queue.ipynb) |
|
|
66
|
+
| 3. | M/G/1/PR | Calculating QS with preemtive priorities (single-channel). | [link](https://github.com/xabarov/most-queue/blob/main/tests/test_qs_sim_prty.py) |[link](https://github.com/xabarov/most-queue/blob/main/tutorials/priority_queue.ipynb) |
|
|
67
|
+
| 4. | M/G/1/NP | Calculating QS with non-preemtive priorities (single-channel). | [link](https://github.com/xabarov/most-queue/blob/main/tests/test_qs_sim_prty.py) |[link](https://github.com/xabarov/most-queue/blob/main/tutorials/priority_queue.ipynb) |
|
|
68
|
+
| 5. | M/G/c/Priority | Calculating QS with NP and PR (multi-channel) by method of relation | [link](https://github.com/xabarov/most-queue/blob/main/tests/test_qs_sim_prty.py) |[link](https://github.com/xabarov/most-queue/blob/main/tutorials/priority_queue.ipynb) |
|
|
70
69
|
|
|
71
70
|
### Queueing Systems with Vacations
|
|
72
71
|
| # | Kendall Notations | Description | Example | Tutorial |
|
|
73
72
|
|-----|-------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------|-------------------|
|
|
74
|
-
| 1. | M/H<SUB>2</SUB>/c | Numerical calculation of the M/H<SUB>2</SUB>/c system with H<SUB>2</SUB>-warming using the
|
|
73
|
+
| 1. | M/H<SUB>2</SUB>/c | Numerical calculation of the M/H<SUB>2</SUB>/c system with H<SUB>2</SUB>-warming using the Takahashi-Takami method. | [link](https://github.com/xabarov/most-queue/blob/main/tests/test_m_h2_h2warm.py) | [link](https://github.com/xabarov/most-queue/blob/main/tutorials/m_h2_h2warm.ipynb)| |
|
|
75
74
|
| 2. | M/G/1 | Solving for QS M/G/1 with warm-up | | |
|
|
76
75
|
| 3. | M/Ph/c | Multichannel queuing system with H<SUB>2</SUB>-serving time, H<SUB>2</SUB>-warm-up, H<SUB>2</SUB>-cold delay and H<SUB>2</SUB>-cold (vacations). The system uses complex parameters, which allows you to calculate systems with arbitrary serving, warm-up, cold-delay and cold variation coefficients | [link](https://github.com/xabarov/most-queue/blob/main/tests/test_mgn_with_h2_delay_cold_warm.py) | |
|
|
77
76
|
| 4. | M/M/c | Multichannel queuing system with exp serving time, H<SUB>2</SUB>-warm-up and H<SUB>2</SUB>-cold (vacations). The system uses complex parameters, which allows to calculate systems with arbitrary warm-up and cold variation coefficients | [link](https://github.com/xabarov/most-queue/blob/main/tests/test_mmn_h2cold_h2warm.py) | |
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
digraph QS {
|
|
2
|
+
graph [rankdir=LR]
|
|
3
|
+
0 [label=0 color=lightblue2 style=filled]
|
|
4
|
+
1 [label=1]
|
|
5
|
+
2 [label=2]
|
|
6
|
+
3 [label=3]
|
|
7
|
+
4 [label=4]
|
|
8
|
+
5 [label=5]
|
|
9
|
+
6 [label=6 color=lightblue2 style=filled]
|
|
10
|
+
0 -> 1 [label=1.0]
|
|
11
|
+
1 -> 2 [label=0.4]
|
|
12
|
+
1 -> 3 [label=0.6]
|
|
13
|
+
2 -> 4 [label=0.6]
|
|
14
|
+
2 -> 5 [label=0.4]
|
|
15
|
+
3 -> 5 [label=1.0]
|
|
16
|
+
4 -> 5 [label=1.0]
|
|
17
|
+
5 -> 6 [label=1.0]
|
|
18
|
+
}
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Methods for fitting distributions to given initial moments.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import cmath
|
|
6
|
+
import math
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
import numpy as np
|
|
10
|
+
|
|
11
|
+
from most_queue.general.distribution_params import (Cox2Params, ErlangParams,
|
|
12
|
+
GammaParams, H2Params,
|
|
13
|
+
ParetoParams,
|
|
14
|
+
WeibullParams)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class FittingParams:
|
|
19
|
+
"""
|
|
20
|
+
Parameters for distribution fitting.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
verbose: bool = True
|
|
24
|
+
ee: float = 0.001
|
|
25
|
+
e: float = 0.02
|
|
26
|
+
e_percent: float = 0.15
|
|
27
|
+
is_fitting: bool = True
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def fit_h2(moments: list[float]) -> H2Params:
|
|
31
|
+
"""
|
|
32
|
+
Aliev's method for calculating the parameters of H2 distribution by given initial moments.
|
|
33
|
+
Only real parameters are selected.
|
|
34
|
+
Returns a list with parameters [y1, mu1, mu2].
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
v = moments[1] - moments[0] * moments[0]
|
|
38
|
+
v = math.sqrt(v) / moments[0]
|
|
39
|
+
res = [0.0] * 3
|
|
40
|
+
if v < 1.0:
|
|
41
|
+
return H2Params(p1=0, mu1=0, mu2=0)
|
|
42
|
+
|
|
43
|
+
q_max = 2.0 / (1.0 + v * v)
|
|
44
|
+
t_min = 1.5 * ((1 + v * v) ** 2) * math.pow(moments[0], 3)
|
|
45
|
+
q_min = 0.0
|
|
46
|
+
tn = 0.0
|
|
47
|
+
|
|
48
|
+
if t_min > moments[2]:
|
|
49
|
+
# one phase distibution
|
|
50
|
+
q_new = q_max
|
|
51
|
+
mu1 = (1.0 - math.sqrt(q_new * (v * v - 1.0) / (2 * (1.0 - q_new)))) * moments[0]
|
|
52
|
+
if math.isclose(mu1, 0):
|
|
53
|
+
mu1 = 1e10
|
|
54
|
+
else:
|
|
55
|
+
mu1 = 1.0 / mu1
|
|
56
|
+
res = H2Params(p1=q_max, mu1=mu1, mu2=1e6)
|
|
57
|
+
return res
|
|
58
|
+
|
|
59
|
+
max_iteration = 10000
|
|
60
|
+
tec = 0
|
|
61
|
+
t1 = 0
|
|
62
|
+
t2 = 0
|
|
63
|
+
while abs(tn - moments[2]) > 1e-8 and tec < max_iteration:
|
|
64
|
+
tec += 1
|
|
65
|
+
q_new = (q_max + q_min) / 2.0
|
|
66
|
+
t1 = (1.0 + math.sqrt((1.0 - q_new) * (v * v - 1.0) / (2 * q_new))) * moments[0]
|
|
67
|
+
t2 = (1.0 - math.sqrt(q_new * (v * v - 1.0) / (2 * (1.0 - q_new)))) * moments[0]
|
|
68
|
+
|
|
69
|
+
tn = 6 * (q_new * math.pow(t1, 3) + (1.0 - q_new) * math.pow(t2, 3))
|
|
70
|
+
|
|
71
|
+
if tn - moments[2] > 0:
|
|
72
|
+
q_min = q_new
|
|
73
|
+
else:
|
|
74
|
+
q_max = q_new
|
|
75
|
+
|
|
76
|
+
res = H2Params(p1=q_max, mu1=1.0 / t1, mu2=1.0 / t2)
|
|
77
|
+
return res
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def fit_h2_clx(moments: list[float], fitting_params: FittingParams | None = None) -> H2Params:
|
|
81
|
+
"""
|
|
82
|
+
Method of fitting H2 distribution parameters to given initial moments.
|
|
83
|
+
Uses the method of moments and optimization to fit the parameters.
|
|
84
|
+
Returns H2Params object with fitted parameters.
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
if fitting_params is None:
|
|
88
|
+
fitting_params = FittingParams()
|
|
89
|
+
|
|
90
|
+
f = [0.0] * 3
|
|
91
|
+
for i in range(3):
|
|
92
|
+
f[i] = complex(moments[i] / math.factorial(i + 1))
|
|
93
|
+
znam = f[1] - pow(f[0], 2)
|
|
94
|
+
c0 = (f[0] * f[2] - pow(f[1], 2)) / znam
|
|
95
|
+
c1 = (f[0] * f[1] - f[2]) / znam
|
|
96
|
+
|
|
97
|
+
d = pow(c1 / 2.0, 2.0) - c0
|
|
98
|
+
|
|
99
|
+
if fitting_params.is_fitting:
|
|
100
|
+
# проверка на близость распределения к экспоненциальному
|
|
101
|
+
coev = cmath.sqrt(moments[1] - moments[0] ** 2) / moments[0]
|
|
102
|
+
if math.fabs(coev.real - 1.0) < fitting_params.ee:
|
|
103
|
+
if fitting_params.verbose:
|
|
104
|
+
print(
|
|
105
|
+
f"H2 is close to Exp. Multiply moments to (1+je)"
|
|
106
|
+
f"coev = {coev:5.3f}, e = {fitting_params.e:5.3f}."
|
|
107
|
+
)
|
|
108
|
+
f = []
|
|
109
|
+
for i, mom in enumerate(moments):
|
|
110
|
+
f.append(mom * complex(1, (i + 1) * fitting_params.e))
|
|
111
|
+
|
|
112
|
+
return fit_h2_clx(f, fitting_params=fitting_params)
|
|
113
|
+
|
|
114
|
+
coev = cmath.sqrt(moments[1] - moments[0] ** 2) / moments[0]
|
|
115
|
+
|
|
116
|
+
# проверка на близость распределения к Эрланга 2-го порядка
|
|
117
|
+
if math.fabs(coev.real - 1.0 / math.sqrt(2.0)) < fitting_params.ee:
|
|
118
|
+
if fitting_params.verbose:
|
|
119
|
+
print(
|
|
120
|
+
f"H2 is close to E2. Multiply moments to (1+je)"
|
|
121
|
+
f"coev = {coev:5.3f}, e = {fitting_params.e:5.3f}."
|
|
122
|
+
)
|
|
123
|
+
f = []
|
|
124
|
+
for i, mom in enumerate(moments):
|
|
125
|
+
f.append(mom * complex(1, (i + 1) * fitting_params.e))
|
|
126
|
+
return fit_h2_clx(f, fitting_params=fitting_params)
|
|
127
|
+
|
|
128
|
+
res = [0, 0, 0] # y1, mu1, mu2
|
|
129
|
+
c1 = complex(c1)
|
|
130
|
+
x1 = -c1 / 2 + cmath.sqrt(d)
|
|
131
|
+
x2 = -c1 / 2 - cmath.sqrt(d)
|
|
132
|
+
y1 = (f[0] - x2) / (x1 - x2)
|
|
133
|
+
|
|
134
|
+
res = H2Params(p1=y1, mu1=1.0 / x1, mu2=1.0 / x2)
|
|
135
|
+
|
|
136
|
+
return res
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def fit_cox(moments: list[float], fitting_params: FittingParams | None = None) -> Cox2Params:
|
|
140
|
+
"""
|
|
141
|
+
Calculates Cox-2 distribution parameters by three given initial moments [moments].
|
|
142
|
+
"""
|
|
143
|
+
|
|
144
|
+
if not fitting_params:
|
|
145
|
+
fitting_params = FittingParams()
|
|
146
|
+
|
|
147
|
+
f = [0.0] * 3
|
|
148
|
+
|
|
149
|
+
if fitting_params.is_fitting:
|
|
150
|
+
# проверка на близость распределения к экспоненциальному
|
|
151
|
+
coev = cmath.sqrt(moments[1] - moments[0] ** 2) / moments[0]
|
|
152
|
+
if abs(moments[1] - moments[0] * moments[0]) < fitting_params.ee:
|
|
153
|
+
if fitting_params.verbose:
|
|
154
|
+
print(
|
|
155
|
+
f"Cox special 1. Multiply moments to (1+je)"
|
|
156
|
+
f"coev = {coev:5.3f} e = {fitting_params.e:5.3f}."
|
|
157
|
+
)
|
|
158
|
+
f = []
|
|
159
|
+
for i, mom in enumerate(moments):
|
|
160
|
+
f.append(mom * complex(1, (i + 1) * fitting_params.e))
|
|
161
|
+
|
|
162
|
+
return fit_cox(f, fitting_params=fitting_params)
|
|
163
|
+
|
|
164
|
+
coev = cmath.sqrt(moments[1] - moments[0] ** 2) / moments[0]
|
|
165
|
+
|
|
166
|
+
# проверка на близость распределения к Эрланга 2-го порядка
|
|
167
|
+
if abs(moments[1] - (3.0 / 4) * moments[0] * moments[0]) < fitting_params.ee:
|
|
168
|
+
if fitting_params.verbose:
|
|
169
|
+
print("Cox special 2. Multiply moments to (1+je)")
|
|
170
|
+
print(f"\tcoev = {coev:5.3f}, e = {fitting_params.e:5.3f}")
|
|
171
|
+
f = []
|
|
172
|
+
for i, mom in enumerate(moments):
|
|
173
|
+
f.append(mom * complex(1, (i + 1) * fitting_params.e))
|
|
174
|
+
return fit_cox(f, fitting_params=fitting_params)
|
|
175
|
+
|
|
176
|
+
for i in range(3):
|
|
177
|
+
f[i] = moments[i] / math.factorial(i + 1)
|
|
178
|
+
|
|
179
|
+
d = np.power(f[2] - f[0] * f[1], 2) - 4.0 * (f[1] - np.power(f[0], 2)) * (
|
|
180
|
+
f[0] * f[2] - np.power(f[1], 2)
|
|
181
|
+
)
|
|
182
|
+
mu2 = f[0] * f[1] - f[2] + cmath.sqrt(d)
|
|
183
|
+
mu2 /= 2.0 * (np.power(f[1], 2) - f[0] * f[2])
|
|
184
|
+
mu1 = (mu2 * f[0] - 1.0) / (mu2 * f[1] - f[0])
|
|
185
|
+
y1 = (mu1 * f[0] - 1.0) * mu2 / mu1
|
|
186
|
+
|
|
187
|
+
return Cox2Params(p1=y1, mu1=mu1, mu2=mu2)
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def fit_pareto_moments(moments: list[float]):
|
|
191
|
+
"""
|
|
192
|
+
Calc parameters of the distribution.
|
|
193
|
+
:param moments: list of initial moments
|
|
194
|
+
"""
|
|
195
|
+
d = moments[1] - moments[0] * moments[0]
|
|
196
|
+
c = moments[0] * moments[0] / d
|
|
197
|
+
disc = 4 * (1 + c)
|
|
198
|
+
a = (2 + math.sqrt(disc)) / 2
|
|
199
|
+
k = (a - 1) * moments[0] / a
|
|
200
|
+
return ParetoParams(alpha=a, K=k)
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def fit_pareto_by_mean_and_coev(f1: float, coev: float):
|
|
204
|
+
"""
|
|
205
|
+
Get parameters of the distribution by mean and coefficient of variation.
|
|
206
|
+
:param f1: float, mean value of the distribution
|
|
207
|
+
:param coev: float, coefficient of variation (mean / std)
|
|
208
|
+
"""
|
|
209
|
+
d = pow(f1 * coev, 2)
|
|
210
|
+
c = pow(f1, 2) / d
|
|
211
|
+
disc = 4 * (1 + c)
|
|
212
|
+
a = (2 + math.sqrt(disc)) / 2
|
|
213
|
+
k = (a - 1) * f1 / a
|
|
214
|
+
return ParetoParams(alpha=a, K=k)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def fit_erlang(moments: list[float]) -> ErlangParams:
|
|
218
|
+
"""
|
|
219
|
+
Calculates parameters of the Erlang distribution by initial moments.
|
|
220
|
+
"""
|
|
221
|
+
r = int(math.floor(moments[0] * moments[0] / (moments[1] - moments[0] * moments[0]) + 0.5))
|
|
222
|
+
mu = r / moments[0]
|
|
223
|
+
return ErlangParams(r=r, mu=mu)
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def calc_gamma_func(x):
|
|
227
|
+
"""
|
|
228
|
+
Gamma-function Г(x)
|
|
229
|
+
"""
|
|
230
|
+
if (x > 0.0) & (x < 1.0):
|
|
231
|
+
return calc_gamma_func(x + 1.0) / x
|
|
232
|
+
if x > 2:
|
|
233
|
+
return (x - 1) * calc_gamma_func(x - 1)
|
|
234
|
+
if x <= 0:
|
|
235
|
+
return math.pi / (math.sin(math.pi * x) * calc_gamma_func(1 - x))
|
|
236
|
+
return gamma_approx(x)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def gamma_approx(x):
|
|
240
|
+
"""
|
|
241
|
+
Get approximation of Gamma function for x in [1,2]
|
|
242
|
+
"""
|
|
243
|
+
p = [
|
|
244
|
+
-1.71618513886549492533811e0,
|
|
245
|
+
2.47656508055759199108314e1,
|
|
246
|
+
-3.79804256470945635097577e2,
|
|
247
|
+
6.29331155312818442661052e2,
|
|
248
|
+
8.66966202790413211295064e2,
|
|
249
|
+
-3.14512729688483657254357e4,
|
|
250
|
+
-3.61444134186911729807069e4,
|
|
251
|
+
6.6456143820240544627855e4,
|
|
252
|
+
]
|
|
253
|
+
q = [
|
|
254
|
+
-3.08402300119738975254354e1,
|
|
255
|
+
3.15350626979604161529144e2,
|
|
256
|
+
-1.01515636749021914166146e3,
|
|
257
|
+
-3.10777167157231109440444e3,
|
|
258
|
+
2.253811842098015100330112e4,
|
|
259
|
+
4.75584667752788110767815e3,
|
|
260
|
+
-1.34659959864969306392456e5,
|
|
261
|
+
-1.15132259675553483497211e5,
|
|
262
|
+
]
|
|
263
|
+
z = x - 1.0
|
|
264
|
+
a = 0.0
|
|
265
|
+
b = 1.0
|
|
266
|
+
for i in range(0, 8):
|
|
267
|
+
a = (a + p[i]) * z
|
|
268
|
+
b = b * z + q[i]
|
|
269
|
+
return a / b + 1.0
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def fit_gamma(moments: list[float]) -> GammaParams:
|
|
273
|
+
"""
|
|
274
|
+
Get parameters of the Gamma distribution from theoretical moments.
|
|
275
|
+
"""
|
|
276
|
+
d = moments[1] - moments[0] * moments[0]
|
|
277
|
+
mu = moments[0] / d
|
|
278
|
+
alpha = mu * moments[0]
|
|
279
|
+
if len(moments) > 2:
|
|
280
|
+
# подбор коэффициентов g
|
|
281
|
+
A = []
|
|
282
|
+
B = []
|
|
283
|
+
for i in range(len(moments) + 1):
|
|
284
|
+
A.append([])
|
|
285
|
+
if i == 0:
|
|
286
|
+
B.append(1)
|
|
287
|
+
else:
|
|
288
|
+
B.append(moments[i - 1])
|
|
289
|
+
for j in range(len(moments) + 1):
|
|
290
|
+
A[i].append(
|
|
291
|
+
calc_gamma_func(alpha + i + j) / (pow(mu, i + j) * calc_gamma_func(alpha))
|
|
292
|
+
)
|
|
293
|
+
g = np.linalg.solve(A, B)
|
|
294
|
+
return GammaParams(mu=mu, alpha=alpha, g=g)
|
|
295
|
+
|
|
296
|
+
return GammaParams(mu=mu, alpha=alpha)
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
def fit_weibull(moments: list[float]) -> WeibullParams:
|
|
300
|
+
"""
|
|
301
|
+
Parameter selection for the distribution based
|
|
302
|
+
on initial moments of the distribution
|
|
303
|
+
|
|
304
|
+
params:
|
|
305
|
+
moments: initial moments of the random variable
|
|
306
|
+
|
|
307
|
+
return:
|
|
308
|
+
WeibullParams
|
|
309
|
+
|
|
310
|
+
"""
|
|
311
|
+
a = moments[1] / (moments[0] * moments[0])
|
|
312
|
+
u0 = math.log(2 * a) / (2.0 * math.log(2))
|
|
313
|
+
ee = 1e-6
|
|
314
|
+
u1 = (1.0 / (2 * math.log(2))) * math.log(
|
|
315
|
+
a * math.sqrt(math.pi) * math.gamma(u0 + 1) / math.gamma(u0 + 0.5)
|
|
316
|
+
)
|
|
317
|
+
delta = u1 - u0
|
|
318
|
+
while math.fabs(delta) > ee:
|
|
319
|
+
u1 = (1.0 / (2 * math.log(2))) * math.log(
|
|
320
|
+
a * math.sqrt(math.pi) * math.gamma(u0 + 1) / math.gamma(u0 + 0.5)
|
|
321
|
+
)
|
|
322
|
+
delta = u1 - u0
|
|
323
|
+
u0 = u1
|
|
324
|
+
k = 1 / u1
|
|
325
|
+
big_w = math.pow(moments[0] / math.gamma(u1 + 1), k)
|
|
326
|
+
|
|
327
|
+
return WeibullParams(k=k, W=big_w)
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
def gamma_moments_by_mean_and_coev(mean: float, coev: float) -> list[float]:
|
|
331
|
+
"""
|
|
332
|
+
Calculate the first three moments of a gamma distribution
|
|
333
|
+
given the mean and coefficient of variation.
|
|
334
|
+
"""
|
|
335
|
+
f = [0, 0, 0]
|
|
336
|
+
alpha = 1 / (coev**2)
|
|
337
|
+
f[0] = mean
|
|
338
|
+
f[1] = pow(f[0], 2) * (pow(coev, 2) + 1)
|
|
339
|
+
f[2] = f[1] * f[0] * (1.0 + 2 / alpha)
|
|
340
|
+
return f
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Distribution parameters classes.
|
|
3
3
|
"""
|
|
4
|
+
|
|
4
5
|
from dataclasses import dataclass
|
|
5
6
|
|
|
6
7
|
|
|
@@ -9,6 +10,7 @@ class H2Params:
|
|
|
9
10
|
"""
|
|
10
11
|
H2 distribution parameters.
|
|
11
12
|
"""
|
|
13
|
+
|
|
12
14
|
mu1: float | complex # Mean of the first phase
|
|
13
15
|
mu2: float | complex # Mean of the second phase
|
|
14
16
|
p1: float | complex # Probability of being in the first phase
|
|
@@ -19,6 +21,7 @@ class Cox2Params:
|
|
|
19
21
|
"""
|
|
20
22
|
Coxian second order distribution parameters.
|
|
21
23
|
"""
|
|
24
|
+
|
|
22
25
|
mu1: float | complex # Mean of the first phase
|
|
23
26
|
mu2: float | complex # Mean of the second phase
|
|
24
27
|
# probability for transition between phase 1 and phase 2.
|
|
@@ -30,6 +33,7 @@ class GammaParams:
|
|
|
30
33
|
"""
|
|
31
34
|
Gamma distribution parameters.
|
|
32
35
|
"""
|
|
36
|
+
|
|
33
37
|
mu: float # 1/theta
|
|
34
38
|
alpha: float
|
|
35
39
|
g: list[float] | None = None
|
|
@@ -38,8 +42,9 @@ class GammaParams:
|
|
|
38
42
|
@dataclass
|
|
39
43
|
class WeibullParams:
|
|
40
44
|
"""
|
|
41
|
-
|
|
45
|
+
Weibull distribution parameters.
|
|
42
46
|
"""
|
|
47
|
+
|
|
43
48
|
k: float # Shape parameter
|
|
44
49
|
W: float # Scale parameter
|
|
45
50
|
|
|
@@ -49,6 +54,7 @@ class GaussianParams:
|
|
|
49
54
|
"""
|
|
50
55
|
Normal distribution parameters.
|
|
51
56
|
"""
|
|
57
|
+
|
|
52
58
|
mean: float # Mean of the distribution
|
|
53
59
|
std_dev: float # Standard deviation of the distribution
|
|
54
60
|
|
|
@@ -58,6 +64,7 @@ class UniformParams:
|
|
|
58
64
|
"""
|
|
59
65
|
Uniform distribution parameters.
|
|
60
66
|
"""
|
|
67
|
+
|
|
61
68
|
mean: float # Mean of the distribution
|
|
62
69
|
half_interval: float # Half interval of the distribution
|
|
63
70
|
|
|
@@ -67,6 +74,7 @@ class ParetoParams:
|
|
|
67
74
|
"""
|
|
68
75
|
Pareto distribution parameters.
|
|
69
76
|
"""
|
|
77
|
+
|
|
70
78
|
alpha: float # alpha of the distribution
|
|
71
79
|
K: float # K of the distribution (or x_m, minimum value of x)
|
|
72
80
|
|
|
@@ -76,5 +84,6 @@ class ErlangParams:
|
|
|
76
84
|
"""
|
|
77
85
|
Erlang distribution parameters.
|
|
78
86
|
"""
|
|
87
|
+
|
|
79
88
|
r: int
|
|
80
89
|
mu: float
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Abstract base class for all distributions.
|
|
3
3
|
"""
|
|
4
|
+
|
|
4
5
|
from abc import ABC, abstractmethod
|
|
5
6
|
|
|
6
7
|
|
|
@@ -58,5 +59,6 @@ class Distribution(ABC):
|
|
|
58
59
|
"""
|
|
59
60
|
:param f1: mean of the distribution.
|
|
60
61
|
:param coev: coefficient of variation (std_dev / mean).
|
|
61
|
-
:return: Parameters for the distribution that correspond
|
|
62
|
+
:return: Parameters for the distribution that correspond
|
|
63
|
+
to the given mean and coefficient of variation.
|
|
62
64
|
"""
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Plotting utilities for simulation results.
|
|
3
3
|
"""
|
|
4
|
+
|
|
4
5
|
from enum import Enum
|
|
5
6
|
|
|
6
7
|
import matplotlib.pyplot as plt
|
|
@@ -10,16 +11,22 @@ class DependsType(Enum):
|
|
|
10
11
|
"""
|
|
11
12
|
Enum to specify the type of dependency for plotting.
|
|
12
13
|
"""
|
|
14
|
+
|
|
13
15
|
NONE = 0
|
|
14
16
|
UTILIZATION_FACTOR = 1
|
|
15
17
|
CHANNELS_NUMBER = 2
|
|
16
18
|
COEFFICIENT_OF_VARIATION = 3
|
|
17
19
|
|
|
18
20
|
|
|
19
|
-
def plot_sim_vs_calc_moments(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
def plot_sim_vs_calc_moments(
|
|
22
|
+
xs: list[float],
|
|
23
|
+
sim_results: list[float],
|
|
24
|
+
calc_results: list[float],
|
|
25
|
+
depends_on: DependsType = DependsType.CHANNELS_NUMBER,
|
|
26
|
+
is_errors=False,
|
|
27
|
+
is_waiting_time=True,
|
|
28
|
+
save_path=None,
|
|
29
|
+
):
|
|
23
30
|
"""
|
|
24
31
|
Plots the simulation and calculated moments for a given list of x values.
|
|
25
32
|
:param xs: A list of x values (e.g., utilization factors or number of channels).
|
|
@@ -27,9 +34,11 @@ def plot_sim_vs_calc_moments(xs: list[float], sim_results: list[float],
|
|
|
27
34
|
:param sim_results: A list of simulated results.
|
|
28
35
|
:type sim_results: list[float]
|
|
29
36
|
:param calc_results: A list of calculated results using some analytical or numerical method.
|
|
30
|
-
:param depends_on: The type of dependency for plotting
|
|
37
|
+
:param depends_on: The type of dependency for plotting
|
|
38
|
+
(utilization factor, number of channels, etc.).
|
|
31
39
|
:type depends_on: DependsType
|
|
32
|
-
:param is_errors: If True, plots the percentage error between
|
|
40
|
+
:param is_errors: If True, plots the percentage error between
|
|
41
|
+
simulation and calculation results.
|
|
33
42
|
:type is_errors: bool
|
|
34
43
|
:param is_waiting_time: If True, labels the y-axis as waiting time; otherwise, as sojourn time.
|
|
35
44
|
:type is_waiting_time: bool
|
|
@@ -39,14 +48,13 @@ def plot_sim_vs_calc_moments(xs: list[float], sim_results: list[float],
|
|
|
39
48
|
"""
|
|
40
49
|
_fig, ax = plt.subplots()
|
|
41
50
|
if is_errors:
|
|
42
|
-
errors = [100 * (w_sim - w_tt) / w_tt for w_sim,
|
|
43
|
-
w_tt in zip(sim_results, calc_results)]
|
|
51
|
+
errors = [100 * (w_sim - w_tt) / w_tt for w_sim, w_tt in zip(sim_results, calc_results)]
|
|
44
52
|
|
|
45
|
-
ax.plot(xs, errors, color=
|
|
53
|
+
ax.plot(xs, errors, color="black")
|
|
46
54
|
ax.set_ylabel(r"$\varepsilon$, %")
|
|
47
55
|
else:
|
|
48
|
-
ax.plot(xs, sim_results, label="Sim", color=
|
|
49
|
-
ax.plot(xs, calc_results, label="Calc", color=
|
|
56
|
+
ax.plot(xs, sim_results, label="Sim", color="black", linestyle="--")
|
|
57
|
+
ax.plot(xs, calc_results, label="Calc", color="black")
|
|
50
58
|
if is_waiting_time:
|
|
51
59
|
ax.set_ylabel(r"$\omega_{1}$")
|
|
52
60
|
else:
|