-
Notifications
You must be signed in to change notification settings - Fork 0
/
Popul.py
116 lines (94 loc) · 3.08 KB
/
Popul.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# -*- coding: utf-8 -*-
from Indiv import Indiv, IndivInt, IndivReal
from random import random
class Popul:
def __init__(self, popsize, indsize, indivs=[]):
self.popsize = popsize
self.indsize = indsize
if indivs:
self.indivs = indivs
else:
self.initRandomPop()
def getIndiv(self, index):
return self.indivs[index]
def initRandomPop(self):
self.indivs = []
for _ in range(self.popsize):
indiv_i = Indiv(self.indsize, [])
self.indivs.append(indiv_i)
def getFitnesses(self, indivs=None):
fitnesses = []
if not indivs:
indivs = self.indivs
for ind in indivs:
fitnesses.append(ind.getFitness())
return fitnesses
def bestSolution(self):
return max(self.indivs)
def bestFitness(self):
indv = self.bestSolution()
return indv.getFitness()
def selection(self, n, indivs=None):
res = []
fitnesses = list(self.linscaling(self.getFitnesses(indivs)))
for _ in range(n):
sel = self.roulette(fitnesses)
fitnesses[sel] = 0.0
res.append(sel)
return res
def roulette(self, f):
tot = sum(f)
val = random()
acum = 0.0
ind = 0
while acum < val:
acum += (f[ind] / tot)
ind += 1
return ind-1
def linscaling(self, fitnesses):
mx = max(fitnesses)
mn = min(fitnesses)
res = []
for f in fitnesses:
val = (f-mn)/(mx-mn)
res.append(val)
return res
def recombination(self, parents, noffspring):
offspring = []
new_inds = 0
while new_inds < noffspring:
parent1 = self.indivs[parents[new_inds]]
parent2 = self.indivs[parents[new_inds+1]]
offsp1, offsp2 = parent1.crossover(parent2)
offsp1.mutation()
offsp2.mutation()
offspring.append(offsp1)
offspring.append(offsp2)
new_inds += 2
return offspring
def reinsertion(self, offspring):
tokeep = self.selection(self.popsize-len(offspring))
ind_offsp = 0
for i in range(self.popsize):
if i not in tokeep:
self.indivs[i] = offspring[ind_offsp]
ind_offsp += 1
class PopulInt(Popul):
def __init__(self, popsize, indsize, ub, indivs=[]):
self.ub = ub
Popul.__init__(self, popsize, indsize, indivs)
def initRandomPop(self):
self.indivs = []
for _ in range(self.popsize):
indiv_i = IndivInt(self.indsize, [], 0, self.ub)
self.indivs.append(indiv_i)
class PopulReal(Popul):
def __init__(self, popsize, indsize, lb=0.0, ub=1.0, indivs=[]):
self.ub = ub
self.lb = lb
Popul.__init__(self, popsize, indsize, indivs)
def initRandomPop(self):
self.indivs = []
for _ in range(self.popsize):
indiv_i = IndivInt(self.indsize, [], self.lb, self.ub)
self.indivs.append(indiv_i)