Está en la página 1de 94

PARALELIZACIN DE UNA APLICACIN DE REGISTRO NO LINEAL DE IMGENES MDICAS

Proyecto de Investigacin I, II Divisin de Ciencias Bsicas e Ingeniera Universidad Autnoma Metropolitana Iztapalapa

Licenciatura en Computacin

Por Mara de la Luz Zamora Venegas Asesoras Dra. Graciela Romn Alonso Dra. Norma Pilar Castellanos Abrego Trimestre 04-P

Este proyecto fue desarrollado en el marco del proyecto CONACYT 342330-A Infraestructura para la construccin de aplicaciones fuertemente distribuidas

PARALELIZACIN DE UNA APLICACIN DE REGISTRO NO LINEAL DE IMGENES MDICAS

Mara de la Luz Zamora Venegas

Asesoras:

Dra. Graciela Romn Alonso

Dra. Norma Pilar Castellanos Abrego

Agradecimientos.
Agradezco a Pap y Mam por haberme regalado la vida, y por haberme apoyado en el transcurso de mis estudios, asimismo a mis queridos hermanos y adorados amigos por no ayudarme en cuanto pudieron y tambin cuando lo hicieron. A la Dra. Graciela Romn Alonso por convertir en realidad uno de mis ms preciados sueos, a la Dra. Norma Pilar Castellanos Abrego por participar en ello, gracias por su tiempo, sus consejos, su paciencia, por tomarme de la mano para caminar juntas. Al Ing. Juan Carlos Rosas Cabrera responsable del Laboratorio de Sper computo y visualizacin en paralelo, y de los Laboratorios de Docencia de CBI por los recursos proporcionados para la realizacin de este trabajo, gracias porque que tus palabras fueron precisas y en el momento indicado. Al Dr. Enrique Daz Herrera y Jos Antonio Moreno Razo gracias por su apoyo, su paciencia y dedicacin hacia mi, porque ellos tambin conocen eso que se llama pasin.

POR SU CONFIANZA, A TODOS

GRACIAS

Dedico este Proyecto de Investigacin a Abel Carrasco Hernndez

Tipografa.

En este documento los ttulos y subttulos son de color azul oscuro, en la parte del pseudocodigo las palabras reservadas estn en color azul plido y negritas ,las palabras reservadas de MPI se encuentran en rojo oscuro.

Tabla de Contenidos

1. Introduccin 1.1 Objetivos 1.2 Introduccin 1.3 Antecedentes 2. Algoritmos Genticos Paralelos 2.1 Algortimos Genticos 2.2 Algoritmos Genticos Paralelos 2.3 Estrategias de Paralelizacin. 3. Alineacin no rgida de imgenes mdicas utilizando Algoritmos Genticos Paralelos 3.1 Paralelizacin del Algoritmo Gentico 3.1.1 Estrategia distribuida modificada 3.1.2 Estrategia distribuida modificada con segmentacin (divisin) de imagen 3.1.2.1 Anlisis del Algoritmo Gentico Paralelo segunda estrategia 4. Resultados 4.1 Algoritmo Gentico Secuencial Algoritmo Gentico Paralelo (estrategia 1). 4.2 Algoritmo Gentico Paralelo (estrategia 2) 4.3 Comparacin entre los algoritmos. 5. Conclusiones. 6. Bibliografa. 7. Anexo A Cdigo fuente en C - MPI para el Algoritmo Gentico Paralelo (estrategia 1) aplicado en la alineacin no rgida de imgenes mdicas 8. Anexo B Ampliacin del Cdigo fuente en C - MPI para el Algoritmo Gentico Paralelo (estrategia 2) aplicado en la alineacin no rgida de imgenes mdicas 9. Anexo C Manual de usuario

8 8 8 10 10 10 12 13 13 26 36 36 40 43 45 47 49 82 91

INTRODUCCION

1. Introduccin 1.1 Objetivos . Implementar un Algoritmo Gentico Paralelo de una aplicacin de registro no lineal de imgenes mdicas. Codificar la implementacin en la librera MPI (Message Passing Interface) de Lenguaje ANSI C. Evaluar el Algoritmo Gentico Paralelo.

1.2 Introduccin El diagnostico de algunas enfermedades se apoya en la informacin que se extrae de las imgenes como Rayos X (Rx), Tomografa Computada (TC), Ultrasonido (US), Resonancia Magntica (RM), Tomografa por Emisin Positron (PET) y Tomografa por emisin de fotn nico (SPECT) medio de radiografas, tomografas, resonancia magntica etc., estas imgenes pueden sufrir distorsiones causadas por el movimiento durante la toma o por el volumen de inspiracin o expiracin donde se presentan deformacin en los tejidos, una tcnica para corregir estas distorsiones en las imgenes mdicas es la Alineacin no rgida de Imgenes Mdicas [ 3]. Este tipo de tecnicas aaden ms grados de libertad que aumentan la dimension del espacio de bsqueda y la complejidad para encontrar los parmetros globales ptimos del modelo de transformacin no lineal. Los algoritmos para la alineacin no rgida de imgenes mdicas requieren alta capacidad en los equipos de computo (hardware), en equipos de computo covencionales (PCs) el tiempo de ejecucin de estos algoritmos es muy grande. La importancia de la infomacin que proporcionan las imgenes mdicas se debe tener en el menor tiempo posible y sugiere la mejora de los algoritmos para disminuir el tiempo de ejecucin. 1.3 Antecedentes En la Universidad Autnoma Metropolitana Iztapalapa, se desarroll una aplicacin para el procesamiento de imgenes mdicas especficamente para la Alineacin no rgida de Imgenes Mdicas, esta aplicacin consiste de una Algoritmo Gentico Secuencial codificado en Matlab, en la cual se observa el requerimiento del uso del procesador de aproximadamente el 90% durante el tiempo de ejecucin que es mayor a 5 horas [3]. En busca de la reduccin del poder de cmputo requerido para esta aplicacin se migro el cdigo fuente de Matlab a Lenguaje ANSI C [1] ejecutndose en el sistema operativo Linux, obteniendo como resultados alta demanda en el uso del procesador y la disminucin considerable en el tiempo de ejecucin.

El presente trabajo parte de la aplicacin implementada en Lenguaje ANSI C, se analizan las estrategias de paralelizacin de los Algoritmos Genticos (AG), y se hacen ajustes a la aplicacin, enseguida explica la implementacin en paralelo para que finalmente, en los resultados observar los beneficios de la programacin en paralelo.

ALGORITMOS GENETICOS PARALELOS

2. Algoritmos Genticos Paralelos. 2.1 Algoritmos Genticos. Los Algoritmos Genticos, tienen sus races en la biologa, surgen al imitar el mecanismo de evolucin de los seres vivos, siguiendo la teora propuesta por Carlos Darwin (1859). Las poblaciones evolucionan en la naturaleza de acuerdo con los principios de seleccin natural y supervivencia de los ms fuertes. Estos Algoritmos son utilizados en problemas de bsqueda y optimizacin. En los algoritmos genticos se busca la solucin a un problema, primero se crea una poblacin inicial de soluciones (coleccin de individuos), se evala utilizando un criterio especifico para obtener la aptitud, se elige una subpoblacin eligiendo a los individuos mas aptos, de esta subpoblacin se elige la generacin prxima siendo sometida a cruzamiento y mutacin.[1] Los pasos de un Algoritmo Gentico General son [2]: 1. 2. 3. 4. 5. 6. 7. Fijar el tamao de la poblacin Iniciar la poblacin Evaluar la poblacin Seleccionar los individuos para la siguiente generacin Cruzar Mutar Confrontar la condicin de termino

2.2 Algoritmos Genticos Paralelos. El adaptar un Algoritmo Gentico, a un conjunto de procesadores, sugiere dos enfoques para hacerlo: Cada procesador opera independientemente con una poblacin aislada de individuos, compartiendo peridicamente el mejor individuo, con los otros procesadores mediante el operador de migracin. A estos algoritmos se las llama algoritmos de grano grueso. Cada procesador resuelve una parte del algoritmo - seleccin, cruzamiento y mutacin -, en la poblacin comn. Subpoblaciones aisladas.En este enfoque, cada procesador acta sobre su propia subpoblacin inicial, en la cual debe de seguir los pasos de un algoritmo Gentico simple, resaltando: Evaluar la Aptitud Seleccionar los individuos para generar la prxima generacin. Hacer los clculos de cruzamiento y mutacin. Luego de k ( k = 1 )generaciones cada procesador comparte su mejor individuo con los otros procesadores. Operador de Migracin. Debido a que se incorpora el operador de migracin, los cambios en la poblacin no proceden slo del cruzamiento y la mutacin, tambin interviene la introduccin de nuevas especies. El operador de migracin es responsable de realizar diversas tareas, que son necesarias para realizar el intercambio de individuos. Seleccionar los emigrantes Enviar los emigrantes Recibir los Inmigrantes

10

Integrar los Inmigrantes El envo y recepcin de mensajes es fcil dentro de un entorno de paso de mensajes, pero las fases de seleccin e integracin pueden causar que le algoritmo converja ms rpido, si esto se hace en forma correcta. Podemos pensar que enviar los mejores individuos a otra subpoblacin en la que se descartaran los peores individuos, es una buena estrategia, notemos que no es as porque esto puede ocasionar alcanzar un ptimo local y no un ptimo global. La tarea de introducir migracin de individuos, produce sobrecarga en la red de comunicacin, lo que indica que se debe considerar la frecuencia y el volumen de la informacin que se va a comunicar (enviar de un procesador a otro), para evitar que la comunicacin domine a la computacin. Modelos de Migracin. Los Enfoques de migracin mas conocidos son: Modelo de la Isla. En este modelo se permite enviar individuos a cualquier subpoblacin.

Subpoblacin Ruta de migracin; cada isla enva a las dems islas.

Modelo de la pasarela o trampoln (stepping model). Aqu la poblacin esta limitada, ya que solo se permite que los emigrantes se desplacen a las subpoblaciones vecinas. Subpoblacin

Ruta de migracin Los dos modelos tienen la ventaja de ser altamente paralelos. Esto es usando p procesadores cada uno de ellos operando independientemente sobre [tamao_de_la_poblacin/p] subpoblaciones, se podra aumentar el coeficiente de aceleracin ([tiempo de ejecucin secuencial]/ [tiempo de ejecucin en paralelo]) en el clculo de k generaciones por un factor de p. El aumento en la velocidad del calculo, es menor a lo mencionado, ya que se debe tomar enguanta el envo de los mejores individuos, desde este punto de vista el modelo stepping stone es mejor porque reduce las comunicaciones, pero ambos modelos tienen las desventajas de que el relativo aislamiento de las subpoblaciones conducira a alcanzar un ptimo local, y el reducido numero de individuos en cada subpoblacin incrementa el numero de generaciones para alcanzar la convergencia. Paralelizar una poblacin comn. Una alternativa de paralelizar subpoblaciones aisladas, es paralelizar la poblacin, en donde se implementan los operadores geneticos (seleccin, cruce y

11

mutacin) en paralelo y cada procesador podran trabajar independientemente en un subconjunto de los individuos seleccionados para desarrollar las operaciones, notemos que la comunicacin restringe la mejora que se alcanza en el paralelismo. Implementacin hbrida. Se pueden combinar las estrategias de subpoblaciones aisladas y poblacin nica, siguiendo una escala: Los niveles bajos de los algoritmos genticos paralelos consisten e n algoritmos de grado fino, que manipulan subpoblaciones, y los en los niveles altos se implementan algoritmos de grano grueso que distribuye las subpoblaciones a los niveles bajos e inspecciona la migracin. 2.3 Estrategias de Paralelizacin. A continuacin se mencionan cuatro estrategias comunes de paralelizacin. Existe un proceso al que denominaremos maestro ( proceso maestro) quien es el controlar el algoritmo gentico, y los otros procesos se llamaran esclavos. comisionado de

Centralizada. El maestro enva algunos individuos a los procesadores esclavos, los cuales ejecutan un nmero conocido de generaciones y envan los resultados obtenidos al proceso maestro, que despus de recibir los resultados, ejecuta el algoritmo de cruzamiento para toda la poblacin. Semi-distribuida. Consiste en clusters de procesadores que ejecutan el mtodo centralizado e intercambian soluciones entre ellos. Distribuida. Se implementan algoritmos de grano grueso tradicional, cada procesador tiene su propia subpoblacin y hacen el intercambio de los mejores individuos cada periodo definido. Totalmente-distribuida. Se aplica el mtodo distribuido sin algn intercambio de individuos, cada procesador ejecuta el algoritmo gentico en forma secuencial, sobre su subpoblacin. No existe comunicacin entre los procesos.

12

ALINEACION NO RIGIDA DE IMGENES MEDICAS UTILIZANDO ALGORITMOS GENETICOS PARALELOS

13

3. Alineacin no rgida de imgenes mdicas utilizando Algoritmos Genticos Paralelos En esta seccin se implementa la paralelizacin del AG Secuencial, propuesto como solucin para mejorar la calidad en la alineacin de mdicas [3]. El punto de partida es el algoritmo Gentico secuencial, que fue implementado en Lenguaje ANSI C [2]. En el que se busca alinear una imagen (fuente) a otra (objetivo), aplicando una transformacin a las posibles soluciones con el objetivo de encontrar la mejor solucin (el mejor individuo) para el alineamiento.

Algoritmo gentico

T(X)
Imagen fuente Imagen destino

Se busca X (el mejor individuo)

El AG secuencial tiene la siguiente estructura: Plantamos la semilla para la cuenta del tiempo. Inicializamos la cuenta del tiempo. Leemos desde el teclado el tamao de la poblacin, el nmero de niveles de gris con lo que desea trabajar el usuario, el tamao de las imgenes y el nombre de las imgenes fuente y objetivo. Abrir los archivos que tienen las imgenes fuente y objetivo. Inicializar la poblacin. Pedir memoria para cada una de las variables que necesitaremos. Normalizar la matriz objetivo. Inicializar las generaciones y el contador de paro del algoritmo gentico. Evaluar la poblacin. Buscar y guardar el mejor individuo de la poblacin. El mejor individuo de la poblacin es guardado en una variable que llamamos Mejor_Global. Si el mejor individuo de esta generacin es mejor que el Mejor_Global, copiar el mejor de esta generacin en el Mejor_Global, en caso contrario se copia el Mejor_Gobal en la poblacin y se incrementa el contador de paro del algoritmo gentico. Verificamos si hay que mutar, si hay que mutar lo hacemos. Reproducimos la poblacin. Incrementamos el contador de las generaciones en 1. Repetimos del paso 9 hasta el paso 14 hasta que se cumpla la condicin de paro del algoritmo.

La condicin de termino en el Algoritmo Gentico secuencial, es generaciones el individuo no mejora.

detenerse si despus de 15

14

3.1 Paralelizacin del Algoritmo Gentico. 3.1.1 Estrategia distribuida modificada.

Esta estrategia es similar a la estrategia distribuida, pero se hace la siguiente modificacin. Hay envo de parmetros e individuos entre el proceso maestro y procesos esclavos, pero no se permite la comunicacin entre procesos esclavos. Subpoblacin

Ruta de migracin; cada isla enva solo a la isla maestra, y en direccin contraria.

A continuacin de especifican en trminos generales las funciones de este modelo.

5,6,9,10

2,7,8 2,7,8 4

3,9,10

2,7,8

2,7,8 4 3,9,10

4 3,9,10

4 3,9,10

1. El proceso maestro recibe, los parmetros para necesarios, para la ejecucin del Algoritmo Gentico (AG). 2. El proceso maestro enva los parmetros a los procesos esclavos, y los procesos esclavos los reciben. 3. Todos los procesos (incluido el maestro), 3.1 Inicializan la subpoblacin. 3.2 Evalan la poblacin, hasta el punto de buscar el mejor individuo de cada subpoblacin. 4. Los procesos esclavos envan el mejor individuo al proceso maestro. 5. El proceso maestro busca el mejor individuo de toda la poblacin, dentro de los mejores individuos que recibi de cada una de las subpoblaciones. 6. El proceso maestro actualiza el contador del mejor individuo global. 7. El proceso maestro enva el mejor individuo global (MIG) a los procesos esclavos. Los procesos esclavos lo reciben. 8. El proceso maestro, enva una copia del contador global a los procesos esclavos. Los procesos esclavos lo reciben. 9. Todos los procesos (incluido el maestro) aplican el operador de Mutacin

15

10. Todos los procesos (incluido el maestro) Reproducen la poblacin. Para la Reproduccin en cada subpoblacin se debe considerar el MIG. 11. Se repiten los pasos 3.2 a 10, mientras no se cumpla la condicin de terminacin en el AG. La condicin de trmino en esta versin paralela del Algoritmo Gentico es detenerse hasta que el MIG, se haya repetido un nmero determinado de veces. A continuacin se detalla la implementacin del AGP, siguiendo el modelo anterior. Recordemos que las imgenes se guardan en matrices de tipo entero, debido a los niveles de gris que son representados por nmeros en un rango de 0 a 255. Las imgenes (fuente - destino) que se va a procesar se guarda en una lista unitaria. Tiene una cabeza en donde se lleva tamao de la lista, y un nodo donde se guardan las coordenadas iniciales de las imgenes, las imgenes, el tamao de ellas y un apuntador a nodo. Grficamente la cabeza de la lista se ve como sigue: entero tama; nodo * first; Cabeza de la lista. En la variable tama, se lleva el tamao de la lista.

El nodo se ve de la siguiente forma:

Inicio Imagen_fuente

x , y
a11 a12 a 22 a21 M A = M an1,1 a n1,2 an1 an 2 a13 a23 K K a1n a2 n M an1, n ann

M an 1, 3 L an3 K

Imagen destino

a11 a12 b22 a 21 B = M M a n1,1 bn1, 2 an 2 a n1

a13

b23 K M bn 1,3 L an 3 K

a1n a2n M an 1, n ann

Tamao siguiente

Para implementar el AGP se utilizaron las funciones diseadas la implementacin del AG secuencial, y se disearon otras funciones y procedimientos que a continuacin se detallan, suponiendo que se tienen k (k>2) procesos, el proceso maestro es el proceso 0, y los procesos esclavos son los k siguientes. Las funciones para enviar y recibir los mensajes, se tomaron de la librera MPI (Message Passing Interface) para Lenguaje ANSI C [4].

16

Diseo de la funcin creanodom, esta funcin crea un nodo, en donde se van a guardar las imgenes de recibe dos apuntadores tipo entero, con la direccin de las imgenes fuente y destino respectivamente, un vector de coordenadas, correspondientes a las coordenadas en donde comienzan estas imgenes, tam de tipo entero, que es el tamao de las imgenes, y regresan, un apuntador a nodo con toda esta informacin.
nodo *creanodom(entero ** fuente, entero **destino,entero coor[2],entero tam) comienza nodo *nnuevo; nnuevo=(nodo *)calloc(1,sizeof(nodo)); si (nnuevo!=NULL) entonces comienza nnuevo->inicia[0]=coor[0]; nnuevo->inicia[1]=coor[1] ; nnuevo->pfuente=fuente; nnuevo->pdestino=destino; nnuevo->tam=tam; nnuevo->sigte=NULL; termina otro comienza escribe (Error de memoria); termina regresa(nnuevo); termina

Los nodos en donde se guardan las imgenes deben permanecer en una lista ligada, como se menciono antes, para eso utilizamos el procedimiento insertanodo, recibe como parmetros la lista en la cual se va a insertar un nodo, y el nodo que se va a insertar.
nada insertanodo(lista *l,nodo *n) comienza nodo *auxn; si (l->first==NULL) entonces comienza l->first=n; l->tama = UNO; termina otro comienza auxn=l->first; mientras (auxn->sigte != NULL) haz auxn = auxn->sigte; (auxn->sigte) = n; l->tama =l-> tama +1 termina termina

Al terminar la ejecucin del AGP se debe liberar memoria, lo que lleva a eliminar nodos en la lista donde se hospedan, con el procedimiento eliminanodo se logra hacer esto. Este procedimiento recibe como parmetro la lista en donde se va a eliminar un nodo.
nada eliminanodo(lista *l)

17

comienza nodo* aux; si (!esvacia(*l)) entonces comienza aux=l->first; l->first=aux->sigte; l->tama= l-> tam - 1 ; aux->pfuente=libera(aux->pfuente,aux->tam); aux->pdestino=libera(aux->pdestino,aux->tam); free(aux); comienza otro comienza escribe ("error la lista esta vacia"); exit(1); termina termina

En el procedimiento eliminanodo, se hace una llamada a la funcin esvacia, la que tiene como fin indicar si la lista que recibe como parmetro es vaca, y regresa un entero con valor 1, si la lista es vaca o valor 0, si no lo es.
entero esvacia(lista l) comienza entero x; si (l.first==NULL)entonces x=1; otro x=0; regresa(x); termina

Para inicializar los datos se utiliza el procedimiento inicializa datos que es el encargado de solicitar los datos al usuario, recibe como parmetros cuatro apuntadores de tipo entero que corresponden al numero de niveles de gris, el tamao de la imagen, el tamao de la poblacin y el nmero de procesos.
nada inicializa_datos(entero*ngris, entero *ntam,entero *npob,entero nproc) comienza escribe ("Proporciona los siguientes datos"); escribe ("Niveles de gris"); lee (ngris); escribe ("Orden de la matriz); lee (ntam); escribe ("Tamao de la poblacin); lee (npob); (*npob)=(*npob)/nproc; //se divide la poblacin total entre los procesos
termina

Las imgenes se guardan en una lista para esto se diseo el procedimiento inicializa_lista, recibe los siguientes parmetros; un apuntador tipo lista, dos enteros, el tamao de la imagen y el numero de niveles de gris, dos arreglos de tipo carcter para obtener nombres de archivos y un apuntador a entero para tomar el mayor nivel de gris en la imagen.

18

nada inicializa_lista(lista *mayorng) comienza

*l, entero tam,entero nivel, caracter

imagen[],caracter

imagen_r[],entero

FILE * fuente; FILE *objetivo; entero origen[DOS]; entero **mf,**mo,**mon; nodo *nodoi; origen[CERO]=origen[UNO]=0; levanta_imagenes(&mf,&mo,tam,imagen,imagen_r); (*mayorng)=Mayor_TGris(mo,tam); mon=crea_matriz(tam); Normalizar(mo,mon,tam,*mayorng,nivel); l->first=NULL; nodoi=creanodom(mf,mon,origen,tam); insertanodo(l,nodoi); mf=NULL; mon=NULL; mo=libera(mo,tam); termina

En el procedimiento inicializa_lista, se hace una llamada al procedimiento levanta_imagenes que tiene la finalidad de subir a dos matrices (imagen fuente, imagen destino) los bits correspondientes a las imgenes (que se encuentran en formato crudo), recibe como parmetros dos apuntadores triples en donde se van a colocar las matrices, un arreglo tipo carcter qu corresponde al nombre del archivo en que se va a guardar la matriz obtenida cuando termine la ejecucin del AGP, y otro arreglo tipo carcter que es el nombre donde se guardan datos para que se pueda reproducir este procesamiento en Matlab.
nada levanta_imagenes(entero ***mf,entero ***mo,entero tam,carcter imagen[30],caracter imagen_r[30]) comienza caracter nomfte[30],nomobj[30]; escribe ("Nombre de la imagen fuente); lee ("nomfte); escribe ("Nombre de la imagen objetivo); lee (nomobj); escribe ("Nombre de la imagen de salida); lee (imagen); concatena (imagen_r,imagen); concatena (imagen_r,"r.txt"); Abre(nomfte,nomobj,mf,mo,tam); termina

Para iniciar la ejecucin del AGP de deben tener las imgenes para lograr esto se diseo el procedimiento asigna_memoriap, que recibe como parmetros dos apuntadores triples de tipo entero donde se va a guardar la imagen fuente y a la imagen fuente transformada respectivamente, recibe tambin dos apuntadores tipo real de doble precisin que son para la creacin de histogramas de acuerdo a los niveles de gris que se hayan requerido, el tamao de la imagen y el nmero de niveles de gris.
nada asigna_memoriap(entero ***mft, entero ***mftn,real_doble **f,double **ft,entero tam,entero niveles) comienza *mft=crea_matriz(tam); *mftn=crea_matriz(tam); *f=Crea_Histograma(niveles+1); *ft=Crea_Histograma(niveles+1); termina

19

El procedimiento geneticop recibe parmetros y se hace una llamada a l en el procedimiento envos. Recibe como parmetros dos apuntadores dobles de tipo entero mf y mon, en donde vienen las imgenes fuente y objetivo respectivamente, notemos que la imagen objetivo llega normalizada a este procedimiento, llegan tambin cuatro variables de tipo entero; niveles, tam_mat, mi_id, y nproc que corresponden a el numero de niveles de gris, el tamao de tamao de la imagen, el identificador de proceso y el numero de procesadores que participan en la ejecucin del AGP respectivamente, asimismo recibe un arreglo de tipo real doble precisin en donde se va a guardar el MIG, que se obtuvo al procesar esa imagen y finalmente una variable tipo MPI_Comm [4], que corresponde al comunicador por el cual se van a enviar algunos mensajes entre los procesos.
nada geneticop(entero **mf,entero **mon,entero tam_pob,entero niveles, entero tam_mat,real_doble mejorg[SEIS], entero mi_id, entero nproc, MPI_Comm komm, FILE **repro_p) comienza real_doble mejor[TAMIND]; real_doble mi_mejor[TAMIND]; entero i; entero cg=0; entero maestro=0; real_doble todos[90]; entero **mft=NULL,**mftn=NULL; real_doble *f=NULL,*ft=NULL; real_doble **pob_c=NULL,**pob=NULL; asigna_memoriap(&mft,&mftn,&f,&ft,tam_mat,niveles); pob=Inicializa(tam_pob,tam_mat,1); pob_c=crea_matriz_P(tam_pob); para i=0 hasta SEIS haz mi_mejor[i]=0.0 mientras (cg<REPMAX) comienza Evaluacion_Total(tam_pob,tam_mat,pob,mon,mf,mft,mftn,niveles,f,ft); Mejor(mejor,pob,tam_pob MPI_Gather(mejor,SEIS,MPI_DOUBLE,todos,SEIS,MPI_DOUBLE,maestro,MPI_COMM_WORLD ); si (mi_id==0) entonces comienza busca_mejor(mejor,todos,nproc); actualiza_mejor_cont(mi_mejor,mejor,&cg); copia_mejorp(mi_mejor,mejorg); escribe_en_archivo(*repro_p,mejor[CERO],mejor[UNO],mejor[DOS],mejor[TRES],mejor[ CUATRO],mejor[CINCO]); termina MPI_Bcast(mejor,SEIS,MPI_DOUBLE,maestro,MPI_COMM_WORLD); MPI_Bcast(&cg,1,MPI_INT,maestro,komm); para i=0 hasta tam_pob haz Copia(pob_c[i],pob[i]); si (Velocidad_Mutacion(cg)) entonces pob_c=Mutacion(pob_c,tam_pob,tam_mat); Reproduccion_Total(tam_pob,pob,niveles,pob_c,tam_mat,mejor);

20

termina mft=libera(mft,tam_mat); mftn=libera(mftn,tam_mat); liberad(pob_c,tam_pob); liberad(pob,tam_pob); termina

En el AGP se menciona que el proceso maestro recibe los mejores de los procesos esclavos, aqu se utiliza la funcin MPI_Ghater de MPI.
MPI_Gather(mejor,SEIS,MPI_DOUBLE,todos,SEIS,MPI_DOUBLE,maestro,MPI_COMM_WORLD ); [4]

En esta funcin, el mejor individuo de todos los procesos se deposita en la variable todos del proceso maestro, grficamente se percibe de la siguiente forma: Ind. Mejor Proceso 0 Ind. Mejor Proceso 1 Ind. Mejor Proceso 2 Ind. Mejor Proceso 3

***

Ind. Mejor Proceso k

Enseguida el proceso maestro busca el mejor individuo de todos los que llegaron a l. Ind. Mejor Proceso 0 Ind. Mejor Proceso 1 Ind. Mejor Proceso 2 Ind. Mejor Proceso 3

***

Ind. Mejor Proceso k

Quin es el mejor?

Para esto se diseo el procedimiento busca_mejor. Se reciben como parmetros dos apuntadores de tipo real de doble precisin, uno es mejor en donde se guarda el MIG, y todos, que guarda todos los mejores individuos llegaron al proceso maestro, este procedimiento recibe tambin nproc, que es el numero de procesos que se levantan al ejecutar el AGP.
nada busca_mejor (real_doble *mejor,real_doble * todos, entero nproc) comienza entero i,j,indice; real_doble valor; valor=todos[CINCO]; indice=CINCO; para i=11 hasta SEIS*nproc comienza si todos[i] > valor comienza valor=todos[i]; indice=i; i=i+SEIS;

21

i=0;

termina para j=indice-CINCO hasta j=indice+1 comienza mejor[i]=todos[j]; j=j+1; termina

termina

Luego de que el maestro tiene el mejor individuo global (MIG) de la generacin L, lo debe comparar con el MIG de la generacin L-1 para verificar si las aptitudes son iguales, o la aptitud del MIG de la generacin L-1 es igual al de la generacin L con el fin de actualizar el contador del MIG, que es la condicin de trmino del AGP.

Aptitud MIG generacin L

>

Aptitud MIG generacin L-1

Contador MIG = 1

Aptitud MIG generacin L

Aptitud MIG generacin L-1

Contador MIG = Contador MIG +1

Estos requerimientos se implementan en el procedimiento actualiza_mejor_cont, que recibe como parmetros dos apuntadores mlocal que corresponde al mejor individuo de la generacin L-1, mglobal que es el mejor individuo de la generacin L, recibe tambin el apuntador tipo entero contglobal, es donde se lleva la cuenta de las repeticiones del MIG.
nada actualiza_mejor_cont( real_doble* mlocal, real_doble *mglobal, entero *contglobal) comienza entero i; si (mglobal[CINCO] > mlocal[CINCO]) entonces comienza para i= hasta SEIS mlocal[i]=mglobal[i]; *contglobal=1; termina otro comienza para i= hasta SEIS mglobal[i]=mlocal[i]; *contglobal=*contglobal+1; termina termina

Para conocer el MIG despus de ejecutar el AG se diseo el procedimiento copia_mejorp, que recibe como parmetros dos arreglos de tipo real de doble precisin.

22

nada copia_mejorp(real_doble mi_mejor[SEIS],real_doble mejor2[SEIS]) comienza entero i; para i=0 hasta SEIS haz mejor2[i]=mi_mejor[i]; termina

Despus de hacer procesado la imagen fuente se debe evaluar la nueva imagen tomando como referencia la matriz objetivo, esto se hace con la funcin eval_final_p la cual recibe como parmetros un entero que es el tamao de la matriz, dos apuntadores dobles tipo entero que donde se encuentran las imgenes fuente (ya procesada) la imagen objetivo, y el nmero de niveles de gris. Se regresa un real de doble precisin, con la evaluacin de la imagen.

real_doble eval_final_p(entero tam_mat,entero ** mfinal,entero **mon,entero niveles) comienza entero mayor; real_doble **mpc=NULL; real_doble *f=NULL,*ft=NULL; real_doble devuelto; f=Crea_Histograma(niveles+1); ft=Crea_Histograma(niveles+1); mpc=ProConjunta(mon,mfinal,tam_mat,niveles); Frec_F(mpc,niveles,f); Frec_FT(mpc,niveles,ft); devuelto=Costo(f,ft,mpc,niveles,tam_mat); liberad(mpc,niveles+1); free(f); free(ft); regresa (devuelto); termina

Todos los procesos deben conocer el MIG y el valor del contador del MIG, para que puedan detener la ejecucin del algoritmo de forma sincronizada. Para lograr esto se utiliza la funcin MPI_Bcast de MPI [4], la sintaxis es la siguiente:
MPI_Bcast(mejor,SEIS,MPI_DOUBLE,maestro,MPI_COMM_WORLD );. Para MPI_Bcast(&cg,1,MPI_INT,maestro,komm);. Para

que todos tomen el MIG.

que todos tomen el valor del contador del MIG.

23

Proceso 0 MIG Contador MIG

Proceso 0 MIG Contador MIG

Proceso 1 MIG Contador MIG

Proceso 2 MIG Contador MIG

Proceso 3 MIG Contador MIG

***

Proceso k MIG Contador MIG

En los AG, se deben aplicar los operadores de mutacin y reproduccin, para implementar el segundo operador en el AG secuencial se diseo el procedimiento Reproduccin_Total, que fue modificada para la versin paralela, veamos los dos procedimientos para apreciar la modificacin y explicar el motivo de haberla hecho. Procedimiento Reproduccin_Total Orginal.
nada Reproduccion_Total(entero Tam_Pob, real **Ap_Pob, real **Ap_Pob_C, entero Tam_Mat) comienza entero i,res; real_doble Ap_Mej[SEIS]; entero Indice=0; Mejor(Ap_Mej,Ap_Pob_C,Tam_Pob,&Indice); para i=0 hasta i<Tam_Pob comienza Reproduccion(Ap_Pob_C[i],Ap_Mej); termina para i=0 hasta i<Tam_Pob comienza res=Restriccion(Ap_Pob_C[i],1,Tam_Mat); si (res==1) entonces Copia(Ap_Pob[i],Ap_Pob_C[i]); termina termina

Procedimiento Reproduccin Modificado para la versin paralela.


nada Reproduccion_Total(entero Tam_Pob, real_doble **Ap_Pob_C, entero Tam_Mat, real_doble mejor_global) comienza entero i,res; entero Indice=0; **Ap_Pob, entero Niveles, real_doble

para i=0 hasta i<Tam_Pob comienza Reproduccion(Ap_Pob_C[i],Niveles,mejor_global); termina para i=0 hasta i<Tam_Pob

24

comienza res=Restriccion(Ap_Pob_C[i],1,Tam_Mat); si (res==1) entonces Copia(Ap_Pob[i],Ap_Pob_C[i]); termina termina

Las diferencias entre las funciones estn marcadas con letra cursiva y negrita, notemos que el segundo procedimiento el mejor individuo, llega como parmetro a la funcin porque fue encontrado por el proceso maestro, de tal forma que los procesos esclavos no ejecuten de nuevo el procedimiento busca_mejor. Finalmente tenemos la funcin el procedimiento envios, controla la n i icializacin de los datos, y la evaluacin inicial y final de la imagen fuente, recibe como parmetros el identificador de cada proceso, el nmero de procesos y el comunicador.
nada envios(entero mi_id, entero nproc, MPI_Comm komm) comienza real_doble calidadf,calidadi,mejor[SEIS]; entero ngris,tpob,tam,tamorig,mayorng,i,terminado=0; entero **mf,**mo,**mtfinal,**mobjetivo,**mnormalizadaf; caracter imagen_final[30] ; carcter imagen_r[30]; FILE * repro_p; mejor[CINCO]=0.0; si (mi_id==0) entonces comienza inicializa_datos(&ngris,&tam,&tpob,nproc); mtfinal=crea_matriz(tam); mobjetivo=crea_matriz(tam); mnormalizadaf=crea_matriz(tam); inicializa_lista(&cab,tam,ngris,imagen_final,imagen_r,&mayorng); copia_matriz(mobjetivo,cab.first->pdestino,tam); calidadi= eval_final_p(tam,cab.first->pfuente,mobjetivo,ngris); repro_p=Abre_ArchivoLee(imagen_r,repro_p,"w"); termina MPI_Bcast(&ngris,UNO,MPI_INT,0,MPI_COMM_WORLD); MPI_Bcast(&tpob,UNO,MPI_INT,0,MPI_COMM_WORLD); MPI_Bcast(&tam,UNO,MPI_INT,0,MPI_COMM_WORLD); mf=crea_matriz(tam); mo=crea_matriz(tam); si (mi_id==0) entonces comienza copia_matriz(mf,cab.first->pfuente,tam); copia_matriz(mo,cab.first->pdestino,tam); eliminanodo(&cab); termina para i=CERO hasta tam haz MPI_Bcast((mf[i]),tam,MPI_INT,0,MPI_COMM_WORLD); para i=CERO hasta tam haz MPI_Bcast((mo[i]),tam,MPI_INT,0,MPI_COMM_WORLD); geneticop(mf,mo,tpob,ngris,tam,mejor,mi_id,nproc, komm,&repro_p);

25

si (mi_id ==0) entonces comienza Transforma_Total(mf,mnormalizadaf,mejor,tam); Normalizar(mtfinal,mnormalizadaf,tam,mayorng,ngris); calidadf=eval_final_p(tam,mtfinal,mobjetivo,ngris); Escribe_Matriz(tam,mtfinal,imagen_final); escribe ("costo imagen inicial ,calidadi); escribe ("costo imagen final, calidadf); termina si (mi_id ==0) entonces Cierra_Archivo(repro_p); termina

3.1.2

Estrategia distribuida modificada con segmentacin (divisin) de imagen.

Estrategia distribuida modificada y divisin de imagen. La segunda estrategia que se plantea consiste en lo siguiente; se tiene una imagen (fuente), que se desea alienar a una segunda imagen (objetivo) y cambia la condicin de termin del AG, ahora se toma en cuenta el nmero de repeticiones del MIG (como antes) y debe cumplir con una aptitud mnima que es establecida por el usuario. Adems se propone dividir la imagen, luego de aplicar al menos una vez el AGP sobre las imgenes. 3.1.2.1 Anlisis del Algoritmo Gentico Paralelo segunda estrategia. Se tiene las imgenes fuente y destino.

Algoritmo gentico Paralelo

T(X)
Imagen fuente Imagen destino

X = Mejor Individuo Global


1. Se aplican el AGP sobre el tamao total de las imgenes y se obtiene el MIG, se verifica la apti tud de este con la mnima establecida por el usuario, si ambas condiciones se cumplen el AGP termina, de otra forma se dividen las imgenes a un tamao igual al tamao original sobre dos;

ntam =

tamao original , teniendo como resultado cuatro imgenes fuentes y sus respectivas 2

imgenes objetivo.

26

Imgenes fuente

Imgenes Objetivo

2.- Para cada una de las nuevas imgenes aplicar el paso 1, si las condiciones no se cumplen procedemos a dividir la imagen, dando como resultado lo siguiente:

Los tres pares de imgenes fuente objetivo a las cuales no se les aplico el AGP, y cuatro pares de imgenes fuente objetivo, de tamao menor, a todas estas imgenes se les debe aplicar el AGP. Surge aqu la interrogacin Hasta cuando se aplica el AGP, a las imgenes?, si las condiciones de termino no se cumplen, adems de tener cada vez ms imgenes y de tamao menor. Este importante detalle se resuelve proporcionando un tamao mnimo de las imgenes. Veamos la implementacin general de la estrategia.
1 5,6 3,4 3,4 3,4 3,4 5 5

Las tareas se desarrollan de la siguiente forma: 1. El proceso maestro inicializa los datos para la ejecucin del AGP.

27

2. El proceso maestro toma las imgenes. 3. El proceso maestro enva los datos a los procesos esclavos. Los procesos esclavos reciben los datos 4. El proceso maestro enva las imgenes a los procesos esclavos. Los procesos esclavos la reciben. 5. Todos los procesos aplican el AGP, y el proceso maestro se queda con el MIG. 6. El proceso maestro decide, hacer o no divisin de la imagen. a. El proceso maestro divide la imagen, si es necesario. 7. El proceso maestro verifica las condiciones de trmino. 8. Se repiten los pasos 4-6 mientras no se cumplan las condiciones de trmino. Nota. No se debe olvidar la comunicacin entre el proceso maestro y los procesos esclavos, en la ejecucin en AGP. En este caso se van a tener un conjunto de imgenes de diferentes tamaos, se utiliza una lista ligada, se utilizan las mismas estructuras que en la estrategia anterior. Detallemos como se utiliza las estructura nodo, inicio es un arreglo de tipo entero, donde se guardan las coordenadas en donde comienzan las imgenes respecto de la imagen original, imagen fuente y destino son apuntadores dobles de tipo entero a donde se encuentran los datos de las imgenes, en tamao como su nombre lo indica se guarda el tamao de las imgenes, y siguiente es un apuntador a nodo, en donde se tiene otra parte de la imagen original. Por ejemplo, supongamos que se tiene una imagen de tamao 128, si se divide se obtienen cuatro imgenes de tamao 64, y la lista quedara como sigue: lista

tama=4 first

inicio (1,1) imagen_fuente* imagen_destino* tamao=64 sigte

inicio (1,64) imagen_fuente* imagen_destino* tamao=64 sigte

inicio (64,1) tamao=64 sigte

imagen_fuente* imagen_destino*

inicio (64,64) imagen_fuente* imagen_destino* tamao=64 sigte

y las imgenes fuente y destino de cada nodo son las siguientes:.

(1,1)

(1,64)

(64,1)

(64,64)

Coordenadas de inicio Imgenes fuente

Imgenes destino

La lista es controlada por el proceso maestro es este quien indica a todos el termino de la ejecucin del AGP, cuando se termina de procesar se debe construir la imagen (de tamao igual al original) obtenida de todo el procesamiento.

28

Imgenes procesadas finales

Imagen final

A continuacin se detalla el algoritmo del AGP. El proceso maestro, inicializa los datos. El proceso maestro inicializa la lista con las imgenes fuente y destino. El proceso maestro obtiene la aptitud inicial de la imagen objetivo. El proceso maestro enva los datos, a los procesos esclavos, estos los reciben. El proceso maestro enva el tamao de las imgenes a procesar. Los procesos esclavos lo reciben. 6. El proceso maestro hace una copia de las imgenes que se encuentran en el primer nodo de la lista. 7. El proceso maestro enva las imgenes a los procesos esclavos, esto la reciben. 8. Todos los procesos (incluyendo el maestro), ejecutan el AGP, expuesto en la estrategia anterior y el proceso maestro se queda con el mejor individuo del procesamiento. 9. El proceso maestro verifica (tomando en cuenta las condiciones de termino del AGP), si la imagen se va a dividir. 10.1 La imagen se divide en caso de que sea necesario, se actualiza el tamao, las nuevas imgenes se colocan en la lista y se eliminan las imgenes de la cual sigui la divisin. 11. Se repiten los pasos 6 a 10, mientras no se hayan terminado de procesar todas las imgenes de la lista. En esta estrategia, se utilizaron funciones que fueron diseadas en la anterior, en algunas se hicieron modificaciones, otras son nuevas. Enseguida se presenta el pseudo cdigo, de cada una de ellas. Como se adicionaron otras parmetros en la condicin de termino del AGP, se modifico el procedimiento inicializa datos para solicitar al usuario los nuevos parmetros. 1. 2. 3. 4. 5.

nada inicializa_datos(entero*ngris, entero *ntam,entero *npob, real_doble *aptitudf,entero *resolucion, entero nproc) comienza escribe ("Proporciona los siguientes datos"); escribe ("Niveles de gris"); lee (ngris);

29

escribe ("Orden de la matriz); lee (ntam); escribe ("Tamao de la poblacin); lee (npob); escribe (Aptitud mnima para finalizar el procesamiento"); lee (aptitudf); escribe ("Resolucin mnima de procesamiento"); lee (resolucin); (*npob)=(*npob)/nproc; //se divide la poblacin total entre los procesos. termina

En la funcin eval_final, se obti ene la calidad de una imagen con respecto a la otra, en la secuencia del AGP, primero se calcula la calidad inicial de la imagen fuente, y despus de terminar el procesamiento se obtiene la calidad de la imagen fuente procesada. Se reciben como parmetros tam_mat, que es el tamao de las imgenes, dos apuntadores dobles de tipo entero mfinal y mon, que corresponden a las matrices la final (o inicial) y la matriz objetivo normalizada donde se cargaron las imgenes y el numero de niveles de gris para el procesamiento, la funcin regresa un real de doble precisin con el valor de la calidad de la matriz.
real_doble eval_final(entero tam_mat,entero ** mfinal, entero **mon,entero niveles) comienza entero mayor; entero **mftn=NULL; real_doble **mpc=NULL; real_doble *f=NULL,*ft=NULL; real_doble devuelto; mftn=crea_matriz(tam_mat); f=Crea_Histograma(niveles+1); ft=Crea_Histograma(niveles+1); mayor=Mayor_TGris(mfinal,tam_mat); Normalizar(mfinal,mftn,tam_mat,mayor,niveles); mpc=ProConjunta(mon,mftn,tam_mat,niveles); Frec_F(mpc,niveles,f); Frec_FT(mpc,niveles,ft); devuelto=Costo(f,ft,mpc,niveles,tam_mat); mftn=libera(mftn,tam_mat); liberad(mpc,niveles+1); free(f); free (ft); regresa (devuelto); termina

Despus de aplicar el AGP se determina si la imagen deben se dividida para continuar con el procesamiento, para esto se diseo el procedimiento decideparticion, que recibe como parmetros una apuntador a lista l, que es la lista donde se van almacenando las imgenes, un apuntador de tipo doble que es el mejor individuo que se obtuvo al procesar la imagen, un doble apuntador a entero que corresponde a la matriz en donde se van incorporando las matrices que se han procesado, un real de doble precisin que indica cual es la aptitud mnima que debe tener el mejor individuo para ya no procesar la imagen, un entero para comparar si e tamao de la imagen corresponde al mnimo, y un doble apuntador a archivo para salvar las coordenadas de inicio de las imgenes respecto al tamao real.

30

nada decideparticion(lista * l, real_doble *mejor ,entero res_min,FILE**repro_p) comienza entero i,j,k,m,n,ntam; entero origen[DOS]; entero ** vfuentes[CUATRO],** vdestinos[CUATRO]; entero **cooresq; nodo * nodok;

**

mfinal, real_doble

aptitudf,entero

si ( !esvacia(*l) ) entonces comienza ntam=(l->first->tam)/DOS; transforma_p(l->first->pfuente,mejor,l->first->tam); si ((mejor[CINCO]<aptitudf) y (ntam>=res_min) ) entonces comienza origen[CERO]=l->first->inicia[CERO]; origen[UNO]=l->first->inicia[UNO]; escribe_en_archivo(*repro_pUNO, l->first->inicia[CERO],l->first->inicia[UNO],l->first>tam,mejor[CERO],mejor[UNO],mejor[DOS],mejor[TRES],mejor[CUATRO],mejor[CINCO]); cooresq=cesquinas(cooresq,origen,l->first->tam); para k=CERO hasta CUATRO haz comienza vdestinos[k]=crea_matriz(ntam); vfuentes[k]=crea_matriz(ntam); termina para i=CERO hasta ntam haz para j=CERO hasta ntam haz comienza vfuentes[CERO][i][j]=l->first->pfuente[i][j]; vdestinos[CERO][i][j]=l->first->pdestino[i][j]; vfuentes[UNO][i][j]=l->first->pfuente[i][j+ntam]; vdestinos[UNO][i][j]=l->first->pdestino[i][j+ntam]; vfuentes[DOS][i][j]=l->first->pfuente[i+ntam][j]; vdestinos[DOS][i][j]=l->first->pdestino[i+ntam][j]; fuentes[TRES][i][j]=l->first->pfuente[i+ntam][j+ntam]; destinos[TRES][i][j]=l->first->pdestino[i+ntam][j+ntam]; termina eliminanodo(l); para k=CERO hasta CUATRO haz comienza nodok= creanodom(vfuentes[k],vdestinos[k],cooresq[k],ntam); insertanodo(l,nodok); termina cooresq=libera(cooresq,CUATRO); termina otro comienza reconstruyematrix(mfinal,l->first); escribe_en_archivo(*repro_p,CERO,l->first->inicia[CERO],l->first->inicia[UNO],l->first>tam,mejor[CERO],mejor[UNO],mejor[DOS],mejor[TRES],mejor[CUATRO],mejor[CINCO]); eliminanodo(l); termina termina termina

En el procedimiento decide particin se hacen llamadas a los procedimientos transforma_p, reconstruyematrix y a la funcin cesquinas. El procedimiento transforma_p, recibe como parmetros un doble apuntador de tipo entero que es corresponde a la imagen a transformar y despus de

31

transformada debe permanecer en esa variable, un arreglo tipo real de doble precisin es el IMG con el que se hace la transformacin, un entero n que indica el tamao de la imagen.
nada transforma_p(entero ** fuente,real_doble mejor[SEIS],entero n) comienza entero **B,**C; B=crea_matriz(n); C=crea_matriz(n); inicia_ceros(B,n); copia_matriz(B,fuente,n); k_suma(B,1,n); transforma(C,B,mejor,n); interpola_matriz1(C,n); k_suma(C,-1,n); copia_matriz(fuente,C,n); B=libera(B,n); B=libera(C,n); termina

El procedimiento reconstruyematrix se utiliza para ir colocando en el lugar correspondiente (respecto a la imagen orginal) las imgenes que se han procesado, para que al finalizar el procesamiento de todas las imgenes en la lista se obtenga la imagen final que debe ser equivalente a la imagen objetivo inicial. Se reciben como parmetro un doble apuntador en donde se va a salvar la imagen procesada final y un apuntador a nodo donde vienen los datos y la imagen que se va a integrar.
nada reconstruyematrix(entero ** final, nodo *part) comienza entero i,j,k,l,x,y,lr,lc; i=part->inicia[CERO]; j=part->inicia[UNO]; lr=i+part->tam; lc=j+part->tam; x=CERO; para k=I hasta lr haz comienza y=CERO; para l=j hasta lc haz comienza final[k][l]=part->pfuente[x][y]; y=y+1; termina x=x+1; termina termina

En el procedimiento envios se hace una llamada a la funcin cesquinas despus de determinar que la imagen se debe dividir. Esta funcin se utiliza para localizar las coordenadas de las imgenes que se van a obtener en la divisin, recibe un doble apuntador a entero en donde se guardan las coordenadas de las imgenes, un apuntador a entero que trae las coordenadas de inicio de la imagen a dividir y un entero que es el tamao de la imagen.
entero ** cesquinas(entero **vector,entero * origen,entero tam) comienza entero x,y,z;

32

x=origen[CERO]; y=origen[UNO]; z=tam/DOS; vector=crea_matriz(CUATRO); vector[CERO][CERO]=x; vector[CERO][UNO]=y; vector[UNO][CERO]=x; vector[UNO][UNO]=(y+z); vector[DOS][CERO]=(x+z); vector[DOS][UNO]=y; vector[TRES][CERO]=(x+z); vector[TRES][UNO]=(y+z); regresa (vector); termina

El procedimiento envios, se encarga para controlar el procesamiento de la lista donde se encuentran las imgenes. Recibe como parmetros dos enteros el identificador del proceso y el nmero de procesos, tambin un tipo MPI_Comm es una copia del comunicador universal.
nada envios(entero mi_id, entero nproc, MPI_Comm komm) comienza real_doble calidadf,calidadi,aptitudf, mejor[SEIS]; entero ngris,tpob,tam,tamorig,res_min,mayorng,i,terminado=0; entero **mf=NULL,**mo=NULL,**mfinal,**mobjetivo,**mnormalizadaf; caracter imagen_final[30] caracter imagen_r[30]; FILE * repro_p; mejor[CINCO]=0.0; si (mi_id==0) entonces comienza inicializa_datos(&ngris,&tam,&tpob,&aptitudf,&res_min,nproc); mfinal=crea_matriz(tam); mobjetivo=crea_matriz(tam); mnormalizadaf=crea_matriz(tam); tamorig= tam; inicializa_lista(&cab,tam,ngris,imagen_final,imagen_r,&mayorng); copia_matriz(mobjetivo,cab.first->pdestino,tamorig); calidadi= eval_final(tamorig,cab.first->pfuente,mobjetivo,ngris); repro_p=Abre_ArchivoLee(imagen_r,repro_p,"w"); termina MPI_Bcast(&ngris,UNO,MPI_INT,0,MPI_COMM_WORLD); MPI_Bcast(&tpob,UNO,MPI_INT,0,MPI_COMM_WORLD); mientras terminado <> 1 haz comienza MPI_Bcast(&tam,UNO,MPI_INT,0,MPI_COMM_WORLD); mf=crea_matriz(tam); mo=crea_matriz(tam); si (mi_id==0) entonces comienza copia_matriz(mf,cab.first->pfuente,tam); copia_matriz(mo,cab.first->pdestino,tam termina

33

para i=0 hasta tam haz MPI_Bcast((mf[i]),tam,MPI_INT,0,MPI_COMM_WORLD); para i=0 hasta tam haz MPI_Bcast((mo[i]),tam,MPI_INT,0,MPI_COMM_WORLD); geneticop(mf,mo,tpob,ngris,tam,mejor,mi_id,nproc, komm); mf=libera(mf,tam); mo=libera(mo,tam); si (mi_id ==0) entonces comienza decideparticion(&cab,mejor,mfinal,aptitudf,res_min,&repro_p); si (esvacia(cab)) entonces comienza terminado=1; Normalizar(mfinal,mnormalizadaf,tamorig,mayorng,ngris); Escribe_Matriz(tamorig,mnormalizadaf,imagen_final); calidadf= eval_final(tamorig,mnormalizadaf,mobjetivo,ngris); escribe ("costo de la imagen inicial =calidadi); escribe ("costo de la imagen final,calidadf); termina otro tam=cab.first->tam; termina MPI_Bcast(&terminado,UNO,MPI_INT,0,MPI_COMM_WORLD); termina si (mi_id ==0) entonces Cierra_Archivo(repro_p); termina

34

RESULTADOS

35

4. Resultados Los experimentos se realizaron en un cluster homogneo de 27 nodos, cada nodo dispuso de un procesador Pentium 4 a 2.8 GHz, 512 MB de memoria RAM. En la ejecucin de los algoritmos para alienacin no rgida de imgenes mdicas, utilizaron las siguientes imgenes obtenidas por Resonancia Magentica de cabeza humana, las cuales tienen 256 nivles de gris.

Imagen fuente

Imagen destino

Imagen fuente transformada

4.1 Algoritmo Gentico Secuencial Algoritmo Gentico Paralelo (estrategia 1). Los resultados se obtuvieron haciendo cinco ejecuciones con los algoritmos, en los cuales los parmetros son distintos, veamos las siguientes tablas. En la Tabla 1a, se muestran la primera configuracin de los parmetros utilizados en la ejecucin de los algoritmos.
PARAMETROS 5 Procesadores Niveles de gris =10 Tamao de la Matriz =256 Tamao de la poblacin =15 Aptitud Mnima =0.71 Resolucin mnima =16

Tabla 1a En la Tabla 1b se encuantra la calidad inicial de la imagen fuente y la calidad final de la imagen fuente transformada, asi como el tiempo que tardo la ejecucin, en el algoritmo secuencial.
NO. EXP 1 2 3 4 5 Promedio

AG SECUENCIAL Aptitud inicial 0.607590 0.607590 0.607590 0.607590 0.607590

Aptitud final 0.6947110 0.6917260 0.6901920 0.6993260 0.6904280 0.6932766

Tiempo min 14.1500000 23.4666670 13.2000000 17.7333330 29.5166670 19.6133334

Tabla 1b En la Tabla 1c se encuentra la calidad inicial de la imagen fuente y la calidad final de la imagen fuente transformada, asi como el tiempo que tardo la ejecucin, en el algoritmo paralelo estrategia 1.

36

NO. EXP 1 2 3 4 5 Promedio

AG PARALELO Aptitud inicial 0.607590 0.607590 0.607590 0.607590

Aptitud final 0.6936920 0.6896030 0.6974950 0.6939930 0.6944282

Tiempo min. 4.7026390 2.3746020 3.9297970 4.2790220 4.0916206

Tabla 1c En la grfica 1 se observa la relacin del coeficiente de aceleracin del algoritmo paralelo estrategia 1 y el algoritmo secuencial.

Coeficiente de Aceleracin

12 10 8 6 4 3.01 2 0 1 2 3 4 5
No. de Experimento

9.88

5.71 3.36 4.14

Grfica 1 En la Tabla 2a, se muestran la segunda configuracin de los parmetros.


PARAMETROS 8 Procesadores Niveles de gris =10 Tamao de la Matriz =256 Tamao de la poblacin =16 Aptitud Mnima =0.71 Resolucin mnima =16

Tabla 2a

En la Tabla 2b se encuentra la calidad inicial de la imagen fuente y la calidad final de la imagen fuente transformada, asi como el tiempo que tardo la ejecucin, en el algoritmo secuencial con la segunda configuracin.

37

NO. EXP 1 2 3 4 5 Promedio

AG SECUENCIAL Aptitud inicial 0.607590 0.607590 0.607590 0.607590 0.607590

Aptitud final 0.6949740 0.6927460 0.6850960 0.6968500 0.6966420 0.6932616

Tiempo min 18.9166670 19.0500000 15.6833330 19.3000000 17.0833330 18.0066666

Tabla 2b En la Tabla 2c se encuentra la calidad inicial de la imagen fuente y la calidad final de la imagen fuente transformada, asi como el tiempo que tardo la ejecucin en el algoritmo paralelo estrategia 1 y los parmetros indicados en la tabla 2a.

NO. EXP 1 2 3 4 5 Promedio

AG PARALELO Aptitud inicial 0.607590 0.607590 0.607590 0.607590 0.607590

Aptitud final 0.6863030 0.7003040 0.7015010 0.6995500 0.6958420 0.6967000

Tiempo min. 1.6671790 2.8591670 5.0402720 4.2530940 3.8606330 3.5360690

Tabla 2c

En la grfica 2 se observa la relacin del coeficiente de aceleracin del algoritmo paralelo estrategia 1 y el algoritmo secuencial, adquiridos con la segunda configuracin de parmetros.

12
Coeficiente de Acelaracin

11.35

10 8 6 4 2 0 1 2 3
No. de Experimento

6.66 4.54 3.11 4.43

Grfica 2

38

En la Tabla 3a, se muestran la tercera configuracin de los parmetros.

PARAMETROS 15 Procesadores Niveles de gris =10 Tamao de la Matriz =256 Tamao de la poblacin =15 Aptitud Mnima 0.71 Resolucin mnima =16

Tabla 3a

En la Tabla 3b se encuentra la calidad inicial de la imagen fuente y la calidad final de la imagen fuente transformada, asi como el tiempo que tardo la ejecucin, en el algoritmo secuencial con la tercera configuracin.

NO. EXP 1 2 3 4 5 Promedio

AG SECUENCIAL Aptitud inicial 0.607590 0.607590 0.607590 0.607590 0.607590

Aptitud final 0.6947110 0.6917260 0.6901920 0.6993260 0.6904280 0.6932766

Tiempo min 14.1500000 23.4666670 13.2000000 17.7333330 29.5166670 19.6133334

Tabla 3b En la Tabla 3c se encuentra la calidad inicial de la imagen fuente y la calidad final de la imagen fuente transformada, asi como el tiempo que tardo la ejecucin en el algoritmo paralelo estrategia 1 y los parmetros indicados en la tabla 3a.

NO. EXP 1 2 3 4 5 Promedio

AG PARALELO Aptitud inicial 0.607590 0.607590 0.607590 0.607590 0.607590

Aptitud final 0.6930930 0.6958400 0.6779740 0.7017180 0.6930940 0.6923438

Tiempo min. 1.3048580 1.3811940 0.8800590 2.7167550 1.4232220 1.5412176

Tabla 3c

39

En la grfica 3 se observa la relacin del coeficiente de aceleracin del algoritmo paralelo estrategia 1 y el algoritmo secuencial, adquiridos con la tercera configuracin de parmetros.

Coeficiente de Aceleracin

25 20 15 10 5 0 1 2 3
No. de Experimento

20.74 16.99 10.84 6.53 15.00

Grfica 3 4.2 Algoritmo Gentico Paralelo (estrategia 2). En este caso se hicieron cuatro ejecuciones del algoritmo, con los parmetros iguales al algoritmo secuencial y algorimo paralelo estrategia 1. En la Tabla 4a, se muestran la primera configuracin de los parmetros
PARAMETROS 5 Procesadores Niveles de gris=10 Tamao de la Matriz=256 Tamao de la poblacin=15 Aptitud Mnima =0.71 Resolucin minima =16

Tabla 4a En la Tabla 4b se encuentra la calidad inicial de la imagen fuente y la calidad final de la imagen fuente transformada, asi como el tiempo que tardo la ejecucin, en el algoritmo paralelo estrategia 2.
NO. EXP 1 2 3 4 Promedio

AG PARALELO Aptitud inicial 0.607590 0.607590 0.607590 0.607590

Aptitud final 0.7044400 0.7263710 0.7289710 0.7296290 0.7223528

Tiempo min. 10.2660210 10.3638950 7.9469650 10.9626660 9.8848868

Tabla 4b En la grfica 1 se observa la relacin del coeficiente de aceleracin del algoritmo paralelo estrategia 2 y el algoritmo secuencial.

40

Coeficiente de Aceleracin

2.5 2 1.5 1 0.5 0 1 2 1.38

2.26 1.66 1.62

No. de Experimento

Grfica 4 En la Tabla 2a, se muestran la segunda configuracin de los parmetros.


PARAMETROS 8 Procesadores Niveles de gris =10 Tamao de la Matriz =256 Tamao de la poblacin =16 Aptitud Mnima =0.71 Resolucin mnima =16

Tabla 5a En la Tabla 5b se encuentra la calidad inicial de la imagen fuente y la calidad final de la imagen fuente transformada, asi como el tiempo que tardo la ejecucin en el algoritmo paralelo estrategia 2 y los parmetros indicados en la tabla 5a.

NO. EXP 1 2 3 4 Promedio

AG PARALELO Aptitud inicial 0.607590 0.607590 0.607590 0.607590

Aptitud final 0.7260670 0.7305100 0.7281850 0.7333770 0.7295348

Tiempo min. 5.6879730 5.0677730 5.3110500 5.4231050 5.3724753

Tabla 5b En la grfica 5 se observa la relacin del coeficiente de aceleracin del algoritmo paralelo estrategia 2 y el algoritmo secuencial, adquiridos con la segunda configuracin de parmetros.

41

Coeficiente de Aceleracin

4 3 2 1 0 1 2 3.33

3.76 2.95

3.56

No. de Experimento

Grfica 5

En la Tabla 5a, se muestran la tercera configuracin de los parmetros.


PARAMETROS 15 Procesadores Niveles de gris =10 Tamao de la Matriz =256 Tamao de la poblacin =15 Aptitud Mnima 0.71 Resolucin mnima =16

Tabla 6a

En la Tabla 6b se encuentra la calidad inicial de la imagen fuente y la calidad final de la imagen fuente transformada, asi como el tiempo que tardo la ejecucin en el algoritmo paralelo estrategia 2 y los parmetros indicados en la tabla 6a.
NO. EXP 1 2 3 4

AG PARALELO Aptitud inicial 0.607590 0.607590 0.607590 0.607590

Aptitud final 0.7314640 0.7389130 0.7270050 0.7397470

Tiempo min. 2.5539160 2.9130880 2.5980660 2.9130850

Promedio

0.7342823

2.7445388

Tabla 6b

42

En la grfica 6 se observa la relacin del coeficiente de aceleracin del algoritmo paralelo estrategia 2 y el algoritmo secuencial, adquiridos con la segunda configuracin de parmetros
Coeficiente de Aceleracin

10 8 6 4 2 0 1 2 3 4
No. de Experimento

8.06 5.54 5.08 6.09

Grfica 6 4.3 Comparacin entre los algoritmos. En las tablas anteriores se observa que hay una disminucin considerable en el tipo de ejecucin del AG secuencial respecto al AGP estrategia 1, igualmente se observa en las grficas del Coeficiente de Aceleracin de cada experimento adems de que las aptitudes de las imgenes finales son mayores en el AGP que en AG secuencial, notemos que no se tiene una tendencia definida en el comportamiento del Coeficiente de Aceleracin. En cuanto al AGP estrategia 2, los tiempos de ejecucin disminuyeron notablemente respecto al AG secuencial sin embargo son mayores a los tiempos de ejecucin del AGP estrategia 1, lo que nos hace suponer que la primera estrategia es mejor, pero un detalle muy importante es la calidad que se obtiene en las imgenes que es mucho mayor comparada con el AGP estrategia 1 y el AG secuencial.

43

CONCLUSIONES

44

5. Conclusiones. En este documento se expusieron dos algoritmos paralelos como mejora en el tiempo de ejecucin en los algoritmos secuenciales para la alineacin no rgida de imgenes mdicas. En el primer algoritmo se busca el vector ptimo para alinear las imgenes, en el segundo algoritmos las imgenes se dividen buscando tambin el vector ptimo para el alineamiento. Los resultados experimentales confirman que las implantaciones en paralelo de los AG mejoran los tiempos de ejecucin de tal forma que la relacin puede ser superlineal, en estas implementaciones se llegan a obtener mejores soluciones que los AG secunciales cuando cada proceso trabaja con subpoblaciones independientes (estrategia 1) [5]. En la AGP estrategia 2 se combino al AGP con la divisin de la imagen de tal forma que se aprovecharon las caractersticas del cluster y se obtuvieron mejores resultados, en ambas estrategias no se tuvo prdida de informacin gentica y no hubo disminucin de aleatoriedad. Advirtamos que la eficacia de los AGP permite indudablemente explotar los recursos de cmputo.

45

BIBLIOGRAFIA

46

6. Bibliografa. [1] Van-dat Cung, Simone L.Artins, Celso C.Ribeiro, Catherine Roucairol: Strategies for the parallel implementation of metaheuristics. 2001. [2] Selene Nochebuena Rojo: Proyecto de Investigacin I y II. Optimizacin e implementacin en cdigo C de un algoritmo secuencial para alineacin de imgenes mdicas. UAMI-2003 [3] Norma Pilar Castellasnos Abrego,P. L. Del Angel, V. Medina, Nonrigid Image Registration

Technique as a Composition of Local Warpings. Pattern Recognition, vol. 37(11), pp. 21412154. 2004.
[4] Francisco Hidrobo,Herbert Hoeger, Introduccin a MPI , Centro Nacional de Calculo Cientfico Universidad de los Andes. [5] Erick Cant-Paz, A Summary of Research on Parallel Genetic Algorithms, Technical Report N 95007. Julio 1995. G. Romn-Alonso, N.P. Castellanos-Abrego, and L. Zamora-Venegas. A parallel Approach for a Non-rigid Image Registration Algorithm. LNCS 3241, Springer, Recent Advances in Parallel Virtual Machine and Message Passing Interface. 11th European PVM/MPI User's Group Meeting Budapest, Hungary, September 2004 Proceedings.

47

ANEXO A CODIGO FUENTE EN C MPI PARA EL ALGORTIMO GENETICO PARALELO (ESTRATEGIA 1) APLICADO EN LA ALINEACION NO RIGIDA DE IMGENES MEDICAS

48

7. Anexo A Cdigo fuente en C - MPI para el Algoritmo Gentico Paralelo (estrategia 1) aplicado en la alineacin no rgida de imgenes mdicas.
/*INCLUSION DE LIBRERIAS*/ #include<stdlib.h> #include<stdio.h> #include<math.h> #include<time.h> #include<string.h> #include<mpi.h> /*DEFINICION DE CONSTANTES SIMBOLICAS*/ #define D 2 #define T 2 #define CERO 0 #define UNO 1 #define DOS 2 #define TRES 3 #define CUATRO 4 #define CINCO 5 #define SEIS 6 #define GEN 2 #define MUTRATEMAX 0.4 #define MUTRATEMIN 0.05 #define REPMAX 25 #define TAMIND 6 #define tope_alfa 2.50000 #define min_alfa 2.010000 /*ETIQUETAS PARA ENVIO Y RECEPCION DE MENSAJES */ #define TARJETA 15 #define MFUENTE 16 #define MOBJET 17 #define TAMA 18 #define NGRIS 19 #define TAMPOBLA 20

/*ESTRUCTURAS DE DATOS PARA VECTOR Y LISTA LIGADA*/ typedef double vector[2]; //vil vector typedef struct mnodo nodo; struct mnodo { int inicia[DOS]; int ** pfuente; int **pdestino; int tam; nodo *sigte; };

49

typedef struct clista lista; struct clista { int tama; nodo *first; }; lista cab; /*VARIABLE TIPO LISTA, PARA ALMACENAMIENTO DE IMAGENES*/ /*PROTOTIPOS DE FUNCIONES*/ /*PROTOTIPOS DE FUNCIONES PARA MANEJO DE VECTORES Y MATRICES*/ double Maxt(double *X,int n); double Mint(double *X,int n); double Maxt2(double a,double b); double Min2(double a,double b); double* Creavektor(int n); void CerosVector(double *A,int Tamano); int **crea_matriz(int TamMatriz); void Escribe_Matriz(int Tam,int **M,char nombre[30]); void inicia_ceros(int **A,int n); void copia_matriz(int **B,int **A,int n); void Copia(double A[TAMIND],double B[TAMIND]); void k_suma(int **A,int k, int n); void K_multiplica(double **matrix,double k,int M); void Mx_Suma(double ** A,double **B,int n); void Mx_Multiplica(double **A,vector punto,int n, vector paux); double* Crea_Histograma(int Nivel); double **crea_matriz_F(int TamMatriz); double **crea_matriz_P(int TamMatriz); void liberad(double **M,int n); int ** libera(int **A,int n); /*PROTOTIPOS DE FUNCIONES PARA TRANFORMACION DE IMAGENES*/ void Transforma_Total(int **Atr,int **A,double ind[TAMIND],int n); void transforma(int **Atr,int **A,double indi[TAMIND],int n); void copia_frontera(int **A,int **B,int n); void Inicia_Vector(vector punto,int n); void Ncoor(vector punto,double fak); int Norma(vector X); double Lamda(vector punto); void G_de_X(vector punto,double indi[TAMIND],vector paux); int Restriccion(double d[TAMIND],double FACTOR,int n); double **Identidad(int n); double **Trans_afin(double indi[TAMIND],int n); /*PROTOTIPOS DE FUNCIONES PARA INTERPOLACION DE IMAGENES*/ void interpola_matriz1(int **A,int n); int Valder(int **A, int i,int pos, int *ch); int Valizq(int **A, int i,int j, int *pos); int Valab(int **A, int i,int j, int *cv); int Varrib(int ** A,int i,int j); int arrder(int **mat,int i,int j,int *arrx,int *arry); int abaizq(int **mat,int i,int j,int *abax,int *abay); int arrizq(int **mat,int i,int j,int *arrx,int *arry); int abader(int **mat,int i,int j,int *abax,int *abay);

50

double Redond(double x); double Prme(double x,double y,double w, double z); double Interp(int vi,int vf,int inter,int pos); /*PROTOTIPOS DE FUNCIONES PARA EL MANEJO DE LA POBLACION DEL ALGORITMO GENETICO*/ double GeneraAleatorio(); double AleatorioUno(void); double GeneraAleatorioMutac(); double AleatorioDosTres(void); int GeneraAleatorioCinco(void); int Velocidad_Mutacion(int contador); double **Mutacion(double **A,int Tam_Pob,int Tam_Mat); void Mejor(double Ap_Mejor[TAMIND],double **Ap,int TamPob); void Reproduccion(double A[TAMIND],int Tonos,double Ap_Mejor[TAMIND]); double Nu(double Ap_Indi[TAMIND]); double Promedio(double elemento[TAMIND]); double Costo(double *Ap_F,double *Ap_T,double **MF,int frec,int Tam_Mat); void Reproduccion_Total(int Tam_Pob,double **Ap_Pob,int Niveles,double **Ap_Pob_C,int Tam_Mat,double *mejor_global); int Redondea(double x); double Suma(double *Ap,int Tam_Mat); double SumaCon(double ** M,int Tam_Mat); void Frec_FT(double **MPC,int Niveles,double *Ap_Ind); void Frec_F(double **MPC,int Niveles,double *Ap_Ind); void Evalua(double *Ap_F,double *Ap_FT,double **MPC,int f,double A[TAMIND],int TamPob); void Evaluacion_Total(int Tam_Pob,int Tam_Mat,double **Ap_Pob,int ** MFN,int **MF,int **MFT,int **MFTN,int Niveles,double *F,double *FT); double **ProConjunta(int **MF,int **MT,int Tam,int Nivel); void Normalizar(int **M,int **NL,int Tam,int MayorGris,int NivelGris); double **Inicializa(int TamPob,int Tam_Mat,double Factor); int Mayor_TGris(int **M,int Tam); /*PROTOTIPOS DE FUNCIONES PARA EL MANEJO DE LISTA LIGADA*/ nodo *creanodom(int ** fuente, int **destino,int coor[2],int tam); void insertanodo(lista *l,nodo *n); void eliminanodo(lista *l); int esvacia(lista l); void inicializa_datos(int *ngris,int *ntam,int *npob, int nproc); void inicializa_lista(lista *l,int tam,int nivel,char imagen[],char imagen_r[],int *mayorng); void levanta_imagenes(int ***mf,int ***mo,int tam,char imagen[30],char imagen_r[30]); /*PROTOTIPOS DE FUNCIONES PARA EL ALGORTIMO GENETICO PARALELO*/ void asigna_memoriap(int ***mft,int ***mftn,double **f,double **ft,int tam,int niveles); void geneticop(int **mf,int **mon,int tam_pob,int niveles,int tam_mat,double mejorg[SEIS], int mi_id, int nproc, MPI_Comm komm,FILE ** repro_p); void busca_mejor(double *mejor, double *todos,int n); void actualiza_mejor_cont(double *mlocal,double*mglobal, int *contglobal); void copia_mejorp(double mi_mejor[SEIS],double mejor2[SEIS]); double eval_final_p(int tam_mat,int ** mfinal,int **mon,int niveles); void envios(int mi_id, int nproc, MPI_Comm komm);

/*REDECLARACION DE FUNCIONES*/ /*En esta funcion regresamos el valor MAXIMO de un vector (de reales) de tamao 2*n*2*n, donde n es un parametro*/

51

double Maxt(double *X,int n) { double yant,ynuevo; int i; yant=Maxt2(X[0],X[1]); for(i=2;i<n;i++) { ynuevo=Maxt2(yant,X[i]); yant=ynuevo; } return(yant); } /*En esta funcion regresamos el valor MINIMO de un vector(de reales) de tamao 2*n*2*n, donde n es un parametro*/ double Mint(double* X,int n) { double yant,ynuevo; int i; yant=Min2(X[0],X[1]); for(i=2;i<n;i++) { ynuevo=Min2(yant,X[i]); yant=ynuevo; } return(yant);

/*Esta funcion Maxt2, regresa el maximo entre dos numeros reales*/ double Maxt2(double a,double b) { double max; if (a>b) max=a; else max=b; return(max); } /*Esta funcion Min2, regresa el minimo entre dos numeros reales*/ double Min2(double a,double b) { double min; if (a<b) min=a; else min=b; return(min); }

52

/*En eta function se cra un vector de tamao (2*n)*(2*n) de tipo real doble precision*/ double* Creavektor(int n) { double *vektor=NULL; vektor=(double*)calloc((T*n)*(T*n),sizeof(double)); if(!vektor) { printf("Error .... de memoria\n); exit(0); } return(vektor);

/*En este procedimiento se inicializa a ceros una matriz de tipo real doble precision y tamao Tamano*/ void CerosVector(double *A,int Tamano) { int i; for(i=0;i<Tamano;i++) A[i]=0.0; } /*Se crea una matriz tipo entero de tamao TamMatriz */ int **crea_matriz(int TamMatriz) { int **mat=NULL; int i; /* Pedimos un arreglo de tamao N de apuntadores */ mat=(int**)calloc(TamMatriz,sizeof(int*)); if(!mat) { printf("Error .... NO HAY memoria\n"); exit(0); } else /* Para cada elemento del arreglo que es un apuntador le asignamos una arreglo de tama o N de enteros */ for(i=0;i<TamMatriz;i++) { mat[i]=(int*)calloc(TamMatriz,sizeof(int)); if(!(mat[i])) { printf("Error .... NO HAY memoria\n"); exit(0); } } return (mat); }

/*Esta procedimiento sirve para escribir el contenido de una matriz en un archivo*/

53

void Escribe_Matriz(int Tam,int **M,char nombre[30]) { int i,j; FILE *Ap_A=NULL; strcat(nombre,".txt"); Ap_A=Abre_ArchivoLee(nombre,Ap_A,"w"); for(i=0;i<Tam;i++) { for(j=0;j<Tam;j++) fprintf(Ap_A," %d ",M[i][j]); fprintf(Ap_A,"\n"); } Cierra_Archivo(Ap_A); }

/*Con este procedimiento se Inicia a cerosuna matriz tipo entero de tama o n*/ void inicia_ceros(int **A,int n) { int i,j; for(i=0;i<n;i++) for(j=0;j<n;j++) A[i][j]=0;

/*con este procedimiento copiamos el contenido de la matriz A, a la matriz B (ambas tipo entero)*/ void copia_matriz(int **B,int **A,int n) { int i,j; for (i=0;i<n;i++) for (j=0;j<n;j++) B[i][j]=A[i][j];

/*con este procedimiento copiamos el contenido del vector B al vector A* (ambos tipo real doble precision)/ void Copia(double A[TAMIND],double B[TAMIND]) { int i; for(i=0;i<TAMIND;i++) A[i]=B[i]; } /*En este procesdimento se suma el valor w a cada elemento de la matriz A (de tamao n)*/ void k_suma(int ** A,int w, int n) {

54

int i,k; for (i=0;i<n;i++) for(k=0;k<n;k++) A[i][k]+=w; } /*En este procesdimento mutiplica el valor r a cada elemento de la matriz A (de tamao M)*/ void K_multiplica(double **matrix,double r,int M) { int i,k; for (i=0;i<M;i++) for(k=0;k<M;k++) matrix[i][k]*=r; } /*En esta funcion sumamos dos matrices de tipo real doble precision y el resultado de la suma los dejamos en la matriz A*/ void Mx_Suma(double ** A,double **B,int n) { int i,k; for(i=0;i<n;i++) for(k=0;k<n;k++) A[i][k]+=B[i][k]; } /*En esta funcion multiplicamos una matriz cuadrada de orden (=2), por un vector de tama o 2*/ void Mx_Multiplica(double **A,vector punto,int n, vector paux) { double **B=NULL; double **C=NULL; int i,k; Inicia_Vector(paux,n); for(i=0;i<n;i++) for (k=0;k<n;k++) paux[i]+=A[i][k]*(punto[k]); } /*En esta funcin se reserva espacio en memeria, de acuerdo a los niveles de gris*/ double *Crea_Histograma(int Nivel) { double *Ap; Ap=(double *)calloc(Nivel,sizeof(double)); if(!Ap) { printf("Error .... Memoria insuficente \n"); exit(0); }

55

return (Ap); } /*En esta funcin se reserva espacio para una matriz ve tamao TamMatriz*/ double **crea_matriz_F(int TamMatriz) { double **mat=NULL; int i; mat=(double**)calloc(TamMatriz,sizeof(double*)); if(!mat) { printf("Error .... NO HAY memoria\n"); exit(0); } else for(i=0;i<TamMatriz;i++) { mat[i]=(double*)calloc(TamMatriz,sizeof(double)); if(!(mat[i])) { printf("Error .... NO HAY memoria\n"); exit(0); } } return (mat); } /*En esta funcin se reserva espacio para una matriz ve tamao TamMatriz*/ double **crea_matriz_P(int TamMatriz) { double **mat=NULL; int i; mat=(double**)calloc(TamMatriz,sizeof(double*)); if(!mat) { printf("Error .... NO HAY memoria\n"); exit(0); } else for(i=0;i<TamMatriz;i++) { mat[i]=(double*)calloc(TAMIND,sizeof(double)); if(!(mat[i])) { printf("Error .... NO HAY memoria\n"); exit(0); } } return (mat); }

/*En esta funcion liberarmos la memoria de la matriz de entrada M, de tipo real doble precision*/

56

void liberad(double **M,int n) { int k; for(k=0;k<n;k++) free(M[k]); free(M); } /*En esta funcion liberarmos la memoria de la matriz de entrada A, de tipo entero*/ int ** libera(int **A,int n) { int k; for(k=0;k<n;k++) free(A[k]); free(A); return(NULL); } /*Esta funcion Transforma_Total, aplicamos la funcion de tranformacion a la matriz A, la Interpolamos, y se modifica la matriz Atr, la cual es A Transformada e Interpolada*/ void Transforma_Total(int **Atr,int **A,double ind[TAMIND],int n) { int **B; B=crea_matriz(n); inicia_ceros(Atr,n); /*inicializamoa a ceros*/ inicia_ceros(B,n); copia_matriz(B,A,n);/*copiamos la matriz A (fuente ) a la matriz B*/ k_suma(B,1,n); /*sumamos 1 a la matriz B*/ transforma(Atr,B,ind,n); /*Aplicamos la Transformacion*/ interpola_matriz1(Atr,n); /*Interpolamos la matriz Transformada*/ k_suma(Atr,-1,n); /*restamos 1, a la matriz Transformada, ya Interpolada*/ B=libera(B,n); } /*En este procedimient se aplican los criterios de transformacin para imagen */ void transforma(int **Atr,int **A,double indi[TAMIND],int n) { double i,k,dd,nd; int j,l,p,q,x,y,xp,yp; vector V, W; Inicia_Vector(V,2); copia_frontera(A,Atr,n); nd=(double)n; i=0.0; for (p=0; p< n;p++) { k=0.0; for(q=0; q< n; q++) { V[0]=i;

57

V[1]=k; if (Norma(V)) //nos aseguramos que el vector tenga Norma <=0.5 con respecto al vector (0.5,0.5) { //y Transformamos el circulo unitario G_de_X(V,indi,W);//aplicamos la funcion G_de_X al vector V Ncoor(W,nd); //actualizamos las coodenadas de W xp=(int)W[0]; yp=(int)W[1]; Ncoor(V,nd); //actualizamos las coodenadas de V x=(int)V[0]; y=(int)V[1]; if ((xp>=0 && yp>=0)&&(xp<n && yp<n)) Atr[xp][yp]=A[x][y]; /*tomamos el valor correspondiente a la matriz Atr, de la matriz A*/ { } else //de otra forma tomamos los valores a la matriz anterior Ncoor(V,nd); x=(int)V[0]; y=(int)V[1]; Atr[x][y]=A[x][y]; } k= k + (1.0/nd); i= i + (1.0/nd); } }

/*Em este procedimiento se copian la frontera de la matriz A, a la matriz B*/ void copia_frontera(int **A,int **B,int n) { int i,i2,j,j2; j=0; j2=n-1; for(i=0;i<n;i++) { B[i][j]=A[i][j]; B[i][j2]=A[i][j2]; } i=0; i2=n-1; for(j=0;j<n;j++) { B[i][j]=A[i][j]; B[i2][j]=A[i2][j]; } } /*Con esta funcion iniciamos las coordenadas de unvector a cero*/ void Inicia_Vector(vector punto,int n) { int k; for (k=0;k<n;k++) (punto[k])=0.0; }

58

/*En esta funcion cambiamos las coordenadas del punto (x,y) x,y en (0,1)[reales en este intervalo] a (x,y) en (0,128) [enteras] */ void Ncoor(vector punto,double fak) { double z,w; z=Redond(punto[0]*fak); w=Redond(punto[1]*fak); punto[0]=z; punto[1]=w;

/*Con esta funcion determinamos si la Norma de un vector (de dos dimensiones) es X menor o igual a 0.5*/ int Norma(vector X) { double nor; int val; nor=sqrt(pow((X[0]-0.5),2.0)+pow((X[1]-0.5),2.0)); if (nor<=0.5000) val=1; else val=0; return(val); } /*Esta es una funcion para calcular el valor de la funcin Lamda*/ double Lamda(vector punto) { double valor; valor=2*sqrt( pow((punto[0]-0.5),2.0) + pow((punto[1]-0.5),2.0) ); return(valor); }

/*En este procedimiento se aplica la funcin G(X) al vector punto y el resultado se deje en el vector paux*/ void G_de_X(vector punto,double indi[TAMIND],vector paux) { double **A,**I; int k; double lam,lam_alfa; k=2; lam=Lamda(punto); //evaluamos el punto(x,y) en la funciona Lamda, Lamda(x,y) // y lo asignamos a lam lam_alfa=pow((lam),indi[4]);//elevamos el valor de lam a la potencia alfa, y lo

59

//asignamos a lam_alfa A=Trans_afin(indi,k);//generamos la Transformacion afin y la llamamos A K_multiplica(A,1.0-lam_alfa,k);//A=(a-lam_alfa)*A I=Identidad(k);// generamos la Transformacion Identidad K_multiplica(I,lam_alfa,k);// I=lam_alfa*I Mx_Suma(A,I,k); // A=(a-lam_alfa)*A+lam_alfa*I Mx_Multiplica(A,punto,k,paux);//paux=A*(*punto) liberad(A,k); liberad(I,k); } /*Esta funcion es para determinar si un individuo es aceptado en la poblacion */ int Restriccion(double d[TAMIND],double FACTOR,int n) { int aceptado,g,o,r,l; double dpg1x,dpg1y,dpg2x,dpg2y; /*variables utilizadas paraderivadas parciales*/ double pm1,pm2,m1t,m2t; /*variables para tomar los valores de las pendientes*/ double w,k; /*variables para contadores*/ double lam; double *listm1, *listm2; /* variables para los vectores de pendientes*/ vector p; // p de punto aceptado=0; /*suponemos que el individuo no es aceptado en la poblacion*/ if (d[4]>min_alfa && d[4]<tope_alfa) /*alfa debe estar en un umbral para verificar que un individuo es aceptado*/ { listm1=Creavektor(n); /*vector para almacenar las pendientes m1*/ listm2=Creavektor(n); /*vector para almacenar las pendientes m2*/ l=0; w=0.0; for (g=0; g<T*n;g++) { k=0.0; for (o=0; o<T*n;o++) { p[0]=w; p[1]=k; if (Norma(p)) { lam=Lamda(p); /*calculo de derivadas parciales de las funciones g1(X),g2(X), evaluadas en cada Y en el dominio de la resolucion*/ dpg1x=(1.0+d[0]*(1.0-pow(lam,d[4]))-(4.0*d[4])*(d[0]*p[0]+d[1]*p[1])*(p[0]0.5)*(pow(lam,d[4]-2.0)))+(1e-4); dpg1y=(d[1]*(1.0-pow(lam,d[4]))-(4.0*d[4])*(d[0]*p[0]+d[1]*p[1])*(p[1]-0.5)*(pow(lam,d[4]-2.0))); dpg2x=(d[2]*(1.0-pow(lam,d[4]))-(4.0*d[4])*(d[2]*p[0]+d[3]*p[1])*(p[0]-0.5)*(pow(lam,d[4]2.0)))+(1e-4); dpg2y=(1.0+d[3]*(1.0-pow(lam,d[4]))-(4.0*d[4])*(d[2]*p[0]+d[3]*p[1])*(p[1]-0.5)*(pow(lam,d[4]2.0))); pm1=fabs(dpg1y/dpg1x); /*pendiente 1 m1 para cada Y en el dominio de la resolucion*/ pm2=fabs(dpg2y/dpg2x); /* pendiente 2 d.Indi[0]m2 para cada Y en el dominio de la resolucion*/ listm1[l]=pm1; /*colocamos la m1 en el vector de m1's*/ listm2[l]=pm2; /*colocamos la m2 en el vector de m2's*/ l++; } k=k+(double)(1.0/(n*T)); } w=w+(double)(1.0/(n*T)); }

60

m1t=Maxt(listm1,l)+(1e-4); /*maximo de las pendientes m1*/ free(listm1); m2t=Mint(listm2,l)-(1e-4);/*minimo de las pendientes m2*/ free(listm2); if ((FACTOR*m1t)<(m2t)) /*prueba para admitir o no el individuo*/ aceptado=1; } return (aceptado); } /*En esta funcion creamos una matriz Identidad de tamao n*/ double **Identidad(int n) { double **id=NULL; int i,k; /*pedimos un arreglo de tama ? o N de apuntadores*/ id=crea_matriz_F(n); for (i=0;i<n;i++) for(k=0;k<n;k++) { if (i==k) id [i][k]=1.0; } return (id); } /*En esta funcion llenamos una matriz de Transformacion afin compuesta por cuatro parametros*/ double **Trans_afin(double indi[TAMIND],int n) { double **a=NULL; a=crea_matriz_F(n); a[0][0]=1.0+indi[0]; a[0][1]=indi[1]; a[1][0]=indi[2]; a[1][1]=1.0+indi[3]; return(a); } /*Esta es la funcion que Interpola los elmentos de la matriz*/ void interpola_matriz1(int **A,int n) { int i,j,k,z,cv,ch,pos,posh,posv; int va,vab,viz,vder,conta=3; int arrx,arry,abax,abay; int valini, valfin,intervalos,posinterv; double diag1,diag2,verti,horizont; for(i=0;i<n;i++) for(j=0;j<n;j++) if (A[i][j]==0)//encontramos un 0 {

61

posv=1; vab=Valab(A,i,j,&cv);// y el valor no 0 que se encuentra abajo de el va=Varrib(A,i,j); //pedimos el valor que se encuentra arriba de el viz=Valizq(A,i,j,&pos);//pedimos el valor no 0 que se encuentra a la izq vder=Valder(A,i,pos,&ch);//pedimos el valor no 0 que se encuentra a la der posh=j-pos+1; verti=Interp(va,vab,cv,posv); horizont= Interp(viz,vder,ch,posh); valini= abaizq(A,i,j,&abax,&abay); valfin= arrder(A,i,j,&arrx,&arry); intervalos= arry-abay + 1; posinterv= j-abay +1; diag1=Interp(valini,valfin,intervalos,posinterv); valini= arrizq(A,i,j,&arrx,&arry); valfin= abader(A,arrx,arry,&abax,&abay); intervalos= abay-arry + 1; posinterv= j-arry +1; diag2=Interp(valini,valfin,intervalos,posinterv); A[i][j]=(int)Redond(Prme(verti,horizont,diag1,diag2)); } } /*Con esta funcion, buscamos y regresamos el primer valor distinto de cero , que se encuentra la derecha de un cero en el renglon i, empezando por la columna pos*/ int Valder(int **A, int i,int pos, int *ch) { int x; *ch=0; while(A[i][pos]==0) { pos++; (*ch)++; } x=A[i][pos]; return(x); } /*Con esta funcion, buscamos y regresamos el primer valor distinto de cero, que se encuentra la izquierda de un cero en el renglon i, empezando por la columna j*/ int Valizq(int **A, int i,int j, int *pos) { int x; *pos=0; while(A[i][j]==0) j--; (*pos)=j+1; x=A[i][j]; return(x); } /*Con esta funcion determinamos el primer valor distinto de cero, que se encuentra debajo de un cero, de la columna j */

62

int Valab(int **A, int i,int j, int *cv) { int x; *cv=0; while(A[i][j]==0) { i++; (*cv)++; } x=A[i][j]; return(x); } /*Con esta funcion regresamos el valor que se encuentra arriba del elemento [i,j], de la matriz A*/ int Varrib(int ** A,int i,int j) { int val; val=A[i-1][j]; return (val); } /*regresa el primer valor no 0 en la diagonal arriba-derecha partiendo de la posicion donde hay un 0: i,j . en arrx y arry guarda las coordenadas donde esta el ultimo 0 de la diagonal*/ int arrder(int **mat,int i,int j,int *arrx,int *arry) { while(mat[i][j]==0) { i--; j++; } *arrx= i+1; *arry= j-1; return(mat[i][j]); } /*regresa el primer valor no 0 en la diagonal abajo-izquierda partiendo de la posicion donde hay un 0: i,j . en abax y abay guarda las coordenadas donde esta el ultimo 0 de la diagonal*/ int abaizq(int **mat,int i,int j,int *abax,int *abay) { while(mat[i][j]==0) { i++; j--; } *abax= i-1; *abay= j+1; return(mat[i][j]); } /*regresa el primer valor no 0 en la diagonal arriba-izquierda partiendo de la posicion donde hay un 0: i,j . en arrx y arry guarda las coordenadas donde esta el ultimo 0 de la diagonal*/ int arrizq(int **mat,int i,int j,int *arrx,int *arry) { while(mat[i][j]==0) { i--; j--;

63

} *arrx= i+1; *arry= j+1; return(mat[i][j]); } /*regresa el primer valor no 0 en la diagonal abajo-derecha partiendo de la posicion donde hay un 0: i,j . en abax y abay guarda las coordenadas donde esta el ultimo 0 de la diagonal*/ int abader(int **mat,int i,int j,int *abax,int *abay) { while(mat[i][j]==0) { i++; j++; } *abax= i-1; *abay= j-1; return(mat[i][j]); } /*Esta funcion sirve para Redondear un numero real al entero mas cercano*/ double Redond(double x) { double xp; if (ceil(x)-x<=0.5) xp=ceil(x); else xp=floor(x); return (xp); } /* En esta funcion calculamos el promedio de dos numeros, double Prme(double x,double y,double w, double z) { double mitad; mitad=((x+y+w+z)/4); return(mitad); } /*En esta funcion determinamos y devolvemos el valor Interpolado, correspondiente a la posicion pos*/ double Interp(int vi,int vf,int inter,int pos) { double vin; vin=(( ( ((double)vf) - ((double)vi) )/ (((double)inter)+1) )* ((double)pos)) + ((double)vi); return (vin); } double GeneraAleatorio(void) { int PAleatorio,j; double SAleatorio; PAleatorio=rand() % 101; y regresamos la parte entera de este*/

64

SAleatorio=((double)PAleatorio/100-0.5); return SAleatorio; } /*Esta funcin se genera un numero Aleatorio entre 1 y -1*/ double AleatorioUno(void) { int Aleatorio_C=0,Aleatorio_U=0; double Aleatorio=0.0; Aleatorio_C=rand() % 101; Aleatorio=((double)Aleatorio_C/100); Aleatorio_U=rand() % 2; if (Aleatorio_U==0) Aleatorio=-1*Aleatorio; return Aleatorio; }

/*Esta funcin se genera un numero Aleatorio entre 2 y 3*/ double AleatorioDosTres(void) { int Aleatorio_C=0; double Aleatorio=0.0; Aleatorio_C=rand() % 101; Aleatorio=((double)Aleatorio_C/100)*(tope_alfa-min_alfa)+min_alfa; return Aleatorio; } /*Esta funcin se genera un numero Aleatorio entre 1 y 5*/ int GeneraAleatorioCinco(void) { int Aleatorio,j; Aleatorio=rand() %5; return Aleatorio;

/*Esta funcin se genera un numero Aleatorio entre -0.125 y +0.125 */ double GeneraAleatorioMutac() { int PAleatorio,j; double SAleatorio; PAleatorio=rand() % 101; // SAleatorio=((double)PAleatorio/100-0.5)/4; SAleatorio=((double)PAleatorio/100-0.5)/10; return SAleatorio;

65

} /*Se determina su debe aplicarse el parmetro de mutacin en el AG*/ int Velocidad_Mutacion(int contador) { double mutrate; int Aleatorio,M=0; //mutrate=MUTRATEMIN+(double)(contador-1)*MUTRATEMAX/REPMAX; mutrate = MUTRATEMAX-(double)(contador-1)*MUTRATEMAX/REPMAX+MUTRATEMIN; Aleatorio=1+rand() %101; if ((double)Aleatorio < mutrate*100) { M=1; } return M; } /*Se mutan los individuos de la poblacin*/ double **Mutacion(double **A,int Tam_Pob,int Tam_Mat) { int i,Aleatorio; double Ale_Mut; for(i=0;i<Tam_Pob;i++) { Ale_Mut=GeneraAleatorioMutac(); Aleatorio=GeneraAleatorioCinco(); A[i][Aleatorio]=A[i][Aleatorio]+Ale_Mut;

} return A; }

/*Se busca el mejor individuo de la Poblacin , y se salva en Ap_Mejor*/ void Mejor(double Ap_Mejor[TAMIND],double **Ap,int TamPob) { int i,j; double Mejor; for(j=0;j<TAMIND;j++) Ap_Mejor[j]=Ap[0][j]; Mejor=Ap[0][5]; for(i=0;i<TamPob;i++) { if(Ap[i][5]>Mejor) { Mejor=Ap[i][5]; for(j=0;j<TAMIND;j++) Ap_Mejor[j]=Ap[i][j];

66

} } } /*Se reproduce un solo individuo de la poblacin*/ void Reproduccion(double A[TAMIND],int Tonos,double Ap_Mejor[TAMIND]) { int i,j,k; double Ap_Resta[TAMIND]; double Aux1; double Niu; Aux1=((Ap_Mejor[5]-A[5])/Ap_Mejor[5]); for(j=0;j<5;j++) Ap_Resta[j]=(Ap_Mejor[j] - A[j])*Aux1; Niu=Nu(Ap_Resta); for(j=0;j<5;j++) A[j]=A[j] + Ap_Resta[j]*Niu; } /*Se calcula el valor de Nu*/ double Nu(double Ap_Indi[TAMIND]) { double Nu_Ind; Nu_Ind=Promedio(Ap_Indi); // Calcula el promedio de los elementos del arreglo (a,b,c,d,alfa) Nu_Ind=1/(100*Nu_Ind+1e-8); } return Nu_Ind;

/*Se calcula el promedio de un conjunto de datos, que llegan en el arreglo Elemento */ double Promedio(double Elemento[TAMIND]) { double Promedio; int i; Promedio=0.0; for(i=0;i<5;i++) Promedio=fabs(Elemento[i])+Promedio; Promedio=Promedio/5; return Promedio; } /*Se calcula costo de acuerdo al numero de nivles de gris */ double Costo(double *Ap_F,double *Ap_T,double **MC,int frec,int Tam_Mat) { double SumF,SumT,SumCF,SumC,Total;

67

SumF=Suma(Ap_F,frec+1); SumT=Suma(Ap_T,frec+1); SumC=SumaCon(MC,frec+1); Total=(SumF+SumT)/SumC; return Total; }

/*Se reproduce la poblacin*/ void Reproduccion_Total(int Tam_Pob,double **Ap_Pob,int Niveles,double **Ap_Pob_C,int Tam_Mat,double *mejor_global) { int i,res; int Indice=0; for(i=0;i<Tam_Pob;i++) { Reproduccion(Ap_Pob_C[i],Niveles,mejor_global); /*SE REPRODUCE LA POBLACION*/ } for(i=0;i<Tam_Pob;i++) { res=Restriccion(Ap_Pob_C[i],1,Tam_Mat); if(res==1) Copia(Ap_Pob[i],Ap_Pob_C[i]); } } /*Funcin que redondea un numero real de doble precision y devulve un entero*/ int Redondea(double x) { int xp; if (ceil(x)-x<=0.5) xp=(int)ceil(x); else xp=(int)floor(x); return (xp); } /*se calcula la suma de un arreglo y se regresa este valor */ double Suma(double *Ap,int Tam_Mat) { int i; double suma; suma=0.0;

68

for(i=0;i<Tam_Mat;i++) suma=((Ap[i])*log10(Ap[i]))+suma; return suma; }

/*Se calcula de los elementosd e una matriz, de tamao Tam_Mat y se regresa este valor*/ double SumaCon(double ** M,int Tam_Mat) { int k,j; double Suma; Suma=0.0; for(k=0;k<Tam_Mat;k++) { for(j=0;j<Tam_Mat;j++) { Suma=Suma+log10(M[k][j])*(M[k][j]); } } Suma=Suma*2; return Suma; } /*Se obtiene la suma de los valores de cada columna de una matriz*/ void Frec_FT(double **MPC,int Niveles,double *Ap_Ind) { int i,j; double Contador; Contador=0.0; for(i=0;i<Niveles+1;i++) { for(j=0;j<Niveles+1;j++) { Contador=MPC[j][i]+Contador; } Ap_Ind[i]=Contador; Contador=0; } } /*Se obtiene la suma de los valores de cada filas de una matriz*/ void Frec_F(double **MPC,int Niveles,double *Ap_Ind) { int i,j; double Contador;

69

Contador=0.0; for(i=0;i<Niveles+1;i++) { for(j=0;j<Niveles+1;j++) { Contador=MPC[i][j]+Contador; } Ap_Ind[i]=Contador; Contador=0; } }

void Evalua(double *Ap_F,double *Ap_FT,double **MPC,int f,double A[TAMIND],int TamPob) { double costo; costo=Costo(Ap_F,Ap_FT,MPC,f,TamPob); A[5]=costo; } /*En este procedimiento se evalua la poblacin*/ void Evaluacion_Total(int Tam_Pob,int Tam_Mat,double **Ap_Pob,int ** MON,int **MF,int **MFT,int **MFTN,int Niveles,double *F,double *FT) { int i,Mayor; double **MPC=NULL; for(i=0;i<Tam_Pob;i++) { Transforma_Total(MFT,MF,Ap_Pob[i],Tam_Mat); Mayor=Mayor_TGris(MFT,Tam_Mat);//obtiene el elemento mayor de la matriz fuente

Transformada

Normalizar(MFT,MFTN,Tam_Mat,Mayor,Niveles);// Normaliza la matriz fuente Transformada segun los niveles de gris deseados MPC=ProConjunta(MON,MFTN,Tam_Mat,Niveles); // Calcula la probabilidad conjunta Frec_F(MPC,Niveles,F); // Calcula las frecuencias de la fuente Frec_FT(MPC,Niveles,FT); // Calcula las frecuencias de la Transformada Evalua(F,FT,MPC,Niveles,Ap_Pob[i],Tam_Pob); /* EVALUA LA POBLACION */ CerosVector(F,Niveles+1); CerosVector(FT,Niveles+1); inicia_ceros(MFTN,Tam_Mat); liberad(MPC,Niveles+1); } }

70

/*Se calcula la probabilidad conjunta y la normaliza , se regresa este valor*/ double **ProConjunta(int **MF,int **MT,int Tam,int Nivel) { int i,j,k,l; double **MPC=NULL; double Total; /* Pide memoria para la matriz de probabilidad conjunta*/ MPC=crea_matriz_F(Nivel+1); /* Obtiene las frecuencias de cada numero de las matrices ( fuente Transformada y objetivo ) */ Total = 0; for(i=0;i<Tam;i++) { for(j=0;j<Tam;j++) { k=MF[i][j]; l=MT[i][j]; MPC[k][l]=MPC[k][l]+1.0; } } Total=Tam*Tam; /* Divide cada elemento de la matriz entre la suma total */ for(i=0;i<Nivel+1;i++) { for(j=0;j<Nivel+1;j++) { MPC[i][j]=MPC[i][j]/Total + 1e-20; } } return MPC;

/*En este procedimiento se normaliza una matriz de acerdo con el mayor valor en ella*/ void Normalizar(int **M,int **NL,int Tam,int MayorGris,int NivelGris) { int i,j;

for(i=0;i<Tam;i++) { for(j=0;j<Tam;j++) NL[i][j]=Redondea(((double)M[i][j])*((double)NivelGris/MayorGris)); } }

71

/*Funcin que inicializa la poblacin */ double **Inicializa(int TamPob,int Tam_Mat,double Factor) { int i,j,k,Elige,Contador; double **Aux=NULL,**Ap=NULL; time_t Uno; time_t DosTres; Ap=crea_matriz_P(TamPob); for(k=0;k<4;k++) Ap[0][k]=0.0; Ap[0][4]=(tope_alfa - min_alfa )/ 2.0 + min_alfa; Contador=0; for(i=0;i<TamPob-1;i++) { Elige=0; for(j=0;j<4;j++) // Coloca un numero aleaorio entre -5 y +5 (a,b,b,d) Ap[i+1][j]=GeneraAleatorio(); // Coloca un numero aleaorio entre +2 y +3 (alfa) Ap[i+1][4]=AleatorioDosTres(); Elige=Restriccion(Ap[i+1],1,Tam_Mat); // Checa si el individuo generado es aceptado if (Elige==0) // No acepto al individuo y decrementa el contador para generar otro // en la misma pocision i=i-1; } } return Ap;

/*Se obtiene el mayor elemento de una matriz, de tamao Tam */ int Mayor_TGris(int **M,int Tam) { int i,j,Mayor; Mayor=M[0][0]; for(i=0;i<Tam;i++) { for(j=0;j<Tam;j++) { if(M[i][j]>Mayor) Mayor=M[i][j]; } return Mayor; }

72

} /*FUNCIONES PARA MANEJO DE LISTA */ /*En esta funcin se crea un nodo*/ nodo *creanodom(int ** fuente, int **destino,int coor[2],int tam) { nodo *nnuevo; nnuevo=(nodo *)calloc(1,sizeof(nodo)); if (nnuevo!=NULL) { nnuevo->inicia[0]=coor[0]; nnuevo->inicia[1]=coor[1] ; nnuevo->pfuente=fuente; nnuevo->pdestino=destino; nnuevo->tam=tam; nnuevo->sigte=NULL; } else { printf("!Error! ... memoria insuficiente\n"); exit(0); } return(nnuevo); }

/*Esta funcion sirve para insertar un nodo en la lista que contiene las matrices fuentes y objetivos*/ void insertanodo(lista *l,nodo *n) { nodo *auxn; if (l->first==NULL) { l->first=n; l->tama = UNO; } else { auxn=l->first; while (auxn->sigte != NULL) auxn = auxn->sigte; (auxn->sigte) = n; (l->tama)++; } } /*Esta funcion sirve para eliminar un nodo de la lista*/ void eliminanodo(lista *l) { nodo* aux; if (!esvacia(*l)) { aux=l->first;

73

l->first=aux->sigte; (l->tama)--; aux->pfuente=libera(aux->pfuente,aux->tam); aux->pdestino=libera(aux->pdestino,aux->tam); free(aux); } else { printf("error la lista esta vacia\n"); exit(1); }

/*Esta funcion sirve para decir si la lista es o no vacia */ int esvacia(lista l) { int x; if (l.first==NULL) x=1; else x=0; return(x); } /*En este procedimiento de inicializan los datos para la ejecucin del AGP*/ void inicializa_datos(int *ngris,int *ntam,int *npob, int nproc) { printf("\n\n* * Proporciona los siguientes datos * * \n\n"); printf("\n[Niveles de gris] "); scanf("%d",ngris); printf("\n[Orden de la matriz] "); scanf("%d",ntam); printf(" Orden de la matriz %d ", *ntam); printf("\n[Tamao de la poblacion] "); scanf("%d",npob); (*npob)=(*npob)/nproc; }

/*En esta funcin se iniicaliza la lista, con la imgenes que se va na aprocesar */ void inicializa_lista(lista *l,int tam,int nivel,char imagen[],char imagen_r[],int *mayorng) { FILE * fuente; FILE *objetivo; int origen[DOS]; int **mf,**mo,**mon; nodo *nodoi; origen[CERO]=origen[UNO]=0; levanta_imagenes(&mf,&mo,tam,imagen,imagen_r);

74

(*mayorng)=Mayor_TGris(mo,tam); mon=crea_matriz(tam); Normalizar(mo,mon,tam,*mayorng,nivel);/*CUIDADO*/ l->first=NULL; nodoi=creanodom(mf,mon,origen,tam); insertanodo(l,nodoi); mf=NULL; mon=NULL; mo=libera(mo,tam); } /*En este procedimiento se colocan los valores de las imgenes en las matrices respectivas*/ void levanta_imagenes(int ***mf,int ***mo,int tam,char imagen[30],char imagen_r[30]) { char nomfte[30],nomobj[30]; printf("\n[Nombre de la imagen fuente] "); scanf("%s",nomfte); printf("\nimagen fuente %s ",nomfte); printf("\n[Nombre de la imagen objetivo] "); scanf("%s",nomobj); printf("\nimagen objetivo %s ",nomobj); printf("\n[Nombre de la imagen de salida] "); scanf("%s",imagen); printf("\nimagen de salida %s ",imagen); strcat(imagen_r,imagen); strcat(imagen_r,"r.txt"); printf("\narchivo para reproduccion %s de imagen_r " ,imagen_r); Abre(nomfte,nomobj,mf,mo,tam); } /*En esta funcin los archivo, donde se encuantra una imagen y se colaca en las matrices */ void Abre(char Fuente[30],char Objetivo[30],int ***MF,int ***MO,int Tam_Mat) { FILE *Ap_A=NULL,*Ap_Ao=NULL; char Modo[2]="r"; int i; Ap_A=Abre_ArchivoLee(Fuente,Ap_A,Modo); // Abre el archivo que contiene los datos de la imagen fuente *MF=Lee_Matriz(Tam_Mat,Ap_A); // Se colocan los datos del archivo en una matiz Cierra_Archivo(Ap_A); Ap_Ao=Abre_ArchivoLee(Objetivo,Ap_Ao,Modo); // Abre el archivo que contiene los datos de la imagen objetivo *MO=Lee_Matriz(Tam_Mat,Ap_Ao); // Se colocan los datos del archivo en una matiz Cierra_Archivo(Ap_Ao); } /*Esta funcin abre un archivo, en el modo que se indique, se regresa el apuntador al archivo*/ FILE *Abre_ArchivoLee(char Nombre[30],FILE *Ap_Archivo,char Modo[2]) { if((Ap_Archivo=fopen(Nombre,Modo))==NULL) // VERIFICA SI HAY ALGUN ERROR // EN LA APERTURA DEL ARCHIVO {

75

printf("ERROR EN LA APERTURA DEL ARCHIVO"); exit(1);//SI HA ERROR EN LA APERTURA DEL ARCHIVO SE TERMINA EL PROGRAMA } else } /*En este procedimiento se cierra un archivo*/ void Cierra_Archivo(FILE *Ap_Archivo) { fclose(Ap_Archivo); // CIERRA EL ARCIVO } /*En este procedimiento se asigna memoria a las matrices */ void asigna_memoriap(int ***mft,int ***mftn,double **f,double **ft,int tam,int niveles) { *mft=crea_matriz(tam); *mftn=crea_matriz(tam); *f=Crea_Histograma(niveles+1); *ft=Crea_Histograma(niveles+1); } /*En este procedimiento se implementa la el AGP estrategia 1-*/ void geneticop(int **mf,int **mon,int tam_pob,int niveles,int tam_mat,double mejorg[SEIS], int mi_id, int nproc, MPI_Comm komm,FILE ** repro_p) { double mejor[TAMIND]; double mi_mejor[TAMIND]; int i; int cg=0; int maestro=0; double todos[90]; int **mft=NULL,**mftn=NULL; double *f=NULL,*ft=NULL; double **pob_c=NULL,**pob=NULL; asigna_memoriap(&mft,&mftn,&f,&ft,tam_mat,niveles); pob=Inicializa(tam_pob,tam_mat,1); /* GENERA POBLACION INICIAL HASTA OBTENER INDIVIDUO VALIDO */ pob_c=crea_matriz_P(tam_pob); for(i=0;i<SEIS;i++) mi_mejor[i]=0.0; while(cg<REPMAX) { Evaluacion_Total(tam_pob,tam_mat,pob,mon,mf,mft,mftn,niveles,f,ft); Mejor(mejor,pob,tam_pob);/*Se obtiene el mejor individuo de la poblacion */ /*El procesador maestro junta todos los individuos en cada poblacion*/ return(Ap_Archivo);

UN

76

MPI_Gather(mejor,SEIS,MPI_DOUBLE,todos,SEIS,MPI_DOUBLE,maestro,MPI_COMM_WORLD); if (mi_id==0) { busca_mejor(mejor,todos,nproc); /*se busca el mejor global*/ actualiza_mejor_cont(mi_mejor,mejor,&cg);/*actualizo cuantas veces se ha repetido el mejor global*/ copia_mejorp(mi_mejor,mejorg); /*el maestro quedo con el mejor global*/ fprintf(*repro_p,"%f %f %f %f %f %f \n",mejor[CERO],mejor[UNO],mejor[DOS],mejor[TRES],mejor[CUATRO],mejor[CINCO]); } MPI_Bcast(mejor,SEIS,MPI_DOUBLE,maestro,MPI_COMM_WORLD); /*todos toman el mejor global*/ MPI_Bcast(&cg,1,MPI_INT,maestro,komm); /*todos toman en contador del mejor global*/ for(i=0;i<tam_pob;i++) Copia(pob_c[i],pob[i]); if (Velocidad_Mutacion(cg)) pob_c=Mutacion(pob_c,tam_pob,tam_mat); Reproduccion_Total(tam_pob,pob,niveles,pob_c,tam_mat,mejor); } /*se libera la memoria utilizada*/ mft=libera(mft,tam_mat); mftn=libera(mftn,tam_mat); liberad(pob_c,tam_pob); liberad(pob,tam_pob); }

/*En este procedimiento se busca el mejor elemento de un conjunto de individuos*/ void busca_mejor(double *mejor, double *todos,int n) { int i,j,indice; double valor; valor=todos[CINCO]; indice=CINCO; for (i=11;i<SEIS*n;i=i+SEIS) if (todos[i]>valor) { valor=todos[i]; indice=i; } i=0; for (j=indice-CINCO;j<indice+1;j++) { mejor[i]=todos[j]; i++;

77

} } /*En este procedimiento se actualiza el contador global del numero de repeticiones*/ void actualiza_mejor_cont(double *mlocal,double*mglobal, int *contglobal) { int i; if (mglobal[CINCO]>mlocal[CINCO]) /*el nuevo mejor global tiene mayor fitness que el anterior*/ { for (i=0;i<SEIS;i++) /*hacemos el intercambio, el nuevo mejor global se queda en el*/ mlocal[i]=mglobal[i]; /*proceso maestro*/ *contglobal=1; } else { for (i=0;i<SEIS;i++) /*hacemos el intercambio al mejor global, porque es el que */ mglobal[i]=mlocal[i]; /*se envia a los demas procesos*/ *contglobal=(*contglobal)+1; /*el nuevo mejor global tiene igual fitness que el anterior*/ } /*incrementamos el contador de repeticiones*/ } /*Se copia de un arreglo a otro */ void copia_mejorp(double mi_mejor[SEIS],double mejor2[SEIS]) { int i; for (i=0;i<SEIS;i++) mejor2[i]=mi_mejor[i]; } /*Se evalua la calidad de una imagen*/ double eval_final_p(int tam_mat,int ** mfinal,int **mon,int niveles) { int mayor; double **mpc=NULL; double *f=NULL,*ft=NULL; double devuelto; f=Crea_Histograma(niveles+1); ft=Crea_Histograma(niveles+1); mpc=ProConjunta(mon,mfinal,tam_mat,niveles); Frec_F(mpc,niveles,f); Frec_FT(mpc,niveles,ft); devuelto=Costo(f,ft,mpc,niveles,tam_mat); liberad(mpc,niveles+1); free(f); free(ft); return(devuelto);

/*En este procedimeinto se envian los parametros a los procesos esclavos, asi como las imagenes*/

78

void envios(int mi_id, int nproc, MPI_Comm komm) { double calidadf,calidadi, mejor[SEIS]; int ngris,tpob,tam,tamorig,mayorng,i,terminado=0; int **mf,**mo,**mtfinal,**mobjetivo,**mnormalizadaf; char imagen_final[30] ; //para guardar el nombre del archivo de la imagen final char imagen_r[30]; //para guardar el nombre del archivo para reproducir el procesamiento FILE * repro_p; mejor[CINCO]=0.0; if (mi_id==0) /*abrir un archivo para escribir comfiguracion */ { inicializa_datos(&ngris,&tam,&tpob,nproc); mtfinal=crea_matriz(tam); mobjetivo=crea_matriz(tam); mnormalizadaf=crea_matriz(tam); inicializa_lista(&cab,tam,ngris,imagen_final,imagen_r,&mayorng); // inicializo la lista copia_matriz(mobjetivo,cab.first->pdestino,tam); calidadi= eval_final_p(tam,cab.first->pfuente,mobjetivo,ngris); repro_p=Abre_ArchivoLee(imagen_r,repro_p,"w"); //se abre el archivo de datos para reproducir el procesamiento. } MPI_Bcast(&ngris,UNO,MPI_INT,0,MPI_COMM_WORLD); MPI_Bcast(&tpob,UNO,MPI_INT,0,MPI_COMM_WORLD); MPI_Bcast(&tam,UNO,MPI_INT,0,MPI_COMM_WORLD); mf=crea_matriz(tam); // se genera espacio para la matrices mo=crea_matriz(tam); if (mi_id==0) { copia_matriz(mf,cab.first->pfuente,tam); // copio la matriz fuente copia_matriz(mo,cab.first->pdestino,tam);// copio la matriz destino eliminanodo(&cab); } for(i=0;i<tam;i++) // se hace un broadcas para el envio de matrices MPI_Bcast((mf[i]),tam,MPI_INT,0,MPI_COMM_WORLD); for(i=0;i<tam;i++) MPI_Bcast((mo[i]),tam,MPI_INT,0,MPI_COMM_WORLD); geneticop(mf,mo,tpob,ngris,tam,mejor,mi_id,nproc, komm,&repro_p); //aqui la matriz objetivo ya va normalizada if (mi_id ==0) Im_Indiv(mejor); if (mi_id ==0) { Transforma_Total(mf,mnormalizadaf,mejor,tam); Normalizar(mtfinal,mnormalizadaf,tam,mayorng,ngris); calidadf=eval_final_p(tam,mtfinal,mobjetivo,ngris); Escribe_Matriz(tam,mtfinal,imagen_final); printf("\ncosto imagen inicial = %f \n",calidadi); printf("costo imagen final = %f \n",calidadf);

if (mi_id ==0)

79

Cierra_Archivo(repro_p); /*cerrar el archivo de configuracion para reproducir*/

/*Funcin Principal. Se inicaliza y se Finaliza el Entorno de Envio de mensajes*/ int main(int argc,char** argv) { MPI_Status status; MPI_Comm komm; MPI_Request request; int mi_id, tag=99,source; int dest =0; int maestro=0,nproc; double tiempo_inicial,tiempo_final; time_t (time1); time1= time(NULL); srand(time1); MPI_Init(&argc,&argv); MPI_Comm_rank(MPI_COMM_WORLD,&mi_id); MPI_Comm_size(MPI_COMM_WORLD,&nproc); MPI_Comm_dup(MPI_COMM_WORLD,&komm); tiempo_inicial=MPI_Wtime(); envios(mi_id, nproc,komm); tiempo_final=MPI_Wtime(); MPI_Barrier(MPI_COMM_WORLD); if (mi_id==0) printf("\ntiempo [%f]m \n", (tiempo_final-tiempo_inicial)/(60.0)); MPI_Finalize(); } /*ZAMORA VENEGAS MARIA DE LA LUZ*/

80

ANEXO B AMPLIACION DEL CODIGO FUENTE EN C MPI PARA EL ALGORTIMO GENETICO PARALELO (ESTRATEGIA 2) APLICADO EN LA ALINEACION NO RIGIDA DE IMGENES MEDICAS

81

8. Anexo B Ampliacin del Cdigo fuente en C - MPI para el Algoritmo Gentico Paralelo (estrategia 2) aplicado en la alineacin no rgida de imgenes mdicas.
/*PROTOTIPOS DE FUNCIONES*/ void envios(int mi_id, int nproc, MPI_Comm komm); void inicializa_datos(int *ngris,int *ntam,int *npob,double *aptitudf,int *resolucion, int nproc); double eval_final(int tam_mat,int ** mfinal,int **mon,int niveles); void geneticop(int **mf,int **mon,int tam_pob,int niveles,int tam_mat,double mejorg[SEIS], int mi_id, int nproc, MPI_Comm komm); void decideparticion(lista * l,double *mejor ,int ** mfinal,double aptitudf,int res_min); void transforma_p(int ** fuente,double mejor[SEIS],int n); void reconstruyematrix(int ** final,nodo *part); int ** cesquinas(int **vector,int * origen,int tam) ; void envios(int mi_id, int nproc, MPI_Comm komm);

/*REDECLARACION DE FUNCIONES */ { double calidadf,calidadi,aptitudf, mejor[SEIS]; int ngris,tpob,tam,tamorig,res_min,mayorng,i,terminado=0; int **mf=NULL,**mo=NULL,**mfinal,**mobjetivo,**mnormalizadaf; char imagen_final[30] ; //para guardar el nombre del archivo de la imagen final char imagen_r[30]; //para guardar el nombre del archivo para reproducir el procesamiento FILE * repro_p; mejor[CINCO]=0.0; if (mi_id==0) { inicializa_datos(&ngris,&tam,&tpob,&aptitudf,&res_min,nproc); mfinal=crea_matriz(tam); mobjetivo=crea_matriz(tam); mnormalizadaf=crea_matriz(tam); tamorig= tam; inicializa_lista(&cab,tam,ngris,imagen_final,imagen_r,&mayorng); // inicializo la lista copia_ma triz(mobjetivo,cab.first->pdestino,tamorig); calidadi= eval_final(tamorig,cab.first->pfuente,mobjetivo,ngris); repro_p=Abre_ArchivoLee(imagen_r,repro_p,"w"); //se abre el archivo de datos para reproducir el procesamiento. } MPI_Bcast(&ngris,UNO,MPI_INT,0,MPI_COMM_WORLD); MPI_Bcast(&tpob,UNO,MPI_INT,0,MPI_COMM_WORLD); while (!terminado) { MPI_Bcast(&tam,UNO,MPI_INT,0,MPI_COMM_WORLD); mf=crea_matriz(tam); mo=crea_matriz(tam); if (mi_id==0) { copia_matriz(mf,cab.first->pfuente,tam); // copio la matriz fuente copia_matriz(mo,cab.first->pdestino,tam);// copio la matriz destino } for(i=0;i<tam;i++) MPI_Bcast((mf[i]),tam,MPI_INT,0,MPI_COMM_WORLD); // mao= *mo; for(i=0;i<tam;i++) MPI_Bcast((mo[i]),tam,MPI_INT,0,MPI_COMM_WORLD);

82

geneticop(mf,mo,tpob,ngris,tam,mejor,mi_id,nproc, komm); mf=libera(mf,tam); mo=libera(mo,tam); if (mi_id ==0) { /*mando el archivo a decide particion para escribir la configuracion para reproducir*/ decideparticion(&cab,mejor,mfinal,aptitudf,res_min,&repro_p); if (esvacia(cab)) { terminado=1; Normalizar(mfinal,mnormalizadaf,tamorig,mayorng,ngris); Escribe_Matriz(tamorig,mnormalizadaf,imagen_final); calidadf= eval_final(tamorig,mnormalizadaf,mobjetivo,ngris); printf(" \ncosto de la imagen inicial = %f \n",calidadi); printf(" costo de la imagen final = %f \n",calidadf); } else tam=cab.first->tam; } MPI_Bcast(&terminado,UNO,MPI_INT,0,MPI_COMM_WORLD); } if (mi_id ==0) Cierra_Archivo(repro_p); } void inicializa_datos(int *ngris,int *ntam,int *npob,double *aptitudf,int *resolucion, int nproc) { printf("\n\n * * Proporciona los siguientes datos * * \n\n"); printf("\n [Niveles de gris] "); scanf("%d",ngris); printf("\n [Orden de la matriz] "); scanf("%d",ntam); printf("\n [Tamao de la poblacion] "); scanf("%d",npob); printf("\n [Aptitud minima para finalizar el procesamiento] "); scanf("%lf",aptitudf); printf("\n [Resolucion minima de procesamiento] "); scanf("%d",resolucion); (*npob)=(*npob)/nproc; }

double eval_final(int tam_mat,int ** mfinal,int **mon,int niveles) { int mayor; int **mftn=NULL; double **mpc=NULL; double *f=NULL,*ft=NULL; double devuelto; mftn=crea_matriz(tam_mat); f=Crea_Histograma(niveles+1); ft=Crea_Histograma(niveles+1); mayor=Mayor_TGris(mfinal,tam_mat); Normalizar(mfinal,mftn,tam_mat,mayor,niveles); mpc=ProConjunta(mon,mftn,tam_mat,niveles); Frec_F(mpc,niveles,f);

83

Frec_FT(mpc,niveles,ft); devuelto=Costo(f,ft,mpc,niveles,tam_mat); mftn=libera(mftn,tam_mat); liberad(mpc,niveles+1); free(f); free(ft); return(devuelto);

void geneticop(int **mf,int **mon,int tam_pob,int niveles,int tam_mat,double mejorg[SEIS], int mi_id, int nproc, MPI_Comm komm) { double mejor[TAMIND]; double mi_mejor[TAMIND]; int i; int cg=0; int maestro=0; double todos[90]; int **mft=NULL,**mftn=NULL; double *f=NULL,*ft=NULL; double **pob_c=NULL,**pob=NULL; asigna_memoriap(&mft,&mftn,&f,&ft,tam_mat,niveles); pob=Inicializa(tam_pob,tam_mat,1); /* GENERA POBLACION INICIAL HASTA OBTENER INDIVIDUO VALIDO */ pob_c=crea_matriz_P(tam_pob); for(i=0;i<SEIS;i++) mi_mejor[i]=0.0; while(cg<REPMAX) { Evaluacion_Total(tam_pob,tam_mat,pob,mon,mf,mft,mftn,niveles,f,ft); Mejor(mejor,pob,tam_pob);/*Se obtiene el mejor individuo de la poblacion */ /*El procesador maestro junta todos los individuos en cada poblacion*/ MPI_Gather(mejor,SEIS,MPI_DOUBLE,todos,SEIS,MPI_DOUBLE,maestro,MPI_COMM_WORLD); if (mi_id==0) { busca_mejor(mejor,todos,nproc); /*se busca el mejor global*/ actualiza_mejor_cont(mi_mejor,mejor,&cg);/*actualizo cuantas veces se ha repetido el mejor global*/ copia_mejorp(mi_mejor,mejorg); /*el maestro quedo con el mejor global*/ } MPI_Bcast(mejor,SEIS,MPI_DOUBLE,maestro,MPI_COMM_WORLD); /*todos toman el mejor global*/ MPI_Bcast(&cg,1,MPI_INT,maestro,komm); /*todos toman en contador del mejor global*/ for(i=0;i<tam_pob;i++) Copia(pob_c[i],pob[i]);

UN

84

if (Velocidad_Mutacion(cg)) pob_c=Mutacion(pob_c,tam_pob,tam_mat); } Reproduccion_Total(tam_pob,pob,niveles,pob_c,tam_mat,mejor);

/*se libera la memoria utilizada*/ mft=libera(mft,tam_mat); mftn=libera(mftn,tam_mat); liberad(pob_c,tam_pob); liberad(pob,tam_pob); } double eval_final(int tam_mat,int ** mfinal,int **mon,int niveles) { int mayor; int **mftn=NULL; double **mpc=NULL; double *f=NULL,*ft=NULL; double devuelto; mftn=crea_matriz(tam_mat); f=Crea_Histograma(niveles+1); ft=Crea_Histograma(niveles+1); mayor=Mayor_TGris(mfinal,tam_mat); Normalizar(mfinal,mftn,tam_mat,mayor,niveles); mpc=ProConjunta(mon,mftn,tam_mat,niveles); Frec_F(mpc,niveles,f); Frec_FT(mpc,niveles,ft); devuelto=Costo(f,ft,mpc,niveles,tam_mat); mftn=libera(mftn,tam_mat); liberad(mpc,niveles+1); free(f); free(ft); return(devuelto); } /*En este procedimiento se determina si la matriz se va a divider, tomando en cuanta las condicones de termino del AGP estrategia 2-*/ void decideparticion(lista * l,double *mejor ,int ** mfinal,double aptitudf,int res_min) { int i,j,k,m,n,ntam; int origen[DOS]; int ** vfuentes[CUATRO],** vdestinos[CUATRO]; int **cooresq; nodo * nodok; if ( !esvacia(*l) ) { ntam=(l->first->tam)/DOS; transforma_p(l->first->pfuente,mejor,l->first->tam); if ((mejor[CINCO]<aptitudf) && (ntam>=res_min) ) { origen[CERO]=l->first->inicia[CERO];

85

que matrices*/

origen[UNO]=l->first->inicia[UNO]; cooresq=cesquinas(cooresq,origen,l->first->tam); /*determinamos las esquinas en deben for (k=CERO;k<CUATRO;k++) { empezar las nuevas

/*creamos las matrices para las posibles particiones*/

} for(i=CERO;i<ntam;i++) /* copiamos a las nuevas matrices el contenido de la particion correspondiente de la*/ for (j=CERO;j<ntam;j++) /*matriz inicial*/ { vfuentes[CERO][i][j]=l->first->pfuente[i][j]; vdestinos[CERO][i][j]=l->first->pdestino[i][j]; vfuentes[UNO][i][j]=l->first->pfuente[i][j+ntam]; vdestinos[UNO][i][j]=l->first->pdestino[i][j+ntam]; vfuentes[DOS][i][j]=l->first->pfuente[i+ntam][j]; vdestinos[DOS][i][j]=l->first->pdestino[i+ntam][j]; vfuentes[TRES][i][j]=l->first->pfuente[i+ntam][j+ntam]; vdestinos[TRES][i][j]=l->first->pdestino[i+ntam][j+ntam]; } eliminanodo(l); for (k=CERO;k<CUATRO;k++) { nodok= creanodom(vfuentes[k],vdestinos[k],cooresq[k],ntam); insertanodo(l,nodok); } cooresq=libera(cooresq,CUATRO); } else { reconstruyematrix(mfinal,l->first); eliminanodo(l); } } } //escribe en archivo

vdestinos[k]=crea_matriz(ntam); vfuentes[k]=crea_matriz(ntam);

void transforma_p(int ** fuente,double mejor[SEIS],int n) { int **B,**C; B=crea_matriz(n); C=crea_matriz(n); inicia_ceros(B,n); copia_matriz(B,fuente,n); k_suma(B,1,n); transforma(C,B,mejor,n); interpola_matriz1(C,n); k_suma(C,-1,n); copia_matriz(fuente,C,n); B=libera(B,n); B=libera(C,n); }

86

void reconstruyematrix(int ** final,nodo *part) { int i,j,k,l,x,y,lr,lc; i=part->inicia[CERO]; j=part->inicia[UNO]; lr=i+part->tam; lc=j+part->tam; x=CERO; for (k=i;k<lr;k++) { y=CERO; for(l=j;l<lc;l++) { final[k][l]=part->pfuente[x][y]; y++; } x++; } } int ** cesquinas(int **vector,int * origen,int tam) { int x,y,z; x=origen[CERO]; y=origen[UNO]; z=tam/DOS; vector=crea_matriz(CUATRO); vector[CERO][CERO]=x; vector[CERO][UNO]=y; vector[UNO][CERO]=x; vector[UNO][UNO]=(y+z); vector[DOS][CERO]=(x+z); vector[DOS][UNO]=y; vector[TRES][CERO]=(x+z); vector[TRES][UNO]=(y+z); return(vector); }

/*En este procedimiento se envan los parmetros a los procesos esclavos, as como las imgenes*/ void envios(int mi_id, int nproc, MPI_Comm komm) { double calidadf,calidadi, mejor[SEIS]; int ngris,tpob,tam,tamorig,mayorng,i,terminado=0; int **mf,**mo,**mtfinal,**mobjetivo,**mnormalizadaf; char imagen_final[30] ; //para guardar el nombre del archivo de la imagen final

87

char imagen_r[30]; //para guardar el nombre del archivo para reproducir el procesamiento FILE * repro_p; mejor[CINCO]=0.0; if (mi_id==0) /*abrir un archivo para escribir comfiguracion */ { inicializa_datos(&ngris,&tam,&tpob,nproc); mtfinal=crea_matriz(tam); mobjetivo=crea_matriz(tam); mnormalizadaf=crea_matriz(tam); inicializa_lista(&cab,tam,ngris,imagen_final,imagen_r,&mayorng); // inicializo la lista copia_matriz(mobjetivo,cab.first->pdestino,tam); calidadi= eval_final_p(tam,cab.first->pfuente,mobjetivo,ngris); repro_p=Abre_ArchivoLee(imagen_r,repro_p,"w"); //se abre el archivo de datos para reproducir el procesamiento. } MPI_Bcast(&ngris,UNO,MPI_INT,0,MPI_COMM_WORLD); MPI_Bcast(&tpob,UNO,MPI_INT,0,MPI_COMM_WORLD); MPI_Bcast(&tam,UNO,MPI_INT,0,MPI_COMM_WORLD); mf=crea_matriz(tam); // se genera espacio para la matrices mo=crea_matriz(tam); if (mi_id==0) { copia_matriz(mf,cab.first->pfuente,tam); // copio la matriz fuente copia_matriz(mo,cab.first->pdestino,tam);// copio la matriz destino eliminanodo(&cab); } for(i=0;i<tam;i++) // se hace un broadcas para el envio de matrices MPI_Bcast((mf[i]),tam,MPI_INT,0,MPI_COMM_WORLD); for(i=0;i<tam;i++) MPI_Bcast((mo[i]),tam,MPI_INT,0,MPI_COMM_WORLD); geneticop(mf,mo,tpob,ngris,tam,mejor,mi_id,nproc, komm,&repro_p); //aqui la matriz objetivo ya va normalizada if (mi_id ==0) Im_Indiv(mejor); if (mi_id ==0) { Transforma_Total(mf,mnormalizadaf,mejor,tam); Normalizar(mtfinal,mnormalizadaf,tam,mayorng,ngris); calidadf=eval_final_p(tam,mtfinal,mobjetivo,ngris); Escribe_Matriz(tam,mtfinal,imagen_final); printf("\ncosto imagen inicial = %f \n",calidadi); printf("costo imagen final = %f \n",calidadf); } if (mi_id ==0) Cierra_Archivo(repro_p); /*cerrar el archivo de configuracion para reproducir*/ } /*Funcin Principal. Se inicaliza y se Finaliza el Entorno de Envio de mensajes*/

88

int main(int argc,char** argv) { MPI_Status status; MPI_Comm komm; MPI_Request request; int mi_id, tag=99,source; int dest =0; int maestro=0,nproc; double tiempo_inicial,tiempo_final; time_t (time1); time1= time(NULL); srand(time1); MPI_Init(&argc,&argv); MPI_Comm_rank(MPI_COMM_WORLD,&mi_id); MPI_Comm_size(MPI_COMM_WORLD,&nproc); MPI_Comm_dup(MPI_COMM_WORLD,&komm); tiempo_inicial=MPI_Wtime(); envios(mi_id, nproc,komm); tiempo_final=MPI_Wtime(); MPI_Barrier(MPI_COMM_WORLD); if (mi_id==0) printf("\ntiempo [%f]m \n", (tiempo_final-tiempo_inicial)/(60.0)); MPI_Finalize(); } /*ZAMORA VENEGAS MARIA DE LA LUZ*/

89

ANEXO C MANUAL DE USUARIO

90

9. Anexo C Manual de usuario. Para la ejecucin de los programas para la alineacin no rgida de imgenes mdicas se necesita lo siguiente: Archivos ejecutables o archivos con el cdigo fuente Archivo de imagen fuente Archivo de imagen objetivo Un cluster (no necesariamente heterogneo) de computadoras con sistema operativo LINUX. Lo primero que se debe hacer es accesar al cluster. Es recomendable tener los archivos necesarios para la ejecucin del programa en un solo directorio, para crearlo se utiliza el comando mkdir. # mkdir genetico_paralelo Luego se cambia al directorio # cd genetico_paralelo Ubicados en este directorio se crea el directorio Result1, para direccionar la salida. # mkdir Result1 Situados en el directorio genetico_paralelo se necesita copiar los archivos aqu, una forma de hace esto es: # cp /cdrom/*.* . , suponiendo que los archivos estn en un cdrom. Para iniciar la ejecucin de los programas se utiliza el siguiente comando: # mpirun -np 5 -machinefile maq8 -nolocal gpnt Despus de ejecutar la instruccin anterior el programa solicita al usuario los siguientes datos: * Proporciona los siguientes datos * * [Niveles de gris] [Orden de la matriz] [Tamao de la poblacion] [Nombre de la imagen fuente] [Nombre de la imagen objetivo] [Nombre de la imagen de salida]

En este caso se deben proporcionar los datos a travs del teclado. Otra forma de ejecutar el programa es generando un script en shell, en donde se escribe la instruccin de inicio, en el shell se direccional los archivos de entrada y salida de datos, veamos un ejemplo: Ejemplo del contenido del shell. mpirun -np 5 -machinefile maq8 -nolocal gpnt < entr_8sgpa > Result1/sal_8sgpant En donde: Maq8 contiene el nombre de los nodos del cluster en donde se va a ejecutar el programa Gpnt es el nombre del archivo ejecutable 5 es el numero de procesadores en donde se va a ejecutar el programa. entr_8sgpa es el archivo de entrada de datos sal_8sgpant es el archivo de salida que se direcciona al directorio Result1.

91

Un archivo de entrada de datos es el siguiente: 10 256 16 15 rmhea169src.raw rmhea169trg1.raw Imag_5sgpa_RM Los nombres de los archivos del shell deben guardarse con extensin .sh, y se les asigna permisos de ejecucin, esto se hace con el comando chmod. # chmod +x nombre_shell.sh Para ejecutar el programa correspondiente al AGP estrategia 2 se introducen los datos desde el teclado o bien se crean shell, con los datos que pida el programa (como en el ejemplo anterior). Si solo se cuenta con el cdigo fuente de ambos programas, se deben compilar para obtener el cdigo ejecutable para esto se utiliza el compilador de mpi para lenguaje C. # mpicc o nombre_archivo_ejecutable nombre_archivo_fuente lm. Se recomienda leer las pginas man que proporciona el sistema operativo LINUX, para el manejo de comandos y compilacin de mpi.

92

También podría gustarte