Você está na página 1de 94

UNIVERSIDADE DO ALGARVE


Faculdade de Ciências e Tecnologia

Processamento distribuı́do do algoritmo
genético compacto através de Web Services

Relatório do projecto do fim de curso de


Samuel Viana, no 18 778
Licenciatura em Informática - Ramo Tecnológico
Orientador: prof. Fernando Lobo

Faro, 2005
Resumo

Este trabalho descreve uma implementação distribuı́da do algoritmo genético


compacto utilizando Web Services. Para isso basta enviar um vector de pro-
babilidades para cada computador disposto a investir algum do seu tempo
de cálculo no referido algoritmo. Usando a Internet como meio de difusão,
será possı́vel estabelecer um esquema de computação em larga escala.
Abstract

This work describes an implementation of the compact genetic algorithm


using Web Services. To accomplish that, a probabilty vector is sent to every
computer willing to contribute some of its processing time in the above-
mentioned algorithm. Using the Internet as the difusion pathway, it will be
possible to establish a large scale computation scheme.
Conteúdo

1 Introdução 7
1.1 Objectivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.2 Organização do relatório . . . . . . . . . . . . . . . . . . . . . 9

2 Web Services 11
2.1 Introdução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.2 Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.2.1 Definição . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.2.2 Vantagens . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2.3 Arquitectura . . . . . . . . . . . . . . . . . . . . . . . . 15
2.3 XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.4 XML Schemas . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.5 WSDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.5.1 Estrutura . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.6 SOAP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.7 Sumário . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

3 O Algoritmo Genético Compacto 33


3.1 Introdução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.2 O Algoritmo Genético Simples . . . . . . . . . . . . . . . . . . 35
3.3 O Algoritmo Genético Compacto . . . . . . . . . . . . . . . . 38
3.4 Aplicação distribuı́da . . . . . . . . . . . . . . . . . . . . . . . 39
3.5 Sumário . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

4 Aplicação Distribuı́da do cGA usando Web Services 46


4.1 Função de teste . . . . . . . . . . . . . . . . . . . . . . . . . . 46
4.2 Simulação em série da arquitectura . . . . . . . . . . . . . . . 49
4.3 Implementação com Web Services . . . . . . . . . . . . . . . . 52
4.4 Sumário . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

5 Resultados e análise 62

1
CONTEÚDO 2

6 Conclusão e Trabalho Futuro 66


6.1 Conclusão . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
6.2 Trabalho Futuro . . . . . . . . . . . . . . . . . . . . . . . . . . 67

A Manual do WebservCGA 69
A.1 Introdução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
A.2 Instalação do servidor . . . . . . . . . . . . . . . . . . . . . . 69
A.3 Instalação do cliente . . . . . . . . . . . . . . . . . . . . . . . 71
A.4 Invocação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

B WEBSERVCGA.WSDL 76

C Código fonte do Webservcga 79


C.1 CGA.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
C.2 CGAmtrap.java . . . . . . . . . . . . . . . . . . . . . . . . . . 84
C.3 CGATesterThread.java . . . . . . . . . . . . . . . . . . . . . . 87
Lista de Figuras

2.1 Arquitectura dos Web Services . . . . . . . . . . . . . . . . . . 15


2.2 Exemplo de um documento estruturado . . . . . . . . . . . . . 18
2.3 XML Namespaces . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.4 XML Schema para o documento mostrado na figura 2.2 . . . . 25
2.5 Hierarquia do WSDL . . . . . . . . . . . . . . . . . . . . . . . 27
2.6 Hierarquia de uma mensagem SOAP . . . . . . . . . . . . . . 30
2.7 Um Pacote SOAP . . . . . . . . . . . . . . . . . . . . . . . . . 30
2.8 Mensagem SOAP enviado pelo cliente . . . . . . . . . . . . . . 31
2.9 Resposta SOAP do servidor . . . . . . . . . . . . . . . . . . . 32

3.1 Um indivı́duo representado por um cromossoma de compri-


mento 10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.2 Passos genéricos de um algoritmo genético . . . . . . . . . . . 36
3.3 Pseudo-Código do cGA([6]) . . . . . . . . . . . . . . . . . . . 40
3.4 O Modelo Worker-Manager . . . . . . . . . . . . . . . . . . . 42

4.1 Função trap de k bits . . . . . . . . . . . . . . . . . . . . . . . 47


4.2 Gráfico de uma trap function de k bits . . . . . . . . . . . . . 48
4.3 Gráficos extraı́dos de [4] . . . . . . . . . . . . . . . . . . . . . 51

5.1 Resultados do Projecto . . . . . . . . . . . . . . . . . . . . . . 63

A.1 Output do programa . . . . . . . . . . . . . . . . . . . . . . . 74

3
Lista de Tabelas

2.1 Alguns tipos primitivos predifinidos . . . . . . . . . . . . . . . 26

4.1 Funções Web Services utilizadas no trabalho . . . . . . . . . . 55


4.2 Parâmetros e valores de retorno das funções Web Services . . . 55
4.3 Elementos XML usados como parâmetros das funções web ser-
vices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

A.1 Opções de Linha de Comandos . . . . . . . . . . . . . . . . . . 73

4
Agradecimentos

Este projecto foi suportado financeiramente pela Fundação de Ciência e Tec-


nologia, no âmbito do projecto de referência POSI/SRI/42065/2001.

5
Lista de acrónimos

cGA Compact Genetic Algorithm

DOM Document Object Model

DTD Document-Type Definition

HTML HyperText MarkUp Language

HTTP HyperText Transfer Protocol

JSP Java Server Pages

RPC Remote Procedure Call

SGML Standard Generalized Markup Language

SOAP Simple Object Access Protocol

SSL Secure Sockets Layer

UDDI Universal Description, Discovery and Integration

URI uniform resource indicator

URL uniform resource locator

WS Web Services

WSCGA Web Services for Compact Genetic Algorithm

WSDL Web Services Definition Language

XML eXtended Markup Language

6
Capı́tulo 1

Introdução

Este trabalho foi realizado no âmbito do projecto final do Ramo tecnológico


da Licenciatura em Informática, leccionada na Universidade do Algarve.

1.1 Objectivos

Este projecto destina-se a demonstrar que o Algoritmo Genético Compacto


[3] pode ser distribuı́do por vários computadores, podendo o mesmo ser exe-
cutado em mais do que um único processador ao mesmo tempo. Várias
formas de aproveitar essa distribuição têm sido desenvolvidas (ver[6] e [4])
nos últimos anos.
O modo comum de proceder estabelece-se de forma que cada unidade
de processamento independente recebe uma cópia de um vector de proba-
bilidades que descreve a frequência de um determinado alelo na população,
gerando indivı́duos a partir desse vector, sendo calculado o mérito (ou fit-
ness) de cada um. Com base nesse fitness, os indivı́duos são sujeitos a um

7
CAPÍTULO 1. INTRODUÇÃO 8

torneio, sendo seleccionados os melhores indivı́duos. Com base nas diferenças


calculadas entre os novos indivı́duos da população e a população original, o
vector de probabilidades é actualizado para reflectir as diferenças entretanto
calculadas.
O tema de projecto proposto vem na sequência de algumas das ideias
sugeridas no trabalho futuro de um projecto anterior, levado a cabo pelo
meu colega Hugo Mártires[6], onde era sugerido utilizar um browser para
fazer as vezes de cliente, em vez dum cliente precisamente desenvolvido para
esse efeito. Ou, em alternativa, desenvolvendo um screensaver que pudesse
aproveitar “tempos mortos” na actividade de um processador com intenção
de aproveitar essas ocasiões para cálculo em projectos de investigação que
exigem um grande poder de cálculo que, na maior parte das vezes, é também
demorado. Em qualquer dos casos, a Internet é usada como meio de trans-
porte por via do qual o vector é transmitido. Deste modo, é possı́vel emular
a actividade de um supercomputador correspondente à soma total do po-
der computacional de cada um dos processadores contribuintes. Esta ideia
inspira-se na ideia original levada a cabo pelo popular projecto SETI@home
[7]. Por falta de tempo, não foi possı́vel concretizar na ı́ntegra as intenções
iniciais da proposta de projecto, mas uma boa parte desse desejo foi concre-
tizado, por exemplo, na parte de distribuir o algoritmo através da Internet,
em vez de o concretizarmos na realidade, recorreu-se ao uso de threads a cor-
rer na mesma máquina, obtendo um efeito semelhante ao de termos vários
clientes a correr cada um na seu computador próprio.
CAPÍTULO 1. INTRODUÇÃO 9

1.2 Organização do relatório

Este relatório possui 6 capı́tulos e 3 apêndices.


Após a corrente introdução, o capı́tulo 2 explica o que são Web Services,
o que é o XML e em que contexto entra na elaboração deste trabalho, sendo
apresentadas as tecnologias em que os Web Services se suportam – o WSDL
e o SOAP (ambas baseadas em XML).
O capı́tulo 3 debruça-se sobre o algoritmo genético compacto(cGA), dando
inicialmente uma ideia geral e resumida dos algoritmos genéticos, como fun-
cionam, para que servem, passando depois ao cGA propriamente dito, e
finalmente descrevendo uma arquitectura possı́vel para explorar a aplicação
distribuı́da.
O capı́tulo 4 mostra o que foi feito para implementar a arquitectura pro-
posta no capı́tulo 3. De seguida descrevem-se todos os passos de imple-
mentação para o corrente projecto usando Web Services, correlacionando-se
as matérias desenvolvidas nos dois capı́tulos anteriores.
No 5o capı́tulo mostram-se os resultados obtidos e tenta-se obter uma
explicação dos resultados.
Finalmente, em anexo, surge um manual de utilizador (apêndice A) da
aplicação desenvolvida, a que dei o nome de WSCGA1 ou WebServCGA,
mais o WSDL que define os web services criados (apêndice B) e o código-
fonte (apêndice C).
De referir, que a filosofia open source foi sempre seguida em todas as fases
deste projecto, visto que todas as aplicações utilizadas na concretização foram
1
Web Services for Compact Genetic Algorithm
CAPÍTULO 1. INTRODUÇÃO 10

desenvolvidas segundo este paradigma.


Existe um blog onde se foi dando conta do desenvolvimento deste projecto,
o seu endereço é http://webservcga.blogspot.com.
Capı́tulo 2

Web Services

Neste capı́tulo, iremos ver o que são web services, em que contexto aparece-
ram, e a que se destinam, quais são as vantagens, os protocolos e formatos
estandardizados que se criaram para lhes servir de suporte. Sendo todos
esses standards baseados em XML, faremos uma breve abordagem a esta
linguagem estruturada de transmissão de dados. Depois veremos, um a um,
cada um desses standards que servem suporte aos WS, como XML Schemas,
WSDL e SOAP.

2.1 Introdução

Vivemos na era da Informação, onde se torna necessário o seu intercâmbio


entre os mais diversos sistemas, que podem assumir as mais diversas formas,
sendo que nessas representações nem sempre está garantido que se torna
possı́vel encontrar os melhores meios possı́veis de partilhar essa informação.
A Internet é a expressão máxima do intercâmbio e da necessidade de par-

11
CAPÍTULO 2. WEB SERVICES 12

tilha de informação do mundo onde habitamos. Mas para a Internet poder


funcionar é necessário encontrar meios de transmissão através dos quais essa
informação possa alcançar todos as partes que a necessitam de partilhar entre
si. Um modelo de comunicação muito utilizado na Internet é o de cliente/-
servidor, usando a arquitectura usual TCP/IP. É uma ideia global e tão
enraı́zada de que são duas componentes que podem estar a interactuar inte-
gradas na mesma máquina, em que uma das partes faz um pedido (cliente) e
a outra satisfaz esse pedido (servidor). No entanto, por dificuldades de vários
nı́veis entre diferentes implementações de sistemas operativos, entre proto-
colos que não seguem normas padronizadas, ou por outros motivos sendo os
mais frequentes a segurança, nem sempre se torna possı́vel que dois sistemas
localizados em quaisquer duas partes do mundo possam comunicar entre si.
Em parte como resposta a esta dificuldades, apareceram os Web Services.

2.2 Web Services

2.2.1 Definição

Pode-se definir WS1 como uma forma de integrar e trocar informação entre
sistemas concebidos sob linguagens de programação ou sistemas operativos
diferentes, usando um formato de texto universalmente utilizado conhecido
por XML, que serve de suporte para normas de formatação e comunicação
estandardizadas necessárias à implementação dos web services, como WSDL,
SOAP e UDDI[5].
1
Web Services
CAPÍTULO 2. WEB SERVICES 13

2.2.2 Vantagens

• são acessı́veis a partir de qualquer parte da Internet

• conseguem funcionar bem na presença de firewalls e servidores proxy,


uma vez que sendo representados por documentos XML, todo o tráfego
usa a porta 80, universalmente utilizada para o protocolo HTTP2 .

• podem tirar partido da autenticação do HTTP, bem como das capaci-


dades de encriptação possibilitadas pelo SSL3

• combinam as melhores caracterı́sticas da programação orientada aos


objectos com a programação para a web

• são independentes das plataformas de desenvolvimento

• apresentam como resultado um documento XML, facilmente legı́vel


para humanos

• permitem a interacção entre aplicações sem intervenção humana

• diminuem a complexidade e custos associados à integração de aplicações

Como se vê, todos os protocolos e formatos utilizados são baseados em


XML, de forma que a sua estrutura pode ser representada por documentos
XML, tornando-os os candidatos ideais para aplicações distribuı́das, trans-
ferência de dados através de firewalls e sistemas de desenvolvimento hete-
rogéneos.
2
HyperText Transfer Protocol
3
Secure Sockets Layer
CAPÍTULO 2. WEB SERVICES 14

Os web services são definidos através de uma interface descrita usando


WSDL4 , que é baseado em XML, e as mensagens são codificadas utilizando
SOAP5 , também baseado em XML. Cada linguagem de programação deve
possuir uma biblioteca capaz de processar o WSDL, utilizando-o depois para
gerar uma API capaz de interagir com o WS definido por aquele WSDL, que
normalmente é um ficheiro de texto, usando as normas do XML. Podemos
pensar num WS como um conjunto de funções disponı́veis num sistema re-
moto (algo que vem na sequência de uma ideia antiga conhecida por RPC6 ).
Nós especificamos os parâmetros (ou argumentos) de que essa função neces-
sita e ela devolve-nos o resultados na forma esperada. O WSDL é transposto
para a linguagem de programação que estamos a utilizar, que, para o caso
concreto deste trabalho, foi o JAVA. O SOAP é então utilizado para formatar
as mensagens que são enviadas entre servidores e clientes. Vamos imaginar
um exemplo concreto, imaginemos que temos um WS que devolve um número
aleatório e que precisa de dois parâmetros, o mı́nimo e o máximo do intervalo
dos valores possı́veis. Através de um cliente, especificamos os valores desses
dois parâmetros, e o servidor de WS devolve-nos o valor desejado. Os tipos
de dados que guardam os valores dos parâmetros são definidos no WSDL,
que também especifica a localização do serviço e os formatos utilizados no
SOAP. A mensagem em si e a forma como ela é estruturada para transmitir
a informação é, de resto, da responsabilidade do SOAP.
4
Web Services Definition Language
5
Simple Object Access Protocol
6
Remote Procedure Call
CAPÍTULO 2. WEB SERVICES 15

Figura 2.1: Arquitectura dos Web Services

2.2.3 Arquitectura

Os Web Services seguem uma arquitectura concebida descrita consoante a


figura 2.1.
Imaginemos que um cliente está interessado a aceder a um determinado
WS, mas não sabe onde encontrar, então ele deve consultar o localizador,
que mantém uma lista de Web Services tipo “páginas amarelas”. Então o
localizador informa ao cliente onde pode encontrar o WS que procura, o cli-
ente contacta directamente o sistema fornecedor do serviço, que lhe anuncia,
através do seu WSDL, qual a forma apropriada de aceder ao WS. Chegamos
finalmente ao passo final, em que o serviço é invocado de acordo com as
especificações recebidas pelo cliente através do WSDL que lhe é enviado.
Temos, então, resumidamente, quatro passos:

• Publicação - processo opcional através do qual o fornecedor do WS


dá a conhecer a existência do serviço, através do registo na lista do
CAPÍTULO 2. WEB SERVICES 16

localizador (UDDI7 ).

• Descoberta - processo também opcional em que um cliente faz uma


pesquisa no localizador e encontra o WS que procura

• Descrição - o fornecedor de serviço envia ao cliente interessado, o seu


WSDL, onde toma conhecimento da interface que precisa de implemen-
tar para poder aceder ao WS

• Invocação - finalmente, o cliente e o servidor são interligados, graças


às especificações comunicadas pelo fornecedor no passo da descrição
anterior

O UDDI permite a integração das duas normas referidas anteriormente,


através de um directório que regista todos os WSDL’s disponı́veis, sendo
como uma espécie de “Páginas Amarelas” de Web Services. Mas como não
foi utilizado neste trabalho, não será aprofundado aqui.
Por outro lado, como se pode constatar, o XML é um denominador co-
mum de todas estas tecnologias, de modo que esse será o tema de toda a
próxima secção.

2.3 XML

Existe uma necessidade sobre um formato que possa ser utilizado univer-
salmente como veı́culo de transmissão de informação. Se todos os sistemas
utilizarem esse formato, então facilmente se poderá propagar muito mais fa-
cilmente a informação, sem haver necessidade de processamento extra para
7
Universal Description, Discovery and Integration
CAPÍTULO 2. WEB SERVICES 17

a tornar disponı́vel de imediato. Por outro lado, essa informação precisa de


estar estruturada, de forma que seja possı́vel aceder imediatamente a algum
item particular que esteja armazenado nalgum ponto dessa estrutura. As
vantagens da utilização de uma estrutura, são, para além disso, as seguintes:

• Validação - o conhecimento prévio da estrutura de um documento


permite a verificação de que a informação contida se encontra de acordo
com as regras definidas

• Reutilização - se a estrutura for conhecida, pode-se encontrar imedi-


atamente o elemento desejado e utilzá-lo para outro fim

• Normalização - o conhecimento da estrutura associada à validação


permite garantir uma produção normalizada.

Sendo assim, para definir a estrutura de um documento é necessário uti-


lizar uma série de etiquetas (ou tags), que dividem o documento que trans-
porta a informação em secções lógicas. Podemos ter dois tipos de anotações:
procedimentais e descritivas. Enquanto as primeiras estão viradas para o
aspecto fı́sico do documento, as segundas preocupam-se com o seu conteúdo,
subdividindo a sua classificação em componentes.
De acordo com o que ficou dito acima, podemos então ter o exemplo
descrito na figura 2.2.
Assim, como se pode ver na figura 2.2, é muito fácil aceder de forma
independente a qualquer um dos elementos que constituem o documento, e
ao mesmo tempo retirar uma informação semântica dos dados representados.
CAPÍTULO 2. WEB SERVICES 18

<receita>
<ingredientes>
<ingrediente>
farinha em pó
</ingrediente>
<ingrediente>
0,5 litros leite
</ingrediente>
<ingrediente>
2 ovos
</ingrediente>
</receita>

Figura 2.2: Exemplo de um documento estruturado

Vários tipos de linguagens de anotação têm vindo a aparecer ao longo dos


últimos 20 anos, com particular destaque para o HTML8 , sem dúvida a mais
bem sucedida de todas as elas. Antes do HTML, existia contudo a SGML9 ,
utilizada para definir idênticas linguagens de anotações. Foi a partir dela
que Tim Barners Lee, o criador da World Wide Web, desenvolveu o HTML,
como linguagem de anotação ideal para definir hiperligações que permitem
navegar de páginas para outras.
O XML foi então desenvolvido, a partir do SGML, para suportar a de-
finição de qualquer tipo de estrutura de informação independentemente de
qualquer utilização funcional que se lhe queira atribuir.
Podemos definir XML10 como uma linguagem de anotação definida para
representar uma estrutura lógica sob a forma da hierarquia de uma árvore,
definindo um modelo de documento (conhecido como DOM11 ) [5] usado como
8
HyperText MarkUp Language
9
Standard Generalized Markup Language
10
eXtended Markup Language
11
Document Object Model
CAPÍTULO 2. WEB SERVICES 19

formato de transmissão de informação através de Internet. Tal como o


HTML, suporte fundamental das páginas Web, é composto por anotações
(tags) que assinalam e delimitam secções lógicas dentro de um documento.
Entre essas anotações poderão aparecer dados.
No entanto, e ao invés do HTML, que é voltado para a formatação da
informação num browser, e onde os nomes das tags são pré-definidos, no XML
eles podem ser definidos livremente pelo utilizador, desde que devidamente
definidos num ficheiro conhecido por DTD12 . Mais recentemente, tornou-se
prática em vez de usar os DTD’s, definir as tags num ficheiro, também ele
formatado em XML, conhecido por XML Schema. Tanto num como noutro
caso, os DTD’s e os XML Schemas especificam uma gramática para definir
uma linguagem, a que os respectivos documentos XML que a implementam
devem obedecer, para poderem ser validados.
Apesar de tudo o que possa ser definido livremente, existe um conjunto
de regras que todos os ficheiros XML devem seguir, e que são:

• qualuqer documento XML deve necessariamente iniciar-se com uma tag


especial <?XML que deve conter obrigatoriamente a versão do XML em
que estamos em presença, mas pode conter outras informações como a
codificação dos caracteres utilizados (usualmente ISO-latin 1 ou ISO-
8859-1). Exemplo: <?XML version="1.0"encoding="iso-8859-1"?>
. Por defeito, se não for especificado nenhum valor, o documento as-
sume a codificação utf-8 (unicode) como valor para a codificação.

• Qualquer tag genérica <X> define uma secção lógica do documento co-
12
Document-Type Definition
CAPÍTULO 2. WEB SERVICES 20

nhecida por elemento, devendo ser terminada pela tag de fecho </X>,
de nome idêntico à que lhe deu inicio, com a diferença de possuir uma
/ à frente do nome. No caso do elemento não albergar mais nenhuma
informação para além da que consta de um atributo dentro da tag, para
não estar a usar uma tag de encerramento inutilmente termina-se a tag
com uma “/” antes do > (como em <br /> ).

• Existe uma tag principal que define o Elemento Raı́z (Root Element),
que assinala o princı́pio e o fim do documento. Por exemplo, para o
HTML o elemento raı́z é a tag <html> , para o WSDL é <definitions>
e no SOAP <envelope> , como veremos em breve. De assinalar, fi-
nalmente, que a linguagem XML é sensı́vel ao tamanho da letra.

• os valores dos atributos têm que estar entre aspas

Resumindo, se o documento XML obedecer às condições enumeradas


acima, diz-se que é bem formado, e se obedecer à estrutura que jura cum-
prir de acordo com o DTD ou XML Schema a que se encontra associado,
ainda afirmamos que o documento XML é válido dentro dessa mesma estru-
tura proposta. Para concluir, podemos dizer que o XML goza das seguintes
caracterı́sticas:

• extensı́vel - o seu autor pode definir as tags à vontade, de acordo com


uma estrutra pré-definida definida de forma apropriada num DTD ou
XML Schema

• estruturada - o conjunto de tags a utilizar em determinado contexto


determina a estrutura para o contexto
CAPÍTULO 2. WEB SERVICES 21

• passı́vel de ser validada - é possı́vel efectuar a validação do conteúdo


do documento relativamente às sua estrutura.

Do que ficou dito acima, vê-se que o XML pode ser usado como metalin-
guagem, quer dizer, é uma linguagem que pode ser usada para criar outras
linguagens.
Os ficheiros XML podem ser combinados usando tags de duas ou mais
fontes diferentes, quer dizer, um documento XML partilha tag’s de duas
proveniências, respeitantes a dois ou mais DTD’s ou XML schemas. Quando
isso acontece, chamamos a cada uma das proveniências um namespace. Um
namespace é identificado por URI13 , que, na maior parte das vezes, assume
a forma de um URL14 , que é um vulgar endereço de um site na Web, que
no entanto, não precisa necessariamente de apontar para o XML Schema
ou DTD que o define. É apenas uma forma convencional de distinguir os
namespaces de acordo com o URL. Neste trabalho, por exemplo, o WSDL
é definido num namespace de URL http://ualg.wscga , que, como se
pode ver, não corresponde sequer a um nome de domı́nio válido de acordo
com as normas. Cada namespace é identificado no documento XML através
de um prefixo seguido de dois pontos identificando o namespace ao qual
pertence. Assim, por exemplo se tivermos dois namespaces A e B com as
tags <SISTEMA> e <EMPRESA> , no novo ficheiro que incorpora as duas
tags, teremos respectivamente <A:SISTEMA> e <B:EMPRESA> . É possı́vel
ainda especificar o namespace por defeito a que pertencem as tags que não
estão precedidas por um prefixo, através do uso de um atributo especial
13
uniform resource indicator
14
uniform resource locator
CAPÍTULO 2. WEB SERVICES 22

XMLNS no elemento raı́z do documento XML. Pode-se ver um exemplo no


diagrama da figura 2.3.
CAPÍTULO 2. WEB SERVICES 23

Figura 2.3: XML Namespaces


CAPÍTULO 2. WEB SERVICES 24

2.4 XML Schemas

Os XML Schemas são uma linguagem baseada em XML criada para definir
as estruturas de novas linguagens em XML. Vieram substituir os DTD’s, no
que toca aos seguintes pontos:

• Os XML Schemas são eles próprios definidos em XML, o que permite


que possam ser processados pelos mesmos aplicativos que processam
qualquer outro documento em XML

• suportam os tipos de dados mais vulgares (também chamados primiti-


vos, por oposição aos objectos, na Programação Orientada a Objectos)
da maior parte das linguagens de programação, além de permitirem ao
utilizador definir os seus próprios tipos.

• suportam o uso de namespaces.

• permitem especificar restrições semânticas sobre o conteúdo dos ele-


mentos e seus atributos

Todos os XML Schema’s têm de ter incluı́da a seguinte informação a


respeito do namespace:
<schema xmlns="http://www.w3.org/2001/XMLSchema">
A figura 2.4 mostra um XML Schema que define a linguagem do XML
mostrada na figura 2.2. Podemos ver que os elementos XML que contêm
subelementos pertencem à categoria de Tipos Complexos e os elementos que
contêm apenas tipos simples ou primitivos chamam-se Tipos Simples. O ele-
mento <ingrediente> é o exemplo de um elemento de tipo simples, pois
CAPÍTULO 2. WEB SERVICES 25

<?xml version="1.0" encoding="iso-8859-1"?>


<schema xmlns="http://www.w3.org/2001/XMLSchema>
<element name="receita">
<complexType>
<sequence>
<element ref="ingredientes" maxOccurs="1" />
</sequence>
</complexType>
</element>
<element name="ingredientes">
<complexType>
<sequence>
<element ref="ingrediente" maxOccurs="unbounded" />
</sequence>
</complexType>
</element>
<element name="ingrediente" type="string" />
</schema>

Figura 2.4: XML Schema para o documento mostrado na figura 2.2

só pode aceitar string’s nos dados que recebe. Por outro lado, vemos que
o elemento <ingredientes> recebe um número indeterminado de subele-
mentos <ingrediente> ( atributo maxOccurs="unbounded"), enquanto que
<receita> (que é o elemento raı́z) apenas recebe um subelemento <ingredientes>
(de acordo com o atributo maxOccurs="1" ). Aliás, poder-se-ia pensar em
remover o subelemento <ingredientes>, uma vez que aparece uma única
vez em todo o documento.
A tabela 2.1 mostra alguns tipos primitivos que podem ser utilizados para
definir elementos simples:
CAPÍTULO 2. WEB SERVICES 26

tipo o que significa


string uma sequência determinada de caracteres
boolean valor lógico: true, false, 1,0
float um número de vı́rgula flutuante com precisão simples
double o mesmo que o anterior, mas com precisão dupla
duration um perı́odo de tempo
dateTime um instante no tempo do calendário gregoriano
int um número inteiro

Tabela 2.1: Alguns valores possı́veis para os tipos de dados primitivos que
um XML schema pode definir. De referir que o namespace para estes tipos
é xsd:

2.5 WSDL

O WSDL é uma formato baseado em XML, como ficou estabelecido atrás, de


descrever uma interface de acesso aos WS de forma que todos os clientes que
lhe desejem aceder, ao implementarem essa interface no seu código, possam
aceder de forma adequada, com os tipos de dados e parâmetros descritos
no WSDL. Este ficheiro normalmente encontra-se online numa localização
especificada através de um URI.

2.5.1 Estrutura

Um ficheiro WSDL é composto por diversos elementos, sendo a raı́z o ele-


mento <definitions> , e dentro deste elemento podem aparecer os seguin-
tes elementos, segundo a ordem seguinte, sendo alguns opcionais e outros
obrigatórios:

• O primeiro elemento é o <types> , onde podem ser definidos os


restantes elementos XML que vão ser utilizados no resto do documento
e que não pertençam a nenhum dos namespaces predefinidos. O uso
CAPÍTULO 2. WEB SERVICES 27

definitions{1}
types{1}
message+
part*
portType+
operation+
input{1}
output{1}
binding{1}
soap:operation+
input{1}
output{1}
service{1}
port+

Figura 2.5: Hierarquia de um documento WSDLa


a
Os números entre chavetas representam o número de elementos possı́veis do tipo dentro
do WSDL, usando a notação usual das expressões regulares.

deste elemento é, no entanto, opcional.

• O elemento <message> seguinte tem que aparecer pelo menos uma


vez, e define normalmente o tipo de parâmetros e o retorno do WS,
sendo que tem normalmente um ou mais elementos filhos <part> ,
para especificar o nome e tipo de cada parâmetro. Normalmente, para
cada função do WS tem-se dois elementos <message> , um de input
e outro de output, de acordo com o que vamos ver na descrição do
elemento que se segue. Por convenção acrescenta-se o sufixo Request
ao termo da função propriamente dita para a mensagem de envio (que
contém os parâmetros de entrada) e o sufixo Response para a mensa-
gem que contém o nome e o tipo do valor de retorno (normalmente
apenas um elemento <part> , em resultado disso). No caso de al-
CAPÍTULO 2. WEB SERVICES 28

guma das mensagens não precisar de parâmetro (ou não devolver nada),
o elemento <Message> não terá qualquer filho.

• O elemento <portType> especifica um conjunto de funções perten-


centes a um mesmo WS que irão estar disponı́veis num servidor. Nor-
malmente, temos aqui apenas um elemento <portType> , com vários
elementos filhos de nome <operation> , sendo que cada um destes
últimos tem dois filhos obrigatoriamente, <input> e <Output> ,
que especificam no seu atributo message, respectivamente, cada um dos
nomes utilizados nos referidos elementos <message> , citados acima.
No elemento <operation> especificamos no atributo name, o nome
da operação propriamente dita. De referir que o <portType> ainda
recebe um nome, usado para aceder, dentro do fornecedor de WS, a um
determinado conjunto de operações, reunidos segundo uma razão lógica
nesse <portType> . O uso do elemento <portType> é obrigatório,
e o número de vezes com que aparece num documento WSDL pode ser
maior que um, mas usualmente usa-se apenas um elemento.

• De seguida, temos o elemento <binding> , que implementa no SOAP


cada uma das operações referidas no elemento <portType> . O atri-
buto transport especifica o protocolo de envio das mensagens SOAP,
que, no caso mais genérico costuma ser o HTTP. Assim, especifica-
se o URL http://schemas.xmlsoap.org/soap/http/ dentro desse
atributo. É quase uma repetição do que ficou especificado no ele-
mento anterior, com os mesmos elementos <operation> , <input>
e <output> , mas aqui, para cada um destes elementos, é especi-
CAPÍTULO 2. WEB SERVICES 29

ficado um URL a ser utilizado para cada WS (de referir que cada
<operation> corresponde a uma função). Dentro de cada <input>
e <output> especificamos o estilo sob o qual queremos codificar a
mensagem a ser enviada através do SOAP.

• Finalmente, o elemento <service> , a partir do nome do <binding>


utilizado anteriormente, estamos a especificar qual a localização dos
WS através de um URI, que, na maior parte das vezes assume a
forma de um URL. Aqui, podemos ter várias funções reunidas numa
mesma localização, que é especificada, no atributo location do filho
<soap:address>

Finalmente, cada um destes elementos principais pode ainda conter um ele-


mento filho chamado <documentation> onde se procede à descrição do
elemento em causa.

2.6 SOAP

O SOAP é um formato de dados baseado em XML especificamente desen-


volvido para a transmissão de dados usando os Web Services. Um pacote
SOAP, unidade básica fundamental, vem embebebido dentro de uma pacote
HTTP (ou outro protocolo, como SMTP ou FTP), e é constituı́do por duas
partes: um envelope, que é por sua vez constituı́do por um cabeçalho opci-
onal (header ) e um corpo (body), de acordo com o que está representado na
gravura 2.6. De acordo com o que se pode ver, o envelope é o elemento raı́z
do documento SOAP, correspondendo ao corpo dentro do pacote HTTP.
CAPÍTULO 2. WEB SERVICES 30

envelope{1}
header?
body{1}
fault?

Figura 2.6: Hierarquia de uma mensagem SOAP

Figura 2.7: Um Pacote SOAP

No interior do envelope temos um corpo (body, em inglês), onde se en-


contra a mensagem a que diz respeito ao WS propriamente dito. Esta men-
sagem é delimitada por uma tag com o mesmo nome da função que estamos
a invocar. Internamente, temos mais um elemento com o mesmo nome do
parâmetro da referida função.
Existe ainda outro elemento que pode aparecer como subelemento do
<body> , é o <fault> , e que serve para especificar erros. Nas duas figuras
que se seguem, aparece o código SOAP da função <DownloadPopulationVector>
, uma das funções deste trabalho. A figura 2.8 diz respeito à mensagem que
CAPÍTULO 2. WEB SERVICES 31

==== Request ====


POST /wscga/services/webservcga HTTP/1.0
Content-Type: text/xml; charset=utf-8
Accept: application/soap+xml, application/dime, multipart/related, text/*
User-Agent: Axis/1.2.1
Host: localhost:18080
Cache-Control: no-cache
Pragma: no-cache
SOAPAction: "http://localhost:8080/wscga/services/webservcga/downloadPopulationVector"
Content-Length: 355

<?xml version="1.0" encoding="UTF-8"?>


<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<DownloadPopulactionVector
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</soapenv:Body>
</soapenv:Envelope>

Figura 2.8: Mensagem de envio SOAP para a função


downloadPopulationVector , pode-se ver que a função não especifica
quaisquer parâmetros de entrada

o cliente envia e a seguinte (figura 2.9) mostra a respectiva resposta.

2.7 Sumário

Vimos neste capı́tulo qual a utilidade dos web services, a arquitectura-padrão


proposta a que tentam obedecer. Para poder entender os web services no seu
todo, é necessário antes entender a linguagem XML na qual eles se sustentam
através dos standard’s WSDL e SOAP, que vimos de seguida. No capı́tulo
seguinte 3, veremos o que são os algoritmos genéticos, como apareceram e a
que se destinam, dando particular atenção à versão compacta dos referidos
algoritmos.
CAPÍTULO 2. WEB SERVICES 32

==== Response ====


HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/xml;charset=utf-8
Date: Mon, 05 Sep 2005 23:11:29 GMT
Connection: close

<?xml version="1.0" encoding="UTF-8"?>


<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<response xmlns="">
<pv>
<array>
<array>10</array>
<array>10</array>
<array>10</array>
<array>10</array>
<array>10</array>
</array>
</pv>
<n>10</n>
<popsize>20</popsize>
</response>
</soapenv:Body>
</soapenv:Envelope>
==============

Figura 2.9: Resposta SOAP da função ao exemplo da figura 2.8, de notar a


forma como um array de cinco elementos é convertido em XML
Capı́tulo 3

O Algoritmo Genético
Compacto

Neste capı́tulo abordaremos os algoritmos genéticos, porque surgiram, como


funcionam, e a que tipo de problemas se destinam. Daremos especial atenção
à versão compacta do referido algoritmo e faremos referências às razões que
assistem à distribuição do referido algoritmo, expondo uma arquitectura que
pretende explorar essa possibilidade.

3.1 Introdução

Os Algoritmos Genéticos apareceram como uma forma de resolver proble-


mas de pesquisa e optimização[1] que, de outro modo, seriam extremamente
difı́ceis de resolver. Estes algoritmos baseiam-se na teoria da evolução base-
ada na selecção natural apresentada em 1858 por Charles Darwin e Alfred
Russel Wallace. No entanto, estes dois investigadores apenas apresentaram

33
CAPÍTULO 3. O ALGORITMO GENÉTICO COMPACTO 34

uma forma como certas caracterı́sticas transmitidas entre gerações podem au-
mentar a sua presença numa determinada população de certa espécie através
da sobrevivência dos mais aptos, que assim permite que os seus genes que
determinam essas caracterı́sticas vantajosas sejam transmitidos à sua des-
cendência em maior número, assegurando assim que essa mesma descendência
possa sobreviver com maior probabilidade. No entanto, Darwin e Wallace
não conseguiram explicar o processo exacto pelo qual essas caracterı́sticas
(codificadas nos genes) eram transmitidos à descendência. Quase ao mesmo
tempo que era apresentada a teoria da evolução, um monge checo de nome
Gregor Mendel, através de experiências realizadas nos jardins do seu con-
vento com ervilhas de cheiro, pôde determinar que o processo de transmissão
das caracterı́sticas dos progenitores são transmitidas através de um entre-
cruzamento de genes de dois progenitores, de forma que os seus descendentes
partilham caracterı́sticas de ambos. Nos Algoritmos Genéticos aplicamos es-
sas regras que a Mãe Natureza utiliza para salvaguardar a sobrevivência dos
seres vivos perante numa superfı́cie planetária sempre instável numa escala
de tempo de milhões de anos. Existe uma classe de problemas onde uma
resolução através de métodos tradicionais é extremamente difı́cil ou ocorre
durante uma duração de tempo extremamente elevada para que se possa
encontrar uma solução em tempo útil. É neste tipo de problemas que os
algoritmos genéticos demonstram todo o seu poder. Os primeiros algoritmos
genéticos foram desenvolvidas por John Holland na Universidade de Michi-
gan durante a década de 70, e foram apenas alvo de um estudo teórico, e só a
partir da década de 80, com a primeira conferência internacional, se começou
a pensar nas aplicações práticas dos referidos algoritmos.
CAPÍTULO 3. O ALGORITMO GENÉTICO COMPACTO 35

1 0 0 1 1 1 1 1 0 1

Figura 3.1: Um indivı́duo representado por um cromossoma de comprimento


10

3.2 O Algoritmo Genético Simples

O Algoritmo Genético Simples (sGA)[1] (também denominado canónico) usa


uma população de indivı́duos, sendo cada um deles representado sob a forma
de um cromossoma que é uma string de bits que podem assumir o valor 0
ou 1 (figura 3.1). A cada um destes bits dá-se o nome de gene. A cada
valor possı́vel do bit dá-se também o nome de alelo. Cada um destes cromos-
somas representa uma potencial solução para um eventual problema, sendo
a sua qualidade como solução medida através de uma função de mérito 1 .
Através desta função, são seleccionados os melhores indivı́duos dentro dessa
população, e esses indivı́duos, de acordo com o operador cruzamento utili-
zado, irão gerar descendência que irá aumentando o efectivo populacional
de indivı́duos de mérito mais elevado, levando a que, a pouco e pouco, o
mérito médio dos indivı́duos vá sendo melhorado, até atingir o valor que
corresponde à solução final para o problema em questão. Quase todos os
algoritmos genéticos existentes seguem quase rigorosamente a sucessão de
passos descrita na figura 3.2, com uma ou outra variação.
Na versão do sGA com cruzamento monoponto, isto é, apenas com um
ponto de cisão dos cromossomas, é usado um operador crossing-over onde
cada um dos cromossomas intervenientes é dividido num ponto aleatório entre
dois genes, sendo que uma das partes resultantes e a proveniente do outro
1
também como função objectivo, ou ainda fitness, em inglês
CAPÍTULO 3. O ALGORITMO GENÉTICO COMPACTO 36

Gerar uma populaç~


ao aleatória
Repetir
Calcular o mérito de cada indivı́duo
Seleccionar os melhores indivı́duos
Aplicar o operador cruzamento aos pares
Aplicar o operador mutaç~
ao
Até atingir a condiç~
ao de paragem

Figura 3.2: Passos genéricos de um algoritmo genético

cromossoma do par são combinadas num novo indivı́duo, gerando assim dois
novos indivı́duos. A probabilidade de ocorrer um crossing-over é executada
de acordo é especificado de acordo com um valor de probabilidade Pc .
Mas antes de ocorrer o crossing-over tem lugar a selecção, que consiste em
seleccionar os indivı́duos para o cruzamento, sendo que neste ponto podemos
ter vários operadores possı́veis: entre os mais utilizados contam-se a roleta e
o torneio.
A roleta opera de acordo com as frequências com que determinado in-
divı́duo aparece na população, conjuntamente com o valor da função de ava-
liação. É feito o somatório dos valores da função de avaliação para todos
os indivı́duos, sendo atribuı́do a cada um deles uma “fatia” da roleta. Os
indivı́duos com maior mérito receberão uma porção maior da área da roleta
e por via disso terão maior probabilidade em serem seleccionados.
No caso do operador torneio, são seleccionados dois indivı́duos ao acaso
dentro da população, após o que são comparados ao nı́vel do seu mérito, sendo
que aquele que tiver o melhor “ganha” o torneio e envia mais uma cópia para
a população, aumentando numa unidade o seu efectivo populacional.
Existe outro parâmetro a prestar atenção, conhecido por pressão de se-
CAPÍTULO 3. O ALGORITMO GENÉTICO COMPACTO 37

lecção, vulgarmente denotado por s. Vulgarmente, e quando nada se afirma


em contrário, a pressão de selecção assume o valor dois, correspondendo ao
facto anunciado anteriormente, em que o vencedor envia duas cópias para a
nova população resultante. Podem, no entanto, aparecer outros valores para
a pressão de selecção, tais como: 4, 6 ou 8, por exemplo; neste caso o que
se passa é que, em vez de termos um torneio entre dois indivı́duos, termos
torneios entre 4, 6 ou 8 indivı́duos. Em todos estes casos, um dos indivı́duos
é sempre o mesmo, que corresponde ao melhor indivı́duo que compete com
outro tirado ao acaso do “pote” da população. Como se pode ver, neste casos
de pressão superior, o que irá suceder é o que os indivı́duos de maior fitness
irão “mais rapidamente” tomar conta da população. Consoante o tipo de
problema em questão, uma maior pressão de selecção poderá ajudar a fazer
a população convergir com melhor eficácia. É o que se no caso concreto do
problema que foi escolhido para ser resolvido neste trabalho.
Em relação aos critérios de paragem, temos que o mais vulgar é o caso em
que se dá a convergência, isto é, em que toda a população está preenchida
apenas com cópias do mesmo indivı́duo, aquele que em princı́pio correspon-
derá à solução final para o problema em questão. Outro critério de paragem
poderá ser um número máximo de gerações, entendendo-se por geração um
determinado estado da população durante o decorrer do algoritmo. Além
da selecção, pode aparecer ainda outro operador, conhecido por mutação.
A mutação altera o valor de um gene individual dentro do cromossoma de
acordo com um valor de probabilidade de mutação(Pm ). Neste trabalho, o
seu uso não foi considerado, tendo em conta que o problema utilizado (ver
[4]) não previa o uso da mutação.
CAPÍTULO 3. O ALGORITMO GENÉTICO COMPACTO 38

3.3 O Algoritmo Genético Compacto

O Algoritmo Genético Compacto[3] (ou simplesmente, cGA2 ), é uma si-


mulação do algoritmo canónico (ou simples) na sua forma de cruzamento
uniforme com operador torneio em que a população é substituı́da por um vec-
tor probabilı́stico3 , em que o valor em cada posição representa a frequência
na população com que aparece o alelo 1 para a posição em questão.
Os passos do cGA são em quase tudo idênticos aos do sGA, com a dife-
rença de que no inı́cio do algoritmo, estarmos a usar um vector probabilı́stico
em que todos as posições do vector assumem o valor 0.5, representando isso
que tanto os alelos 0 e 1 estão na mesma proporção relativamente à população
que o vector pretende representar.
Assim, durante o decorrer do algoritmo, são gerados dois novos indivı́duos
a partir do vector, simulando o processo de seleccionar aleatoriamente um
indivı́duo, e a partir daı́ os passos são uma vez mais idênticos aos da versão
simples, mas quando chega a ocasião de “criar” a nova geração, é o vector
população a ser actualizado através da comparação, bit a bit, entre vencedor
e vencido do torneio, sendo que, para o caso dos valores serem diferentes,
e esse valor para o vencedor ser um 0, o valor no vector é reduzido em 1
unidade ou em uma fracção de 1 para o efectivo populacional ( N1 ), consoante
estivermos a usar frequências absolutas ou relativas. Em caso de ser 1, o
vector é incrementado segundo valores idênticos.
E isto continua assim, até que todas as posições do vector população
2
Compact Genetic Algorithm
3
também conhecido como vector população
CAPÍTULO 3. O ALGORITMO GENÉTICO COMPACTO 39

contenham apenas frequências de 1.0 e 0.0. 4 . A figura 3.3 mostra, de forma


resumida, todo o algoritmo usando pseudo-código.
Entre as várias funções possı́veis existentes para testar a eficiência do
algoritmo, usa-se a simples função conhecida por OneMax, que consiste em
contar o número de uns do cromossoma. Para este tipo extremamente sim-
ples de problema, a convergência é rapidamente alcançada no sentido da
população ficar apenas com cromossomas compostos apenas por uns, como é
de esperar. De salientar que o cGA não pretende ser uma alternativa total ao
algoritmo genético tradicional na sua forma uniforme, mas prova ser eficaz
em resolver problemas de pequena complexidade e em que a quantidade de
memória disponı́vel seja escassa.

3.4 Aplicação distribuı́da

A principal razão para distribuir o cGA provém da constatação que o vec-


tor probabilı́stico é uma representação compacta da população[4], daı́ que
se possa transmitir esse vector e não a população na sua totalidade. Desta
forma, os custos na comunicação podem ser reduzidos significativamente uma
vez que o vector população precisa de muito menos memória que toda uma
população. E dado que esses custos de comunicação podem ser drastica-
mente reduzidos, faz sentido que o vector possa ser enviado para diferentes
processadores, de modo que cada um seja processado independentemente dos
outros, através da execução de um cGA em cada computador. Torna-se ne-
cessário que de vez em quando cada um destes vectores seja enviado de volta
4
ou, no caso de usarmos frequências absolutas, como o caso do presente trabalho,valores
de N e 0, respectivamente, sendo N o tamanho da população
CAPÍTULO 3. O ALGORITMO GENÉTICO COMPACTO 40

Figura 3.3: Pseudo-Código do cGA([6])


CAPÍTULO 3. O ALGORITMO GENÉTICO COMPACTO 41

para uma entidade central capaz de coordenar todo o processo.


Foi desenvolvida uma arquitectura que permite explorar esta possibili-
dade, denominada de worker-manager onde intervêm duas entidades funda-
mentais: o worker e o manager. O manager tem por finalidade gerar um
vector que depois distribui por todos os workers, que são processadores dis-
postos a contribuir com algum do seu tempo no processamento do vector,
através da execução de um cGA baseado no vector que acabam de receber.
Esta execução mantém-se dentro de um perı́odo de tempo controlado por
um número predefinido de execuções da função de fitness, valor a que vamos
chamar m daqui em diante. Após esse número de iterações ter sido cum-
prido, um vector com as diferenças entre o vector recebido e o estado em que
se encontra após ter cumprido as m execuções de fitness é enviado de volta
para o manager. O número de workers não é controlado pelo manager e pode
crescer sem limite, de modo que quantos mais workers houver, menos tempo
levará até concluir todo o processo. De salientar que não ocorre qualquer
comunicação dos workers entre si, toda a comunicação estabelece-se somente
entre manager e workers.
Assim, e de acordo com [4], é sugerido o seguinte método de distribuir o
cGA entre os vários workers:

1. O manager inicializa o vector probabilı́stico de comprimento ` em que


a cada posição desse vector é atribuı́do o valor 0.5 e o manager fica
então à espera de ligações de eventuais workers

2. quando o worker contacta o manager pela primeira vez, envia-lhe um


sinal dando conta da sua intenção de participar
CAPÍTULO 3. O ALGORITMO GENÉTICO COMPACTO 42

Figura 3.4: O modelo worker-manager, retirado de [4]

3. O manager envia uma cópia do vector ao worker, ficando novamente à


espera de novos contactos por parte de eventuais novos workers

4. Logo que o worker recebe o vector, começa a executar um cGA com os


parâmetros especificados pelo manager, através da criação de m novos
indivı́duos. Durante esse processo, igualmente m cálculos de fitness (
um por cada um dos indivı́duos) têm lugar, sendo o vector actualizado
de forma habitual.

5. Após os m cálculos de fitness terem tido lugar, o worker envia para o


manager os resultados do seu trabalho, representado pelas diferenças
entre o vector actual e o vector inicial, no estado em que estava quando
foi enviado inicialmente pelo manager

6. Quando o manager recebe as referidas diferenças referidas no passo


CAPÍTULO 3. O ALGORITMO GENÉTICO COMPACTO 43

anterior, actualiza o vector que tem em memória, de acordo com os


valores das diferenças

7. É enviado para o worker um novo vector, que corresponde ao vector


acabado de actualizar (ou não, se outro worker tiver actualizado o
vector, no meio do processo de actualização do vector patente no ma-
nager ). Todo o processo desde o passo 4 tem lugar novamente até o
vector ter finalmente convergido

Esta arquitectura tem vários pontes fortes, entre os quais se destacam:

• Custos de sincronização baixos

• Tolerância a falhas

• Escalabilidade

Os custos de sincronização são baixos graças ao facto de ser apenas ne-


cessário comunicar um vector, e, quando ocorrer a actualização do vector
no manager, não se torna necessário estar a comunicar esse facto a todos os
workers intervenientes.
A tolerância a falhas é possı́vel porque se o manager não voltar a ter
notı́cia de certo worker, isso não perturba em nada o processo global, já que
o que se perdeu foi apenas o estado do vector num determinado instante,
sendo que, entretanto, um grande número de workers permite compensar
esse desiderato, uma vez que entretanto o vector pode já ter atingido um
estádio mais avançado, em nada sendo, portanto, prejudicado pela “perda”
deste ou doutro worker.
CAPÍTULO 3. O ALGORITMO GENÉTICO COMPACTO 44

Finalmente, a escalabilidade é possı́vel porque não existe um limite, do


ponto de vista teórico, para o número de workers que poderão estar a traba-
lhar no mesmo vector ao mesmo tempo.
Existem alguns pormenores ainda a salientar, como o facto do passo 7
não ser uma operação de broadcast, em que o manager, ao actualizar o seu
vector de acordo com as últimas diferenças recebidas, teria que fazer reflec-
tir essa modificação em todos os workers, algo manifestamente impossı́vel
e inútil de concretizar porque o que na realidade se passa é que foi apenas
o último worker que enviou as diferenças que recebe um novo vector para
poder prosseguir o seu trabalho que recebe um novo vector para prosseguir
o seu trabalho. De reparar igualmente que o estado em que se encontra o
vector no manager em determinado momento resulta dos esforços acumu-
lados de todos os diferentes workers que associaram ao trabalho. Daı́ que
possa suceder que, em determinado momento, o vector em que os workers
que ainda não completaram o seu trabalho não seja aquele que o manager
detém naquele momento. No entanto, este problema pode ser resolvido se
constatarmos que uma iteração do cGA representa apenas um pequeno passo
no processo global do algoritmo genético no seu todo.

3.5 Sumário

Neste capı́tulo abordámos os Algoritmos Genéticos desde o seu aparecimento,


com destaque para a versão de algoritmo sobre o qual este projecto se de-
bruça, o Algoritmo Genético Compacto. Descrevemos o tipo de problemas
a que se aplica e em que situações pode substituir a versão tradicional. Fi-
CAPÍTULO 3. O ALGORITMO GENÉTICO COMPACTO 45

nalmente, foram apontadas as razões que tornam útil a aplicação distribuı́da


destea algoritmo e foi proposta uma arquitectura que permite explorar as
suas vantagens. No próximo capı́tulo veremos descreve-se a forma como se
procedeu à implementação do referido algoritmo e os diferentes passos se-
guidos para o alcançar. Portanto, o próximo capı́tulo será uma tentativa de
juntar o que foi exposto nos dois capı́tulos anteriores de forma a alcançar os
objectivos a que nos propomos neste trabalho.
Capı́tulo 4

Aplicação Distribuı́da do cGA


usando Web Services

Neste capı́tulo iremos referir-nos à intenção inicial deste projecto e de que


forma foi levada a cabo a implementação de tornar possı́vel todos os objecti-
vos a que me propus quando aceitei este tema de projecto. Começaremos por
nos referir à função que se entendeu usar para testar a aplicação distribuı́da
do referido algoritmo.

4.1 Função de teste

Para além do OneMax para testar a eficácia do cGA, existe uma função
conhecida por função deceptiva ou trap 1 , definida de acordo com o que está
na figura 4.1. A versão mais simples da trap atribui o valor de 1 quando
a string conter apenas uns, mas para o valor imediatamente abaixo inferior
1
armadilha, em português

46
CAPÍTULO 4. APLICAÇÃO DISTRIBUÍDA DO CGA USANDO WEB SERVICES 47




 1 , o=k
trap(c) =   0 , o=k−1
d

 − k−1 o+d , o<k−1

Figura 4.1: Função trap de k bits, em que temos um cromossoma c de com-


primento k, representando o a quantidade de bits a 1 dentro do cromossoma,
e d é a razão deceive to optimal

(k − 1), a função devolve o valor 0. De resto, a função “segue” uma recta2 a


partir deste valor até assumir o valor de 1 − d quando o número de uns no
cromossoma for zero. A d dá-se o nome de deceptive to optimal ratio.
Esta função, em vez de conduzir o algoritmo para uma convergência no
valor desejado, leva-o para valores subóptimos, uma vez que ao parecer que
converge na direcção de crescimento da função, isso conduze-o, na realidade,
na direcção do pior valor, que se encontra no ponto imediatamente abaixo.
O interesse desta função reside no facto de, como a população evolui gra-
dualmente no sentido de privilegiar os indivı́duos de maior fitness, se torna
muito difı́cil de resolver, porque a população acaba por convergir quase sem-
pre na direcção do indivı́duo que só tem zeros, e só se dispor de uma po-
pulação numerosa, consegue “chegar” ao indivı́duo de melhor fitness, aquele
que só tem uns. O cGA, consegue, contudo, resolver este problema, com
maior ou menor dificuldade. Existe, no entanto, uma versão mais elaborada
de trap, que consiste numa função com múltiplas trap’s, isto é, o cromossoma
é dividido em blocos de comprimento igual, sendo aplicado a cada um desses
blocos a função trap como se um cromossoma independente se tratasse. O
2
na realidade, a função é representada por pontos isolados, a recta é apenas para ter
uma ideia da sua progressão
CAPÍTULO 4. APLICAÇÃO DISTRIBUÍDA DO CGA USANDO WEB SERVICES 48

Figura 4.2: Configuração genérica do gráfico de uma função trap de k bits


com deceive-to-optimal ratio d
CAPÍTULO 4. APLICAÇÃO DISTRIBUÍDA DO CGA USANDO WEB SERVICES 49

resultado final da função fitness global é a soma das fitness individuais cal-
culadas sobre cada um desses blocos. Isto é um problema que, dada a sua
complexidade, o cGA não consegue resolver, precisando de uma população
numerosa para o conseguir. Este problema foi utilizado numa simulação em
série[4] (ver secção 4.2) e também foi utilizado neste trabalho.

4.2 Simulação em série da arquitectura

De acordo com [4], é proposta uma implementação da arquitectura referida


na secção anterior através de uma simulação em série do processo sem ser
necessário usar uma rede real. Uma implementação em série tem os mes-
mos efeitos do que algo semelhante na forma distribuı́da visto que os wor-
kers, como ficou exposto anteriormente, nunca comunicam entre si. Ainda
de acordo com [4], esta implementação permite analisar o algoritmo em
condições bastante controladas, permitindo ainda testar a sua escalabilidade,
sem ser necessário possuir o hardware necessário para fazer os testes de forma
real.
A implementação em série desenvolvida pretende então simular a situação
real de termos P processadores workers e apenas 1 processador manager.
Fazem-se as pressupostos de que tanto o manager como os workers arran-
cam no mesmo instante e trabalham à mesma velocidade. Para além disso,
também se assume que os custos de comunicação associados aos contactos
manager /worker são constantes e proporcionais ao tamanho do vector de
probabilidades.
Temos então P cGA’s correndo simultaneamente, cada um com um vec-
CAPÍTULO 4. APLICAÇÃO DISTRIBUÍDA DO CGA USANDO WEB SERVICES 50

tor próprio independente, a ser executado em cada processador worker. E,


quando tiverem decorrido m cálculos de fitness em cada worker, são enviadas
apenas as diferenças entre o vector inicial recebido originalmente e o último,
saı́do da execução controlada do cGA.
Para testar o algoritmo foi utilizada uma função deceptiva que consiste
na concatenação de 10 cópias de uma trap simples de 3 bits com uma deceive
to optimal ratio de 0.7, ver secção 4.1. A pressão de selecção utilizada s foi
de 8 e o tamanho da população N =100000. A razão para a escolha deste
efectivo populacional prende-se com o facto de com uma população grande
todos os blocos 3 possam ser resolvidos correctamente. Por outro lado, o uso
de uma efectivo populacional enorme permite que os efeitos da computação
distribuı́da sejam mais acentuados.
Estabelecidos que ficam o efectivo populacional e a pressão de selecção,
procedeu-se ao uso de uma combinação de diferentes valores para P , número
de processadores workers e m, o número de indivı́duos gerados por um worker
entre cada recepção e envio de um vector de volta ao manager. Assim foram
experimentadas todas as combinações possı́veis entre valores de P no con-
junto {1,2,4,8,16,32,64,128,256,512,1024} e m no conjunto {8,80,800,8000,80000}.
Isto corresponde a 55 combinações possı́veis, que foram executadas ao todo
30 vezes cada uma. De notar que o parâmetro m afecta o número de comu-
nicações, uma vez que é ele que controla ao fim de quanto ”tempo”(não sendo
este tempo algo determinável, mas é proporcional ao valor de m). Para valo-
res baixos, o número de contactos worker /manager é elevado, uma vez que
o número baixo de cálculos necessários para completar um ciclo de trabalho
3
building blocks
CAPÍTULO 4. APLICAÇÃO DISTRIBUÍDA DO CGA USANDO WEB SERVICES 51

Figura 4.3: No primeiro gráfico, aparecem os resultados do número de total


de cálculos da função de fitness em função do número total de processa-
dores workers que colaboraram no trabalho. Seguidamente, apresentam-se o
número de contactos entre workers e manager, também em função do número
de workers. De notar que ambos os gráficos estão numa escala logarı́tmica
(10/2). Os gráficos constam do artigo [4]
CAPÍTULO 4. APLICAÇÃO DISTRIBUÍDA DO CGA USANDO WEB SERVICES 52

por parte de um worker é curto, e assim que o worker necessita de um novo


vector para que possa prosseguir no seu trabalho, contacta imediatamente o
manager para o obter. Valores elevados de m diminuem o número de comu-
nicações, mas têm um impacto no desempenho global, uma vez que assim
aumenta o número de workers processando um vector já bastante desactua-
lizado. A figura 4.3 mostra os resultados. Para o caso dos cálculos de fitness
de atingir a convergência global em função do número total de processadores
workers envolvidos, verifica-se a presença de uma linha quase recta para va-
lores de m baixos (8,80,800). Para valores mais elevados (8000,80000) deixa
de ocorrer essa relação uma vez que muitos workers continuam a trabalhar
em vectores já desactualizados há muito tempo.
No que toca aos custos de comunicação, verificamos que à medida que
aumentamos o parâmetro m, constata-se uma esperada redução nos custos,
e ainda em função do número de workers os declives são mais ou menos
parecidos, excepto para valores elevados, em que o número de contactos
aproxima-se de zero, em virtude de m ser elevado (80000). Nesta situação, o
algoritmo é concluı́do em apenas um ciclo de um dos workers, ficando uma
grande parte dos restantes workers trabalhando no mesmo vector mesmo
depois de o manager já ter dado todo o trabalho por concluı́do.

4.3 Implementação com Web Services

A arquitectura proposta em 3.4 foi transposta, com algumas modificações


que vieram a ser necessárias, de que se vão dando conta aos poucos ao longo
desta secção.
CAPÍTULO 4. APLICAÇÃO DISTRIBUÍDA DO CGA USANDO WEB SERVICES 53

A escolha do Java como linguagem de programação prende-se com a ex-


periência e o à vontade do executante deste projecto com esta linguagem,
para além das suas claras vantagens, onde se incluem:

• código compilado num sistema operativo pode ser executado noutro


sistema operativo sem haver necessidade de estar a recompilar nova-
mente, tudo graças à máquina virtual Java que abstrai o hardware da
máquina onde está a ser executado o código

• a interoperabilidade dos Web Services pode ser melhor explorada com


uma linguagem multi-plataforma, de modo que em qualquer sistema
operativo, o torne imediatamente uma plataforma susceptı́vel de exe-
cutar um cliente de Web Services sem demais necessidades de estar a
portar o código para essa plataforma. Desta forma, todas as potencia-
lidades dessa plataforma podem ser imediatamente exploradas.

Para a implementação com Web Services utilizei o servlet Axis em con-


junto com o servidor de JSP4 Tomcat, ambos open-source, e da alçada da
Apache Software Foundation, responsável pelo servidor web do mesmo nome
que é o mais usado em todo o mundo.
Antes de prosseguir, convém fazer alguns esclarecimentos. Um servlet é
um programa escrito em Java que corre num servidor JSP, como o Tomcat.
Neste caso, o Axis é o servlet e é o responsável por gerir os Web Services da
forma como foram implementados para a arquitectura proposta [2].
Para escrever código de forma que seja compatı́vel para utilização com o
Axis, é necessário em primeiro lugar, escrever o ficheiro WSDL (este pode
4
Java Server Pages
CAPÍTULO 4. APLICAÇÃO DISTRIBUÍDA DO CGA USANDO WEB SERVICES 54

ser consultado no apêndice B) do Web Service que pretendemos criar. Após


essa fase, este é processado por um programa chamado WSDL2Java que faz
a conversão do código (e implementa) a interface de acesso aos Web Servi-
ces em código Java. São gerados vários ficheiros Java, cada um com a sua
especificidade própria. Nem todo o código está completo para ser compi-
lado e pronto a ser utilizado, é necessário por exemplo implementar algumas
das funções que correspondem aos WS necessários para os elementos XML
que foram convertidos em objectos, mas, basicamente, o que WSDL2Java faz
é converter alguns dos tipos definidos na secção <types> do WSDL em
objectos que depois serão utilizados para transmitir a informação necessária.
No código gerado as funções WS assumem a mesma assinatura, com o
mesmos parâmetros e seus respectivos tipos mais os valores de retorno, tal e
qual da forma como foram definidos do WSDL.
De notar que o programador só precisa de se concentrar em utilizar as
funções no código onde vai precisar utilizar as funções dos WS tratando-
os pelo seu próprio nome, e nunca precisando de saber detalhes a respeito
da forma de transmissão dos web services. Quanto muito, terá que indicar
apenas alguns dados como o URL do servidor de WS ou de algum eventual
servidor proxy HTTP através do qual será feita a ligação para poder alcançar
o dito servidor de WS.
O WSDL utilizado neste trabalho pode ser visto em anexo (apêndice B)
a este relatório, mas pode-se fazer, desde já um resumo sucinto de todos os
web services implementados, assim como os parâmetros utilizados, e a que
fim se destinam.
A tabela 4.1 mostra as funções implementadas como Web Services. A
CAPÍTULO 4. APLICAÇÃO DISTRIBUÍDA DO CGA USANDO WEB SERVICES 55

Função Para que serve


CreateNewPopulationVector Cria um novo vector no servidor
DownloadPopulationVector Envia um novo vector a um cliente
SendPopulationVector Envia o vector para o servidor

Tabela 4.1: Funções Web Services utilizadas no trabalho


função do WS Request ou Response? nome tipo do parâmetro
CreateNewPopulationVector Request initData wscga:CreateNewPopulationVectorElement
Response returncode xsd:int
DownloadPopulationVector Request
Response response wscga:DownloadPopulationVectorElement
SendPopulationVector Request newPopVect wscga:IntArrayElement
Response statuscode xsd:int

Tabela 4.2: Parâmetros e valores de retorno das funções Web Services

tabela seguinte 4.2 os nomes dos parâmetros, valores de retorno e seus res-
pectivos tipos.
Os elementos XML com o namespace wscga: foram definidos na secção
<TYPES> do ficheiro WSDL e são elementos XML que são depois serializados
(é este o termo de conversão de objectos em XML) quando se torna necessário
enviá-los usando SOAP. Dentro de cada elemento XML estão definidos alguns
subelementos, de acordo com o que está na tabela 4.3.
De notar que, ao contrário que é habitual, mas não é nenhum contra-senso,
o vector população transmitido adopta como tipo de dados base inteiros e não
números reais, como costuma ser costume na implementação do cGA, isto
deve-se ao facto de uma implementação do dito vector usando inteiros torna
mais reduzida a informação a enviar dentro da mensagem SOAP. Usando

Nome do elemento nome do parâmetro tipo finalidade


CreateNewPopulationVectorElement m xsd:int limite de cálculos de fitness
popsize xsd:int tamanho da população
s xsd:int pressão de selecção
DownloadPopulationVectorElement pv wscga:IntArrayElement novo vector população
m xsd:int limite de cálculos de fitness
popsize xsd:int tamanho da população
s xsd:int pressão de selecção
IntArrayElement IntArray xsd:int[] array de inteiros com o vector população

Tabela 4.3: Elementos XML usados como parâmetros das funções web ser-
vices
CAPÍTULO 4. APLICAÇÃO DISTRIBUÍDA DO CGA USANDO WEB SERVICES 56

reais podia fazer aparecer dı́zimas infinitas, que ao serem necessariamente


convertidas para strings ao ser enviadas nas mensagens SOAP, iriam ocupar
enorme espaço. Desta forma conseguiu-se reduzir o tamanho da informação
a ser transmitida.
Para além disso, por dificuldades relacionadas com a falta de meios e de
tempo por parte do executante deste projecto não foi possı́vel concretizar um
dos objectivos iniciais que constavam do enunciado da proposta original deste
projecto, que era o de distribuir o processamento através da Internet. Como
tal não foi possı́vel, recorreu-se como forma de substituir um processador
individual ao uso de threads baseadas na ideia de programação concorrente,
algo que já vem de raı́z na biblioteca padrão de Java.
Deste modo, entendeu-se que, em vez de utilizar hardware real espalhado
pela Internet, os mesmos resultados poderiam ser obtidos pondo uma thread
a simular o mesmo efeito de ter um processador real a trabalhar para esse
fim. Ter uma thread equivale, portanto, a ter aproximadamente o mesmo
resultado de um processador. De notar que, assim, e de acordo com a ar-
quitectura worker /manager proposta, cada thread, apesar de estar a correr
no mesmo computador, nunca comunica com as restantes threads, de modo
que cada uma tem o seu próprio vector população. Isto resultou nalguns
problemas práticos, porque o uso de um vector população composto por 30
inteiros, para o caso 256 ou mais threads (até 1024, caso extremo do gráfico
da figura 4.3) revelou-se impossı́vel de concretizar, uma vez que a máquina
virtual Java não consegue alocar tanta memória (mesmo num sistema de 768
MB, onde foram efectuados os testes) que viabilizasse a execução do soft-
ware cliente nessas mesmas condições. De referir finalmente que as threads
CAPÍTULO 4. APLICAÇÃO DISTRIBUÍDA DO CGA USANDO WEB SERVICES 57

são arrancadas todas ao mesmo tempo por um mesmo programa cliente.


Os meios usados para efectuar as experiências foram duas máquinas exis-
tentes no laboratório. Uma das máquinas, de nome “girafa”, tem um pro-
cessador Pentium III a 600 MHz apenas com 192 MB de RAM, ficou como
servidor de WS, visto que como servidor, o seu trabalho não envolvia poder
de cálculo e alocação de memória para fazer ao número de threads necessário
para correr o cliente que foi executado numa máquina de nome “gazela” com
processador AMD Athlon 2000+ e 768 MB de RAM.
É de verificar que a arquitectura proposta em [4], pode ser mais ou menos
transposta, para o modelo TCP-IP, passando os workers a serem clientes e
o manager a servidor. Foi a isso que se propôs o meu colega Hugo Mártires,
num trabalho anterior[6], em que usava sockets Stream (TCP) para estabe-
lecer a comunicação. O modo de proceder é em tudo semelhante no corrente
projecto, também com servidor e clientes. Passo a descrever o processo pelo
qual se dá a comunicação. De acordo com a lista proposta na arquitectura
que surge em 3.4, os mesmos passos foram seguidos, com algumas nuances.
Cito os passos um a um, com as alterações que se entendeu fazer:

1. o servidor inicializa um novo vector população com todas as posições a


0.5. Fica então à espera de eventuais ligações por parte das eventuais
threads.

2. Cada uma das threads criadas pelo cliente invoca a função DownloadPopulationVector
, sinal de que pretende participar no trabalho. Os passos 2 e 3 da arqui-
tectura proposta juntam-se assim num único passo, descrito de seguida.

3. Nesta fase, o cliente invoca a função DownloadPopulationVector para


CAPÍTULO 4. APLICAÇÃO DISTRIBUÍDA DO CGA USANDO WEB SERVICES 58

“ir buscar” o vector população entretanto inicializado no servidor. De


referir que a função enunciada não necessita de qualquer parâmetro
para a sua correcta invocação. O servidor responde enviando então o
vector população, conjuntamente os valores de m e s.

4. Este passo foi implementado mais ao menos nos mesmos moldes des-
critos. Não há de novo a acrecentar ou a retirar daqui.

5. Findo o seu trabalho, o cliente devolve as diferenças entre o vector no


estado a que chegou após ter cumprido as condições estabelecidas, e
o estado inicial no momento da recepção. As diferenças entram como
o único parâmetro necessário na função necessária para cumprir este
passo, de nome SendPopulationVector .

6. O servidor, no momento da recepção, actualiza o seu vector de acordo


com as diferenças recebidas, truncando os valores que causem overflow
nalgum posição do vector, e verificando se o vector se encontra num
estado a que se poderá considerar como representando se se trata de
uma população constituı́da apenas por cópias de um único indivı́duo,
o que indica que alcançou convergência. Em função deste último re-
sultado, o servidor envia ao servidor como valor de retorno da função
SendPopulationVector um inteiro dando conta do resultado da ve-
rificação de convergência, que assume o valor 0 se esse resultado não
tiver sido positivo, 1 assinalando que o vector convergiu naquele preciso
instante, sendo esta última thread que enviou o último vector com as
diferenças a que cometeu a ”proeza”de completar o trabalho. Em caso
do trabalho no actual vector já estar concluı́do, e alguma thread tentar
CAPÍTULO 4. APLICAÇÃO DISTRIBUÍDA DO CGA USANDO WEB SERVICES 59

invocar a função SendPopulationVector , após esse instante, recebe


o valor -1 de volta, sinal de que o algoritmo já foi concluı́do no servi-
dor e que a thread deve, portanto, dar o seu trabalho também como
terminado

7. No caso da resposta anterior for de que o vector ainda não corres-


ponde a um estado de convergência, é dever da thread invocar a função
DownloadPopulationVector para descarregar um novo vector e pros-
seguir o seu trabalho. Se a função der como resultado null nesse
instante, isso significa que o algoritmo já terá convergido e irá obrigar
a thread a terminar a sua execução imediatamente.

A iniciativa de inicializar o vector população cabe ao programa cliente.


Isto deve-se a uma questão prática de ter de recolher uma amostra de re-
sultados de forma rápida para posterior tratamento estatı́stico. Para obter
os resultados foi necessário executar o programa cliente com uma série de
combinações de parâmetros que tinham de ser introduzidas de seguida de
forma que se pudesse recolher esses parâmetros ao fim de um curto espaço
de tempo. Isto poderá parecer como indo contra o modelo de implementação
proposto em 3.4, mas tornou-se necessário pelos motivos descritos anterior-
mente. O servidor não conserva qualquer registo do número de threads que
se encontram a executar em determinado instante. Assim, não tem forma de
saber quando a última thread termina o seu trabalho, para então inicializar
o novo vector correspondente à nova sessão de trabalho que vai ter inı́cio a
seguir. Isto não viola a arquitectura proposta por quem inicializa o vector
população continua a ser o servidor, mas apenas o faz após um sinal posi-
CAPÍTULO 4. APLICAÇÃO DISTRIBUÍDA DO CGA USANDO WEB SERVICES 60

tivo por parte do cliente. E quem faz o pedido não são as threads, mas sim
o programa cliente, que antes de arrancar todas as threads, “faz sinal” ao
servidor dando conta dessa intenção. Para tudo isto ser possı́vel tornou-se
necessário criar uma nova função ( CreateNewPopulationVector ), que ini-
cializasse um novo vector população no servidor, assim que o trabalho no
anterior estivesse concluı́do. De notar, no entanto, que enquanto o servidor
(que corresponde ao manager da arquitectura proposta) estiver ocupado a
atender clientes, recusa inicializar um novo vector população enquanto o tra-
balho no vector população actual não estiver concluı́do. Deste modo, evitou-
se que um cliente (relembrar, corresponde a um worker ) destruı́sse todo o
trabalho entretanto em processamento ao invocar indevidamente a função
CreateNewPopulationVector . Entre os valores enviados pelo cliente para
inicializar o vector, conta-se o limite de cálculos de fitness por cliente(m),
o tamanho da população(N ) e a pressão de selecção(s). Esta função de-
volve um inteiro (parâmetro de nome status-code) resultado especificando se
o vector população ”requisitado”foi inicializado correctamente (retorna 1),
se ocorreu algum erro durante esse processo (retorna 0), ou se o servidor já
estava ocupado a monitorizar algum trabalho nalgum vector entretanto já
iniciado.

4.4 Sumário

Vimos neste capı́tulo como foi possı́vel criar uma implementação usando Web
Services para fazer processamento distribuı́do do cGA. Após uma breve abor-
dagem da arquitectura proposta para a aplicação distribuı́da do cGA, vimos
CAPÍTULO 4. APLICAÇÃO DISTRIBUÍDA DO CGA USANDO WEB SERVICES 61

as tentativas para implementar a referida arquitectura, como a simulação


efectuada em [4]. Depois viu-se a implementação efectuada usando Web Ser-
vices através de Java para este trabalho, e as pequenas alterações práticas
que se entendeu efectuar para conseguir obter um número de resultados mais
rápida e eficientemente. No próximo irão ser mostrados os resultados obtidos
e faremos a sua subsequente interpretação.
Capı́tulo 5

Resultados e análise

Neste capı́tulo irei apresentar os resultados obtidos usando as mesmas condições


utilizadas na simulação em série de [4]. O número de execuções é que não
foi elevado quanto o do artigo, que era de 30 vezes, apenas 5 para cada
combinação m com P , visto que para m = 8, para valores de P baixos,
cada execução chegava a demorar várias horas, de modo que não foi assim
possı́vel reunir um número de resultados idêntico para todas as combinações
experimentadas. Por outro lado, também não foi possı́vel experimentar o
programa cliente para valores de P maiores do que 128, visto que o hardware
disponibilizado e as limitações da máquina virtual Java infelizmente não o
permitiram.
Na figura 5.1 surgem os gráficos referentes aos resultados obtidos, com
várias séries de dados agrupados de acordo com o valor de m. As escalas
usadas são em tudo idênticas às que foram usadas nos gráficos usados na
figura 4.3, de forma a permitar uma comparação por inspecção visual directa.
Os gráficos foram gerados com o GnuPlot. Podemos então verificar que,

62
CAPÍTULO 5. RESULTADOS E ANÁLISE 63

Figura 5.1: Resultados experimentais resultantes de execução distribuı́da do


cGA através de WS usando threads de Java como workers. Todas as threads
correram na mesma máquina, mas o servidor correu numa máquina separada.
Comparar estes resultados com os da figura 4.3
CAPÍTULO 5. RESULTADOS E ANÁLISE 64

consoante esperado, o número de cálculos de fitness, principais responsáveis


pelo tempo de processamento de um algoritmo genético diminuem duma
forma quase linear à medida que cada vez mais threads vão aparecendo para
participar no trabalho. Quantas mais existirem, maior é possibilidade de
serem explorados mais indivı́duos, de modo que a convergência é atingida
com um número muito menor de execuções da função de fitness. Por outro
lado, o aumento do parâmetro m aumenta o número de cálculos em cada
ciclo recepção/envio do vector. Esse número traduz-se no tempo despendido
com esses cálculos muito mais elevado do que para valores de m mais baixos.
Mas, por outro lado, esse maior perı́odo de tempo despendido evita que o
servidor de WS esteja a ser contactado quase constantemente. Em resultado
disso, o número de comunicações também baixa progressivamente. Assim,
em resumo do que foi dito atrás, temos que:

Tt = Te + Tc

sendo Tt o tempo total gasto para resolver o problema, Te o tempo des-


pendido em cálculos da função fitness e, finalmente, Tc o tempo gasto nas
comunicações para enviar e receber o vector. Como todas as threads, em
princı́pio, trabalham à mesma velocidade, o tempo gasto por uma thread em
particular é directamente proporcional ao tempo total. Como já vimos, o au-
mento de m diminui o Tc , enquanto que P tem um efeito global tanto sobre
Tc como Te no sentido de os reduzir de uma forma inversamente proporcio-
nal ao seu crescimento. Em relação a m, para valores elevados (a partir de
8000) verifica-se uma degradação da sua eficácia no que toca a uma relação
CAPÍTULO 5. RESULTADOS E ANÁLISE 65

quase-proporcional para valores mais mais elevados de P . Essa eficiência


reduz-se drasticamente para m = 80000 a partir de P = 8, aproximada-
mente. Verifica-se finalmente que a redução no número de comunicações é
proporcional ao aumento de m. Os tempos elevados para m = 8 podem
ser esclarecidos com a grande frequência com que as threads contactavam
o servidor, e daı́ devido ao grande volume de tráfego resultante, a rede da
sala ter atingido muito provavelmente o estado de saturação, tendo ainda em
conta que é servida por um hub. Uma extrapolação pode ser obtida destes
resultados, tendo em conta que existem valores de m que parecem ser os
ideais para uma eventual aplicação prática do tema deste trabalho. Mas terá
de ser considerada a largura de banda praticada na Internet para atender a
casos onde valores de largura de banda sejam mais desfavoráveis, uma vez
que valores de m mais baixos exigem uma comunicação quase constante com
o servidor e onde a largura de banda seja mais reduzida isso será manifes-
tamente impossı́vel. Por isso, uma indicação desse parâmetro por parte do
cliente torna-se fundamental quando chegar a altura do cliente querer iniciar
o seu trabalho. O servidor deverá então, indicar um valor de m que seja mais
consentâneo com a largura de banda indicada. Os resultados obtidos foram
semelhantes aos do artigo [4], o que era de esperar. Apesar de não se tratar
de uma implementação em série, utilizei threads que acabam por correr na
mesma máquina assemelhando-se o seu efeito bastante aos resultados de uma
implementação em série.
Capı́tulo 6

Conclusão e Trabalho Futuro

6.1 Conclusão

Através de uma análise cuidada dos resultados mostrados no capı́tulo an-


terior, infere-se que os resultados confirmam em quase tudo os que provêm
da simulação efectuada em [4]. Apesar de se tratar de uma simulação e de
os workers terem sido executados em série em vez de forma distribuı́da, a
experiência prática utilizando web services veio comprovar na realidade os
resultados da simulação. Por outro lado, ficou desta forma demonstrado
também o poder dos Web Services como meio de apoio a cálculo cientı́fico
não ficando em nada atrás de métodos mais tradicionais como o uso de soc-
kets no que toca à facilidade de distribuição e a eficiência em tempo real
não seja muito importante. Este trabalho também pode ser visto como uma
forma de apoio aos Web Services, provando que têm um largo futuro pela
frente no qual podem vir a ter um papel ainda mais activo.

66
CAPÍTULO 6. CONCLUSÃO E TRABALHO FUTURO 67

6.2 Trabalho Futuro

Os objectivos que constam na proposta do projecto não foram concretizados


por falta de tempo, não dispor do hardware tanto na universidade como em
casa, e não ter sido possı́vel encontrar redes com as dimensões apropriadas
e estabilidade de ligação com a largura de banda necessária que pudessem
explorar o seu uso através da Internet. Mesmo em minha casa, os meus
computadores não correspondiam ao hardware desejado e também a minha
ligação ADSL não tem a estabilidade desejável. Aqui, a Universidade po-
dia ter contribuı́do os meios necessários, disponibilizando um máquina com
portas abertas na Internet que pudesse funcionar como servidor de WS, mas
duvido que com os Serviços de Informática que temos, isso tivesse sido al-
guma vez possı́vel. Pelo que ficou dito acima, não foi possı́vel concretizar
os objectivos iniciais que constam na proposta do projecto, ficaram de fora
alguns aspectos interessantes como desenvolver um applet JAVA que corresse
no browser, de forma que oferecesse uma interface mais user friendly. De-
vido à sua grande dificuldade de implementação, que cheguei a tentar, não
foi possı́vel obter uma medida empı́rica de Te e Tc , o que teria permitido
esclarecer com maior convicção os resultados obtidos no capı́tulo anterior.
Também é de considerar a possibilidade das threads não arrancaram todas
ao mesmo tempo, mas seguindo uma distribuição exponencial ao longo do
tempo. Ficou também por explorar a interoperabilidade dos Web Services,
desenvolvendo um cliente noutra linguagem de programação ou plataforma
computacional, sendo um bom exemplo o .NET da Microsoft.
APÊNDICES
Apêndice A

Manual do WebservCGA

A.1 Introdução

A aplicação WebservCGA vem separada em duas partes: a parte do cliente


e a parte do servidor. Grande parte do código próprio é partilhada entre as
duas aplicações. Existe também uma grande parte de bibliotecas necessárias
que são compartilhadas. Isso diz respeito sobretudo às bibliotecas do servlet
Axis e demais código de manipulação de XML.

A.2 Instalação do servidor

Para correr o servidor são necessários 3 componentes básicos:

• Uma máquina virtual Java para o sistema operativo em questão, e aqui


existem duas opções, retirar o JRE (Java Runtime Environment), que
apenas permite executar programas de Java, ou retirar o JDK (Java
Development Kit), que, para além de executar programas, também

69
APÊNDICE A. MANUAL DO WEBSERVCGA 70

compila programas em Java. De salientar ainda que é preciso usar


Java na sua versão 5 (ou 1.5), uma vez que todo o código foi escrito
usando essa versão. O site da Sun dedicado ao Java é onde se pode
encontrar: http://java.sun.com.

• Um servidor de Java Server Pages. Existem vários, mas o único onde


fiz testes foi o http://tomcat.apache.org/. Existem versões para
Windows e Linux.

• Finalmente, para podes usar os Web Services é necessário o Axis. Pode


ser encontrado em http://ws.apache.org/axis/. Como é um pro-
grama escrito em Java, o código serve tanto para Windows ou Linux.

Existe ainda um componente opcional, o Apache Ant, que é uma espécie


de make feito em Java. Corre script’s baseados em XML que simplificam
a tarefa de compilar e executar código, assim como outras tarefas repetiti-
vas que são assim bastante simplificadas. O Ant pode ser encontrado em
http://ant.apache.org/. Vou ser muito sucinto nos passos descritos para
a instalação do servidor, porque uma descrição mais pormenorizada exigiria
estar a descrever a instalação para cada sistema operativo diferente. Basica-
mente os passos necessários são os seguintes:

1. instalar o Tomcat

2. abrir o axis, mas descarregando apenas o subdirectório axis , existente


no directório webapps para o directório webapps do tomcat.

3. mudar o nome do subdirectório axis para wscga


APÊNDICE A. MANUAL DO WEBSERVCGA 71

4. colocar o ficheiro WSCGA-xxxxxxxxxxxx.jar no subdirectório WEB-INF/lib.


Os xxxxxxxxxxxx podem variar e representam a data de última com-
pilação do ficheiro jar que guarda as classes java dos web services do
projecto.

5. arrancar o tomcat, o servidor deve estar disponı́vel em http:<maquina>:


8080/wscga/. Aparece uma página com o tı́tulo “Apache-Axis” , sinal
de que o servidor JSP foi instalado correctamente

6. Seguir o link “List” e ver se aparece na lista de WS disponı́veis “web-


servcga”, clicando no link “(wsdl)” irá abrir um wsdl do respectivo WS,
sinal de que tudo está a funcionar como deve de ser.

A.3 Instalação do cliente

Nada mais simples do que abrir o ficheiro zip. Isto irá descomprimir um
ficheiro principal, WSCGA.jar, que contém as classes principais do cliente, e
criar um directório de nome dep , que contém as bibliotecas necessárias à
execução do cliente. Será escusado dizer que é necessário ter instalada uma
máquina virtual Java, no mı́nimo na versão 1.5. O Ant também poderá ser
útil, para usar uns scripts que simplificam a tarefa de lançar o programa
sem estar a passar por escrever toda a linha de comandos. O script do Ant
encarrega-se de ir perguntando os dados necessários um a um.
APÊNDICE A. MANUAL DO WEBSERVCGA 72

A.4 Invocação

Como já ficou dito, o Axis deve ficar num subdirectório de webapps, sob o
nome wscga, de modo que o URL completo (considerando que o Tomcat usa
a porta 8080, por defeito) para aceder aos WS é http://nomedamaquina:
8080/wscga/services/webservcga . Para lançar o cliente faz-se:
>java -jar WSCGA.jar u=girafa:8080 t=2 m=800 N=100000 T=4
Isto irá lançar um cliente para correr duas threads que vão trabalhar
sobre um vector que representa uma população de 100 000 indivı́duos, sendo
que cada thread envia de volta um vector com as diferenças após terem sido
gerados 800 indivı́duos. Esta execução irá ser repetida ao todo 4 vezes (opção
T).
De notar que as letras que especificam cada uma das opções são separadas
dos seus respectivos valores por sinais de = . A tabela A.1 apresenta a lista
de opções possı́veis e seus respectivos valores. De assinalar que as opções refe-
ridas como ”permitindo valores múltiplos”executam repetidamente a mesma
tarefa mas com outros valores, separados entre : . Por exemplo, se se desejar
repetir o mesmo algoritmo, mas com outro valor de threads, pode-se usar a
seguinte linha de comando:
>java -jar WSCGA.jar u=girafa:8080 t=2:4:8 m=800 N=100000 T=4

, sendo que a diferença em relação ao exemplo anterior A.4é de que o


algoritmo irá ser executado, com os restantes parâmetros sem alteração, com
4 e 8 threads.
De seguida apresento o output da execução do comando A.4 especificado
APÊNDICE A. MANUAL DO WEBSERVCGA 73

opção Significado Valor por


defeito
s Pressão de selecção 8
m Parâmetro m Limite de indivı́duos durante um ciclo (admite 8
valores múltiplos)
N Dimensão da população 100000
t Número de threads (admite valores múltiplos) -
u nome da servidor e porta ( formato servidor:porta ) , pres- localhost:
supõe que o resto do URL é /wscga/services/webservcga 8080
U URL completo do servidor de WS http://
localhost:
8080/
wscga/
services/
webservcga
P HTTP Proxy (formato servidor:porta) -
T número de execuções 1
r ficheiro para onde se deve redireccionar o output do cliente -

Tabela A.1: Opções de Linha de Comandos

no exemplo acima:
O programa informa toda uma série de resultados obtidos, desde o número
de cálculos de fitness (relembrar, é o parâmetro m) até o ao número de contac-
tos thread/servidor. Os dados antecedidos por um número e dois pontos di-
zem respeito dizem respeito a uma thread em particular. A thread assinalada
como o ”WINNER”foi a que despoletou o estado de convergência no servidor.
A partir daqui, o servidor não irá aceitar novos envios do vector população,
e assim cada thread termina o seu trabalho mostrando os dados recolhidos
durante a execução, aparecendo depois os dados globais. O programa cria
automaticamente ainda um subdirectório csv onde irá guardar todos os dados
recolhidos durante a execução em ficheiros .csv separados de acordo com o
tamanho da população utilizado (nome threadstatsx.csv), sendo x o efectivo
APÊNDICE A. MANUAL DO WEBSERVCGA 74

URL of WS is: http://girafa:8080/wscga/services/webservcga


Total of turns: 1
* * * * * * *
Starting with the following parameters:N=100000,s=8,m=800
1 turns missing to go!
Starting at: 16:35 22/11/2005
Now launching 2 threads:0 1
0:<=======WINNER!
0: Terminated!
0:Total fitness calculations:1072408
0:Total communication steps:1341
1: Terminated!
1:Total fitness calculations:1064000
1:Total communication steps:1330
====> Calculations total:2136408
====> Communications total:2671
Started at: 16:35 22/11/2005
Total lasted time:291729 milliseconds!
fitness/thread:1068204.0
commSteps/thread:1335.5
1:This algorithm have already terminated! !
There are are no more vectors which could be accepted!

Figura A.1: Output do programa


APÊNDICE A. MANUAL DO WEBSERVCGA 75

populacional utilizado , que são ficheiros de texto que usam um sı́mbolo para
delimitar dados diferentes contidos na mesma linha. Este formato é universal
em todas as folhas de cálculos e aplicações estatı́sticas, de modo que se possa a
proceder a uma análise. Para calcular médias dos dados recolhidos por pares
m/P, para depois traçar gráficos existem duas classes de Java que o permitem
fazer: ualg.wscga.util.CsvAverages (calcula médias e cria um novo fi-
cheiro de nome threadstatsx avg.csv) e ualg.wscga.util.CsvPlot que gera
ficheiros de dados prontos para serem processados pelo gnuplot separados
de acordo com o valor de m.
Apêndice B

WEBSERVCGA.WSDL

1 <?xml version="1.0" encoding="ISO-8859-1"?>


2 <definitions
3 name="webservcga"
4 targetNamespace="http://wscga.ualg"
5 xmlns="http://schemas.xmlsoap.org/wsdl/"
6 xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
7 xmlns:wscga="http://wscga.ualg"
8 xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
9 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
10 <types>
11 <xsd:schema
12 targetNamespace="http://wscga.ualg"
13 xmlns:SOAP−ENC="http://schemas.xmlsoap.org/soap/encoding/"
14 xmlns:wscga="http://wscga.ualg"
15 xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
16 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
17 <xsd:import namespace="http://schemas.xmlsoap.org/wsdl/"/>
18 <xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
19 <xsd:element name="IntArrayElement">
20 <xsd:complexType name="IntArray">
21 <xsd:restriction base="SOAP-ENC:Array">
22 <xsd:sequence>
23 <xsd:element maxOccurs="unbounded" minOccurs="0" name="item" type="xsd:int"/>
24 </xsd:sequence>
25 <xsd:attribute arrayType="xsd:int[]" ref="SOAP-ENC:arrayType"/>
26 </xsd:restriction>
27 </xsd:complexType>
28 </xsd:element>
29 <xsd:element name="DownloadPopulationVectorElement">
30 <xsd:complexType name="DownloadPopulationVectorComplexType">
31 <xsd:sequence>
32 <xsd:element name="pv" element="wscga:IntArrayElement"/>
33 <xsd:element maxOccurs="1" minOccurs="1" name="m" type="xsd:int"/>
34 <xsd:element maxOccurs="1" minOccurs="1" name="popsize" type="xsd:int"/>
35 <xsd:element maxOccurs="1" minOccurs="1" name="s" type="xsd:int"/>
36 </xsd:sequence>
37 </xsd:complexType>

76
APÊNDICE B. WEBSERVCGA.WSDL 77

38 </xsd:element>
39 <xsd:element name="CreateNewPopulationVectorElement">
40 <xsd:complexType name="CreateNewPopulationVectorComplexType">
41 <xsd:sequence>
42 <xsd:element maxOccurs="1" minOccurs="1" name="popsize" type="xsd:int"/>
43 <xsd:element maxOccurs="1" minOccurs="1" name="m" type="xsd:int"/>
44 <xsd:element maxOccurs="1" minOccurs="1" name="s" type="xsd:int"/>
45 </xsd:sequence>
46 </xsd:complexType>
47 </xsd:element>
48 </xsd:schema>
49 </types>
50
51 <message name="CreateNewPopulationVectorRequest">
52 <part name="initData" element="wscga:CreateNewPopulationVectorElement"/>
53 </message>
54 <message name="CreateNewPopulationVectorResponse">
55 <part name="return_code" type="xsd:int" />
56 </message>
57
58 <message name="DownloadPopulationVectorRequest">
59 </message>
60 <message name="DownloadPopulationVectorResponse">
61 <part name="response" element="wscga:DownloadPopulationVectorElement"/>
62 </message>
63
64 <message name="SendPopulationVectorRequest">
65 <part name="newPopVect" element="wscga:IntArrayElement"/>
66 </message>
67 <message name="SendPopulationVectorResponse">
68 <part name="status_code" type="xsd:int"/>
69 </message>
70
71
72 <portType name="webservcga">
73 <operation name="CreateNewPopulationVector">
74 <input message="wscga:CreateNewPopulationVectorRequest"/>
75 <output message="wscga:CreateNewPopulationVectorResponse"/>
76 </operation>
77 <operation name="DownloadPopulationVector">
78 <input message="wscga:DownloadPopulationVectorRequest"/>
79 <output message="wscga:DownloadPopulationVectorResponse"/>
80 </operation>
81 <operation name="SendPopulationVector">
82 <input message="wscga:SendPopulationVectorRequest"/>
83 <output message="wscga:SendPopulationVectorResponse"/>
84 </operation>
85 </portType>
86 <binding name="webservcgaBinding" type="wscga:webservcga">
87 <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
88
89 <operation name="CreateNewPopulationVector">
90 <soap:operation
91 soapAction="http://viana:8080/wscga/services/webservcga/createNewPopulationVector" />
92 <input>
93 <soap:body
94 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
95 use="literal"/>
96 </input>
97 <output>
98 <soap:body
99 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
APÊNDICE B. WEBSERVCGA.WSDL 78

100 use="literal"/>
101 </output>
102 </operation>
103
104 <operation name="DownloadPopulationVector">
105 <soap:operation
106 soapAction="http://viana:8080/wscga/services/webservcga/downloadPopulationVector"/>
107 <input>
108 <soap:body
109 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
110 parts=""
111 use="literal"/>
112 </input>
113 <output>
114 <soap:body
115 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
116 parts="response"
117 use="literal"/>
118 </output>
119 </operation>
120
121 <operation name="SendPopulationVector">
122 <soap:operation
123 soapAction="http://viana:8080/wscga/services/webservcga/sendPopulationVector"/>
124 <input>
125 <soap:body
126 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
127 use="literal"/>
128 </input>
129 <output>
130 <soap:body
131 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
132 use="literal"/>
133 </output>
134 </operation>
135 </binding>
136 <service name="webservcga">
137 <port binding="wscga:webservcgaBinding" name="webservcga">
138 <soap:address location="http://viana:8080/wscga/services/webservcga"/>
139 </port>
140 </service>
141 </definitions>
Apêndice C

Código fonte do Webservcga

Neste apêndice aparecem apenas os ficheiros mais importantes da aplicação,


por manifesta falta de espaço. O restante código, assim como a respectiva
documentação podem ser consultados em http://www.deei.fct.ualg.pt/
~a18778/webservcga/, ou, futuramente, em http://webservcga.sourceforge.
net.

C.1 CGA.java
1 package ualg.wscga;
2
3 import ualg.wscga.util.Util;
4
5 /∗∗
6 ∗ Classe principal responsavel pela execucao do CGA. Entendeu−se implementar
7 ∗ como classe abstracta, devido ao facto de ser necessario formular um problema
8 ∗ que permitisse a demonstracao do funcionamento
9 ∗ @author Samuel Viana
10 ∗ aluno num. 18778
11 ∗
12 ∗ @since 14 Fev 2005
13 ∗ $Id: CGA.java,v 1.3 2005/11/28 16:40:37 sam Exp $
14 ∗/
15 abstract public class CGA {
16
17 // os valores destas variaveis sao inicializados pelas subclasses
18 /∗∗ comprimento do cromossoma (vector populacao) ∗/
19 protected int lchrom;
20 /∗∗ tamanho da populacao ∗/
21 protected int popsize;
22 /∗∗ pressao de seleccao ∗/
23 protected int s;
24 /∗∗ controla se mostra output para depuracao ou nao ∗/
25 boolean debug;
26 /∗∗ vector populacao∗/
27 protected PopVect pv;
28
29 /∗∗ numero maximo de calculos de fitness por ciclo

79
APÊNDICE C. CÓDIGO FONTE DO WEBSERVCGA 80

30 ∗ recepcao−envio (para o Web Service)


31 ∗ 0 = ilimitado ∗/
32 protected int max evaluations;
33 /∗∗ nome da thread que está a correr este objecto ∗/
34 String threadName = null;
35 /∗∗ contador do numero de execucoes da funcao fitness ∗/
36 protected int function evaluations = 0;
37
38 public void incrFuncEvaluations()
39 {
40 this.function evaluations++;
41 }
42 /∗∗
43 ∗ @return Returns the function evaluations.
44 ∗/
45 public int getFunction evaluations() {
46 return function evaluations;
47 }
48
49 /∗∗ mensagem para efeitos de depuração, o parâmeetro force print
50 ∗ força a mensagem a ser impressa, independentemente do valor da variavel debug
51 ∗ para imprimir ou nao mensagens de depuração
52 ∗/
53 protected void debugMessage(String message,boolean force print)
54 {
55 if (this.debug || force print)
56 System.out.println(((this.threadName!=null)?
57 this.threadName + ":" :"" ) + message);
58 }
59
60 /∗∗ wrapper da anterior, apenas imprime a mensagem se a variavel debug for true
61 ∗/
62 protected void debugMessage(String message)
63 {
64 debugMessage(message,false);
65 }
66
67 /∗∗ a funcao fitness e’ declarada como abstracta, de forma que as subclasses
68 ∗ do CGA a implementem para o caso especifico
69 ∗/
70 public abstract Number fitness(Individual ind);
71
72 /∗∗
73 ∗ @return o vector população actualmente a ser utilizado pelo algoritmo
74 ∗/
75 public PopVect getPv() {
76 return pv;
77 }
78
79 /∗∗
80 ∗ @param pv altera para este novo vector população
81 ∗/
82 public void setPv(PopVect pv) {
83 this.pv = pv;
84 }
85
86 /∗∗
87 ∗ Construtor principal, que receber os principais parametros de funcionamento
88 ∗ do algoritmo.
89 ∗ @param lchrom Comprimento do cromossoma, ou melhor dizendo, do vector populacao
90 ∗ @param popsize Tamanho da populacao
91 ∗ @param s pressao de seleccao
APÊNDICE C. CÓDIGO FONTE DO WEBSERVCGA 81

92 ∗ @param debug Variavel logica que representa se queremos ou nao que seja
93 ∗ mostrada informacao detalhada sobre o metodo durante a execucao
94 ∗ do algoritmo
95 ∗ @param max evaluations numero máximo de cálculos de fitness a serem executadas
96 ∗ antes de terminar, se for 0, apenas termina quando se verificar a convergência
97 ∗ @param pv vector população inicial, se for null, é gerado um novo de raı́z
98 ∗ @param threadName nome da thread que esta’ a correr o objecto da classe corrente, pode ser null
99 ∗ se nao estiverem a serem usadas treads
100 ∗/
101
102 public CGA(int lchrom, int popsize, int s, boolean debug, int max evaluations, PopVect pv,String threadName)
103 {
104 this.lchrom = lchrom;
105 this.popsize = popsize;
106 this.s = s;
107 this.debug = debug;
108 this.max evaluations = max evaluations;
109 this.pv = pv;
110 this.threadName = threadName;
111 }
112
113 /∗∗
114 ∗ construtor que invoca o principal e ignora se o algoritmo estar
115 ∗ a ser utilizado por uma thread
116 ∗/
117 public CGA(int lchrom, int popsize, int s, boolean debug, int max evaluations, PopVect pv)
118 {
119 this(lchrom,popsize,s,debug,max evaluations,pv,null);
120 }
121
122
123 /∗∗
124 ∗ construtor que invoca o anterior, inicializando o vector populacao
125 ∗ com valores de raı́z
126 ∗/
127 public CGA(int lchrom, int popsize, boolean debug, int max evaluations)
128 {
129 this(lchrom,popsize,2,debug,max evaluations,null);
130 }
131
132
133 /∗∗
134 ∗ construtor simplificado que inicializa o vector população
135 ∗ com valor de raı́z, sendo a pressão de selecção igual a 2, e
136 ∗ sem limitação no número de gerações
137 ∗/
138 public CGA(int lchrom, int popsize, boolean debug)
139 {
140 this(lchrom, popsize, 2, debug, 0, null);
141 }
142
143 public CGA(int lchrom, int popsize,int s)
144 {
145 this(lchrom,popsize,s,false);
146 }
147
148 /∗∗
149 ∗ Constructor que invoca o construtor principal, invocando apenas os
150 ∗ parametros lchrom e popsize. O parametro debug recebe por defeito
151 ∗ o valor false, para nao imprimir no ecra qq mensagens de depuracao
152 ∗ a pressao de selecção recebe por defeito o valor 2
153 ∗ @param lchrom comprimento do cromossoma (vector−populacao)
APÊNDICE C. CÓDIGO FONTE DO WEBSERVCGA 82

154 ∗ @param popsize tamanho da populacao


155 ∗/
156 public CGA(int lchrom, int popsize)
157 {
158 this(lchrom,popsize,2);
159 }
160
161
162 /∗∗
163 ∗ Construtor secundario que inicializa o vector população, com valores
164 ∗ de raiz, sem um limite para o numero de gerações, e sem invocar um nome
165 ∗ para a Thread que usa o algoritmo
166 ∗/
167 public CGA(int lchrom, int popsize,int s,boolean debug)
168 {
169 this(lchrom,popsize,s,debug,0,null,null);
170 }
171
172 /∗∗
173 ∗ Construtor secundario sem parametros que inicializa os parametros com
174 ∗ os seguintes valores por defeito:
175 ∗ lchrom = 10
176 ∗ popsize = 10
177 ∗ debug = false
178 ∗/
179 public CGA()
180 {
181 this(10,10,false);
182 }
183
184 /∗∗
185 ∗ Metodo principal da classe. Poe o algoritmo a correr.
186 ∗/
187 public boolean run()
188 {
189 int generations counter = 1; // contador do num. de geracoes
190 /∗ inicializar vector da populacao (pv) no caso de nao ter sido especificado
191 como parametro ∗/
192 if (this.pv == null)
193 this.pv = new PopVect(lchrom,popsize);
194
195 /∗ marca o tempo no instante antes do inicio do algoritmo∗/
196 long before = System.currentTimeMillis();
197
198 debugMessage("PV inicial: " + this.pv);
199 do {
200
201 debugMessage("Geracao " + generations counter++);
202
203 /∗ inicializar array de individuos (sem os gerar todavia) ∗/
204 Individual [] ind = new Individual[s]; // array que recebe os individuos gerados
205
206 /∗ inicializar variaveis que guardam registo do melhor individuo ∗/
207 int best index = −1;
208 double melhor fitness = Double.NEGATIVE INFINITY;
209
210 /∗ calcula os fitness para cada um dos individuos, seleccionando o melhor
211 ∗ e guardando os fitness dentro de cada individuo ∗/
212
213 for (int i=0;i<s;i++)
214 {
215 /∗ gera novo individuo no vector populacao ∗/
APÊNDICE C. CÓDIGO FONTE DO WEBSERVCGA 83

216 ind[i] = pv.generate individual();


217
218 /∗ calcula fitness para o novo individuo ∗/
219 Number fitness value = fitness(ind[i]);
220 /∗ verifica se e’ o melhor ∗/
221 if (fitness value.doubleValue() > melhor fitness)
222 {
223 melhor fitness = fitness value.doubleValue();
224 best index = i;
225 }
226 /∗ regista o fitness obtido com cada Individuo ∗/
227 ind[i].setFitness(fitness value.doubleValue());
228 debugMessage("Individuo " + i + " = " + ind[i]);
229 }
230 debugMessage ("Melhor individuo: " + best index);
231
232 // coloca o melhor individuo na cabeça do array
233 Util.array flip(ind,best index,0);
234 /∗ actualizar o VP de acordo com o vencedor ∗/
235 for (int h=1; h<s; h++)
236 {
237 // procede à actualização do vector posição a posição
238 for (int i=0; i<lchrom; i++ )
239 {
240 if (ind[0].getGene(i) != ind[h].getGene(i))
241 {
242 if (ind[0].getGene(i) == 1) pv.update(i,+1);
243 else pv.update(i,−1);
244 }
245 }
246
247 /∗ em caso dalguma posição exceder popsize ou for menor 0
248 ∗ corrigir os valores errados
249 ∗/
250 for (int i=0;i<lchrom;i++)
251 {
252 if (pv.getFreqAt(i) < 0) pv.update(i,+1);
253 else if (pv.getFreqAt(i) > popsize) pv.update(i,−1);
254 }
255 }
256
257 debugMessage(""+pv);
258 debugMessage("********");
259 /∗ verificar se o vector convergiu ou nao excedeu o numero requerido
260 ∗ de geracoes maximo∗/
261 } while (!pv.has converged()
262 && (this.max evaluations ==0 || function evaluations < this.max evaluations ) );
263
264 /∗ calcula o tempo decorrido ∗/
265 long duracao = System.currentTimeMillis() − before;
266
267 /∗pv representa a solucao final ∗/
268 debugMessage("Resultado final:" + pv);
269 //System.out.println (”Total de geracoes:” + generations counter );
270 //System.out.println(”Tempo decorrido: ” + duracao + ” milissegundos!”);
271
272 /∗ devolve se o algoritmo convergiu ou não após o fim da execução ∗/
273 return ! pv.has converged();
274 }
275 }
APÊNDICE C. CÓDIGO FONTE DO WEBSERVCGA 84

C.2 CGAmtrap.java
1 package ualg.wscga;
2
3 import java.io.PrintStream;
4
5 /∗∗
6 ∗ excepção gerada se o comprimento do cromossoma nao for um multiplo de k
7 ∗/
8 class ChromossomeSizeException extends Exception
9 {
10 public ChromossomeSizeException(String message) {
11 super(message);
12 }
13
14 }
15 /∗∗
16 ∗ Classe que implementa uma trap−functon multipla, por forma
17 ∗ a testar a eficiencia do CGA implementado
18 ∗ @author Samuel Viana
19 ∗ subclasse de CGA, implementa a função abstracta fitness
20 ∗/
21 public class CGAmtrap extends CGA {
22
23 /∗∗ numero de bits da funcao trap − caso simples igual
24 ao comprimento do cromossoma ∗/
25 int k = 3;
26 /∗∗ deceptive−to−optimal ratio ∗/
27 double d2or = 0.7;
28
29 public CGAmtrap(int lchrom, int popsize, int s, boolean debug,
30 int max generations, PopVect pv, String threadName) {
31 super(lchrom, popsize, s, debug, max generations, pv, threadName);
32 }
33
34 public CGAmtrap(int lchrom, int popsize, boolean debug,
35 int max generations, PopVect pv) {
36 this(lchrom, popsize, 2,debug, max generations, pv,null);
37 }
38
39 public CGAmtrap(int lchrom, int popsize, boolean debug, int max generations) {
40 super(lchrom, popsize, debug, max generations);
41 }
42
43 /∗∗
44 ∗ Construtor principal onde se especificam os principais
45 ∗ parâmetros
46 ∗ @param lchrom
47 ∗ @param popsize
48 ∗ @param s
49 ∗ @param debug
50 ∗ @throws ChromossomeSizeException para o caso do comprimento
51 do cromossoma nao for um multiplo de k
52 ∗ @see CGA
53 ∗/
54 public CGAmtrap(int lchrom, int popsize, int s, boolean debug)
55 throws ChromossomeSizeException
56 {
57 super(lchrom, popsize, s, debug);
58 if ((lchrom % k) != 0) throw new ChromossomeSizeException("lchrom=" +
59 lchrom + " should be a multiple of k=" + k);
APÊNDICE C. CÓDIGO FONTE DO WEBSERVCGA 85

60 }
61
62 public CGAmtrap(int lchrom,int popsize,boolean debug,int max eval,PopVect pv,String threadName)
63 throws ChromossomeSizeException
64 {
65 super(lchrom,popsize,2,debug,max eval,pv,threadName);
66 if ((lchrom % k) != 0) throw new
67 ChromossomeSizeException("lchrom=" + lchrom + " should be a multiple of k=" + k);
68 }
69 // CGAmtrap(lchrom,popsize, false,max evaluations,actualPv,this.getName());
70 public CGAmtrap(int lchrom, int popsize) throws Exception {
71 this(lchrom, popsize, 2,false);
72 }
73
74 public CGAmtrap() throws Exception {
75 this(30,100);
76 }
77
78
79 /∗∗
80 ∗ Implementação do fitness para a função de multiplas traps
81 ∗ concateandas
82 ∗ @param id o indivı́duo do qual se quer saber o fitness
83 ∗ @see CGA#fitness(Individual id)
84 ∗/
85 public Number fitness(Individual ind) {
86 double fit = 0;
87 int num blocks = ind.getChromLength() / k;
88 int [] chrom = ind.getChrom();
89
90 for (int i=0;i<num blocks;i++)
91 {
92 int [] block = new int[k];
93 System.arraycopy(chrom,k∗i,block,0,k);
94 fit += trap(block);
95 }
96
97 function evaluations++;
98
99 return new Double(fit);
100 }
101
102 /∗∗
103 ∗ calcula o valor do trap para um bloco particular
104 ∗ @param chrom bloco de k bitsdo cromossoma do qual
105 ∗ se quer saber o fitness
106 ∗/
107 private double trap(int [] chrom)
108 {
109 int oneMax = oneMax(chrom);
110 double fit;
111
112 if (oneMax == k) fit = 1.0;
113 else if (oneMax == k−1) fit = 0.0;
114 else fit = ((−d2or) / ((double) (k − 1 ))) ∗ (double) oneMax + d2or;
115 return fit;
116 }
117
118 /∗∗
119 ∗ calcula o one−max para um determinado bloco do cromossoma
120 ∗ @param chrom um bloco do cromossoma
121 ∗ @return o valor do one−max para o bloco
APÊNDICE C. CÓDIGO FONTE DO WEBSERVCGA 86

122 ∗/
123 private int oneMax(int [] chrom) {
124
125 int cont = 0;
126
127 for (int i=0; i<chrom.length; i++)
128 {
129 if (chrom[i] == 1) cont++;
130 }
131 return cont;
132 }
133
134 /∗∗
135 ∗ calcula o numero de ”building blocks” correctos
136 ∗ no fim de execução do CGA
137 ∗ @param ind o indivı́duo do qual se pretende calclar o numero de blocos
138 ∗ @return a quantidade de building blocks contabilizados
139 ∗/
140 public int correctBBS(Individual ind)
141 {
142 int numblocks = ind.getChromLength() / k;
143 int [] chrom = ind.getChrom();
144 int [] array de uns = new int[k];
145 int correctBBS = 0;
146
147 /∗ inicializa array de un’s para comparacao ∗/
148 java.util.Arrays.fill(array de uns,1);
149
150 for (int i=0; i<numblocks; i++)
151 {
152 int [] block = new int[k];
153 System.arraycopy(chrom,i∗k,block,0,k);
154 boolean arrays equal = java.util.Arrays.equals(block,array de uns);
155 if (arrays equal) correctBBS++;
156 }
157 return correctBBS;
158 }
159
160
161 }
APÊNDICE C. CÓDIGO FONTE DO WEBSERVCGA 87

C.3 CGATesterThread.java
1
2 package ualg.wscga.client;
3
4 import ualg.wscga.util.Util;
5 import ualg.wscga.wsdl.∗;
6 import ualg.wscga.CGA;
7 import ualg.wscga.CGAmtrap;
8 import ualg.wscga.PopVect;
9
10 public class CGATesterThread extends Thread {
11
12 static int thread number = 0;
13 static int total evaluations;
14 static int threads running = 0;
15 static int total communications = 0;
16 static long time calcs = 0;
17 static long time comms = 0;
18 int communication steps;
19 int function evaluations;
20
21 boolean debug;
22
23 public CGATesterThread(String name,boolean debug) {
24 super(name);
25 total evaluations = 0;
26 communication steps = 0;
27 this.function evaluations = 0;
28 this.communication steps = 0;
29 this.debug=debug;
30 thread number++;
31 }
32
33 public static void resetFunctionEvals()
34 {
35 total evaluations = 0;
36 }
37
38 public static void resetTotalCommunications()
39 {
40 total communications = 0;
41 }
42
43 public static void resetAllStatics()
44 {
45 total evaluations = 0;
46 total communications = 0;
47 time calcs = 0;
48 time comms = 0;
49 }
50 public CGATesterThread(String name)
51 {
52 this(name,false);
53 }
54
55 public static int getNumEvals()
56 {
57 return total evaluations;
58 }
59
APÊNDICE C. CÓDIGO FONTE DO WEBSERVCGA 88

60 public static int getTotalCommunications()


61 {
62 return total communications;
63 }
64
65 private void debugMessage(String message)
66 {
67 if (this.debug)
68 System.out.println(this.getName() + ":" + message);
69 }
70
71 private void infoMessage(String message)
72 {
73 System.out.println(this.getName() + ":" + message);
74 }
75
76 private void errorMessage(String message)
77 {
78 System.err.println(this.getName() + ":" + message);
79 }
80
81 /∗∗
82 ∗ @param args
83 ∗/
84 public void run() {
85 // imprime o numero da thread sequencialmente numa linha
86 System.out.print(this.getName() + " ");
87
88 Webservcga ServiceLocator locator = new Webservcga ServiceLocator();
89 locator.setwebservcgaEndpointAddress(CGAExperimenter.wsURL);
90 DownloadPopulationVectorElement dpvct = null;
91 CGA cga = null;
92 long before sending = 0;
93 Integer return code = null;
94
95 threads running ++;
96 try {
97 Webservcga PortType port = locator.getwebservcga();
98
99 PopVect newPv = null;
100 do {
101 /∗ descarrega um novo vector populacao do servidor ∗/
102 dpvct = (DownloadPopulationVectorElement)
103 port.downloadPopulationVector();
104 if (before sending !=0) /∗ calcula dispendido na comunicacao ∗/
105 {
106 time comms += (System.currentTimeMillis() − before sending);
107 }
108 debugMessage("NOVO VECTOR DESCARREGADO:"+dpvct);
109 int[] popVectArrayInt = null;
110 /∗ retira o vector populacao do ”envelope” obtido do WS ∗/
111 try {
112 popVectArrayInt = dpvct.getPv().getArray();
113 }
114 catch (NullPointerException e) /∗ algorithm session stopped ∗/
115 {
116 errorMessage(this.getName() + ":This algorithm session has
117 already stopped. Restart Tomcat to start a new one");
118 break;
119 }
120 int lchrom = popVectArrayInt.length;
121 int max evaluations = dpvct.getM();
APÊNDICE C. CÓDIGO FONTE DO WEBSERVCGA 89

122 int popsize = dpvct.getPopsize();


123 int s = dpvct.getS();
124 // invoca o WebService para descarregar
125 PopVect actualPv = new PopVect(popVectArrayInt,popsize);
126 PopVect oldPv = (PopVect) actualPv.clone();
127
128 /∗ cria um novo objecto CGA e poe o algoritmo a correr ∗/
129 cga = new CGAmtrap(lchrom,popsize, s,false, max evaluations,
130 actualPv,this.getName());
131 long before cga = System.currentTimeMillis();
132 cga.run();
133 /∗ calcula o tempo gasto no calculo do CGA∗/
134 time calcs += (System.currentTimeMillis() − before cga);
135 /∗ obtem o novo VP apos terminarem as m execucoes de fitness ∗/
136 this.function evaluations += cga.getFunction evaluations();
137 debugMessage("Exec. Fit = " + cga.getFunction evaluations());
138 newPv = cga.getPv();
139
140 /∗ calcula a diferenca entre o vector actual e o anterior ∗/
141 int[] diff array = PopVect.calculateDifference(newPv,oldPv);
142
143 debugMessage("Inicial Vector: " + oldPv);
144 debugMessage("Last Vector: " + newPv);
145 debugMessage("Vector difference : " +
146 Util.intArrayToString(diff array));
147
148 before sending = System.currentTimeMillis();
149 // invoca o WebService para enviar
150 return code = port.sendPopulationVector(new IntArrayElement(diff array));
151 if (return code == 0)
152 {
153 debugMessage("The algorithm must go on!");
154 }
155 else if ( return code == 1)
156 {
157 System.out.println("");
158 infoMessage("<=======WINNER!");
159 infoMessage("Final PV:" + newPv);
160 }
161 else if (return code == −1)
162 {
163 errorMessage("This algorithm have already terminated! !
164 There are are no more vectors which could be accepted!");
165 }
166 /∗ incrementa o contador de comunicacoes ∗/
167 this.communication steps++;
168
169 } while (return code == 0); /∗ enquanto a resposta do WS nao for diferente
170 de zero ∗/
171 infoMessage(" Terminated!");
172 infoMessage("Total fitness calculations:" + this.function evaluations);
173 infoMessage("Total communication steps:" + this.communication steps);
174 total evaluations += this.function evaluations;
175 total communications += this.communication steps;
176 threads running−−;
177 }
178 catch (Exception e)
179 {
180 e.printStackTrace();
181 }
182
183 }
APÊNDICE C. CÓDIGO FONTE DO WEBSERVCGA 90

184 }
Bibliografia

[1] David E. Goldberg. Genetic Algorithms in Search, Optimization and


Machine Learning. Addison Wesley, 1989.

[2] Steve Graham. Building Web Services with Java. Developers’ Library.
Sams Publishing, 2nd edition, 2005.

[3] G. R. Harik, F. G. Lobo, and D. E. Goldberg. The compact genetic


algorithm. IEEE Transactions on Evolutionary Computation, 3(4):287–
297, November 1999.

[4] F. G. Lobo, C. F. Lima, and H. Mártires. Massive parallelization of the


compact genetic algorithm. Proceedings of the International Conference
on Adaptive and Natural computiNG Algorithms (ICANNGA-2005), pa-
ges 530–533, 2005.

[5] Carlos Jorge Lopes and José Carlos Ramalho. Web Services - Apli-
cacações Distribuı́das sobre Protocolos Internet. Lidel, 1st edition, 2005.

[6] Hugo Mártires. Processamento distribuı́do do algoritmo genético com-


pacto. Technical report, Universidade do Algarve, 2002.

[7] Seti@home. http://setiathome.ssl.berkeley.edu/.

91

Você também pode gostar