import numpy as np
import random
import pandas as pd
# Ingresar datos
g1 = (1, 5, "DIESEL", 15, 0, 12, 27.6)
g2 = (2, 2, "DIESEL", 1, 0, 20, 43.5)
g3 = (3, 2, "DIESEL", 2, 0, 20, 43.5)
g4 = (4, 2, "CARBON", 1, 0, 76, 14.4)
g5 = (5, 2, "CARBON", 2, 0, 76, 14.4)
g6 = (6, 6, "GAS NATURAL", 7, 0, 100, 23)
g7 = (7, 1, "CARBON", 7, 0, 155, 11.6)
g8 = (8, 1, "CARBON", 15, 0, 155, 11.7)
g9 = (9, 1, "CARBON", 16, 0, 155, 11.7)
g10 = (10, 1, "CARBON", 23, 0, 155, 11.7)
g11 = (11, 6, "GAS NATURAL", 22, 0, 197, 22.1)
g12 = (12, 1, "CARBON", 23, 0, 350, 11.4)
g13 = (13, 1, "NUCLEAR", 21, 0, 400, 6)
g14 = (14, 1, "NUCLEAR", 18, 0, 400, 6)
dtype = [('No', int), ('#G', int), ('Tipo', str), ('Barra', int),
('Pmin', float), ('Pmax', float), ("Costo", float)]
l1 = [1, 2, 0.014, 193]
l2 = [1, 3, 0.211, 208]
l3 = [1, 5, 0.085, 208]
l4 = [2, 4, 0.127, 208]
l5 = [2, 6, 0.192, 208]
l6 = [3, 9, 0.119, 208]
l7 = [3, 24, 0.084, 510]
l8 = [4, 9, 0.104, 208]
l9 = [5, 10, 0.088, 208]
l10 = [6, 10, 0.061, 193]
l11 = [7, 8, 0.061, 208]
l12 = [8, 9, 0.165, 208]
l13 = [8, 10, 0.165, 208]
l14 = [9, 11, 0.084, 510]
l15 = [9, 12, 0.084, 510]
l16 = [10, 11, 0.084, 510]
l17 = [10, 12, 0.084, 510]
l18 = [11, 13, 0.048, 600]
l19 = [11, 14, 0.042, 600]
l20 = [12, 13, 0.048, 600]
l21 = [12, 23, 0.097, 600]
l22 = [13, 23, 0.087, 600]
l23 = [14, 16, 0.039, 600]
l24 = [15, 16, 0.017, 600]
l25 = [15, 21, 0.025, 600]
l26 = [15, 24, 0.052, 600]
l27 = [16, 17, 0.026, 600]
l28 = [16, 19, 0.023, 600]
l29 = [17, 22, 0.105, 600]
l30 = [18, 21, 0.013, 600]
l31 = [19, 20, 0.020, 600]
l32 = [20, 23, 0.011, 600]
l33 = [21, 22, 0.068, 600]
b1 = [1, 0.038]
b2 = [2, 0.034]
b3 = [3, 0.063]
b4 = [4, 0.026]
b5 = [5, 0.025]
b6 = [6, 0.048]
b7 = [7, 0.044]
b8 = [8, 0.06]
b9 = [9, 0.061]
b10 = [10, 0.068]
b11 = [11, 0]
b12 = [12, 0]
b13 = [13, 0.093]
b14 = [14, 0.068]
b15 = [15, 0.111]
b16 = [16, 0.035]
b17 = [17, 0]
b18 = [18, 0.117]
b19 = [19, 0.064]
b20 = [20, 0.045]
b21 = [21, 0]
b22 = [22, 0]
b23 = [23, 0]
b24 = [24, 0]
B = [b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15,
b16, b17, b18, b19, b20, b21, b22, b23, b24]
#Crear arreglos
L = [l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15,
l16, l17, l18, l19, l20, l21, l22, l23, l24, l25,
l26, l27, l28, l29, l30, l31, l32, l33]
G = [g1, g2, g3, g4, g5, g6, g7, g8, g9, g10, g11, g12, g13, g14]
G = np.array(G, dtype=dtype)
L = pd.DataFrame(L)
# Ordenar arreglo de menor a mayor costo
GS = np.sort(G, order='Costo')
class DNA():
def __init__(self, mutation_rate, n_individuals, n_selection,
n_generations, verbose=True, data=0, p=0, dataL = 0, dataB = 0):
self.mutation_rate = mutation_rate
self.n_individuals = n_individuals
self.n_selection = n_selection
self.n_generations = n_generations
self.verbose = verbose
self.data = data
self.length = len(data)
self.p = p
self.dataL = dataL
self.dataB = dataB
# Crear listas
def create_list(self, l):
lst = []
for i in range(l):
lst.insert(i, 0)
return lst
# Crear individuos con restricciones
def create_individual(self):
wc = True
individual = self.create_list(self.length)
while wc:
individual = self.create_list(self.length)
ps = 0
for i in range(self.length):
min = int(self.data[i][4])
max = int(self.data[i][5]) * int(self.data[i][1])
individual[i] = random.uniform(min, max)
ps += individual[i]
if ps >= self.p:
r = individual[i]
individual[i] = individual[i] - (ps - self.p)
ps += individual[i] - r
wc = False
break
return individual
# Crear poblacion
def create_population(self):
population = [self.create_individual() for i in
range(self.n_individuals)]
return population
# Crear arreglo de costos
def costm(self):
cm = []
for i in range(self.length):
c = float(self.data[i][-1])
cm.insert(i, c)
return cm
# Obtener costo total
def costT(self, ar):
costT = 0
for i in ar:
costT += i
return costT
# Obtener costo individual y total
def co(self, individual):
cost = self.costm()
co = []
for i in range(len(cost)):
v = cost[i] * individual[i]
co.insert(i, v)
cot = self.costT(co)
return cot
#Obtener cuantos generadores no se usan
def genind(self, individual):
c = 0
for i in individual:
if i == 0:
c += 1
return c
# Obtener valor de castigo por exceder el limite de transmision
def overl(self, individual):
c = 0
ol = self.fDC(individual)
for i in ol:
if i > 90:
c += i-90
return c
# Seleccionar el mejor adaptado
def selection(self, population):
scores = [((10*(self.genind(i))+1)/((0.001*self.co(i)
+0.1*self.overl(i))), i) for i in population]
scores = [(i[0], i[1]) for i in sorted(scores)]
costos = [self.co(i) for i in population]
selected = [i[1] for i in scores]
selected = selected[-self.n_selection:]
print('Mejor: ', self.reord(selected[-1]))
print('Costo promedio de la poblacion: ',
sum(costos)/len(costos))
return selected
# Cruce
def reproduction(self, population, selected):
for i in range(len(population)):
point = np.random.randint(1, len(population[0]) - 1)
father = random.sample(selected, 2)
population[i][:point] = father[0][:point]
population[i][point:] = father[1][point:]
return population
# Corregir si es menor
def corindmenor(self, individual):
c = 0
for i in individual:
c += i
if c < self.p:
m = self.p - c
for i in range(len(individual)):
max = int(self.data[i][5]) * int(self.data[i][1])
d = max - individual[i]
if d < m:
individual[i] = max
m -= d
elif d > m:
individual[i] = individual[i] + m
m = 0
return individual
# Corregir si es mayor
def corindmayor(self, individual):
c = 0
for i in individual:
c += i
if c > self.p:
n = c - self.p
for i in range(len(individual)):
if n > 0:
if individual[-i - 1] > n:
individual[-i - 1] = individual[-i - 1] - n
break
elif individual[-i - 1] < n:
n -= individual[-i - 1]
individual[-i - 1] = 0
return individual
# Corregir poblacion ya mutada y cruzada
def corpop(self, population):
population = [self.corindmenor(i) for i in population]
population = [self.corindmayor(i) for i in population]
return population
# Mutar poblacion
def mutation(self, population):
for i in range(len(population)):
if random.random() <= self.mutation_rate:
min = int(self.data[i][4])
max = int(self.data[i][5]) * int(self.data[i][1])
point = random.randint(0, len(population[0]) - 1)
if population[i][point] != 0:
new_value = random.uniform(min, max)
while new_value == population[i][point]:
new_value = random.uniform(min, max)
population[i][point] = new_value
return population
# Eliminar individuos que no se lograron corregir y crear uno nuevo
en su lugar
def deletei(self, individual):
c = 0
de = 0
for i in individual:
c += i
if c > self.p:
individual = self.create_individual()
elif c < self.p:
individual = self.create_individual()
for i in range(len(individual)):
max = int(self.data[i][5]) * int(self.data[i][1])
if individual[i] > max:
de += 1
if de > 0:
individual = self.create_individual()
return individual
def deletep(self, population):
c = 0
population = [self.deletei(i) for i in population]
return population
# Imprimir individuos
def printpop(self, population):
temp = population[:]
for i in temp:
i = np.array(i)
i = np.round(i, 2)
print(self.reord(i))
#Reordenar
def reord(self, individual):
temp = self.create_list(self.length)
for i in range(len(individual)):
pos = self.data[i][0]-1
temp[pos] = individual[i]
return temp
def run_gen_alg(self):
population = self.create_population()
for i in range(self.n_generations):
if self.verbose:
print('________________________')
print("GENERACION", i)
#print('POBLACION')
#self.printpop(population)
selected = self.selection(population)
population = self.reproduction(population, selected)
population = self.mutation(population)
population = self.corpop(population)
population = self.deletep(population)
print('Flujo DC:', self.fDC(population[0]))
# Crear matriz de admitancias
def matsupInv(self):
B = max(max(self.dataL[0]), max(self.dataL[1]))
Bbus = np.zeros([B, B])
for i in range(len(self.dataL)):
k = int(self.dataL.loc[i][0] - 1)
m = int(self.dataL.loc[i][1] - 1)
Zkm = self.dataL.loc[i][2]
Bbus[k][m] = -1 / Zkm
Bbus[m][k] = -1 / Zkm
for i in range(len(Bbus)):
c = 0
for j in range(len(Bbus)):
c += Bbus[i][j]
Bbus[i][i] = -c
Bbus = np.round(Bbus, 2)
BbusInv = np.linalg.inv(Bbus)
return BbusInv
# Crear matriz de potencias
def matpot(self, individual):
temp = individual[:]
mp = np.zeros(24)
for i in range(len(temp)):
barra = self.data[i][3] - 1
mp[barra] += temp[i]
for i in range(len(self.dataB)):
mp[i] -= self.dataB[i][1] * self.p
mp = mp/self.p
return mp
# Obtener los angulos
def teta(self, individual):
teta = self.matsupInv() @ self.matpot(individual)
return teta
#Obtener los flujos de potencia
def fDC(self, individual):
c = 0
teta = self.teta(individual)
temp = self.create_list(len(self.dataL))
for i in range(len(self.dataL)):
k = int(self.dataL.loc[i][0] - 1)
m = int(self.dataL.loc[i][1] - 1)
temp[i] = ((teta[k] - teta[m]) / (self.dataL.loc[i][2])) *
self.p
temp[i] = abs((temp[i] * 100) / (self.dataL.loc[i][3]))
return temp
model = DNA(0.5, 14, 4, 50, True, GS, 2856, L, B)
model.run_gen_alg()