Algoritmo de enrutamiento de Lee 
En 1961 el Lee C.Y. de los Bell Telephone Labs desarrolló un algoritmo muy sencillo y eficaz para el trazado de rutas sobre mallas de puntos. Este algoritmo es muy usado en la actualidad para el enrutado automático de las pistas de cobre en las placas de circuitos impresos.

El algoritmo, que parte de dos puntos que se desean conectar, se divide en dos pasos:

Paso 1. Se genera un frente de onda partiendo del punto origen de la ruta hasta tocar al punto destino. Este frente de onda se va extendiendo por la malla mediante un recorrido en amplitud marcando los puntos por los que va pasando y asignándoles valores cada vez mayores a medida que el frente de onda se aleja del punto origen.

A continuación puede verse cómo se propagaría el frente de onda desde el punto $o=(5, 5)$ y llega hasta el punto $d=(9, 9)$ sobre una malla de 11x11.
 0  10   9   8   7   6   7   8   9  10   0  
10 9 8 7 6 5 6 7 8 9 10
9 8 7 6 5 4 5 6 7 8 9
8 7 6 5 4 3 4 5 6 7 8
7 6 5 4 3 2 3 4 5 6 7
6 5 4 3 2 o1 2 3 4 5 6
7 6 5 4 3 2 3 4 5 6 7
8 7 6 5 4 3 4 5 6 7 8
9 8 7 6 5 4 5 6 7 8 9
0 9 8 7 6 5 6 7 8 d9 10
0 0 9 8 7 6 7 8 9 10 0

Paso 2. Se genera la ruta partiendo del punto destino y volviendo hacia atrás sobre las marcas generadas por el frente de onda de tal forma que cada punto sólo se conecta con otro que tenga una marca con un valor menor. Así hasta llegar al punto origen.
 0   0   0   0   0   0   0   0   0   0   0  
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 0 0 0 0
0 0 0 0 0 0 1 1 0 0 0
0 0 0 0 0 0 0 1 1 0 0
0 0 0 0 0 0 0 0 1 1 0
0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0

En pseudocódigo sería algo así:
Entrada:
M : Malla de puntos en la que cada punto tiene una marca (número) y un trazo
origen : Punto origen de la malla
destino: Punto destino de la malla
Salida:
La misma malla M con los puntos trazados uniendo origen con destino
Algoritmo:
cola := {}
meter(cola, origen)
poner todas las marcas de la malla a 0
poner_marca(M, origen, 1)
hacer
p := sacar(cola)
para cada punto q de M vecino de p, no marcado, ni trazado hacer
meter(cola, q)
poner_marca(M, q, obtener_marca(M, p) + 1)
fin para
fin hacer mientras ((cola no vacía) y (p != destino))
si (p == destino)
p := destino
poner_trazo(M, p)
mientras (p != origen) hacer
aux := punto de la vecindad de p con marca inferior a p y más cercano a origen
poner_trazo(M, aux)
p := aux
fin mientras
en otro caso
error: no hay ruta desde origen a destino
fin si

En la sección soft de la web puede descargarse una implementación en C++ que he hecho de este algoritmo. Como se puede apreciar la mayor carga de complejidad computacional recae en la primera parte, encargada de la propagación del frente de onda ya que se trata de un recorrido en amplitud.
El código de ejemplo en C++ genera una malla de 11 por 11 puntos e intenta trazar sobre ella 6 rutas. Las 5 primeras rutas se trazan mientras que para el último par de puntos el algoritmo no encuentra una ruta válida.
tracing from (5, 5) to (9, 9)... ok
tracing from (5, 10) to (9, 3)... ok
tracing from (0, 10) to (10, 6)... ok
tracing from (1, 1) to (1, 1)... ok
tracing from (0, 1) to (2, 1)... ok
tracing from (6, 8) to (3, 2)... no route found
output grid:
5 5 5 0 0 0 0 0 0 0 0
5 4 5 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 3 3 3
0 0 0 0 0 0 0 3 3 2 3
0 0 0 0 3 3 3 3 0 2 3
0 0 0 0 3 1 1 0 0 2 3
0 0 0 0 3 0 1 1 0 2 3
0 0 0 3 3 0 0 1 1 2 2
0 0 3 3 0 0 0 0 1 1 2
0 3 3 0 0 0 0 0 0 1 2
3 3 0 0 0 2 2 2 2 2 2

Como se puede ver es un algoritmo muy útil para el trazado automático de circuitos impresos.

[ 2 comentarios ] ( 853 visualizaciones )   |  [ 0 trackbacks ]   |  enlace permanente
  |    |    |    |   ( 3 / 728 )

<< <Anterior | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | Siguiente> >>