Está en la página 1de 7

TP: Mochila - Algoritmos voraces

Diana H. - dianna13_1@hotmail.com
1. Descripcin del prolema
!. Algoritmo He"r#stico
3. Algoritmo de $r"s%al
&. 'as"#stica
(. 'onvergencia del prolema
Descripcin del prolema:
El problema consiste en llenar una mochila con unos objetos dados. Cada objeto tiene un tamao y un valor.
Lo que se quiere conseguir es maximizar la suma del tamao*valor de todos los objetos introducidos
en la mochila. En el caso de que un objeto no se pueda meter entero, se fraccionar, quedando la
mochila totalmente llena. Limitaciones de la soluci!n" El algoritmo esta implementado utilizando un
array, por lo que en la b#squeda para obtener el mejor objeto, se recorren incluso los elementos que
ya han sido insertados en la mochila. El algoritmo se podr$a mejorar utilizando una cola de prioridad.
%oluci!n"
&ara resolver el problema utilizamos un algoritmo voraz. Las principales operaciones que realiza el
algoritmo son"
%eleccionar aquel objeto que mejor cumpla una condici!n 'se darn varias opciones al usuario("
o aquel objeto cuyo valor sea el mximo,
o el objeto de m$nimo peso, o
o el objeto con mayor valor por unidad de peso.
Colocar en la mochila el objeto entero, o una fracci!n en el caso de que sea demasiado grande.
)etener el algoritmo, cuando la mochila este llena.
Los datos de los objetos 'peso y valor(, se cargan desde un fichero de texto. La primera fila de dicho fichero
contiene los pesos de los objetos, y la segunda fila los valores, todos ellos separados por espacios en
blanco. En la soluci!n planteada, se permite llenar la mochila dependiendo del valor de los objetos, el peso
o el valor por unidad de peso, sin embargo, s!lo esta ultima condici!n, garantiza que la soluci!n sea !ptima.
'digo )"ente:
p"lic class *ochila +
private float pesos,-.
private float valores,-.
private float peso*aximo.
private oolean descartados,-.
private float pct%eleccionados,-.
private int num/bjetos.

p"lic *ochila'float pesos,-, float valores,-, float peso*aximo( +
i) 'pesos.length 01 valores.length( +
thro* ne* +llegalArg"ment,-ception'2pesos.length 01 valores.length2(.
3
num/bjetos 1 pesos.length.
this.pesos 1 pesos.
this.valores 1 valores.
this.peso*aximo 1 peso*aximo.
pct%eleccionados 1 ne* float,num/bjetos-.
descartados 1 ne* oolean,num/bjetos-.
3
p"lic float,- get%olucion'( +
ret"rn pct%eleccionados.
3
45%e invoca al algoritmo seg#n la funci!n de selecci!n
5%ELECC678" 9:*ayor valor ;:*enor peso <: *ayor valor por unidad de peso
5)evuelve una matriz con los trozos a tomar de cada elemento 'en orden(
54
p"lic float,- algoritmo'int seleccion( +
int i 1 =.
float peso>ctual 1 =.
)or 'int j 1 =. j ? num/bjetos. j@@( +
pct%eleccionados,j- 1 =. 44 =A de cada objeto
descartados,j- 1 )alse. 44 todos disponibles
3
do +
./stem.out.println'2%olicitamos nuevo objeto...2(.
./stem.out.println'2peso*aximo12 @ peso*aximo(.
./stem.out.println'2peso>ctual12 @ peso>ctual(.
i 1 mejor/bjeto'seleccion(.
./stem.out.println'2pesos,2 @ 'i @ 9( @ 2-12 @ pesos,i-(.
i) 'peso>ctual @ pesos,i- ?1 peso*aximo( +
./stem.out.println'2peso>ctual @ pesos,2 @ 'i @ 9( @ 2- ?1 peso*aximo2(.
pct%eleccionados,i- 1 9==. 44 se coge el objeto entero '9==A(
peso>ctual @1 pesos,i-.
3
else +
./stem.out.println'20npeso>ctual @ pesos,2 @ 'i @ 9( @ 2- B peso*aximo2(.
pct%eleccionados,i- 1 ' 'peso*aximo : peso>ctual( 5 9== 4 pesos,i-(.
peso>ctual 1 peso*aximo.
3
./stem.out.println'20npeso>ctualizado12 @ peso>ctual(.
./stem.out.println'2Cogemos el 2 @ pct%eleccionados,i- @
2A del elemento 2 @ 'i @ 9((.
./stem.out.println'2BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB2(.
3
*hile 'peso>ctual ? peso*aximo(.
ret"rn pct%eleccionados.
3

private int mejor/bjeto'int seleccion( +
int indice*ejor/bjeto 1 =.
s*itch 'seleccion( +
case 9" 44 *ayor valor
indice*ejor/bjeto 1 maximoCalor'(.
rea%.
case ;" 44 *enor peso
indice*ejor/bjeto 1 minimo&eso'(.
rea%.
case <" 44*ayor valor por unidad de peso
indice*ejor/bjeto 1 maximoCalor&orDnidad)e&eso'(.
rea%.
3
descartados,indice*ejor/bjeto- 1 tr"e.
ret"rn indice*ejor/bjeto.
3

private int maximoCalor'( +
int indice*ejor/bjeto 1 =.
float maxCalor 1 1loat.*68EC>LDE.
)or 'int i 1 =. i ? num/bjetos. i@@( +
i) '0descartados,i- FF valores,i- B maxCalor( +
indice*ejor/bjeto 1 i.
maxCalor 1 valores,i-. 44 se actualiza el maximo
3
3
ret"rn indice*ejor/bjeto.
3
private int minimo&eso'( +
int indice*ejor/bjeto 1 =.
float min&eso 1 1loat.*>GEC>LDE.
)or 'int i 1 =. i ? num/bjetos. i@@( +
i) '0descartados,i- FF pesos,i- ? min&eso( +
indice*ejor/bjeto 1 i.
min&eso 1 pesos,i-. 44 se actualiza el minimo
3
3
ret"rn indice*ejor/bjeto.
3
private int maximoCalor&orDnidad)e&eso'( +
int indice*ejor/bjeto 1 =.
float maxCalorHelativo 1 1loat.*68EC>LDE.
float valorHelativo>ctual.
)or 'int i 1 =. i ? num/bjetos. i@@( +
i) '0descartados,i-( +
valorHelativo>ctual 1 valores,i- 4 pesos,i-.
i) 'valorHelativo>ctual B maxCalorHelativo( +
indice*ejor/bjeto 1 i.
maxCalorHelativo 1 valorHelativo>ctual. 44 se actualiza el maximo
3
3
3
ret"rn indice*ejor/bjeto.
3
3
Complejidad" El caso peor supone que caben todos en la mochila" / 'n;(.La complejidad se podr$a mejorar
si los objetos se almacenan en un mont$culo" /'n5Log'n((
Algoritmo He"r#stico
En computaci!n, dos objetivos fundamentales para la mayor$a de casos son encontrar algoritmos con
buenos tiempos de ejecuci!n y buenas soluciones, usualmente las !ptimas. Dna he"r#stica es un algoritmo
que ofrece uno o ambos objetivos. por ejemplo, normalmente encuentran buenas soluciones, aunque en
ocasiones no hay pruebas de que la soluci!n no pueda ser arbitrariamente err!nea. o se ejecuta
razonablemente rpido, aunque no existe tampoco prueba de que deba ser as$.
> menudo, pueden encontrarse instancias concretas del problema donde la heur$stica producir resultados
muy malos o se ejecutar muy lentamente. >#n as$, estas instancias concretas pueden ser ignoradas
porque no deber$an ocurrir nunca en la prctica por ser de origen te!rico, y el uso de heur$sticas es muy
com#n en el mundo real.
He"r#sticas para encontrar el camino m2s corto
&ara problemas de b#squeda del camino ms corto el tIrmino tiene un significado ms espec$fico. En este
caso una heurstica es una funci!n matemtica, h'n( definida en los nodos de un rbol de b#squeda, que
sirve como una estimaci!n del coste del camino ms econ!mico de un nodo dado hasta el nodo objetivo.
Las heur$sticas se usan en los algoritmos de b#squeda informada como la b#squeda ego$sta. La b#squeda
ego$sta escoger el nodo que tiene el valor ms bajo en la funci!n heur$stica. >5 expandir los nodos que
tienen el valor ms bajo para g'n( @ h'n(, donde g'n( es el coste 'exacto( del camino desde el estado inicial
al nodo actual. Cuando h'n( es admisible, esto es si h'n( nunca sobrestima los costes de encontrar el
objetivo. >5 es probablemente !ptimo.
Dn problema clsico que usa heur$sticas es el puzzle:n. Contar el n#mero de casillas mal colocadas y
encontrar la suma de la distancia *anhattan entre cada bloque y su posici!n al objetivo son heur$sticas
usadas a menudo para este problema.
,)ecto de las he"r#sticas en el rendimiento comp"tacional
En cualquier problema de b#squeda donde hay b opciones en cada nodo y una profundidad d al nodo
objetivo, un algoritmo de b#squeda ingenuo deber buscar potencialmente entre b
d
nodos antes de
encontrar la soluci!n. Las heur$sticas mejoran la eficiencia de los algoritmos de b#squeda reduciendo el
factor de ramificaci!n de b a 'idealmente( una constante b 5 .>unque cualquier heur$stica admisible
devolver una respuesta !ptima, una heur$stica que devuelve un factor de ramificaci!n ms bajo es
computacionalmente ms eficiente para el problema en particular. &uede demostrarse que una heur$stica
h;'n( es mejor que otra h9'n(, si h;'n( domina h9'n(, esto quiere decir que h9'n( ? h;'n( para todo n.
He"r#sticas en la +nteligencia Arti)icial
*uchos algoritmos en la inteligencia artificial son heur$sticos por naturaleza, o usan reglas heur$sticas. Dn
ejemplo reciente es %pam>ssassin que usa una amplia variedad de reglas heur$sticas para determinar
cuando un correo electr!nico es spam. Cualquiera de las reglas usadas de forma independiente pueden
llevar a errores de clasificaci!n, pero cuando se unen m#ltiples reglas heur$sticas, la soluci!n es ms
robusta y cre$ble. Esto se llama alta credibilidad en el reconocimiento de patrones 'extra$do de las
estad$sticas en las que se basa(. Cuando se usa la palabra heur$stica en el procesamiento del lenguaje
basado en reglas, el reconocimiento de patrones o el procesamiento de imgenes, es usada para referirse a
las reglas.
Algoritmo de $r"s%al
El algoritmo de $r"s%al es un algoritmo de la teor$a de grafos para encontrar un rbol expandido m$nimo
en un grafo conexo y ponderado. Es decir, busca un subconjunto de aristas que, formando un rbol,
incluyen todos los vIrtices y donde el valor total de todas las aristas del rbol es el m$nimo. %i el grafo no es
conexo, entonces busca un bosque expandido m$nimo 'un rbol expandido mnimo para cada componente
conexa(.
El algoritmo de JrusKal es un ejemplo de algoritmo voraz.
Dn ejemplo de rbol expandido m$nimo. Cada punto representa un vIrtice, el cual puede ser un rbol por s$
mismo. %e usa el >lgoritmo para buscar las distancias ms cortas 'rbol expandido( que conectan todos los
puntos o vIrtices. Lunciona de la siguiente manera"
se crea un bosque B 'un conjunto de rboles(, donde cada vIrtice del grafo es un rbol separado
se crea un conjunto C que contenga a todas las aristas del grafo
mientras C es novaco
o eliminar una arista de peso m$nimo de C
o si esa arista conecta dos rboles diferentes se aade al bosque, combinando los dos
rboles en un solo rbol
o en caso contrario, se desecha la arista
>l acabar el algoritmo, el bosque tiene una sola componente, la cual forma un rbol de expansi!n m$nimo
del grafo.
Este algoritmo fue publicado por primera vez en Proceedings of the American Mathematical Societ, pp. MNO
P= en 9QPR, y fue escrito por Soseph JrusKal.
'omple3idad del algoritmo
%iendo m el n#mero de aristas del grafo y n el n#mero de vIrtices, el algoritmo de JrusKal muestra una
complejidad /'m log m( o, equivalentemente, /'m log n(, cuando se ejecuta sobre estructuras de datos
simples. Los tiempos de ejecuci!n son equivalentes porque"
m es a lo sumo n
;
y log n
;
1 ;logn es /'log n(.
ignorando los vIrtices aislados, los cuales forman su propia componente del rbol de expansi!n
m$nimo, n T ;m, as$ que log n es /'log m(.
%e puede conseguir esta complejidad de la siguiente manera" primero se ordenan las aristas por su peso
usando una ordenaci!n por comparaci!n 'comparison sort( con una complejidad del orden de /' m log m(.
esto permite que el paso 2eliminar una arista de peso m$nimo de C2 se ejecute en tiempo constante. Lo
siguiente es usar una estructura de datos sobre conjuntos disjuntos 'disjoint:set data structure( para
controlar quI vIrtices estn en quI componentes. Es necesario hacer varias operaciones del orden de
/'m(, dos operaciones de b#squeda y posiblemente una uni!n por cada arista. 6ncluso una estructura de
datos sobre conjuntos disjuntos simple con uniones por rangos puede ejecutar operaciones del orden de
/'m( en /'m log n(. &or tanto, la complejidad total es del orden de /'m log m( 1 /'m log n(.
Con la condici!n de que las aristas estIn ordenadas o puedan ser ordenadas en un tiempo lineal 'por
ejemplo mediante counting sort o radix sort(, el algoritmo puede usar estructuras de datos de conjuntos
disjuntos ms complejas para ejecutarse en tiempos del orden de /'m U'n((, donde U es la inversa 'tiene un
crecimiento extremadamente lento( de la funci!n de >cKermann.
Demostracin de la correccin
%ea P un grafo conexo y valuado y sea ! el subgrafo de P producido por el algoritmo. ! no puede tener
ciclos porque cada vez que se aade una arista, Ista debe conectar vIrtices de dos rboles diferentes y no
vIrtices dentro de un subrbol. ! no puede ser disconexa ya que la primera arista que une dos
componentes de ! deber$a haber sido aadida por el algoritmo. &or tanto, ! es un rbol expandido de P.
%ea !" el rbol expandido de peso m$nimo de P, el cual tiene el mayor n#mero de aristas en com#n con !.
%i !"1! entonces ! es un rbol de expansi!n m$nimo. &or otro lado, sea e la primera arista considerada por
el algoritmo que est en ! y que no est en !". %ean C" y C# las componentes de P que conecta la arista e.
Va que !" es un rbol, !"$e tiene un ciclo y existe una arista diferente f en ese ciclo que tambiIn conecta C"
y C#. Entonces !#1!"$e%f es tambiIn un rbol expandido. Va que e fue considerada por el algoritmo antes
que f, el peso de e es al menos igual que que el peso de f y ya que !" es un rbol expandido m$nimo, los
pesos de esas dos aristas deben ser de hecho iguales. &or tanto, !# es un rbol expandido m$nimo con ms
aristas en com#n con ! que las que tiene !", contradiciendo las hip!tesis que se hab$an establecido antes
para !". Esto prueba que ! debe ser un rbol expandido de peso m$nimo.
P: 'amio de monedas 4con l#mite de monedas5- Algoritmos voraces
Descripcin del prolema
El problema del cambio consiste en disponiendo de un sistema monetario compuesto en esta caso por
monedas de P==, ;==, 9==, P=, ;P, 9=, P, y 9 pesetas, devolver una cantidad n de dinero utilizando el menor
n#mero de monedas posible. )isponemos de una cantidad ilimitada de monedas de cada tipo.
6imitaciones 7"e tiene la sol"cin dada
Dna limitaci!n t$pica de este problema es que no se pueda devolver una cantidad de dinero en concreto.
&ero con el sistema monetario utilizado es posible calcular el cambio para cualquier cantidad de dinero. &or
tanto, no tiene limitaciones.
'omentario a la sol"cin implementada
Empleamos un array que llamamos valores de tamao N inicializado con los valores del sistema monetario
ordenado de la moneda de mayor valor a la de menor valor. El array quedar$a con estos valores" +P==, ;==,
9==, P=, ;P, 9=, P, 93. Empleamos tambiIn otro array que llamamos cantidades del mismo tamao que el
valores y en el que iremos almacenando la cantidad de cada moneda que devolvamos. Cada posici!n de
este array se corresponde con la misma posici!n del array valores. 6nicializamos todas las posiciones del
array a =.
He"r#stico empleado
Consiste en devolver siempre la moneda de mayor valor posible sin que exceda a la cantidad que nos
queda por devolver. W)a la soluci!n !ptimaX %i. Entendiendo como soluci!n !ptima devolver el menor
n#mero de monedas posibles, con este sistema monetario siempre se devuelve la soluci!n !ptima para
cualquier cantidad que se introduzca. En ocasiones dependiendo del sistema monetario que se emplee
puede encontrarse una soluci!n no !ptima.
C!digo del programa
pacKage cambio.
import java.io.5
p"lic class Cambio +
static int devolver.
static int,- valores 1 +P==, ;==, 9==, P=, ;P, 9=, P, 93.
static int,- caja 1 +<, ;, ;, P, R, <, 9=, R3.44 >adido <= : 99 : ;==R por ::YYYY
static int,- cantidades 1 +=, =, =, =, =, =, =, =3.
static 8"))ered9eader teclado 1 ne* 8"))ered9eader'ne* +np"t.tream9eader'
./stem.in((.
455
5 *Itodo que halla la soluci!n final.
5 Hellena el array de cantidades en funci!n de la cantidad a devolver Zparam devolver El importe que hay
que devolver 54
p"lic static void calcular'int devolver( +
int i 1 =.
*hile 'devolver B =( +
i) ''valores,i- ?1 devolver( FF 'caja,i- B =( 45>adido al if <= : 99 : ;==R por ::YYYY54( +
devolver :1 valores,i-.
caja,i-::. 44 >adido <= : 99 : ;==R por ::YYYY
cantidades,i-@@.
3
else +
i@@.
3
3
3
455
5 *Itodo auxiliar empleado para pedir al usuario el importe que hay que devolver 5 y validar si es una
cantidad de dinero correcta 5 Zreturn )evuelve el importe introducido por el usuario 54
private static int pedir)atos'( +
int importe 1 =.
./stem.out.println'2 6ntroduce importe" 2(.
tr/ +
importe 1 6nteger.parse6nt'teclado.readLine'((.
3 catch '+:,-ception e( +

3
ret"rn importe.
3

455 5 *Itodo main 5 Zparam args 54
p"lic static void main'.tring,- args( +
Cambio cambio9 1 ne* Cambio'(.
devolver 1 pedir)atos'(.
calcular'devolver(.
)or 'int i 1 =. i ? cantidades.length. i@@( +
./stem.out.println'valores,i- @ 2 : 2 @ cantidades,i-(.
3
3

3
Complejidad"La complejidad de este problema se medir en relaci!n al tiempo empleado en rellenar el array
cantidades que variar en funci!n del importe n a devolver. &or tanto, su complejidad es /'n(.
Prolema del via3ante
8ase del prolema
El problema del Agente via3ero es un ejemplo que muestra y analiza la problemtica que subyace tras
algunos tipos de problemas matemticos que a priori parecen tener una soluci!n relativamente fcil, y en la
prctica presentan un gran problema.
La respuesta al problema es conocida, es decir se conoce la forma de resolverlo, pero s!lo en teor$a, en la
prctica la soluci!n no es aplicable debido al tiempo que computacionalmente se precisa para obtener su
resultado. &ara una mayor profundidad en el tema ver el art$culo 8&:completos, del que este es un ejemplo
[maestro[ asequible de entender incluso por nios.
El prolema del via3ante 'tambiIn conocido como prolema del via3ante de comercio o por sus siglas en
inglIs" T.P( es uno de los problemas ms famosos 'y quizs el mejor estudiado( en el campo de la
optimizaci!n combinatoria computacional. > pesar de la aparente sencillez de su planteamiento, el \%& es
uno de los ms complejos de resolver y existen demostraciones que equiparan la complejidad de su
soluci!n a la de otros problemas aparentemente mucho ms complejos que han retado a los matemticos
desde hace siglos.
,n"nciado
%ean 8 ciudades de un territorio. El objetivo es encontrar una ruta que, comenzando y terminando en una
ciudad concreta, pase una sola vez por cada una de las ciudades y minimice la distancia recorrida por el
viajante. Es decir, encontrar una permutaci!n P 1 +c=,c;,...,cn ] 93 tal que
sea m$nimo. La distancia entre cada ciudad viene dada por la matriz )" 8x8, donde d,x, y- representa la
distancia que hay entre la ciudad G y la ciudad V
La soluci!n ms directa es la que aplica la fuerza bruta" evaluar todas las posibles combinaciones de
recorridos y quedarse con aquella cuyo trazado utiliza la menor distancia. El problema reside en el n#mero
de posibles combinaciones que viene dado por el factorial del n#mero de ciudades '80( y esto hace que la
soluci!n por fuerza bruta sea impracticable para valores de 8 incluso moderados con los medios
computacionales actualmente a nuestro alcance. &or ejemplo, si un ordenador fuese capaz de calcular la
longitud de cada combinaci!n en un microsegundo, tardar$a algo ms < segundos en resolver el problema
para 9= ciudades, algo ms de medio minuto en resolver el problema para 99 ciudades y... ^^.9MR aos en
resolver el problema para s!lo ;= ciudades.
&or ejemplo las rutas posibles entre 9; ciudades son 'M^Q millones( M^Q.==9.R== combinaciones y los
caminos individuales entre ciudades son el sumatorio de las 9;:9 ciudades es decir RR.
%e puede demostrar que el requerimiento de volver a la ciudad de partida no cambia la complejidad
computacional del problema.
.it"acin act"al respecto de s" resol"cin
)esde el punto de vista prctico, el problema no est resuelto y desde el punto de vista te!rico, las tIcnicas
empleadas son s!lo aproximaciones. 8o suponen una resoluci!n real del \%& y s!lo ofrecen soluciones
aproximadas suficientemente aceptables. Los algoritmos clsicos no son capaces de resolver el problema
general, debido a la explosi!n combinatoria de las posibles soluciones. &or ello, a su soluci!n se han
aplicado distintas tIcnicas computacionales" heur$sticas evolutivas, redes de _opefield, etc.
'as"#stica
_ay algoritmos que se basan en una configuraci!n concreta del problema. &or ejemplo, algunos algoritmos
de ramificaci!n y consolidaci!n se pueden utilizar para resolver problemas de entre M= a R= ciudades.
/tros han mejorado a Istos con tIcnicas reminiscentes de la programaci!n lineal que permiten resolver el
\%& para valores de 8 entre 9;= y ;== ciudades. En el ao ;==9 se utiliz! una red de 99= ordenadores para
resolver el \%& para las 9P.99; poblaciones de >lemania y utilizando el equivalente computacional a ;;,P
aos de un &C.
En mayo del ;==M se aplicaron algunas de estas tIcnicas para la resoluci!n del problema aplicado a las
;M.Q^N poblaciones suecas en un ciclo de unos ^;.P== Km 'probndose adems que no se pod$a encontrar
un ciclo ms corto(.Los algoritmos genIricos basados en heur$sticas no encuentran soluciones exactas,
pero permiten encontrar aproximaciones suficientemente buenas 'un Q^A de optimizaci!n( y se pueden
aplicar a conjuntos de ciudades muy grandes 'redes con millones de nodos( con tiempos de ejecuci!n
razonables en un superordenador 'semanas o meses(.
'onvergencia del prolema
Dna formulaci!n equivalente en tIrminos de la teor$a de grafos es la de encontrar en un grafo
completamente conexo y con arcos ponderados el ciclo hamiltoniano de menor coste. En esta formulaci!n
cada vIrtice del grafo representa una ciudad, cada arco representa una carretera y el peso asociado a cada
arco representa la longitud de la carretera. El \%& est entre los problemas denominados 8&:completos,
esto es, los problemas que no se pueden resolver en tiempo polinomial en funci!n del tamao de la entrada
'en este caso el n#mero 8 de ciudades que el viajante debe recorrer(. %in embargo, algunos casos
concretos del problema s$ han sido resueltos hasta su optimizaci!n, lo que le convierte en un excelente
banco de pruebas para algoritmos de optimizaci!n que pertenezcan a la misma familia 'lo que en jerga
matemtica se denominan problemas isomorfos(.
Aplicaciones
El problema tiene considerables aplicaciones prcticas, aparte de las ms evidentes en reas de log$stica
de transporte, que cualquier negocio pequeo o grande de reparto conoce. &or ejemplo, en rob!tica,
permite resolver problemas de fabricaci!n para minimizar el n#mero de desplazamientos para conseguir
realizar un n#mero determinado de perforaciones en una plancha o en un circuito impreso. Control y
operativa optimizada de semforos, etc.

También podría gustarte