Sunteți pe pagina 1din 37

Indice

Introducci
on

1. Resumen

2. Palabras Clave

3. Introducci
on teorica
3.1. Splines c
ubicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2. Optimizaci
on combinatoria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3
3
3

II

Desarrollo

1. Interpolaci
on y extrapolaci
on

2. Intercepci
on de trayectorias
2.1. Algoritmo Greedy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2. Algoritmo genetico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3. Implementaci
on . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

4
4
5
5

3. Experimentos

III

Resultados

1. Prueba 1

2. Prueba 2

3. Prueba 3

4. Prueba 4

10

IV

Discusi
on

11

1. Sobre los resultados

11

2. Sobre los algoritmos

11

12

Conclusi
on

1. Sobre el trabajo

12

2. Extensiones al trabajo

12

VI

13

VII

Ap
endice A
Ap
endice B

15

1. Spline.h

15

2. Spline.cpp

15

3. Punto.h

20

4. Punto.cpp

21

5. PosicionBomba.h

22

6. PosicionBomba.cpp

23

7. Misil.h

23

8. Misil.cpp

24

9. Circulo.h

24

10.Circulo.cpp

24

11.EscudoMisiles.h

25

12.EscudoMisiles.cpp

26

13.EscudoMisilesBruto.h (algoritmo greedy)

28

14.EscudoMisilesBruto.cpp

29

15.Genetico.py

32

VIII

37

Referencias

Parte I

Introducci
on
1.

Resumen

Se implement
o un mecanismo de predicci
on de trayectorias de cuerpos utilizando splines c
ubicos naturales
a partir de lecturas equiparables a las obtenidas por un radar. A continuacion se elaboraron estrategias para,
a partir de dichas trayectorias, interceptar la mayor cantidad posible de ellas utilizando impactos de bomba
en ubicaciones e instantes precisos, utilizando algoritmos greedy y geneticos.

2.

Palabras Clave
Extrapolaci
on con splines c
ubicos
Algoritmo Greedy
Algoritmo Genetico
Optimizaci
on

3.
3.1.

Introducci
on teorica
Splines c
ubicos

En muchas situaciones es necesario aproximar funciones arbitrarias en intervalos determinados a partir de


solo algunos puntos de las mismas. Un primer acercamiento a este problema es la interpolacion mediante
polinomios. Sin embargo la interpolaci
on mediante el polinomio de Lagrange es muy sensible a fluctuaciones
en el intervalo, asi como tambien al hecho de que con una cantidad alta de puntos el polinomio resultante
tendra un alto car
acter oscilatorio.
Una extension natural a dicho metodo consiste en dividir el intervalo en otros subintervalos mas peque
nos.
Dentro de este enfoque se encuentran los splines. El spline c
ubico es un polinomio de grado a lo sumo 3 al
que se le pide no s
olo que interpole los puntos, sino que ademas tenga derivadas continuas en ellos. Ademas
se piden otras condiciones de frontera. En este trabajo se utilizo el spline natural que pide como condicion
de frontera que las segundas derivadas en los puntos extremos valgan 0.

3.2.

Optimizaci
on combinatoria

La optimizaci
on combinatoria explora el (usualmente muy grande) conjunto de posibles soluciones a un
problema de optimizaci
on discreto y utiliza tecnicas diversas para mejorar la performance respecto de una
b
usqueda exhaustiva. Estas tecnicas pueden incluir la restriccion del espacio de posibilidades o la b
usqueda
inteligente dentro del mismo.
En particular nuestro problema de optimizacion tiene un conjunto de candidatos del orden de:
 
n
k
con k la cantidad de bombas a ubicar y n un numero del orden de 109 (correspondiente a la discretizacion
empleada para el espacio de soluciones).
Por tanto, resulta prohibitivo resolver el problema mediante fuerza bruta y recurrimos a algoritmos mas
eficientes que se detallar
an en la secci
on correspondiente del informe.

Parte II

Desarrollo
1.

Interpolaci
on y extrapolaci
on

El objetivo del trabajo es interceptar, mediante impactos de bomba, las trayectorias de misiles que se
aproximan a un planeta en base a lecturas de radar que indican la posicion de los mismos en algunos
instantes dados. Para ello se realiz
o una interpolacion de su trayectoria mediante splines c
ubicos naturales y
se extrapolo su posici
on fuera de los puntos predichos.
Para la realizaci
on del algoritmo de interpolacion por splines c
ubicos naturales se reprodujo el algoritmo
de referencia de (Burden, 1991) sobre una clase de representacion en C++, a la que se a
nadio una funcion de
evaluacion pertinente. Dicha funci
on permite calcular los valores predichos por el polinomio interpolante en
puntos distintos a los provistos para interpolar, y tanto dentro como fuera del rango determinado por estos.
Los puntos interpolados son almacenados en una lista enlazada ya que solo son accedidos secuencialmente
y se facilita el pasaje del par
ametro (ya que no hay que proporcionar el largo de la lista), y los coeficientes de
cada polinomio c
ubico se almacenan en arreglos ya que deben ser accedidos de forma relativamente arbitraria,
y por tanto una secuencia resultara en evaluaciones mas lentas del polinomio.

2.

Intercepci
on de trayectorias

El problema dado es, a partir de un n


umero de trayectorias predichas, interceptar la mayor cantidad de
ellas utilizando una cantidad predefinida de impactos de bomba en instantes y posiciones determinadas.
Atacar un problema de estas caractersticas de forma analtica escapa ampliamente a nuestros conocimientos, y es probable que sea inabordable por sus caractersticas sumamente complejas. Se decidio entonces
recurrir a una discretizaci
on del espacio de soluciones, tanto en tiempo como en espacio, para poder recurrir
a soluciones iterativas que, si bien no son necesariamente optimas, pueden serlo en muchos casos.
El universo de combinaciones que resulta de esta discretizacion es muy grande para simplemente recorrerlo
y tomar el mejor candidato: la cantidad de combinaciones es exponencial respecto de los parametros de
entrada, y se exige que el tiempo de corrida del programa sea menor a 20 segundos. Por lo tanto debemos
utilizar un algoritmo que mediante aproximaciones, o alguna heurstica, nos provea de una solucion razonable
en un tiempo peque
no.
A continuaci
on se detallan los dos algoritmos propuestos.

2.1.

Algoritmo Greedy

El primero de los algoritmos propuestos utiliza la metaheurstica conocida como greedyness o codicia. Los
algoritmos de este tipo se caracterizan por el siguiente comportamiento: con el fin de maximizar la aptitud
de una combinaci
on dada de elementos, se busca maximizar la aptitud de uno solo de ellos y se reproduce
este mecanismo hasta obtener una combinacion del largo necesario.
Por ejemplo, si el problema es el de obtener una determinada suma de dinero en la menor cantidad posible
de monedas, un mecanismo greedy para resolver este problema consiste en tomar siempre la moneda de
mayor valor posible que entra en la suma total, y reproducir el procedimiento con el importe restante. As,
para obtener una combinaci
on de monedas que sumen 33 centavos, se toma una de 25 centavos (restan 8
centavos), a continuaci
on una de 5 centavos (restan 3) y finalmente 3 de un centavo. En particular para este
problema la soluci
on propuesta por el algoritmo greedy es optima, pero esto se debe a las caractersticas
inherentes de este ejemplo.
Para la optimizaci
on de ubicaci
on de las bombas en tiempo y espacio, la heurstica utilizada fue simplemente tomar la ubicaci
on espacial y temporal de la bomba que mas misiles intercepta. Para ello se recorren
los tiempos discretizados en busca de este m
aximo. A continuacion se reproduce el mecanismo en los tiempos
posteriores al elegido, y limitando la b
usqueda a los misiles que no fueron eliminados por la bomba anterior.
Ademas, y para acelerar la b
usqueda, solo se recorren los puntos tales que una bomba ubicada en ellos
alcanza cuando menos un misil.

Es claro que este mecanismo no produce necesariamente soluciones optimas, pero su ejecucion es rapida y
estimamos que provee una buena aproximaci
on a la solucion. Por otra parte, al ser un algoritmo determinista
que debe ejecutarse en un tiempo constante, pueden ocurrir dos cosas: que sobre tiempo, y por tanto se
desperdicie la posibilidad de optimizar a
un mas la solucion obtenida, o que no se llegue a completar el
algoritmo en el tiempo especificado, no pudiendo as proveer ninguna solucion. En nuestra implementacion
decidimos solo preocuparnos por la segunda cuestion: si el algoritmo prevee que se quedara sin tiempo para
terminar su ejecuci
on, esta se aborta en el punto en que se encuentra y se terminan de posicionar las demas
bombas utilizando una heurstica a
un m
as sencilla que garantiza u
nicamente que las bombas interceptan
alg
un misil, en lugar de caer en la nada.

2.2.

Algoritmo gen
etico

Los algoritmos geneticos son una forma refinada de comparar candidatos al azar para optimizar un problema. Se comienza con un conjunto de candidatos aleatorios (la poblacion), y se los somete a procesos
comparables a los de la evoluci
on natural de una especie: se cruzan, mutan y envejecen, sobreviviendo solo
los mas aptos dentro del conjunto. La aptitud de un candidato se mide con una funcion definida de forma tal
que deba maximizarse para obtener la soluci
on optima al problema. Ademas se establecen varios parametros
de simulacion, como ser las tasas de mutaci
on y mortalidad, y la forma en que se mutan o cruzan los candidatos para obtener otros nuevos. Estas heursticas resultan en una convergencia que en general conduce a
una buena soluci
on del problema.
En nuestro caso, cada candidato es una secuencia de PosicionesBomba (que se componen de un punto y
un instante), y la funci
on de aptitud eval
ua varios factores: se favorece que el conjunto de posiciones elimine
la mayor cantidad posible de misiles, y que una cierta PosicionBomba elimine un n
umero grande de misiles
(aunque con menor fuerza que el criterio anterior, que es el verdadero determinante de las cualidades de una
solucion). Se penaliza por otra parte que haya bombas desperdiciadas, y que alguna bomba impacte con la
superficie del planeta.
Este procedimiento tiene la ventaja de que al ser iterativo, se puede aprovechar al maximo el tiempo
disponible para realizar los c
alculos. Sin embargo, y por su naturaleza aleatoria, es imposible garantizar las
cualidades de la soluci
on obtenida, a pesar de que un buen conjunto de heursticas de cruza, mutacion y
aptitud dan la pauta de que se obtiene una solucion cuando menos decente en un tiempo razonable. Por lo
tanto, puede ocurrir que en una corrida para una instancia dada del problema se obtenga rapidamente la
solucion optima, mientras que en otra ejecucion subsiguiente no se consiga el resultado deseado.

2.3.

Implementaci
on

Se realizaron prototipos de los algoritmos en Python con la idea de luego portarlos C++. Finalmente
se resolvio portar u
nicamente el algoritmo greedy ya que el algoritmo genetico usaba muchas cualidades
dinamicas del lenguaje y se haca muy complejo de implementar en C++, ademas de que requeria tiempo
del que no disponiamos. Se presentan de todos modos las versiones de los prototipos en Python, que son
perfectamente funcionales, as como el c
odigo en C++. En ambos algoritmos se considero que el tiempo
maximo que le insume a un misil alcanzar el planeta esta acotado. El lmite elegido fue 10, ya que este es el
largo de la simulaci
on realizada por el simulador de referencia. Para modificar este lmite, solo es necesario
alterar el valor de T IEM P O BU SQU EDA en EscudoMisiles.cpp y escudo.py.

3.

Experimentos

Para estudiar el funcionamiento de los algoritmos se realizaron experiencias que pretendan buscar casos
donde los mismos pudieran mostrar un comportamiento no optimo. Asi se busco, por ejemplo, un caso donde
por tomar un valor
optimo localmente, el algoritmo greedy no logra obtener el maximo global, as como
otro donde la soluci
on
optima no sea encontrada por el algoritmo genetico ya que resultaba ser demasiado
sensible a peque
nos cambios de posici
on (el conjunto de soluciones optimas era muy reducido). Para esto se
utilizaron los archivos de prueba provistos por los docentes, asi como tambien otros elaborados por nosotros
mismos y otros grupos. Los resultados de algunas de las simulaciones obtenidas se encuentran en el apartado
de resultados.

A diferencia de los trabajos pr


acticos anteriores no se realizaron mediciones de tiempo de ejecucion ya que
este estaba acotado por 20 segundos.
En la seccion resultados se encuentra lo obtenido en las siguientes experiencias:
Prueba 1: Se utiliza un conjunto de misiles donde las soluciones optimas son muy pocas.
Prueba 2: La solucion
optima se puede lograr con una cantidad mas grande de ubicaciones para las
bombas.
Prueba 3: Se utiliza un conjunto que hace que la union de los maximos locales no redunde en un
maximo global, para mostrar las limitaciones del algoritmo greedy.
Prueba 4: Similar a la prueba 3 pero esta vez la cantidad de misiles es mayor.

Parte III

Resultados
1.

Prueba 1

Figura 1: Bombas colocadas por el algoritmo greedy

Figura 2: Bombas colocadas por el algoritmo genetico

2.

Prueba 2

Figura 3: Bombas colocadas por el algoritmo greedy

Figura 4: Bombas colocadas por el algoritmo genetico

3.

Prueba 3

Figura 5: Bombas colocadas por el algoritmo greedy

Figura 6: Bombas colocadas por el algoritmo genetico

4.

Prueba 4

Figura 7: Bombas colocadas por el algoritmo greedy

Figura 8: Bombas colocadas por el algoritmo genetico

10

Parte IV

Discusi
on
1.

Sobre los resultados

En la prueba 1 se observa como el algoritmo greedy logra encontrar una solucion optima mientras que
el algoritmo genetico no. Esto se debe a que para lograr contener a todos los misiles del lado izquierdo, el
margen para colocar la bomba es muy peque
no, por lo cual el algoritmo genetico no consigue localizarlo en
los 20 segundos que se le otorgan. En cambio, como en este caso la union de los maximos locales - es decir
interceptar cada vez la mayor cantidad posible de misiles - es una solucion optima, el greedy obtiene un
mejor resultado.
En la prueba 2 ambos algoritmos logran una solucion optima. Esto se debe a que nuevamente la union
de los maximos locales permite encontrar un maximo global, y que a diferencia de la prueba anterior las
bombas tienen un margen m
as amplio para ser colocadas logrando interceptar a todos los misiles, por lo cual
el tiempo del algoritmo genetico resulta suficiente para hallar la solucion optima.
En la prueba 3 se pone de manifiesto como el algoritmo greedy por su condicion eager se inclina por una
solucion no adecuada. En este caso el m
aximo local que toma es el primer cruce de dos misiles, al eliminar
a esos dos misiles se queda con otros dos disjuntos a los que no puede matar con una sola bomba. Si no se
quedara con ese m
aximo local, podra haber logrado interceptar a los 4 misiles como lo hizo el otro algoritmo.
En la prueba 4 ninguno de los dos metodos logra un resultado optimo. El algoritmo greedy no lo hace por
las mismas razones por las que no lo hace en la prueba 3. En cambio el genetico, que antes s lo resolva
correctamente ahora falla tambien. Esto se debe a que en esta prueba el n
umero de misiles es mas grande
por lo cual necesita de m
as iteraciones hasta lograr una mejor solucion. Sin embargo, como el tiempo de
ejecucion es el mismo, no logra encontrarla y devuelve la mejor solucion que encontro, y que no es la mejor
posible.

2.

Sobre los algoritmos

En general se observ
o que para la mayora de los casos el algoritmo greedy se comporta de forma muy
satisfactoria, eliminando una cantidad m
axima de misiles en un tiempo de calculo muy acotado.
Sin embargo es de destacarse tambien que esto puede deberse fuertemente al modelo utilizado para representar los misiles. Cuando se construye la trayectoria de un misil se hace a partir de puntos en la misma, y
esto introduce la limitaci
on de que solo pueden utilizarse bombas luego de colocada la u
ltima medicion. De
esta forma, el comportamiento de un misil luego de ese momento sigue una funcion c
ubica tradicional, sin
alteraciones mayores, y no se producen grandes cambios en la direccion de un misil, en esta circunstancia
uniforme el algoritmo greedy se comporta particularmente bien (por naturaleza).
En general el algoritmo genetico es inherentemente mas lento que el greedy, por la complejidad adicional
de las operaciones que realiza y porque no fue implementado en C++. Con el lmite de tiempo de 20 segundos
que se le impone, los resultados que se obtienen son en general peores que los del otro algoritmo, aunque en
general ofrece resultados bastante razonables como es esperable.
Por otro lado si observamos el (relativamente sencillo) contraejemplo hallado para la optimalidad de los
resultados del algoritmo greedy, resulta claro que el algoritmo genetico produce una respuesta mejor. A esto
se agrega el hecho de que con m
as tiempo de ejecucion, es probable que el algoritmo genetico hubiera resuelto
correctamente el caso propuesto en la prueba 4.
Como generalizaci
on podra decirse que el algoritmo genetico produce resultados de calidad menor pero
mas parejos, mientras que el algoritmo greedy, al ser mas ingenuo, puede producir resultados muy buenos
tanto como muy malos.

11

Parte V

Conclusi
on
1.

Sobre el trabajo

El problema de optimizaci
on a resolver es altamente complejo dadas las condiciones impuestas sobre el
algoritmo de resoluci
on, tanto en tiempo de ejecucion como de desarrollo. Propusimos dos alternativas que,
en conjunto, consiguen resolver de forma relativamente satisfactoria el problema para instancias peque
nas
del mismo.

2.

Extensiones al trabajo

Las mejoras m
as obvias al trabajo son las de mejorar su eficiencia, ya sea implementando el algoritmo
genetico en C++ y optimizando su comportamiento, como explorando otras alternativas para la resolucion del problema. En particular puede resultar interesante evaluar un algoritmo utilizando programacion
dinamica, aunque por la complejidad del problema puede llegar a resultar prohibitivamente lento. Alternativamente, puede resultar adecuado implementar varias alternativas de resolucion y elegir entre ellas la que
mas apta resulte para una instancia dada, ya que los diferentes algoritmos tienen capacidades distintas frente
a problemas de diferentes caractersticas.

12

Parte VI

Ap
endice A
Laboratorio de M
etodos Num
ericos - Segundo cuatrimestre 2007
Trabajo Pr
actico N
umero 4: Impacto profundo

Introducci
on
Nos encontramos nuevamente en el Centro de Operaciones Logsticas Laterales (C.o.l.l.), en uno de los
momentos mas dram
aticos de la XLII Guerra Intergalactica. El planeta Z-80 esta siendo atacado por un
conjunto de misiles que amenazan su integridad, y nuestra mision consiste en detener este cruel ataque.
Para defender al planeta Z-80 contamos con un n
umero reducido de bombas de destruccion masiva. Estas
bombas son enviadas a un punto del espacio circundante a nuestro planeta, donde se las hace explotar. La
explosion genera una onda expansiva que destruye todos los objetos (y misiles) ubicados a menos de un cierto
radio crtico del centro de la explosi
on.
Nuestros radares nos proporcionan la posicion exacta de los misiles enemigos a intervalos de tiempo
aproximadamente constantes1 . En funci
on de estas mediciones deberemos determinar las trayectorias futuras
de los misiles y, sobre la base de estas estimaciones, deberemos decidir en que lugar y en que momento tenemos
que producir las explosiones de nuestras bombas defensivas, con el objetivo de destruir la mayor cantidad de
misiles enemigos. La supervivencia de nuestro planeta esta en sus manos.
Enunciado
El objetivo del trabajo pr
actico es implementar un programa que lea las mediciones de las posiciones
de los misiles desde un archivo de texto, y que deje en otro archivo el momento y la posicion en la que
debera detonarse cada bomba defensiva, con el objetivo de maximizar la cantidad de misiles enemigos destruidos. Debido a la urgencia que tenemos para activar nuestras defensas, el programa no debera utilizar
mas de 20 sg. de procesamiento total.
El archivo de entrada contiene las posiciones de los misiles enemigos a intervalos de tiempo constantes de
1 sg. Para estimar la trayectoria futura de cada misil se deberan interpolar las mediciones de las posiciones
enemigas con splines parametricos naturales, utilizando la extrapolacion de cada spline hacia el futuro como
una estimacion de la trayectoria correspondiente.
El programa debe tomar por lnea de comandos los nombres del archivo de entrada y del archivo de salida,
de la siguiente forma:
tp4.exe misiles.txt bombas.txt
El archivo con los datos de entrada (llamado misiles.txt en el ejemplo) tiene en la primera lnea la
cantidad n de misiles y la cantidad m de mediciones para cada uno. A continuacion, se incluyen m filas
correspondientes al primer misil, cada una de las cuales contiene las coordenadas x e y de la posicion del
misil en los instantes t = 1, 2, . . . , m sg. (simplificamos el analisis considerando un espacio bidimensional).
Luego de las m lneas correspondientes al primer misil, el archivo contiene m lneas con el mismo formato
correspondientes al segundo misil, etc. Por u
ltimo, el archivo contiene una lnea con la cantidad b de bombas
defensivas, el radio r de la onda expansiva de cada una y el radio R de nuestro planeta, cuyo centro suponemos
ubicado en el origen de coordenadas. Por ejemplo, el siguiente archivo es un ejemplo de datos de entrada
validos:
3 4
1.0
1.1
1.23
1.27

2.5
2.4
2.3
2.15

1 Dominamos

los viajes interplanetarios pero nuestros radares usan la anticuada tecnologa del siglo XXI.

13

1.9
1.8
1.7
1.75

3.5
3.4
3.2
2.9

-2.2
-2.15
-2.12
-2.08

2.3
2.23
2.17
2.11

2 0.7 1.0
Por su parte, el archivo de salida (llamado bombas.txt en el ejemplo) debe tener una lnea por cada bomba,
que contenga el instante de la explosi
on y las coordenadas x e y del centro de la explosion. Es importante
notar que el punto central de cada explosi
on debe tener una distancia al origen de coordenadas de al menos
R + r, para evitar que parte del planeta sea destruido por nuestras mismas bombas defensivas. Por ejemplo,
si b = 2 el siguiente es un ejemplo de archivo de salida:
2.4
1.6

2.15 2.80
-2.04 2.50

El informe debe contener todas las opciones que el grupo haya considerado para determinar los instantes
y posiciones en los que se deben detonar las bombas defensivas.

Fecha de entrega: Lunes 19 de Noviembre

14

Parte VII

Ap
endice B
1.

Spline.h

#ifndef spline H
#define spline H
#include
#include
#include
#include
#include

<list>
<iostream>
<cstdlib>
<math.h>
<assert.h>

#include Punto.h
#include Circulo.h
using namespace std;
class Spline {
public:
Spline();
Spline(const Spline& otro);
Spline(list<Punto>& puntosDePaso);
Spline();
double evaluar(double x);
void mostrar();
Spline operator=(const Spline &otro);
bool operator!=(Spline otro);
double operator() (double x);
bool operator==(Spline otro);

private:
double** l;
list<Punto> puntos;
void borrar();
void copiar(const Spline &otro);
};
#endif /* Spline H*/

2.

Spline.cpp

#include Spline.h
#include imprimirLista.h

15

Spline :: Spline(){}
void Spline :: mostrar(){
list<Punto> :: iterator p = this->puntos.begin();
Punto xj = (*p);
p++;
Punto xjm1 =(*p);
for(unsigned int i = 0; i < puntos.size()-1; i++){
cout<<Spline entre: <<xj<< <<xjm1<<endl;
cout<<l[i][0]<< ;
cout<< l[i][1]<< ;
cout<< l[i][2]<< ;
cout<< l[i][3]<< ;
cout<<endl;
xj=xjm1;
p++;
cout<<i: <<i<<endl;
if(p != puntos.end())
xjm1=(*p);
}
cout<<endl;
}

void Spline :: copiar(const Spline &otro){


for(list<Punto> ::const iterator it = (otro.puntos).begin(); it != (otro.puntos).end();
it++){
(this->puntos).insert((this->puntos).end(),*it);
}
l = new double *[(puntos.size()-1)];
for(unsigned int i = 0; i < puntos.size()-1; i++){
l[i] = new double[4];
l[i][0] = (otro.l)[i][0];
l[i][1] = (otro.l)[i][1];
l[i][2] = (otro.l)[i][2];
l[i][3] = (otro.l)[i][3];
}
}
Spline :: Spline(const Spline &otro){
copiar(otro);
}
Spline Spline :: operator=(const Spline &otro){
if(*this != otro){
copiar(otro);
}
return *this;
}
bool Spline :: operator==(Spline otro){

16

bool iguales = otro.puntos == this->puntos;


if(iguales){
for(unsigned int i = 0;iguales && i < puntos.size()-1; i++){
iguales = iguales && l[i][0] == (otro.l)[i][0];
iguales = iguales && l[i][1] == (otro.l)[i][1];
iguales = iguales && l[i][2] == (otro.l)[i][2];
iguales = iguales && l[i][3] == (otro.l)[i][3];
}
}
return iguales;
}
bool Spline :: operator!=(Spline otro){
return !(*this == otro);
}
Spline :: Spline(list<Punto>& puntosDePaso) {
// algoritmo de resolucion basado en Burden
int n = puntosDePaso.size() - 1;
double* h = new double[n];
list<Punto> :: iterator it = puntosDePaso.begin();
double xj = (*it).x;
it++;
double xjm1 = (*it).x;
for(int i = 0; i < n; i++) {
xjm1 = (*it).x;
h[i] = xjm1 - xj;
xj = xjm1;
it++;
}

double* a = new double [n+1];


double* xs = new double [n+1];
int i = 0;
for(it = puntosDePaso.begin(); it != puntosDePaso.end(); it++) {
a[i] = (*it).y;
xs[i] = (*it).x;
i++ ;
}
double* alfa = new double[n];
it = puntosDePaso.begin();
for(int i = 1; i < n; i++) {
alfa[i] = 3 * (a[i+1] * h[i-1] - a[i] * (xs[i+1] - xs[i-1]) + a[i-1] * h[i]) /
(h[i-1]*h[i]);
}

double* l = new double [n+1];


double* mu = new double [n+1];
double* z = new double [n+1];

17

l[0] = 1;
mu[0] = 0;
z[0] = 0;

double* b = new double [n+1];


double* c = new double [n+1];
double* d = new double [n+1];
for(int i = 1; i < n; i++) {
l[i] = 2.0 * (xs[i+1] - xs[i-1]) - h[i-1] * mu[i-1];
mu[i] = h[i] / l[i];
z[i] = (alfa[i] - h[i-1] * z[i-1])/l[i];
}

l[n] = 1;
z[n] = 0;
c[n] = 0;
int j;
for(int i = 1; i < n+1; i++) {
j = n-i;
c[j] = z[j] - mu[j] * c[j+1];
b[j] = (a[j+1] - a[j])/h[j] - (h[j]*(c[j+1] + 2*c[j]))/3.0;
d[j] = (c[j+1] - c[j]) / (3.0 * h[j]);
}
// preparo el vector donde voy a guardar los coeficientes obtenidos
this->l = new double* [n];
for(int i = 0; i < n ; i++) {
this->l[i] = new double[4];
}
// los guardo
for(int i = 0; i < n; i ++) {
this->l[i][0] = a[i];
this->l[i][1] = b[i];
this->l[i][2] = c[i];
this->l[i][3] = d[i];
}
puntos = puntosDePaso;
delete[]
delete[]
delete[]
delete[]
delete[]
delete[]
delete[]
delete[]
delete[]

h;
alfa;
l;
mu;
z;
a;
xs;
b;
c;

18

delete[] d;
}
void Spline :: borrar(){
int largo = puntos.size() - 1;
for(int i=0; i < largo; i++) {
delete[] l[i];
}
delete[] l;
}
Spline :: Spline() {
borrar();
}

double Spline :: evaluar(double x) {


int n = puntos.size() - 1;
double nx;
// busco a que intervalo corresponde X, ya que si esta
// fuera del intervalo de los puntos interpolados, debo
// usar el polinomio mas cercano
// si esta antes del primero
if(x < puntos.front().x) {
nx = x - puntos.front().x;
return pow(nx, 3) * l[0][3] +
pow(nx, 2) * l[0][2] +
nx * l[0][1] +
l[0][0];
}
// si esta despues del ultimo
else if( x >= puntos.back().x) {
// tomo puntos[n-1]
Punto penultimo = *(--(--(puntos.end())));
nx = x - penultimo.x;
return pow(nx, 3) * l[n-1][3] +
pow(nx, 2) * l[n-1][2] +
nx * l[n-1][1] +
l[n-1][0];
}
// si esta en el medio, busco en cual subintervalo
else {
int intervalo = 1;
double xIntervaloAnterior = puntos.front().x;
list<Punto> :: iterator it = puntos.begin();
it++;

19

while(x > (*it).x) {


intervalo++;
xIntervaloAnterior = (*it).x;
it++;
}
nx = x - xIntervaloAnterior;
return pow(nx, 3) * l[intervalo - 1][3] +
pow(nx, 2) * l[intervalo - 1][2] +
nx * l[intervalo - 1][1] +
l[intervalo - 1][0];
}
}
double Spline :: operator() (double x) {
return evaluar(x);
}

3.

Punto.h

#ifndef punto H
#define punto H
#include
#include
#include
#include

<list>
<cstdlib>
<math.h>
<iostream>

using namespace std;


class Punto{
public:
Punto();
Punto(double x, double y);
double x;
double y;
Punto operator+ (Punto);
Punto operator- (Punto);
Punto operator* (double);
bool operator== (Punto);
bool operator!= (Punto);
bool operator== (const Punto& p) const;
double norma();
double distancia(Punto p);
double maxCoord();
list<Punto>* puntosLindantes(double radio, double discretizacion);
friend std::ostream& operator<< (ostream&, const Punto&);
};

20

#endif /* punto H*/

4.

Punto.cpp

#include Punto.h
Punto :: Punto() {
}
Punto :: Punto(double xx, double yy) {
x = xx;
y = yy;
}

Punto Punto :: operator+ (Punto p) {


return Punto(x+p.x, y+p.y);
}
Punto Punto :: operator- (Punto p) {
return Punto(x-p.x, y-p.y);
}
Punto Punto :: operator* (double f) {
return Punto(x*f, y*f);
}
bool Punto :: operator== (Punto p) {
return x == p.x && y == p.y;
}
bool Punto :: operator== (const Punto& p) const {
return x == p.x && y == p.y;
}
bool Punto :: operator!= (Punto p) {
return !(*this == p);
}
double Punto :: norma() {
return (double)sqrtl(powl(x,2)+powl(y,2));
}
double Punto :: distancia(Punto p) {
return (*this - p).norma();
}
list<Punto>* Punto :: puntosLindantes(double radio, double discretizacion) {
list<double> xs;
for(double i = -1*discretizacion; i < discretizacion; i++){
xs.insert(xs.begin(), x + radio*i/discretizacion);
}
21

list<double> ys;
for(double i = -1*discretizacion; i < discretizacion; i++){
ys.insert(ys.begin(), y + radio*i/discretizacion);
}
list<Punto>* puntos = new list<Punto>;
for(list<double> :: iterator itx = xs.begin(); itx != xs.end(); itx++){
for(list<double> :: iterator ity = ys.begin(); ity != ys.end(); ity++){
puntos->insert(puntos->begin(), Punto((*itx), (*ity)));
}
}
return puntos;
}
double Punto :: maxCoord(){
if (x >= y) {
return x;
}
else {
return y;
}
}

std::ostream& operator<< (std::ostream& o, const Punto& p) {


return o << <Punto (<< p.x << ,<< p.y << )>;
}

5.

PosicionBomba.h

#ifndef PosBomba H
#define PosBomba H
#include
#include
#include
#include
#include

<list>
<iostream>
<cstdlib>
<math.h>
<assert.h>

#include Spline.h
#include Punto.h
#include Circulo.h
class PosicionBomba {
public:
PosicionBomba();
PosicionBomba(double tiempo, Punto punto);
bool operator<(PosicionBomba otro);

22

Punto punto;
double tiempo;
};
#endif /* PosBomba H*/

6.

PosicionBomba.cpp

#include PosicionBomba.h
PosicionBomba :: PosicionBomba() {}
PosicionBomba ::PosicionBomba(double tiempo, Punto punto) {
this->tiempo = tiempo;
this->punto = punto;
}
bool PosicionBomba :: operator<(PosicionBomba otro) {
return tiempo < otro.tiempo;
}

7.

Misil.h

#ifndef Misil H
#define Misil H
#include
#include
#include
#include
#include

<list>
<iostream>
<cstdlib>
<math.h>
<assert.h>

#include Spline.h
#include Punto.h
#include Circulo.h
class Misil {
public:
Misil();
Misil(Spline splinex, Spline spliney);
Punto posicion(double t);
Spline spx;
Spline spy;
};
#endif /* Misil H*/

23

8.

Misil.cpp

#include Misil.h
Misil :: Misil() {}
Misil :: Misil(Spline splinex, Spline spliney) {
spx = splinex;
spy = spliney;
}
Punto Misil :: posicion(double t) {
return Punto(spx(t), spy(t));
}

9.

Circulo.h

#ifndef Circulo H
#define Circulo H
#include Punto.h
class Circulo {
public:
Circulo();
Circulo(Punto centro, double radio);
double radio;
Punto centro;
bool pertenece(Punto p);
unsigned int cuantosPertenecen(list<Punto> puntos);
friend std::ostream& operator<< (std::ostream&, const Circulo&);
};
#endif /* Circulo H*/

10.

Circulo.cpp

#include Circulo.h
Circulo :: Circulo() {
}
Circulo :: Circulo(Punto p, double r){
centro = p;
radio = r;
}

24

bool Circulo :: pertenece(Punto p){


return p.distancia(centro) < radio;
}

unsigned Circulo :: cuantosPertenecen(list<Punto> l){


unsigned pertenecen = 0;
for(list<Punto> :: iterator it = l.begin(); it != l.end(); it++){
if(pertenece(*it)){
pertenecen ++;
}
}
return pertenecen;
}
std::ostream& operator<< (std::ostream& o, const Circulo& c) {
return o << <Circulo de radio << c.radio << en (<< c.centro.x << ,<< c.centro.y
<< )>;
}

11.

EscudoMisiles.h

#ifndef Escudo H
#define Escudo H
#include
#include
#include
#include
#include
#include
#include

<list>
<iostream>
<cstdlib>
<math.h>
<assert.h>
<string>
<fstream>

#include timer.h
#include
#include
#include
#include
#include

Spline.h
Punto.h
Circulo.h
PosicionBomba.h
Misil.h

#define DELAY INICIAL 0.025 // delay a partir de t0 para tirar la 1ra bomba
#define PASO TIEMPO 0.05
#define TIEMPO MAXIMO CORRIDA 20
using namespace std;
class EscudoAntiMisiles {
public:
EscudoAntiMisiles();
25

EscudoAntiMisiles(string ruta);
void guardar(string ruta);
void mostrar();
int bombas;
int tiempos;
double radioBomba;
double radioTierra;
double tiempoInicial;
double tiempoFinal;
list<Misil> misiles ;
list<PosicionBomba> posicionesBombas;
timer timer total;
private:
double cuandoEntraEnRadio(Misil m, double radio, double t0=0, double paso=PASO TIEMPO);
};
#endif /* Escudo H*/

12.

EscudoMisiles.cpp

#include EscudoMisiles.h
#include imprimirLista.h
#define TIEMPO CRITICO 19.8
#define TIEMPO BUSQUEDA 10
EscudoAntiMisiles :: EscudoAntiMisiles() {}
void EscudoAntiMisiles :: mostrar() {
cout<<Cantidad de bombas: <<bombas<<endl;
cout<<Tiempos: << tiempos<<endl;
cout<<lista de misiles: <<endl;
for(list<Misil> :: iterator m = misiles.begin(); m != misiles.end(); m++) {
cout<<misil:<<endl;
m->spx.mostrar();
m->spy.mostrar();
}
}
EscudoAntiMisiles :: EscudoAntiMisiles(string ruta) {
timer total.start();
cout << Leyendo datos de radar...
cout.flush();
fstream f (ruta.c str());
assert(f.is open());
int mediciones, cantMisiles;
f>>cantMisiles;
f>>mediciones;

26

f.ignore( 1, 0 \n0 );
list<Misil> lista misiles;
for(int m =0; m < cantMisiles; m++) {
list<Punto> puntos x;
list<Punto> puntos y;
for(int t = 1; t < mediciones + 1; t++) {
double x, y;
f>>x;
f>>y;
puntos x.insert(puntos x.end(),Punto(t, x));
puntos y.insert(puntos y.end(),Punto(t, y));
}
f.ignore( 1, 0 \n0 ); //linea vacia
Spline* sx = new Spline(puntos x);
Spline* sy = new Spline(puntos y);
Misil* misi = new Misil(*sx, *sy);
lista misiles.insert(lista misiles.end(),*misi);
delete sx;
delete sy;
delete misi;
puntos x.clear();
puntos y.clear();
}
f>>this->bombas;
double radio tierra, radio bomba;
f>> radio bomba;
f>> radio tierra;
this->tiempos = mediciones;
this->misiles = lista misiles;
this->radioBomba = radio bomba;
this->radioTierra = radio tierra;
this->tiempoInicial = mediciones;
cout << OK!<< endl;

cout << Calculando tiempo total de simulacion...


;
cout.flush();
if(timer total.elapsed time() >= TIEMPO CRITICO){
cout<<Situacion critica<<endl;
return;
}
double radioPeligro = this->radioTierra + this->radioBomba;
double maxTiempo = tiempoInicial+DELAY INICIAL;
list<Misil> :: iterator m = (this->misiles).begin();
for(unsigned int i = 0; i < this->misiles.size(); i++) {
double aux = cuandoEntraEnRadio(*m, radioPeligro, this->tiempoInicial);

27

if( aux > maxTiempo) {


maxTiempo = aux;
}
if(timer total.elapsed time() >= TIEMPO CRITICO){
cout<<Situacion critica<<endl;
return;
}
m++;
}
if(timer total.elapsed time() >= TIEMPO CRITICO){
cout<<Situacion critica<<endl;
return;
}
this->tiempoFinal = maxTiempo;
cout << OK!<< endl;
}
double EscudoAntiMisiles ::cuandoEntraEnRadio(Misil m, double radio, double t0, double paso)
{
Punto p0 = m.posicion(t0);
Punto p = p0;
double t = t0;
Punto origen = Punto(0,0);
while(! (p.distancia(origen) <= radio) && t < TIEMPO BUSQUEDA) {
t += paso;
p = m.posicion(t);
}
return t;
}
void EscudoAntiMisiles :: guardar(string ruta) {
cout << Guardando posiciones calculadas...
cout.flush();

ofstream f(ruta.c str());


f << endl;
for(list<PosicionBomba> :: iterator b = posicionesBombas.begin(); b != posicionesBombas.end();
b++) {
f << b->tiempo << << b->punto.x << << b->punto.y << endl;
}
f << endl;
f.close();
cout << OK!<< endl;
}

13.

EscudoMisilesBruto.h (algoritmo greedy)

#ifndef Bruto H
#define Bruto H

28

#include
#include
#include
#include
#include

<list>
<iostream>
<cstdlib>
<math.h>
<assert.h>

#include
#include
#include
#include

Spline.h
Punto.h
Circulo.h
EscudoMisiles.h

class EscudoAntiMisilesBruto : public EscudoAntiMisiles {


public:
EscudoAntiMisilesBruto(string ruta): EscudoAntiMisiles(ruta) {};
void proponerSolucion();
private:
void solucionRapida();
Circulo mejorCirculo( double t,int& cuantosMata, int discretizacion=10 );
};
#endif /* Bruto H*/

14.

EscudoMisilesBruto.cpp

#include EscudoMisilesBruto.h
#define TIEMPO CRITICO 19.8
void EscudoAntiMisilesBruto :: proponerSolucion() {
if(timer total.elapsed time() >= TIEMPO CRITICO){
cout<<Solucion de emergencia<<endl;
solucionRapida();
return;
}
cout << Optimizando posiciones de las bombas...
cout.flush();
int totalMAtados=0;
list<PosicionBomba> bombas;
double t = this->tiempoInicial + DELAY INICIAL;
for(int i = 0; i < this->bombas; i++) {
Circulo mejor;
double tiempoMejor = 0;
int misilesQueAlcanza = 0;
while(t <= this->tiempoFinal) {
if(timer total.elapsed time() >= TIEMPO CRITICO){
cout<<Solucion de emergencia<<endl;
solucionRapida();
return;
}
if(misiles.empty()) {
29

// elijo un circulo arbitrario que no toque la tierra


mejor = Circulo(Punto(0, radioBomba + radioTierra + 1), radioBomba);
tiempoMejor = (this->tiempoInicial + this->tiempoFinal)/2;
misilesQueAlcanza = 0;
} else {
// tomo el mejor a partir del instante t
int cuantosAlcanza = 0;
Circulo candidato = mejorCirculo(t, cuantosAlcanza);
if(cuantosAlcanza > misilesQueAlcanza) {
mejor = candidato;
tiempoMejor = t;
misilesQueAlcanza = cuantosAlcanza;
}
}
t += PASO TIEMPO;
}
// guardo los misiles que no fueron alcanzados
list<Misil> aux;
for(list<Misil> :: iterator m = misiles.begin(); m != misiles.end(); m++) {
if(! mejor.pertenece(m->posicion(tiempoMejor))) {
aux.insert(aux.begin(),*m);
}
}
totalMAtados +=misilesQueAlcanza;
// los vuelvo a guardar en la lista de misiles para filtrarlos en la proxima iteracion
misiles.clear();
for(list<Misil> :: iterator m = aux.begin(); m != aux.end(); m++) {
misiles.insert(misiles.begin(),*m);
}
aux.clear();
bombas.insert(bombas.end(),PosicionBomba(tiempoMejor, mejor.centro));
t = this->tiempoInicial + DELAY INICIAL;
}
this->posicionesBombas.assign(bombas.begin(), bombas.end());
cout << OK!(hemos destruido <<totalMAtados<< misiles)<< endl;
}

// toma el circulo que mas misiles alcanza en el instante t, para todos los misiles disponibles
Circulo EscudoAntiMisilesBruto :: mejorCirculo(double t, int& cuantosMata, int discretizacion)
{
list<Punto> puntos;
for(list<Misil> :: iterator m = misiles.begin(); m != misiles.end(); m++) {
puntos.insert(puntos.begin(), m->posicion(t));
}
list<Punto> centrosPosibles;
for(list<Punto> :: iterator p = puntos.begin(); p != puntos.end(); p++) {
list<Punto>* aux = p->puntosLindantes(this->radioBomba, discretizacion);
centrosPosibles.insert(centrosPosibles.begin(), aux->begin(), aux->end());
delete aux;
}

30

list<Circulo> circulos;
for(list<Punto> :: iterator p = centrosPosibles.begin(); p != centrosPosibles.end(); p++)
{
circulos.insert(circulos.begin(), Circulo(*p, radioBomba));
}
Circulo mejor;
if(!circulos.empty()) {
mejor = circulos.front();
} else {
abort();
}
int cuantos = mejor.cuantosPertenecen(puntos);
for(list<Circulo> :: iterator c = circulos.begin(); c != circulos.end(); c++) {
int n = c->cuantosPertenecen(puntos);
Punto p = c->centro;
if(n > cuantos && (p.distancia(Punto(0,0)) > radioBomba+radioTierra)) {
mejor = *c;
cuantos = n ;
}
}
cuantosMata = cuantos;
return mejor;
}
void EscudoAntiMisilesBruto :: solucionRapida(){
for(int i = 0; i <bombas; i++){
Misil mis = misiles.front();
Circulo c(mis.posicion(tiempoInicial+DELAY INICIAL),radioBomba);
list<Misil> aux;
for(list<Misil> :: iterator m = misiles.begin(); m != misiles.end(); m++) {
if(! c.pertenece(m->posicion(tiempoInicial+DELAY INICIAL))) {
aux.insert(aux.begin(),*m);
}
}
PosicionBomba p(tiempoInicial+DELAY INICIAL, mis.posicion(tiempoInicial+DELAY INICIAL));
posicionesBombas.insert(posicionesBombas.begin(), p );
misiles.clear();
for(list<Misil> :: iterator m = aux.begin(); m != aux.end(); m++) {
misiles.insert(misiles.begin(),*m);
}
aux.clear();
}
}

31

15.

Genetico.py

Las clases escudo, misil, posicionBomba, Punto, Circulo que aparecen en el archivo, son iguales a sus
homonimas en C++ salvando las diferencias de sintaxis. Por cuestiones de espacio no se adjunta en este
apendice todo el c
odigo.
#!/usr/bin/python
# -*- coding: iso-8859-1 -*import sys, getopt
import psyco
psyco.full()
from escudo import *

class EscudoAntiMisilesGenetico(EscudoAntiMisiles):
TASA MORTALIDAD = 0.5
TASA MUTACION = 0.3
TAMANIO POBLACION = 40
PASO COORDENADA = 0.1
generacion = 1
poblacion = []
cuantosMueren = int(TAMANIO POBLACION * TASA MORTALIDAD)
cuantosMutan = int(TAMANIO POBLACION * TASA MUTACION)
def posicionAleatoria(self, indiv=[]):
tiempoAleat = random.sample(self.tiemposPosibles,1)[0]
misilAleat = random.sample(self.misiles,1)[0]
puntos = misilAleat.posicion(tiempoAleat).puntosLindantes(self.radioBomba, 10)
lugarAleat = random.sample(puntos, 1)[0]
return PosicionBomba(tiempoAleat,lugarAleat)
def mutar(self, individuo):
random.shuffle(individuo)
for i in range(self.MAXIMAS MUTACIONES):
individuo.pop()
for i in range(self.MAXIMAS MUTACIONES):
individuo.append(self. posicionAleatoria(individuo))
individuo.sort()
def aptitud(self, individuo):
misilesQueHay = self.misiles[:]
misilesQueQuedan = self.misiles[:]
indicesQueFueron = []
borrados = 0
min cuantosMata = len(self.misiles)

32

esHabil = 0
for b in individuo:
cuantosMata = 0
for i in range(len(misilesQueHay)):
if Circulo(b.punto,self.radioBomba).pertenece(misilesQueHay[i].posicion(b.tiempo)):
borrados += 1
cuantosMata += 1
indicesQueFueron.append(i)
misilesQueHay = [misilesQueHay[j] for j in range(len(misilesQueHay)) if not j in
indicesQueFueron]
esHabil += cuantosMata**2
if cuantosMata < min cuantosMata:
min cuantosMata = cuantosMata
indicesQueFueron = []
# penalizo fuertemente las bombas que no golpean nada (a menos que se consiga matar todos los
misiles)
penalidadPorInutil = 0
if borrados != len(self.misiles) and min cuantosMata == 0:
penalidadPorInutil = -30
# penalizo fuertemente las bombas que tocan la tierra
cero = Punto(0,0)
tocanLaTierra = 0
for b in individuo:
if b.punto.distancia(cero) <= self.radioTierra + self.radioBomba:
tocanLaTierra += 1
penalidadPorTocarLaTierra = tocanLaTierra * -50
# favorezco que cada bomba golpee una buena cantidad de misiles en lugar de solo uno
bonusPorGolpearMuchosMisiles = esHabil * 0.1
# favorezco que se elimine la mayor cantidad posibles de misiles
bonusPorEliminarMisiles = -(len(self.misiles) - borrados) * 2
return bonusPorEliminarMisiles + \
bonusPorGolpearMuchosMisiles + \
penalidadPorTocarLaTierra + \
penalidadPorInutil

def cruzar(self, padre, madre):


# tomo algunas bombas del padre y algunas de la madre
cuantos padre = random.sample(xrange(self.bombas + 1),1)[0]
if cuantos padre == self.bombas and self.bombas != 1 :
cuantos padre -=1
cuantos madre = self.bombas - cuantos padre
maxApto=ind = random.sample(padre, cuantos padre) + random.sample(madre, cuantos madre)
ind.sort()

33

for i in range(5):
aux = random.sample(padre, cuantos padre) + random.sample(madre, cuantos madre)
aux.sort()
if self. aptitud(ind) < self. aptitud(aux) :
ind = aux[:]
return ind
def cmpindividuos(self, a, b):
return cmp(self. aptitud(a), self. aptitud(b))
def avanzarGeneracion(self):
print Generacion %s: % self.generacion,
# mato a los menos aptos
self.poblacion.sort(self. cmpindividuos)
self.poblacion.reverse()
print max(aptitud) = %s % self. aptitud(self.poblacion[0])
for i in range(self.cuantosMueren):
self.poblacion.pop()
# cruzo
hijos = []
for i in range(self.cuantosMueren):
padre, madre = random.sample(self.poblacion, 2)
hijos.append(self. cruzar(padre, madre))
self.poblacion.extend(hijos)
# muto
for i in range(self.cuantosMutan):
self. mutar(self.poblacion[self.TAMANIO POBLACION -1 - i])
self.generacion += 1
def inicializarPoblacion(self):
self.MAXIMAS MUTACIONES = self.bombas
# genero los posibles tiempos
self.tiemposPosibles = []
t = self.tiempoInicial + DELAY INICIAL
while(t <= self.tiempoFinal):
self.tiemposPosibles.append(t)
t += PASO TIEMPO

# genero la poblacion inicial


for i in range(self.TAMANIO POBLACION):
ind = []
for p in range(self.bombas):
pos = self. posicionAleatoria()
ind.append(pos)
ind.sort()

34

self.poblacion.append(ind)

def proponerSolucion(self):
self. inicializarPoblacion()
machoAlfa = self.poblacion[0]
t = time.time()+ TIEMPO MAXIMO CORRIDA - 1
while (time.time() < t):
f = self. avanzarGeneracion()
self.poblacion.sort(self. cmpindividuos)
self.poblacion.reverse()
machoAlfa = self.poblacion[0]
self.posicionesBombas = self.poblacion[0]

def usage():
print Uso: python genetico.py --input=<archivoDeEntrada> --output=<archivoDeSalida>
def main():
try:
opts, args = getopt.getopt(sys.argv[1:], :, [help, output=, input=])
except getopt.GetoptError:
# print help information and exit:
usage()
sys.exit(2)
input = None
output = None
for o, a in opts:
if o == --help:
usage()
sys.exit()
elif o == --output:
output = a
elif o == --input:
input = a
if output is None or input is None:
print Debe especificar un archivo de entrada y uno de salida!
usage()
sys.exit(1)
#try:
e = EscudoAntiMisilesGenetico(input)
#except:
#
print El archivo de entrada no es correcto!
# sys.exit(1)
e.proponerSolucion()
try:
e.guardar(output)
except:

35

print No se pudo guardar la salida del programa!


sys.exit(1)
sys.exit(0)
if

name ==
main()

main

36

Parte VIII

Referencias
Bibliografa
[1] Kincaid, David - Cheney, Ward An
alisis numerico : las matematicas del calculo cientfico Wilmington,
DE : Addison Wesley Iberoamericana, c1994
[2] Richard L. Burden, J. Douglas Faires Analisis Numerico Grupo Editorial Iberoamerica
[3] http://es.wikipedia.org/wiki/Spline
http://en.wikipedia.org/wiki/Greedy_algorithm
http://en.wikipedia.org/wiki/Genetic_algorithm
[4] Tambien estuvimos en contacto con otros grupos durante los das que trabajamos en los laboratorios de
la facultad. As, estuvimos en contacto con los grupos de:
Marta Ponzoni, Victoria Elizalde, Santiago Avenda
no;
Martn Page, Martn Fernandez, Gonzalo Castillo;
Sergio Gonz
alez, Emiliano Gonz
alez,
Gaston Krasny, Jonathan Tapicer
Matias Grunberg, Pablo Rozanski
con quienes compartimos los laboratorios y con otras inquietudes propias de los resultados de las experiencias.

37

S-ar putea să vă placă și