DM AEP - Quentin FOMBARON et Guillaume BESNARD

setData = function(N, mu, lambda, mode, modearri) {
  #set.seed(37);
  #N = 10; # N <- 100; # N <<- 100;
  Arrival = cumsum(rexp(n=N, rate=lambda));

  if (modearri == 'exp') {
    Service = rexp(n=N, rate=mu);
  }
  else if (modearri == 'gamma') {
    Service = rgamma(n=N, shape = 0.1, rate = 0.1);
  }
  # uni
  else {
    Service = runif(n=N, min=0.5, max=1.5);
  }
  Remaining = rep(N, x=NA);
  Completion = rep(N, x=NA);
  t = 0;
  CurrentTask = NA;
  NextArrival = 1;
  NbRemaining = 0;
  
  while (TRUE) {
      dtA = NA;
      dtC = NA;
      if(length(Arrival[Arrival>t])>0) {
          dtA = head(Arrival[Arrival>t],n=1)-t  # temps jusqu'à la prochaine arrivée
      }
        if(!is.na(CurrentTask)) {
          if (mode == 'fair_share') {
            NbRemaining=length((1:N)[!is.na(Remaining)]);
            dtC = Remaining[CurrentTask] * NbRemaining; # il faut plus de temps pour effectuer un quantum identique
        } else {
            dtC = Remaining[CurrentTask]; # temps jusqu'à la prochaine terminaison
        }
        }
      if(is.na(dtA) & is.na(dtC)) {
          break;
      } 

      dt = min(dtA,dtC,na.rm=T)
  
      # Mettre à jour comme il faut:
      #   la date
      t = t + dt;
      
      #   le remaining 
      if (mode == 'fair_share') {
        if(!is.na(CurrentTask)) {
            # Enlève du quantum à tout le monde
            for (i in 1:N) {
                Remaining[i] = Remaining[i] - (dt/NbRemaining);
                
                if (!is.na(Remaining[i]) && Remaining[i] <= 0) {
                    # sera nécessairement CurrentTask par construction
                    # car il contient le minimum de quantum restant
                    Completion[CurrentTask] = t;
              Remaining[CurrentTask] = NA;
                } 
            }
        }
      }
      
            if (mode != 'fair_share') {
                if(!is.na(CurrentTask)) {
                Remaining[CurrentTask] = Remaining[CurrentTask] - dt ;
                if(Remaining[CurrentTask] <= 0) {
                    Completion[CurrentTask] = t;
                    Remaining[CurrentTask] = NA;
                }
                }
            }
      
      CurrentTask = NA;
      
      # les arrivées : placé après consommation du quantum
      # pour éviter qu'un nouvel arrivé consomme sa part, et donc fausse
      # notre calcul de quantum partagé fait précedemment
      ## 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;
      }
            
            if (mode == 'fifo') {
              # FIFO
              WaitingList=(1:N)[!is.na(Remaining)];
              if(length(WaitingList)>0) {
                  CurrentTask = head(WaitingList,n=1);
              }
            }
      
      if (mode == 'fair_share') {
        NbRemaining = length((1:N)[!is.na(Remaining)]);
        if(NbRemaining > 0) {
            CurrentTask = which.min(Remaining);
        }
      }
      
      if (mode == 'lifo_restart') {
        # LIFO RESTART
        # Si on l'event est une arrivé,
        # on restart le temps de service de l'ancienne tâche
        if (dt == dtA && !is.na(Remaining[CurrentTask])) {
          Remaining[CurrentTask]=Service[CurrentTask];
        }
        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=mode, ModeArri=modearri));
}

TESTS

FIFO

lambda = seq(from=0.05, to= .95, by = .1);
library(ggplot2);
library(dplyr);
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
genGraph = function(mode, modearri) {
    #for(l in lambda){
      df = setData(N=50, mu=1, lambda=0.95, mode=mode, modearri=modearri);
    #}
    
    ggplot(df, aes(xmin = Arrival, xmax= Completion, y = Idx, ymin=Idx, ymax=Idx+1)) + geom_rect() + ggtitle(paste(df$ModeSched, df$ModeArri, sep=" ")) + xlab("temps");
}
genGraph2 = function(mode, modearri) {
    df2 = NULL;
    for(l in lambda){
      df2 = rbind(df2,setData(N=1000, mu=1, lambda=l, mode=mode, modearri=modearri));
    }
    
    df2 %>% group_by(lambda) %>% summarise(resp_mean = mean(Completion-Arrival), se=sd(Completion-Arrival)/sqrt(n())) %>% ggplot(aes(x=lambda, y=resp_mean)) + geom_smooth(method = 'loess', se=FALSE, colour='red') + geom_point() + geom_line() + geom_errorbar(aes(ymin=resp_mean-2*se, ymax=resp_mean+2*se)) + ggtitle(paste(df2$ModeSched, df2$ModeArri, sep=" "))
}

Uniforme

genGraph("fifo", "uni")

genGraph2("fifo", "uni")

Exponentiel

genGraph("fifo", "exp")

genGraph2("fifo", "exp")

Gamma

genGraph("fifo", "gamma")

genGraph2("fifo", "gamma")

LIFO RESTART

Uniforme

genGraph("lifo_restart", "uni")

genGraph2("lifo_restart", "uni")

Exponentiel

genGraph("lifo_restart", "exp")

genGraph2("lifo_restart", "exp")

Gamma

genGraph("lifo_restart", "gamma")

genGraph2("lifo_restart", "gamma")

FAIR SHARE

Uniforme

genGraph("fair_share", "uni")

genGraph2("fair_share", "uni")

Exponentiel

genGraph("fair_share", "exp")

genGraph2("fair_share", "exp")

Gamma

genGraph("fair_share", "gamma")

genGraph2("fair_share", "gamma")