05.01.2017 Views

EDITORIAL

Revista_54

Revista_54

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

TEMA DA CAPA<br />

PROGRAMAÇÃO GENÉTICA<br />

<br />

o campo fitness é definido como Maybe Float. Depois<br />

de calculada a função objetivo para um individuo o<br />

valor da sua aptidão é guardada aqui. Enquanto não<br />

for calculada a função objetivo o seu valor é Nothing.<br />

Podemos pensar no Nothing como o que em Java ou<br />

C++ é o valor Null. Em Haskell um valor do tipo Maybe<br />

pode ser Nothing ou aquilo que foi definido, neste<br />

caso um real (float).<br />

Continuemos a ver o módulo Individual.hs. De seguida<br />

o tipo derivado Individual é estendido com Eq e Ord. Estas<br />

duas definições permitem ordenar os indivíduos da população<br />

de acordo com a sua aptidão. Desta forma torna-se<br />

trivial detetar o elemento mais válido da população.<br />

instance Eq Individual where<br />

Individual { fitness = a } == Individual<br />

{ fitness = b } = Just a == Just b<br />

instance Ord Individual where<br />

compare Individual { fitness = a } Individual<br />

{ fitness = b } = compare (Just a) (Just b)<br />

A função newIndividual, definida abaixo, é uma interface<br />

conveniente para construir um indivíduo a partir de um<br />

novo cromossoma. O valor inicial da aptidão é Nothing.<br />

newIndividual :: [ (Int, Int) ] -> Individual<br />

newIndividual gs = Individual { chromosome = gs<br />

, fitness = Nothing }<br />

A função createIndividual devolve um novo indivíduo.<br />

De cada vez que é invocada um indivíduo com um diferente<br />

cromossoma é gerado. A ordem da visita às cidades é gerada<br />

aleatoriamente.<br />

createIndividual :: Int -> IO Individual<br />

createIndividual n = do<br />

gen Float<br />

calcTotalDistance [] = error "Unsuficient number<br />

of cities, module Popoulation, function calcFitness"<br />

calcTotalDistance [_] = 0<br />

calcTotalDistance (c1:c2:cs) = squareDistance c1<br />

c2<br />

+ calcTotalDistance<br />

(c2:cs)<br />

calcFitness :: Cities -> Population -> Population<br />

calcFitness _ [] = []<br />

calcFitness cities (p:ps) =<br />

p { fitness = Just (calcTotalDistance (map<br />

(findCity cities . snd) (chromosome p))) }<br />

: calcFitness cities ps<br />

Finalmente a função calcFitnessPopulation faz a méida<br />

das distâncias percorridas em todos os elementos da<br />

população.<br />

calcFitnessPopulation :: Population -> Float<br />

calcFitnessPopulation p =<br />

(sum $ map fit p) / fromIntegral (length p)<br />

where<br />

fit x = fromMaybe (error "Clashes unknown,<br />

module Population, function calcFitnessPopulation")<br />

(fitness x)<br />

No módulo Population.hs são ainda definidas outras<br />

importantes funções, como por exemplo a função ordPopulation<br />

que reorganiza os indivíduos de uma população do mais<br />

apto para o menos apto.<br />

ordPopulation :: Population -> Population<br />

ordPopulation = sort<br />

A função tournamentSelection escolhe n elementos<br />

da população de forma aleatória e, no final, retorna o indivíduo<br />

mais apto desse grupo.<br />

tournamentSelection :: Int -> Population -> IO Individual<br />

tournamentSelection n p = do<br />

is Population -> IO<br />

(Individual, Individual)<br />

selectParents n p = do -- tournament size, previous<br />

population<br />

parent1

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!