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