PlanificacióN Temporal Esquema Voraz Tecnoacademy

2,801 views

Published on

Aplicación del esquema algorítmico voraz (greedy) a planificación de tareas. Casos, demostraciones y ejemplos

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
2,801
On SlideShare
0
From Embeds
0
Number of Embeds
339
Actions
Shares
0
Downloads
41
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

PlanificacióN Temporal Esquema Voraz Tecnoacademy

  1. 1. ESQUEMA VORAZ Planificación de tareas <ul><li>http://tecnoacademy.blogspot.com </li></ul>TECNO ACADEMY Salvador Fernández Fernández
  2. 2. Planificación de tareas <ul><li>Un sistema da servicio a n tareas, cada una con un tiempo de ejecución t i para i entre 1 y n . Se desea minimizar el tiempo medio de estancia de una tarea en el sistema, esto es, el tiempo transcurrido desde el comienzo de todo el proceso hasta que la tarea termina de ejecutarse. Resolver el problema cuando </li></ul><ul><li>se dispone de un único procesador </li></ul><ul><li>se tienen s procesadores idénticos </li></ul>
  3. 3. a) Se dispone de un único procesador <ul><li>El problema consiste en minimizar </li></ul><ul><li>donde T i es el tiempo en el sistema de la tarea i , y como n es constante, esto equivale a minimizar el tiempo total </li></ul><ul><li>para la tarea i , T i es la suma de su tiempo de ejecución t i más todos los tiempos de ejecución de las tareas que se ejecutan antes que ella. La planificación óptima se consigue cuando se atiende a las tareas por orden creciente de tiempo de ejecución . </li></ul>
  4. 4. a) Se dispone de un único procesador <ul><li>En efecto, supongamos un orden cualquiera de tareas donde no se considere un orden creciente de tiempos: </li></ul><ul><li>El tiempo total correspondiente a esta permutación sería: </li></ul><ul><li>Por tanto, la contribución del tiempo de cada tarea al tiempo total depende del número de tareas que la siguen. </li></ul>
  5. 5. a) Se dispone de un único procesador <ul><li>Ya que en I no se ha empleado la estrategia voraz propuesta, podríamos suponer posiciones a y b tales que a<b y t ia >t ib , esto es, posiciones a y b que siguen un orden decreciente según su tiempo de ejecución. Si las intercambiamos obtenemos una nueva permutación I ’ </li></ul><ul><li>Ahora el tiempo total queda como </li></ul>
  6. 6. a) Se dispone de un único procesador <ul><li>Si restamos los tiempos de la permutación que no sigue la estrategia voraz para las posiciones a y b de la que sí sigue la estrategia voraz de ordenar a y b por orden creciente de sus tiempos de ejecución, determinaremos cuál es mejor. </li></ul>TODA PERMUTACIÓN QUE COLOCA LAS TAREAS POR ORDEN CRECIENTE DE TIEMPOS DE EJECUCIÓN ES ÓPTIMA
  7. 7. b) Se dispone de s procesadores idénticos <ul><li>Del apartado a) podemos extraer un par de consecuencias útiles para el caso de varios procesadores. Recordemos. Para </li></ul><ul><li>Hemos demostrado que el tiempo total correspondiente a esta permutación sería mínimo cuando ordenamos los t ik por orden creciente: </li></ul>LEMA
  8. 8. b) Se dispone de s procesadores idénticos <ul><li>Además del lema anterior, debemos recordar que cada tarea contribuye al tiempo total multiplicando su tiempo de ejecución por un factor igual al número de tareas pendientes más uno. </li></ul><ul><li>Observamos que si a un procesador p se le asignan m tareas y a otro procesador p’ se le asignan m+w tareas, con w> 1 , entonces, el tiempo de servicio de la primera tarea asignada a p’ se multiplica por un factor m+w , mientras que si se traslada al primer puesto en p (desplazando las m tareas) tendría un factor m+ 1 <m+w , sin que el resto del tiempo computado por ambos procesadores se viera afectado porque para las restantes tareas no cambiaría el número de ellas que le siguen. De esta forma, el tiempo total decrecería estrictamente. </li></ul><ul><li>Por tanto, cualquier planificación óptima debe mantener equilibrada la carga de todos los procesadores, de forma que la diferencia en el número de tareas asignadas sea a lo sumo uno, es decir, la carga de cada procesador será n div s ó n div s + 1 . Además, en caso de que unos procesadores tengan una tarea más que el resto, éstos serán los primeros. </li></ul>
  9. 9. b) Se dispone de s procesadores idénticos El algoritmo voraz óptimo consistiría en considerar de nuevo las tareas ordenadas por orden creciente de tiempo de ejecución y repartirlas entre los procesadores como si de naipes se tratara. s = nº de procesadores n = nº total de tareas p i = procesador i n j = nº de tareas asignadas a p j t i j = tarea i-ésima dentro de p j
  10. 10. Planificación de tareas <ul><li>Tenemos que ejecutar un conjunto de n tareas, cada una de las cuales requiere un tiempo unitario. La tarea i produce unos beneficios b i >0 sólo en el caso de que sea ejecutada en un instante menor o igual a p i </li></ul><ul><li>Diseña una estrategia voraz para maximizar el beneficio total teniendo en cuenta que pueden quedar tareas sin ejecutar. </li></ul><ul><li>¿Sería válida la misma estrategia si el tiempo de ejecución de cada tarea fuese arbitrario? </li></ul>VUELTA ATRÁS Y RAMIFICACIÓN Y PODA
  11. 11. a) Estrategia voraz para maximizar el beneficio total <ul><li>Diremos que un conjunto de tareas es factible si existe alguna secuencia de ejecución admisible que permita ejecutar todas las tareas del conjunto respetando sus respectivos plazos. </li></ul><ul><li>La estrategia voraz que proponemos consiste en ir seleccionando las tareas de forma que, en cada etapa, se escoja la tarea aún no considerada con mayor beneficio, con la condición de que el subconjunto formado siga siendo factible </li></ul><ul><li>Demostración de optimalidad: </li></ul><ul><ul><li>Supondremos las tareas ordenadas por beneficio de forma decreciente </li></ul></ul><ul><ul><li>La estrategia voraz obtiene un conjunto de índices I </li></ul></ul><ul><ul><li>Otra estrategia óptima, diferente de la voraz, consiste en un subconjunto de índices J </li></ul></ul><ul><ul><li>Sean S i y S j las secuencias admisibles de tareas de los subconjuntos I y J , respectivamente </li></ul></ul><ul><ul><li>En general, habrá tareas comunes en I y en J </li></ul></ul><ul><ul><li>Transformamos S i en S j de tal forma que dichas tareas comunes se ejecuten en los mismos instantes, obteniendo secuencias S’ i y S’ j . Esto siempre es posible ya que: </li></ul></ul><ul><ul><ul><li>Si la tarea a se ejecuta más tarde en S j que en S i , podemos modificar S i de la siguiente manera: </li></ul></ul></ul><ul><ul><ul><ul><li>Si en el instante d en el que la tarea a se ejecuta en S j no se ejecuta ninguna tarea en S i podemos retrasar la ejecución de a hasta el instante d en la secuencia S i , obteniendo una secuencia también admisible </li></ul></ul></ul></ul><ul><ul><ul><ul><li>Si en el instante d ya se ejecuta una tarea b en S i , podemos intercambiar las tareas a y b obteniendo otra secuencia admisible, ya que la ejecución de toda tarea se puede adelantar sin mayor problema. </li></ul></ul></ul></ul><ul><ul><ul><li>Si la tarea a se ejecuta más tarde en S i que en S j , podemos hacer la misma modificación pero en S j </li></ul></ul></ul>
  12. 12. a) Estrategia voraz para maximizar el beneficio total <ul><li>Comparemos ahora las secuencias S’ i y S’ j hasta encontrar una posición k donde difieran: </li></ul><ul><ul><li>No puede ocurrir que en S’ i se ejecute una tarea en el instante k y ninguna en S’ j , porque añadiendo dicha tarea a J obtendremos un conjunto factible con una suma de beneficios mayor, y J es óptima. </li></ul></ul><ul><ul><li>Tampoco puede ocurrir que se ejecute una tarea en S’ j y ninguna en S’ i , porque la estrategia voraz al considerar dicha tarea la habría añadido a I, ya que había hueco para recolectarla </li></ul></ul><ul><ul><li>Por lo tanto, se ejecuta una tarea a en S’ i y una tarea b en S’ j . Veamos qué relación puede haber entre los beneficios b a y b b </li></ul></ul><ul><ul><ul><li>Si fuera mayor el beneficio b a , cambiando a por b en J obtendríamos una solución mejor y eso no es posible, ya que J es óptima. </li></ul></ul></ul><ul><ul><ul><li>Tampoco puede ocurrir que b b >b a porque la estrategia voraz considera las tareas en orden decreciente de beneficios y habría considerado antes b que a . </li></ul></ul></ul><ul><ul><ul><li>Es decir, el único caso posible es b a = b b </li></ul></ul></ul><ul><li>Se deduce, por tanto, que si S’ i y S’ j ejecutan tareas distintas en un mismo instante, estas tareas tienen que producir el mismo beneficio. Se puede cambiar b por a en J y el beneficio total de ambas soluciones es el mismo. Sucesivas transformaciones de este estilo nos llevan a una solución óptima igual que la solución voraz. </li></ul>
  13. 13. a) Estrategia voraz para maximizar el beneficio total <ul><li>LEMA: </li></ul><ul><ul><li>Un conjunto de tareas T es factible si y sólo si la secuencia de la tareas de T ordenadas de forma creciente según plazo es admisible. </li></ul></ul><ul><li>La implicación  es trivial. </li></ul><ul><li>Demostración de  (por reducción al absurdo): </li></ul><ul><ul><li>Sea T = {t 1 , t 2 , …, t k } con p 1 ≤ p 2 ≤ … ≤ p k tal que la secuencia t 1 ,t 2 , …,t k no es admisible, es decir, existe alguna tarea t r , r є {1,…,k} tal que p r < r . Pero entonces se cumple que p 1 ≤ p 2 ≤ … ≤ p r-1 ≤ p r ≤ r-1 </li></ul></ul><ul><ul><li>Esto demuestra que hay r tareas cuyos plazos son menores o iguales que r-1 y, por tanto, es imposible ejecutar todas las tareas dentro de su plazo; en otras palabras, el conjunto T no es factible. Llegada la contradicción queda demostrado el lema. </li></ul></ul><ul><li>El test de factibilidad consistirá en comprobar si la secuencia de tareas ordenadas por plazos es admisible. Es decir, hay que comprobar que la tarea ejecutada en la i-ésima posición tenga un plazo de i o más . En la implementación del algoritmo, aunque suponemos que las tareas vienen ordenadas por beneficio decreciente, las tareas seleccionadas para su ejecución se mantendrán ordenadas por plazo creciente. </li></ul>
  14. 14. a) Algoritmo 1 <ul><ul><li>{b[1]≥ b[2]≥ …≥ b[n]} </li></ul></ul><ul><ul><li>fun planificar(p[1..n], b[1..n] de nat + ) dev (tarea[1..n] de 1..k, k:1..n) </li></ul></ul><ul><ul><li>/* tarea[i] es la tarea ejecutada en el instante i, para i entre 1 y k */ </li></ul></ul><ul><ul><li>/* k es el número total de tareas ejecutadas */ </li></ul></ul><ul><ul><li>var aux[1..n] de 1..n /* secuencia auxiliar ordenada por plazos */ </li></ul></ul><ul><ul><li>k:=1; aux[1]:=1 /* la primera tarea siempre se ejecuta */ </li></ul></ul><ul><ul><li>para i=2 hasta n hacer </li></ul></ul><ul><ul><li>/* buscar hueco lo más tarde posible */ </li></ul></ul><ul><ul><li>d:=k; </li></ul></ul><ul><ul><li> mientras d>0 AND* (p[aux[d]]>=p[i] AND p[aux[d]]>d) hacer </li></ul></ul><ul><ul><li>d:=d-1; </li></ul></ul><ul><ul><li> finmientras </li></ul></ul><ul><ul><li> /* d=0 OR p[aux[d]]≤max(P[i],d) */ </li></ul></ul><ul><ul><li>si p[i]>d entonces /* puede ejecutarse */ </li></ul></ul><ul><ul><li> /* desplazar una unidad de tiempo las tareas posteriores */ </li></ul></ul><ul><ul><li>para j=k hasta d+1 paso -1 hacer </li></ul></ul><ul><ul><li> aux[j+1]:=aux[j] </li></ul></ul><ul><ul><li>fpara </li></ul></ul><ul><ul><li> k:=k+1 </li></ul></ul><ul><ul><li>aux[d+1]=i </li></ul></ul><ul><ul><li> fsi </li></ul></ul><ul><ul><li>fpara </li></ul></ul><ul><ul><li>tarea[1..k]:=aux[1..k] </li></ul></ul><ul><ul><li>ffun </li></ul></ul>Al margen de la ordenación de las tareas por beneficio decreciente (que puede hacerse con un coste en Θ (nlogn)), el coste del algoritmo está en Θ( n 2 ), ya que en el caso peor hay que ejecutar todas las tareas, y para cada una de ellas desplazar un lugar todas las anteriores, lo que equivale a una ordenación por inserción de las tareas por plazo creciente
  15. 15. a) Estrategia voraz para maximizar el beneficio total <ul><li>Podemos obtener una implementación más eficiente basándonos en este otro LEMA: </li></ul><ul><ul><li>Un conjunto de tareas T es factible si y sólo si la secuencia de la tareas de T donde éstas se ejecutan “lo más tarde posible” es admisible. “Lo más tarde posible” se refiere a que para cada tarea se elige el instante libre más tardío que no se pase de plazo, es decir para cada tarea t i el instante elegido será </li></ul></ul><ul><li>La implicación  es trivial. </li></ul><ul><li>Demostración de  (por contrarrecíproco): </li></ul><ul><ul><li>Supongamos que existe alguna tarea en T tal que todos los instantes antes de que expire su plazo p están ocupados. Para w=min{n,p} sea r>w el primer instante libre; entonces en T hay al menos r tareas ( r-1 puestas más la que se está intentando colocar) con plazo menor que r , siendo por tanto imposible ejecutar todas las tareas de T dentro de su plazo, por lo que el conjunto T no es factible. </li></ul></ul><ul><li>Para implementar este test de factibilidad definimos una relación de equivalencia sobre los instantes de ejecución . Si definimos libre(i)=max {d≤i | d libre}, es decir el primer predecesor libre de i, entonces i y j estarán en la misma clase si y sólo si libre(i)=libre(j) . Para que libre(i) esté definido incluso si todos los instantes están ocupados, se considera también el instante 0, que permanecerá siempre libre. La idea es que cada tarea t i debería ejecutarse en el instante libre(p i ), porque representa el último instante libre que respeta su plazo. </li></ul>
  16. 16. a) Estrategia voraz para maximizar el beneficio total <ul><li>libre(i) va cambiando a medida que se va planificando la ejecución de las tareas. Inicialmente , como no se ha planificado ninguna ejecución, se tiene que para todo i entre 1 y n , libre(i)=i ( cada instante está en una clase de equivalencia diferente ); si ejecutamos la tarea ti en el instante libre(p i ) (siempre que éste no sea 0), al ocupar dicho instante hay que fusionar la clase de equivalencia a la que pertenece libre(p i ) con la correspondiente al día anterior. </li></ul><ul><li>Para obtener una implementación eficiente de esta relación de equivalencia dinámica recurrimos a una estructura de partición. Como la implementación de la estructura de partición no garantiza que el representante de la clase de equivalencia que devuelve la operación buscar sea el mínimo, que es lo que necesitamos, utilizaremos un vector L[0..n] tal que L[i]=libre[i] para todo i que sea representante de una clase de equivalencia. </li></ul><ul><li>Nos limitaremos a considerar los instantes de tiempo que no sobrepasen los plazos máximos de forma que, aunque declaremos el conjunto base de la partición como {0,…,n} , la parte útil es {0,…w} para w=min{n, max 1≤i ≤n {p i }} </li></ul>
  17. 17. a) Algoritmo 2 <ul><ul><li>{b[1]≥ b[2]≥ …≥ b[n]} </li></ul></ul><ul><ul><li>fun planificar2(p[1..n], b[1..n] de nat + ) dev (tarea[1..n] de 1..k, k:1..n) </li></ul></ul><ul><ul><li>var L[0..n], aux[1..n] de 0..n, particion: particion[0..n] </li></ul></ul><ul><ul><li>l:=p[1]; </li></ul></ul><ul><ul><li>para i=2 hasta n hacer </li></ul></ul><ul><ul><li>l:=max(l,p[i]) </li></ul></ul><ul><ul><li>fpara </li></ul></ul><ul><ul><li>l:=min(n,l) </li></ul></ul><ul><ul><li>particion:=crear_particion() </li></ul></ul><ul><ul><li>aux[1..l]:=[0] </li></ul></ul><ul><ul><li>para i=0 hasta l hacer </li></ul></ul><ul><ul><li>L[i]:=i </li></ul></ul><ul><ul><li>fpara </li></ul></ul><ul><ul><li>para i=1 hasta n hacer </li></ul></ul><ul><ul><li>c1:=buscar(p[i],particion) </li></ul></ul><ul><ul><li>m:=L[c1] </li></ul></ul><ul><ul><li>si m <> 0 entonces </li></ul></ul><ul><ul><li> aux[m]:=i </li></ul></ul><ul><ul><li> c2:=buscar(m-1,particion) </li></ul></ul><ul><ul><li> fusionar(c1,c2,particion); L[c1]:=L[c2] </li></ul></ul><ul><ul><li>fsi </li></ul></ul><ul><ul><li>fpara </li></ul></ul>/* comprimir solución */ k:=0 para i=1 hasta l hacer si aux[i]>0 entonces k:=k+1 aux[k]:=aux[i] fsi fpara tarea[1..k]:=aux[1..k] ffun
  18. 18. a) Algoritmo 2 <ul><ul><li>Métodos de la partición: </li></ul></ul><ul><ul><li>proc fusionar(a, b: nat + , conjunto[0..n] de nat + ) </li></ul></ul><ul><ul><li>si altura[a]=altura[b] entonces </li></ul></ul><ul><ul><li>altura[a]:=altura[a]+1 </li></ul></ul><ul><ul><li>conjunto[b]:=a </li></ul></ul><ul><ul><li>si no si altura[a]>altura[b] entonces </li></ul></ul><ul><ul><li>conjunto[b]:=a </li></ul></ul><ul><ul><li>si no </li></ul></ul><ul><ul><li>conjunto[a]:=b </li></ul></ul><ul><ul><li>fsi </li></ul></ul><ul><ul><li>fproc </li></ul></ul><ul><ul><li>fun buscar(x: nat + ,conjunto[0..n] de nat + ) dev (r:nat + ) </li></ul></ul><ul><ul><li>/* buscar el rótulo del conjunto que </li></ul></ul><ul><ul><li>contiene el elemento x */ </li></ul></ul><ul><ul><li>r:=x </li></ul></ul><ul><ul><li>mientras conjunto[r]<>r hacer </li></ul></ul><ul><ul><li>r:=conjunto[r] </li></ul></ul><ul><ul><li>fmientras </li></ul></ul><ul><ul><li>/* r es la raíz del árbol */ </li></ul></ul><ul><ul><li>i:=x </li></ul></ul><ul><ul><li>mientras i<>r hacer </li></ul></ul><ul><ul><li> j:=conjunto[i] </li></ul></ul><ul><ul><li> conjunto[i]:=r </li></ul></ul><ul><ul><li> i:=j </li></ul></ul><ul><ul><li>fmientras </li></ul></ul><ul><ul><li>dev r </li></ul></ul><ul><ul><li>ffun </li></ul></ul>El coste de la fase de inicialización de este segundo algoritmo, incluyendo la creación de la partición, está en Θ (n). En cuanto al coste del bucle principal se observa que en el peor caso, cuando se planifican todas las tareas, se realizan 2n búsquedas en la partición y n fusiones de coste prácticamente lineal, hasta obtener una única clase de equivalencia. El coste total del algoritmo está en Θ( nlogn), una vez considera la ordenación previa de las tareas.
  19. 19. a) Ejemplo algoritmo 2 Primero, hay que ordenar la matriz según orden decreciente de los beneficios a i  t i g i  b[i] d i  p[i] j[ ]  aux[ ]
  20. 20. a) Ejemplo algoritmo 2
  21. 21. a) Ejemplo algoritmo 2
  22. 22. b) ¿Es válida la estrategia voraz para planificación con plazo variable? <ul><ul><li>Supongamos que el beneficio de una tarea sólo puede contabilizarse si la tarea termina su ejecución dentro del plazo correspondiente, es decir, si una tarea tiene plazo 4 y su ejecución dura dos unidades de tiempo, entonces ha de empezar a ejecutarse en los tres primeros días. </li></ul></ul><ul><ul><li>La estrategia del apartado a) ya no es válida en este caso. Veamos un contraejemplo: tenemos 3 tareas, todas con plazo 4, pero mientras la primera tarda 3 unidades de tiempo en ejecutarse, las otras dos necesitan 2 días. Supongamos que los beneficios son 10, 8 y 6 respectivamente. Entonces, la estrategia voraz anterior escogerá la primera tarea para empezar a ejecutarla en el primer instante, por lo que las otras dos tareas jamás se ejecutarán y el beneficio se reduce a 10. Sin embargo, es posible ejecutar las otras dos en cualquier orden y obtener un beneficio de 14 </li></ul></ul><ul><ul><li>La única forma de resolver este problema es mediante Vuelta Atrás y Ramificación y Poda. </li></ul></ul>
  23. 23. Estructuras de datos y métodos algorítmicos. Ejercicios resueltos. Narciso Martí Oliet, Yolanda Ortega Mallén y José Alberto Verdejo López. Pearson. Prentice Hall Fundamentos de algoritmia. G. Brassard y P. Bratley. Prentice Hall Referencias

×