diff --git a/code/8c.R b/code/8c.R index b8f52cc..f74deb9 100644 --- a/code/8c.R +++ b/code/8c.R @@ -1,23 +1,36 @@ -ρ <- 0.5 -s1 <- 1 -p1 <- 0.99 -s2 <- 101 -p2 <- 0.01 +params_all <- list( + list(s1 = 1, p1 = 0.9, s2 = 11, p2 = 0.1), + list(s1 = 1, p1 = 0.99, s2 = 101, p2 = 0.01) +) -μ <- 1 / (s1 * p1 + s2 * p2) -λ <- ρ * μ -λ1 <- p1 * λ -λ2 <- p2 * λ +calc_stats <- function(params) { + ρ <- 0.5 + μ <- 1 / (params$s1 * params$p1 + params$s2 * params$p2) + λ <- ρ * μ + λ1 <- params$p1 * λ + λ2 <- params$p2 * λ -wq1 <- (λ1 * s1^2 + λ2 * s2^2) / (2 * (1 - λ1 * s1)) -wq2 <- (λ1 * s1^2 + λ2 * s2^2) / (2 * (1 - λ1 * s1) * (1 - λ1 * s1 - λ2 * s2)) + wq1 <- (λ1 * params$s1^2 + λ2 * params$s2^2) / (2 * (1 - λ1 * params$s1)) + wq2 <- (λ1 * params$s1^2 + λ2 * params$s2^2) / (2 * (1 - λ1 * params$s1) * (1 - λ1 * params$s1 - λ2 * params$s2)) -wq <- (λ1 * wq1 + λ2 * wq2) / (λ1 + λ2) + wq <- (λ1 * wq1 + λ2 * wq2) / (λ1 + λ2) -cat(sprintf("μ = %.2f\n", μ)) -cat(sprintf("λ = %.2f\n", λ)) -cat(sprintf("λ1 = %.4f\n", λ1)) -cat(sprintf("λ2 = %.4f\n", λ2)) -cat(sprintf("wq1 = %.2f\n", wq1)) -cat(sprintf("wq2 = %.2f\n", wq2)) -cat(sprintf("wq = %.2f\n", wq)) + data.frame( + s1 = signif(params$s1, 4), + p1 = signif(params$p1, 4), + s2 = signif(params$s2, 4), + p2 = signif(params$p2, 4), + μ = signif(μ, 4), + λ = signif(λ, 4), + λ1 = signif(λ1, 4), + λ2 = signif(λ2, 4), + wq1 = signif(wq1, 4), + wq2 = signif(wq2, 4), + wq = signif(wq, 4) + ) +} + +data <- lapply(params_all, calc_stats) +data <- do.call(rbind, data) +str(data) +write.table(data, "output/8c.csv", sep = "\t", row.names = FALSE) diff --git a/typst/exercises/8.typ b/typst/exercises/8.typ index 6ee3477..b4beeb5 100644 --- a/typst/exercises/8.typ +++ b/typst/exercises/8.typ @@ -103,3 +103,65 @@ #indent_par[This makes sense, as despite our _elephants_ occurring less often, their larger size ensures that the users that come after them have a much higher average queue delay, which in turn increases the variance of the system.] #pagebreak() + +==== c. + +#let results_c = csv("/output/8c.csv", delimiter: "\t") + +#indent_par[In our current implementation, we treat both the _elephants_ and _mice_ the same. _Elephants_ will always have a large size and thus need more time in queue, but this shouldn't affect the _mice_ that can be dispatched quickly.] + +#indent_par[To remedy this, we can treat both categories of users differently, by performing *packet scheduling*. In specific, we can use a *strict priority* with _mice_ having a higher priority than the _elephants_. This leads to a higher average delay for the _elephants_, but with the tradeoff of the _mice_ having much lower average delay.] + +#indent_par[To be able to calculate exactly whether this tradeoff is valuable, we can use the following formulas 11 through 15 to calculate the average queuing delay for each type of user:] + +$ λ_1 = p_1 dot λ $ +$ λ_2 = p_2 dot λ $ + +$ W_"q1" = (λ_1 s_1^2 + λ_2 s_2^2) / (2 (1 - λ_1 s_1)) $ +$ W_"q2" = (λ_1 s_1^2 + λ_2 s_2^2) / (2 (1 - λ_1 s_1) (1 - λ_1 s_1 - λ_2 s_2)) $ + +$ W_q = (λ_1 W_"q1" + λ_2 W_"q2") / (λ_1 + λ_2) $ + +#indent_par[Where $W_"q1"$ is the average queueing delay of _mice_, $W_"q2"$ is the average queueing delay of _elephants_ and $W_q$ is the total average queueing delay] + +#indent_par[With these formulas in hand, we have computed the values in the following table 17:] + +#figure( + pad(1em, tablex( + columns: (auto, auto, auto, auto, auto, auto, 1fr, 1fr, 1fr, 1fr), + align: center + horizon, + + rowspanx(3)[ System ], + rowspanx(3)[ $ρ$ ], + rowspanx(3)[ $S_1$ ], + rowspanx(3)[ $p_1$ ], + rowspanx(3)[ $S_2$ ], + rowspanx(3)[ $p_2$ ], + colspanx(4)[ Average delay ], + rowspanx(2)[ Standard ], + colspanx(3)[ Strict priority packet scheduling ], + [ _mice_ ], + [ _elephants_ ], + [ Total ], + + rowspanx(2)[ `M/G/1` ], + rowspanx(2)[ 0.5 ], + [ 1 ], [ 0.9 ], [ 11 ], [ 0.1 ], + [ #results_a.at(1).at(6) ], + [ #results_c.at(1).at(8) ], + [ #results_c.at(1).at(9) ], + [ #results_c.at(1).at(10) ], + + [ 1 ], [ 0.99 ], [ 101 ], [ 0.01 ], + [ #results_a.at(1).at(10) ], + [ #results_c.at(2).at(8) ], + [ #results_c.at(2).at(9) ], + [ #results_c.at(2).at(10) ], + )), + kind: table, + caption: [Results] +) + +#indent_par[The average delay of the _mice_ is now considerably lower than before. The _elephants_' average delay rose about as much as the _mice_'s lowered, but given that we have many more _mice_ than _elephants_, this is a valuable tradeoff, which can be further reinforced by looking at the average total, which is lower in general, by a considerable amount.] + +#pagebreak() diff --git a/zbuild.yaml b/zbuild.yaml index 44074c4..eb6684a 100644 --- a/zbuild.yaml +++ b/zbuild.yaml @@ -17,6 +17,7 @@ default: - rule: ex7_c - rule: ex8_a - rule: ex8_b + - rule: ex8_c rules: # Typst @@ -229,3 +230,14 @@ rules: exec: - - Rscript - code/8b.R + + # Exercise 8.c + ex8_c: + out: + - output/8c.csv + deps: + - code/8.R + - code/8c.R + exec: + - - Rscript + - code/8c.R