Simulateur

simulator = function(N = 100, modeService = "exp", modeSched = "fifo", lambda = 0.2, 
    mu = 1) {
    
    Arrival = cumsum(rexp(n = N, rate = lambda))
    
    if (modeService == "exp") {
        Service = rexp(n = N, rate = mu)
    } else if (modeService == "uni") {
        Service = runif(n = N, min = 0.5, max = 1.5)
    } else if (modeService == "gamma") {
        Service = rgamma(n = N, shape = 0.1, rate = 0.1)
    }
    
    Remaining = rep(N, x = NA)
    Completion = rep(N, x = NA)
    
    df = data.frame()
    if (modeSched == "fifo") {
        df = fifo(N, Arrival, Service, lambda, mu, modeService)
    } else if (modeSched == "lifo") {
        df = lifo(N, Arrival, Service, lambda, mu, modeService)
    } else if (modeSched == "fair_sharing") {
        df = fair_sharing(N, Arrival, Service, lambda, mu, modeService)
    }
    
    return(df)
}

FIFO

fifo = function(N = 100, Arrival, Service, lambda, mu, modearri) {
    
    Remaining = rep(N, x = NA)
    Completion = rep(N, x = NA)
    
    t = 0
    
    CurrentTask = NA
    NextArrival = 1
    
    while (TRUE) {
        dtA = NA
        dtC = NA
        
        # temps jusqu'à la prochaine arrivée
        if (length(Arrival[Arrival > t]) > 0) {
            dtA = head(Arrival[Arrival > t], n = 1) - t
        }
        
        # temps jusqu'à la prochaine terminaison
        if (!is.na(CurrentTask)) {
            dtC = Remaining[CurrentTask]
        }
        
        if (is.na(dtA) & is.na(dtC)) {
            break
        }
        
        dt = min(dtA, dtC, na.rm = T)
        
        t = t + dt
        
        # les arrivées je met un <= et pas un == car 3-2.9!=0.1 ...
        if ((NextArrival <= N) & (Arrival[NextArrival] <= t)) {
            Remaining[NextArrival] = Service[NextArrival]
            NextArrival = NextArrival + 1
        }
        
        # le remaining
        if (!is.na(CurrentTask)) {
            Remaining[CurrentTask] = Remaining[CurrentTask] - dt
            if (Remaining[CurrentTask] <= 0) {
                Completion[CurrentTask] = t
                Remaining[CurrentTask] = NA
            }
            CurrentTask = NA
        }
        
        # et currentTask (politique d'ordonnancement : FIFO)
        WaitingList = (1:N)[!is.na(Remaining)]
        if (length(WaitingList) > 0) {
            CurrentTask = head(WaitingList, n = 1)
        }
    }
    
    return(data.frame(lambda = lambda, mu = mu, Idx = 1:N, Completion = Completion, 
        Arrival = Arrival, ModeSched = "fifo", ModeArri = modearri))
}

LIFO

lifo = function(N = 100, Arrival, Service, lambda, mu, modearri) {
    
    Remaining = rep(N, x = NA)
    Completion = rep(N, x = NA)
    
    t = 0
    
    CurrentTask = NA
    NextArrival = 1
    
    while (TRUE) {
        dtA = NA
        dtC = NA
        
        # temps jusqu'à la prochaine arrivée
        if (length(Arrival[Arrival > t]) > 0) {
            dtA = head(Arrival[Arrival > t], n = 1) - t
        }
        
        # temps jusqu'à la prochaine terminaison
        if (!is.na(CurrentTask)) {
            dtC = Remaining[CurrentTask]
        }
        
        if (is.na(dtA) & is.na(dtC)) {
            break
        }
        
        dt = min(dtA, dtC, na.rm = T)
        
        t = t + dt
        
        # les arrivées je met un <= et pas un == car 3-2.9!=0.1 ...
        if ((NextArrival <= N) & (Arrival[NextArrival] <= t)) {
            Remaining[NextArrival] = Service[NextArrival]
            NextArrival = NextArrival + 1
        }
        
        # le remaining
        if (!is.na(CurrentTask)) {
            Remaining[CurrentTask] = Remaining[CurrentTask] - dt
            if (Remaining[CurrentTask] <= 0) {
                Completion[CurrentTask] = t
                Remaining[CurrentTask] = NA
            }
            CurrentTask = NA
        }
        
        # et currentTask (politique d'ordonnancement : LIFO)
        WaitingList = (1:N)[!is.na(Remaining)]
        if (length(WaitingList) > 0) {
            CurrentTask = tail(WaitingList, n = 1)
        }
    }
    
    return(data.frame(lambda = lambda, mu = mu, Idx = 1:N, Completion = Completion, 
        Arrival = Arrival, ModeSched = "lifo", ModeArri = modearri))
}

Fair sharing

fair_sharing = function(N = 100, Arrival, Service, lambda, mu, modearri) {
    
    Remaining = rep(N, x = NA)
    Completion = rep(N, x = NA)
    
    t = 0
    
    NextArrival = 1
    
    while (TRUE) {
        CurrentTask = (1:N)[!is.na(Remaining)]
        NbCurrentTask = length(CurrentTask)
        
        dtA = NA
        dtC = NA
        
        # temps jusqu'à la prochaine arrivée
        if (length(Arrival[Arrival > t]) > 0) {
            dtA = head(Arrival[Arrival > t], n = 1) - t
        }
        
        # temps jusqu'à la prochaine terminaison
        if (NbCurrentTask > 0) {
            dtC = min(Remaining[CurrentTask] * NbCurrentTask)
        }
        
        if (is.na(dtA) & is.na(dtC)) {
            break
        }
        
        dt = min(dtA, dtC, na.rm = T)
        
        t = t + dt
        
        if ((NextArrival <= N) & (Arrival[NextArrival] <= t)) {
            Remaining[NextArrival] = Service[NextArrival]
            NextArrival = NextArrival + 1
        }
        
        if (length(CurrentTask) > 0) {
            Remaining[CurrentTask] = Remaining[CurrentTask] - dt/length(CurrentTask)
            Completion[Remaining <= 0] = t
            Remaining[Remaining <= 0] = NA
        }
    }
    
    return(data.frame(lambda = lambda, mu = mu, Idx = 1:N, Completion = Completion, 
        Arrival = Arrival, ModeSched = "fair_sharing", ModeArri = modearri))
}

Simulation

FIFO

set.seed(37)

lambda = seq(from = 0.05, to = 0.9, by = 0.1)

df1 = data.frame()
for (l in lambda) {
    df1 = rbind(df1, simulator(N = 1000, modeService = "exp", modeSched = "fifo", 
        lambda = l, mu = 1))
}

df2 = data.frame()
for (l in lambda) {
    df2 = rbind(df2, simulator(N = 1000, modeService = "uni", modeSched = "fifo", 
        lambda = l, mu = 1))
}

df3 = data.frame()
for (l in lambda) {
    df3 = rbind(df3, simulator(N = 1000, modeService = "gamma", modeSched = "fifo", 
        lambda = l, mu = 1))
}
df1 %>% group_by(lambda) %>% summarise(resp_mean = mean(Completion - Arrival), se = sd(Completion - 
    Arrival)/sqrt(n())) %>% ggplot(aes(x = lambda, y = resp_mean)) + geom_point() + 
    geom_errorbar(aes(ymin = resp_mean - 2 * se, ymax = resp_mean + 2 * se)) + geom_line() + 
    geom_smooth() + ggtitle("FIFO exponentielle")

df2 %>% group_by(lambda) %>% summarise(resp_mean = mean(Completion - Arrival), se = sd(Completion - 
    Arrival)/sqrt(n())) %>% ggplot(aes(x = lambda, y = resp_mean)) + geom_point() + 
    geom_errorbar(aes(ymin = resp_mean - 2 * se, ymax = resp_mean + 2 * se)) + geom_line() + 
    geom_smooth() + ggtitle("FIFO uniforme")

df3 %>% group_by(lambda) %>% summarise(resp_mean = mean(Completion - Arrival), se = sd(Completion - 
    Arrival)/sqrt(n())) %>% ggplot(aes(x = lambda, y = resp_mean)) + geom_point() + 
    geom_errorbar(aes(ymin = resp_mean - 2 * se, ymax = resp_mean + 2 * se)) + geom_line() + 
    geom_smooth() + ggtitle("FIFO gamma")

LIFO

set.seed(37);

lambda = seq(from = 0.05, to = 0.9, by = 0.1)

df1 = data.frame()
for (l in lambda) {
    df1 = rbind(df1, simulator(N = 1000, modeService = "exp", modeSched = "lifo", 
        lambda = l, mu = 1))
}

df2 = data.frame()
for (l in lambda) {
    df2 = rbind(df2, simulator(N = 1000, modeService = "uni", modeSched = "lifo", 
        lambda = l, mu = 1))
}

df3 = data.frame()
for (l in lambda) {
    df3 = rbind(df3, simulator(N = 1000, modeService = "gamma", modeSched = "lifo", 
        lambda = l, mu = 1))
}
df1 %>% group_by(lambda) %>% summarise(resp_mean = mean(Completion - Arrival), se = sd(Completion - 
    Arrival)/sqrt(n())) %>% ggplot(aes(x = lambda, y = resp_mean)) + geom_point() + 
    geom_errorbar(aes(ymin = resp_mean - 2 * se, ymax = resp_mean + 2 * se)) + geom_line() + 
    geom_smooth() + ggtitle("LIFO exponentielle")

df2 %>% group_by(lambda) %>% summarise(resp_mean = mean(Completion - Arrival), se = sd(Completion - 
    Arrival)/sqrt(n())) %>% ggplot(aes(x = lambda, y = resp_mean)) + geom_point() + 
    geom_errorbar(aes(ymin = resp_mean - 2 * se, ymax = resp_mean + 2 * se)) + geom_line() + 
    geom_smooth() + ggtitle("LIFO uniforme")

df3 %>% group_by(lambda) %>% summarise(resp_mean = mean(Completion - Arrival), se = sd(Completion - 
    Arrival)/sqrt(n())) %>% ggplot(aes(x = lambda, y = resp_mean)) + geom_point() + 
    geom_errorbar(aes(ymin = resp_mean - 2 * se, ymax = resp_mean + 2 * se)) + geom_line() + 
    geom_smooth() + ggtitle("LIFO gamma")

Fair sharing

set.seed(37);

lambda = seq(from = 0.05, to = 0.9, by = 0.1)

df1 = data.frame()
for (l in lambda) {
    df1 = rbind(df1, simulator(N = 1000, modeService = "exp", modeSched = "fifo", 
        lambda = l, mu = 1))
}

df2 = data.frame()
for (l in lambda) {
    df2 = rbind(df2, simulator(N = 1000, modeService = "uni", modeSched = "fifo", 
        lambda = l, mu = 1))
}

df3 = data.frame()
for (l in lambda) {
    df3 = rbind(df3, simulator(N = 1000, modeService = "gamma", modeSched = "fifo", 
        lambda = l, mu = 1))
}
df1 %>% group_by(lambda) %>% summarise(resp_mean = mean(Completion - Arrival), se = sd(Completion - 
    Arrival)/sqrt(n())) %>% ggplot(aes(x = lambda, y = resp_mean)) + geom_point() + 
    geom_errorbar(aes(ymin = resp_mean - 2 * se, ymax = resp_mean + 2 * se)) + geom_line() + 
    geom_smooth() + ggtitle("Fair sharing exponentielle")

df2 %>% group_by(lambda) %>% summarise(resp_mean = mean(Completion - Arrival), se = sd(Completion - 
    Arrival)/sqrt(n())) %>% ggplot(aes(x = lambda, y = resp_mean)) + geom_point() + 
    geom_errorbar(aes(ymin = resp_mean - 2 * se, ymax = resp_mean + 2 * se)) + geom_line() + 
    geom_smooth() + ggtitle("Fair sharing uniforme")

df3 %>% group_by(lambda) %>% summarise(resp_mean = mean(Completion - Arrival), se = sd(Completion - 
    Arrival)/sqrt(n())) %>% ggplot(aes(x = lambda, y = resp_mean)) + geom_point() + 
    geom_errorbar(aes(ymin = resp_mean - 2 * se, ymax = resp_mean + 2 * se)) + geom_line() + 
    geom_smooth() + ggtitle("Fair sharing gamma")

Interprétation des résultats

Avec la loi exponentielle comme distribution du temps de service, on observe que les politiques LIFO et FIFO donnent des résultats similaires. On peut noter que l’incertitude sur la mesure est plus grande pour LIFO, en particulier quand lambda augmente. Concernant la politique Fair Sharing on obtient un temps de réponse moyen plus grand de 2 unités en moyenne lorsque lambda est supérieur à 0.75.

Avec la loi uniforme, la politique fifo fournit les temps de réponse les plus bas. Encore une fois l’incertitude est plus grande pour la politique lifo.

Concernant la loi gamma, on observe de façon générale une plus grande oscillation des valeurs et une incertitude sur les mesures beaucoup plus grande que pour les précédentes lois. La politique FIFO est de loin la moins performante avec un délai de réponse pouvant atteindre 60 unités quand lambda approche de 1. La politique LIFO offre les meilleures performances.