• Aucun résultat trouvé

Un problème potentiel affectant le temps d’exécution de l’algorithme est que chaque instant unitaire doit être représenté par un nœud dans le graphe. Comme l’horizon peut atteindre une taille pseudo-polynomiale, c’est le nombre de nœuds d’instant qu’il faut réduire afin d’améliorer le temps d’exécution de l’algorithme. Une approche est de partitionner la fenêtre d’exécution globale. Chaque partition est formée d’instants consécutifs format un intervalle de temps. Le but est de remplacer les nœuds d’instant par des nœuds d’intervalle. Cette approche permet de garder un contrôle flexible sur la taille du graphe.

Compresser les nœuds d’instant en intervalles disjoints requiert de faire des ajustements au graphe. D’abord, la source du réseau est maintenant reliée à des intervalles par des arêtes qui admettent autant de flot qu’il y a d’instants recoupés par l’intervalle relié. Autrement dit, soit un intervalle de temps Il,u = [l, u) contenant les instants l, l + 1, . . . , u − 1, alors c(s, Il,u) = u − l. Ensuite, il y a une arête qui relie un intervalle Il,u à une tâche i si cette

dernière peut s’y exécuter partiellement. Le cas échéant, la capacité de l’arête est :

c(Il,u, i) = min(u, lcti) − max(l, esti)

Au final, l’interprétation du flot dans le réseau est légèrement différente. La quantité de flot circulant entre la tâche i et l’intervalle Il,u indique le nombre d’instants d’exécution de cette tâche dans l’intervalle Il,u. Soit f (Il,u, i) cette quantité, alors :

f (Il,u, i) = |Ei∩ [l, u)|

Exemple 3.4. Soit l’instance de l’exemple 3.3 modifiée en augmentant d’un facteur de 10 la précision de l’ordonnancement :

DisjunctiveTardiness([Si, Sj], [pi = 20, pj = 10], [di= 10, dj = 20], T )

dom(Si) = [0, 10], dom(Sj) = [0, 30], dom(T ) = [0, 20]

40 nœuds d’instant sont requis pour représenter cette instance dans le graphe non compressé. La figure3.2montre un ordonnancement préemptif optimal des tâches dans un graphe résiduel

t i j [0, 25) [25, 30) [30, 40) s 20 10 5(0) 20(0) 5(1) 10(2) 20(0) 5(0) 5(−1) 10(2) 25 5 10

Figure 3.2 – Graphe compressé pour l’exemple 3.3avec seulement 3 nœuds de valeur

compressé. Le nombre de nœuds de valeurs passe de 40 instants à 3 intervalles. La capacité et le coût résiduel de chaque arête sont indiqués selon le format capacité(coût). Un exemple de calcul de capacité est :

c(I25,30, i) = min(30, 40) − max(25, 0) = 5

Le calcul du coût résiduel est expliqué à la section 3.6.1.

3.6.1 Impact sur la qualité de la borne

Un défaut de la compression du graphe est que cette technique diminue potentiellement la qualité de la borne sur le seuil T . La quantité de flot circulant entre les nœuds de tâche et les nœuds d’intervalle n’est plus unitaire. Cette représentation cache l’ordre d’exécution préemptive des tâches à travers les intervalles. Par conséquent, il faut que le calcul du retard soit plus relaxé que lorsque le graphe n’est pas compressé. Pour une tâche i s’exécutant dans un intervalle Il,u, un retard suffisamment optimiste selon la définition3.1 est :

w(Il,u, i) = w(max(l, esti), i) ≤ w(e, i) tel que max(l, esti) ≤ e < u

Soit f (Il,u, i) le nombre d’instants d’exécution de la tâche i dans l’intervalle Il,u, le retard

engendré par l’exécution de la tâche i dans l’intervalle Il,u est :

f (Il,u, i) · w(max(l, esti), i) ≤

X

e∈Ei∩[max(l,esti),u)

w(e, i)

Exemple 3.5. En reprenant la figure 3.2, un exemple de calcul de coût résiduel (poids entre parenthèses sur l’arête) est :

w(I25,30, i) = w(25, i) =  max(0, 25 + 1 − di) pi  = max(0, 25 + 1 − 10) 20  = 1

Bien que la taille du graphe soit réduite de façon substantielle, la qualité de la borne se retrouve impactée par le choix du partitionnement des instants. Effectivement, une borne pour le retard déterminée à partir du graphe non compressé est de 10, alors qu’elle n’est que de f (I25,30, j) ·

w(I25,30, j) = 5 avec le graphe compressé de la figure 3.2. Un partitionnement permettant de retrouver la borne originale serait I0,10, I10,30 et I30,40. Dans ce cas, il devient possible de considérer les instants d’exécution en retard de la tâche i.

Un partitionnement judicieux de la fenêtre d’exécution globale est donc de mise pour maximiser la qualité de la borne. Trouver un partitionnement maximisant la qualité de la borne est un problème d’optimisation qui s’avère complexe à lui seul. Dans le cadre de la résolution, ce choix doit être fait rapidement pour que l’algorithme de filtrage s’exécute en un temps raisonnable. Les prochaines sections présentent deux heuristiques de compressions retenues.

3.6.2 Compression simple avec au plus 3n − 1 intervalles

Une heuristique simple est de définir un intervalle pour chaque esti, lcti et diparmi les tâches I. Soit θ = {esti}ni=1∪ {lcti}ni=1∪ {di}ni=1, les instants θ = {t1, . . . , t|θ|} triés en ordre croissant

déterminent le choix des intervalles. De chaque paire d’instants (tj, tj+1) résulte un intervalle

Itj,tj+1. Ce partitionnement donne au plus 3n − 1 intervalles dans le cas où tous les esti, lcti

et di sont distincts.

Cette heuristique a certains avantages. D’abord, soit i ∈ I, elle simplifie le calcul des capacités :

c(Il,u, i) = min(u, lcti) − max(l, esti) = u − l = c(s, Il,u)

Puisque tout flot passant par une arête (Il,u, i) provient de l’arête (s, Il,u), c(s, Il,u) est la

capacité limitante. De ce fait, il n’est plus pertinent de borner la capacité sur les arêtes reliant les intervalles aux tâches et il devient redondant de fixer la capacité c(Il,u, i). Le calcul du coût résiduel est également plus simple. Les instants déterminants pour calculer les coûts résiduels sont les bornes inférieures des intervalles. :

w(Il,u, i) = w(max(l, esti), i) = w(l, i)

La coupure faite aux di permet d’assurer une qualité minimale de la borne sur le retard. Par

définition :

w(di, i) = w(di− 1, i) + 1 > w(di− 1, i)

Ainsi, pour une tâche i, chaque instant e ∈ Ei exécuté au-delà de l’échéance préférable di

engendre un retard non nul.

Exemple 3.6. La figure3.3montre une version compressée du graphe de l’exemple3.2. L’heu- ristique de la section3.6.2 est utilisée pour choisir les intervalles. La capacité n’est pas bornée

t i j [0, 2) [2, 3) [3, 4) s 2 1 (1) (2) (0) (1) 2 1 1

Figure 3.3 – Graphe compressé pour l’exemple 3.1avec au plus 3n − 1 intervalles

pour le flot circulant entre une tâche et un intervalle. Les capacités des arêtes sortantes de la source et celles entrantes au puits sont indiquées. Les coûts résiduels sont indiqués entre parenthèses.

Le nombre de nœuds de valeurs passe de 4 dans le graphe non compressé à 3 dans le graphe compressé. Cette fois-ci le partitionnement maximise la qualité de la borne. Les coûts résiduels sont les mêmes que dans le graphe non compressé.

3.6.3 Compression aléatoire forçant 3n intervalles

Cette heuristique force un nombre minimal de 3n intervalles. Elle ne fait pas de raisonnement particulier sur le choix des intervalles. L’idée est de compresser le graphe au préalable selon une autre heuristique (comme celle de la section 3.6.2) et de choisir au hasard des intervalles supplémentaires. Le tout est dans l’optique de ne pas obtenir un graphe trop compressé et ainsi diminuer l’impact sur la qualité de la borne.

L’ajout d’un intervalle supplémentaire revient à faire une coupe dans un intervalle existant. Une coupe se fait en choisissant un instant k dans l’horizon qui n’est pas une borne d’un intervalle existant. Soit un intervalle Il,u tel que u > l + 1 et soit l’instant k ∈ Il,u\ {l}, cet intervalle est remplacé par les nouveaux intervalles Il,k et Ik,u. La stratégie aléatoire retenue dans le mémoire est de choisir uniformément selon les instants k disponibles.

3.6.4 Filtrage avec le graphe compressé

La compression permet de garder le contrôle sur la taille du graphe. Cependant, la valeur du flot circulant dans le réseau peut toujours ne pas être bornée par un polynôme. Dans ce contexte, l’algorithme de Klein [17] permettant de calculer le flot maximum à coût minimum

s’exécute en temps pseudo-polynomial et il devient nécessaire de la remplacer par une variante polynomiale, soit l’algorithme MinimumMeanCycleCancelingAlgorithm de Goldberg et Tarjan [12]. L’algorithme 1 permet de filtrer le est des tâches. Par symétrie, le raisonnement est réutilisable pour filtrer les lcti.

Algorithme 1 : FiltrageEstGrapheCompressé((N , A), I, T )

1 (N , Afmax) ← MinimumMeanCycleCancelingAlgorithm((N , A)) 2 si |fmax| < pI alors

3 soulever une incohérence

4 min(dom(T )) ← max(min(dom(T )), cost(fmax)) 5 pour i ∈ I faire

6 tableauCoûtPlusCourtsCheminsi← Bellman-Ford((N, Afmax), i)

7 pour (Il,u, i) ∈ Afmax et tel que l < esti+ pi faire

8 coûtRéduit ← tableauCoûtPlusCourtsCheminsi[Il,u] + w(Il,u, i) 9 si coûtRéduit> 0 alors

10 quantitéFlotÀEnvoyer ← min(c(Il,u, i), esti+ pi− l) 11 quantitéFlotAdmissible ←



max(dom(T ))−cost(fmax)

coûtRéduit



12 si quantitéFlotÀEnvoyer > quantitéFlotAdmissible alors 13 esti ← u − quantitéFlotAdmissible

14 Afmax ← Afmax \ {(Il,u, i) : esti≥ u}

L’algorithme débute en calculant le flot maximum à coût minimum fmax du réseau d’ordon- nancement avec retards compressé (N , A). Tel que mentionné à la section 3.5.3, la validation à la ligne 2 est redondante si la règle de l’edge-finding est cohérente au préalable.

Les domaines des temps de début Si étant encodés par un intervalle, le filtrage est fait aux

bornes. Aux lignes 4 et13, l’opération ajuste la borne inférieure. L’algorithme peut soulever une incohérence si l’opération vide le domaine de la variable.

L’exécution de l’algorithme de Bellman-Ford à la ligne 6 retourne un tableau du coût des plus courts chemins dans le graphe résiduel. La requête au tableau à la ligne 8 de la forme tableaui[Il,u] retourne le coût du plus court chemin (i → . . . → Il,u).

Pour que le estid’une tâche i puisse être cohérent, il faut, pour chaque intervalle Il,urecoupant les instants [esti, esti+ pi), pouvoir envoyer min(c(Il,u, i), esti+ pi− l) unités de flot sur l’arête

(Il,u.i) sans que cela ne cause un dépassement du seuil T . Pour effectuer cette validation, il

faut trouver une borne supérieure sur la quantité de flot admissible qui peut être envoyée sur une arête (Il,u.i). Une borne adéquate est basée sur le coût réduit d’un cycle optimal passant

par l’arête (Il,u.i). Si la quantité de flot à envoyer dépasse celle admissible, alors un filtrage est déclenché. Le cas échéant, la tâche doit débuter au plus petit instant tel qu’il n’est pas possible d’envoyer plus de flot que la quantité admissible pour l’intervalle Il,u. Au final, valider

Chapitre 4

Expérimentations

Ce chapitre vise à comparer différentes versions de l’algorithme de filtrage présenté pour la contrainte DisjunctiveTardiness. Ces variantes sont comparées avec l’approche naïve NDT

présentée à la section 3.2. La comparaison est faite en mesurant la performance lors de la résolution d’instances pour le problème PDT à la section 3.3. Une instance de ce problème est caractérisée par le tuple (I, T ) où I est l’ensemble ordonné des tâches et T est une borne supérieure sur le retard admissible. Pour certaines instances, T = ∞ et l’objectif est seulement de minimiser le retard. Lorsque T est fini, l’intérêt est de savoir si l’instance a une solution et, le cas échéant, de minimiser le retard. Pour toutes les instances, esti= 0 et lcti = ∞ pour

toutes les tâches i ∈ I. L’emphase est donc mise sur l’optimisation d’une solution plutôt que la recherche d’une solution réalisable.

Les implémentations ont été effectuées en utilisant le solveur Choco 4 [20]. Les expérimen- tations ont été exécutées sur le superordinateur Graham de Calcul Canada [3]. Sur chaque processeur Intel E5-2683 v4 Broadwell cadencé à 2.1 GHz était allouée 28 800 MB de mémoire vive, soit 1 800 MB par coeur. Un coeur était alloué pour une instance à résoudre avec les différents algorithmes à tour de rôle.

Les différents algorithmes à comparer sont d’abord présentés. Ensuite, chaque section carac- térise les instances du problème pour lesquelles les résolutions sont comparées. Les résultats expérimentaux sont analysés et suivis d’une discussion sur les travaux futurs.

Documents relatifs