Curiosity - Mot-clé - ascenseur2024-01-27T00:01:40+01:00urn:md5:167b0ddfbb8af8fbf0a6e94ec75719b5DotclearStratégie de programmation d'ascenseururn:md5:74cbc70bb3607fbe18fa0e2c24b851502006-04-26T18:27:00+00:002015-11-20T12:45:42+00:00Eric CabrolIntelloascenseurMatlabscience amusantesimulation<p>Quand un bout de code me conforte dans mes intuitions ...</p>
<p>J'avais <a href="http://eric.cabrol.free.fr/dotclear/index.php/2006/02/23/107-programmation-d-ascenseurs-et-economies-d-energie" hreflang="fr">déjà écrit</a> que je ne comprenais pas la stratégie employée par les ascenseurs de mon immeuble, qui se replacent systématiquement (au bout d'un certain temps) aux "extrémités" de la plage d'étages qu'ils sont censés couvrir. Ca ne me semblait pas permettre de minimiser les temps d'attente, et encore moins de minimiser les déplacements et donc la consommation d'énergie.</p> <p>Or donc voilà, Matlab me prouve que j'avais raison. C'est codé comme un cochon, c'est simplifié avec un seul ascenseur, mais ça semble marcher comme je le souhaite, et les tendances sont là : lorsque le temps de latence est faible (c'est-à-dire lorsque l'ascenseur revient souvent vers sa position par défaut) "ma" stratégie permet un gain de temps d'attente moyen de l'ordre de 10%, et une réduction de près de 15% des déplacements effectués par l'ascenseur.<br />
<br />
<a href="http://eric.cabrol.free.fr/dotclear/images/tech/ascenseur_sensi_latence.gif">Résultats obtenus en faisant varier le temps de latence, pour une position par défaut au 17è étage.</a><br />
<a href="http://eric.cabrol.free.fr/dotclear/images/tech/ascenseur_influence_pos_def.gif">Résultats obtenus en faisant varier le temps de latence, pour une position par défaut au 8è étage.</a>
</p>
<p>Voici le code :</p>
<pre>nb_et = 17; % nb d'etages
nb_hab_et = 10; % nb d'habitants par étage
latence = 120; % temps de latence avant raz
sec_et = 3; % vitesse ascenseur : nb de secondes par etage
tps_ouvr = 8; % temps de transfert (ouverture - entree - fermeture)
%
pos_def = 8; % position par défaut de l'ascenseur
%
%
for n=1:50
%
% Génération des temps aléatoires
%
temps=sort(abs(floor(randn(nb_hab_et,nb_et)*3600+7200)));
k=0;
raz=0; % compteur raz
pos=pos_def; % initialisation à la position par défaut
cumul_dep=0; % compteur déplacements
tmp=0; % var temporaire
missed=0; % booléen
hab = nb_hab_et*ones(nb_et,1); % vecteur compteur d'habitants par étage
attente = zeros(nb_et*nb_hab_et,1); % initialisation vecteur attente par habitant
%
while max(hab)>0 % Tant qu'il reste du monde
t=min(min(temps)); % t prochain appel
if t==99999
break
end
if (t-tmp)>latence
cumul_dep=cumul_dep+abs(pos-pos_def);
pos=pos_def;
raz=raz+1;
end
[i,j]=find(temps==min(min(temps))); % déterminer etage correspondant
if length(j)>1 % Si deux min identiques ...
[a,b]=max(j); % on prend l'étage le plus haut
i=i(b);
j=j(b);
end
cumul_dep=cumul_dep+abs(pos-j); % compte déplacements
if missed==0
k=k+1;
else
missed=0;
end
attente(k)=attente(k)+abs(pos-j)*sec_et; % calcul tps attente pour hab k
tmp=t+attente(k)+tps_ouvr; % temps dép + ouv portes
hab(j)=hab(j)-1; % decremente le nb d'hab à l'étage j
temps(i,j)=99999; % "supprime" ce t du tableau
pos=j; % ascenseur chargé
%
t=min(min(temps)); % recherche prochain appel
[i,j]=find(temps==min(min(temps))); % etage ...
if length(j)>1
[a,b]=max(j);
i=i(b);
j=j(b);
end
% Si l'ascenseur n'est pas encore passé
if j < pos & t > tmp & t < tmp+(pos-j)*sec_et
k=k+1;
attente(k)=attente(k)+tmp+(pos-j)*sec_et-t;
tmp=t+tps_ouvr;
hab(j)=hab(j)-1;
temps(i,j)=99999;
end
% Si l'ascenseur est déjà passé mais encore en mouvement
if j < pos & t > tmp+(pos-j)*sec_et & t < tmp+pos*sec_et
k=k+1; % L'attente de l'hab k est augmentée du
attente(k)=attente(k)+tmp+pos*sec_et+tps_ouvr-t;% temps correspondant à la descente
missed=1;
end
% On descend
cumul_dep=cumul_dep+pos;
pos=0;
tmp=tmp+pos*sec_et+tps_ouvr;
end
attente_moy(n)=mean(attente);
deplacement_total(n)=cumul_dep;
end
disp(sprintf('Attente moyenne = %4.2f',mean(attente_moy)));
disp(std(attente_moy));
disp(sprintf('Moyenne du cumul des déplacements = %4.2f',mean(deplacement_total)));
disp(std(deplacement_total));
</pre>