class Alimentador(Arvore): def __init__(self, nome, setores, chaves): assert isinstance(nome, str), 'O parâmetro nome da classe Alimentador' \ 'deve ser do tipo string' assert isinstance(setores, list), 'O parâmetro setores da classe' \ 'Alimentador deve ser do tipo list' assert isinstance(chaves, list), 'O parâmetro chaves da classe' \ 'Alimentador deve ser do tipo list' self.nome = nome self.setores = dict() for setor in setores: self.setores[setor.nome] = setor self.chaves = dict() for chave in chaves: self.chaves[chave.nome] = chave self.nos_de_carga = dict() for setor in setores: for no in setor.nos_de_carga.values(): self.nos_de_carga[no.nome] = no for setor in self.setores.values(): print 'Setor: ', setor.nome setores_vizinhos = list() for chave in self.chaves.values(): if chave.n1 is setor: setores_vizinhos.append(chave.n2) elif chave.n2 is setor: setores_vizinhos.append(chave.n1) for setor_vizinho in setores_vizinhos: print 'Setor Vizinho: ', setor_vizinho.nome nos_de_ligacao = list() for i in setor.nos_de_carga.values(): for j in setor_vizinho.nos_de_carga.values(): if i.nome in j.vizinhos: nos_de_ligacao.append((j, i)) for no in nos_de_ligacao: setor.ordena(no[1].nome) setor.rnp_associadas[setor_vizinho.nome] = (no[0], setor.rnp) print 'RNP: ', setor.rnp self.trechos = dict() _arvore_da_rede = self._gera_arvore_da_rede() super(Alimentador, self).__init__(_arvore_da_rede, str) # def _gera_arvore_da_rede(self): # # for percorre os setores da subestação # arvore_da_rede = dict() # for i, j in self.setores.iteritems(): # setores_outra_subest = set() # # # for percorre os vizinhos do setor analisado # for w in j.vizinhos: # # se o setor vizinho ainda nao esta entre os vizinhos do # # setor vizinho este setor é setado na lista da vizinhança # # do setor analisado # if w in self.setores.keys(): # if i not in self.setores[w].vizinhos: # self.setores[w].vizinhos.append(i) # else: # # armazena os setores que pertencem a outra subestação # setores_outra_subest.add(w) # # print '%-12s vizinhos %s' % (str(j), j.vizinhos) # # # atualiza a arvore de setores # arvore_da_rede[i] = list(set(j.vizinhos) - setores_outra_subest) # # return arvore_da_rede def ordena(self, raiz): super(Alimentador, self).ordena(raiz) for setor in self.setores.values(): caminho = self.caminho_no_para_raiz(setor.nome) if setor.nome != raiz: setor_jusante = caminho[1, 1] setor.rnp = setor.rnp_associadas[setor_jusante][1] def _gera_arvore_da_rede(self): arvore_da_rede = {i: list() for i in self.setores.keys()} for chave in self.chaves.values(): if chave.n1.nome in self.setores.keys() and chave.estado == 1: arvore_da_rede[chave.n1.nome].append(chave.n2.nome) if chave.n2.nome in self.setores.keys() and chave.estado == 1: arvore_da_rede[chave.n2.nome].append(chave.n1.nome) return arvore_da_rede def gera_arvore_nos_de_carga(self): # define os nós de carga do setor raiz da subestação como os primeiros # nós de carga a povoarem a arvore nós de carga e a rnp nós de carga setor_raiz = self.setores[self.rnp[1][0]] self.arvore_nos_de_carga = Arvore(arvore=setor_raiz._gera_arvore_do_setor(), dtype=str) self.arvore_nos_de_carga.ordena(raiz=setor_raiz.rnp[1][0]) # define as listas visitados e pilha, necessárias ao processo recursivo de visita # dos setores da subestação visitados = [] pilha = [] # inicia o processo iterativo de visita dos setores # em busca de seus respectivos nós de carga self._gera_arvore_nos_de_carga(setor_raiz, visitados, pilha) def _gera_arvore_nos_de_carga(self, setor, visitados, pilha): # atualiza as listas de recursão visitados.append(setor.nome) pilha.append(setor.nome) # for percorre os setores vizinhos ao setor atual # que ainda não tenham sido visitados vizinhos = setor.vizinhos for i in vizinhos: # esta condição testa se existe uma ligação entre os setores de uma mesma # subestação, mas que possuem uma chave normalmente aberta entre eles. # caso isto seja constatado o laço for é interrompido. if i not in visitados and i in self.setores.keys(): for c in self.chaves.values(): if c.n1.nome == setor.nome and c.n2.nome == i: if c.estado == 1: break else: pass elif c.n2.nome == setor.nome and c.n1.nome == i: if c.estado == 1: break else: pass else: continue prox = i setor_vizinho = self.setores[i] no_insersao, rnp_insersao = setor_vizinho.rnp_associadas[setor.nome] arvore_insersao = setor_vizinho._gera_arvore_do_setor() setor_vizinho.no_de_ligacao = no_insersao setor_vizinho.rnp = rnp_insersao self.arvore_nos_de_carga.inserir_ramo(no_insersao.nome, (rnp_insersao, arvore_insersao), no_raiz=rnp_insersao[1, 0]) break else: continue else: pilha.pop() if pilha: anter = pilha.pop() return self._gera_arvore_nos_de_carga(self.setores[anter], visitados, pilha) else: return return self._gera_arvore_nos_de_carga(self.setores[prox], visitados, pilha) def atualiza_arvore_da_rede(self): _arvore_da_rede = self._gera_arvore_da_rede() self.arvore = _arvore_da_rede def gera_trechos_da_rede(self): self.trechos = dict() j = 0 for i in range(1, size(self.arvore_nos_de_carga.rnp, axis=1)): prof_1 = int(self.arvore_nos_de_carga.rnp[0, i]) prof_2 = int(self.arvore_nos_de_carga.rnp[0, j]) while abs(prof_1 - prof_2) is not 1: if abs(prof_1 - prof_2) == 0: j -= 1 elif abs(prof_1 - prof_2) == 2: j = i - 1 prof_2 = int(self.arvore_nos_de_carga.rnp[0, j]) else: n_1 = str(self.arvore_nos_de_carga.rnp[1, j]) n_2 = str(self.arvore_nos_de_carga.rnp[1, i]) setor_1 = None setor_2 = None print 'Trecho: ' + n_1 + '-' + n_2 # verifica quais os nós de carga existentes nas extremidades do trecho # e se existe uma chave no trecho for setor in self.setores.values(): if n_1 in setor.nos_de_carga.keys(): setor_1 = setor if n_2 in setor.nos_de_carga.keys(): setor_2 = setor if setor_1 is not None and setor_2 is not None: break else: if setor_1 is None: n = n_1 else: n = n_2 for setor in self.setores.values(): if n in setor.nos_de_carga.keys() and size(setor.rnp, axis=1) == 1: if setor_1 is None: setor_1 = setor else: setor_2 = setor break if setor_1 != setor_2: for chave in self.chaves.values(): if chave.n1 in (setor_1, setor_2) and chave.n2 in (setor_1, setor_2): self.trechos[n_1 + n_2] = Trecho(nome=n_1 + n_2, n1=self.nos_de_carga[n_1], n2=self.nos_de_carga[n_2], chave=chave) else: self.trechos[n_1 + n_2] = Trecho(nome=n_1 + n_2, n1=self.nos_de_carga[n_1], n2=self.nos_de_carga[n_2]) def podar(self, no, alterar_rnp=False): poda = super(Alimentador, self).podar(no, alterar_rnp) rnp_setores = poda[0] arvore_setores = poda[1] if alterar_rnp: # for povoa dicionario com setores podados setores = dict() for i in rnp_setores[1, :]: setor = self.setores.pop(i) setores[setor.nome] = setor # for povoa dicionario com nos de carga podados nos_de_carga = dict() for setor in setores.values(): for j in setor.nos_de_carga.values(): if j.nome in self.nos_de_carga.keys(): no_de_carga = self.nos_de_carga.pop(j.nome) nos_de_carga[no_de_carga.nome] = no_de_carga # for atualiza a lista de nós de carga da subestação # excluindo os nós de carga podados for setor in self.setores.values(): for no_de_carga in setor.nos_de_carga.values(): self.nos_de_carga[no_de_carga.nome] = no_de_carga if no_de_carga.nome in nos_de_carga.keys(): nos_de_carga.pop(no_de_carga.nome) # poda o ramo na arvore da subetação poda = self.arvore_nos_de_carga.podar(setores[no].rnp[1, 0], alterar_rnp=alterar_rnp) rnp_nos_de_carga = poda[0] arvore_nos_de_carga = poda[1] # for povoa dicionario de chaves que estao nos trechos podados # e retira do dicionario de chaves da arvore que esta sofrendo a poda # as chaves que não fazem fronteira com os trechos remanescentes chaves = dict() for chave in self.chaves.values(): if chave.n1.nome in setores.keys(): if not chave.n2.nome in self.setores.keys(): chaves[chave.nome] = self.chaves.pop(chave.nome) else: chave.estado = 0 chaves[chave.nome] = chave elif chave.n2.nome in setores.keys(): if not chave.n1.nome in self.setores.keys(): chaves[chave.nome] = self.chaves.pop(chave.nome) else: chave.estado = 0 chaves[chave.nome] = chave # atualiza os trechos da rede self.gera_trechos_da_rede() return (setores, arvore_setores, rnp_setores, nos_de_carga, arvore_nos_de_carga, rnp_nos_de_carga, chaves) else: return rnp_setores def inserir_ramo(self, no, poda, no_raiz=None): (setores, arvore_setores, rnp_setores, nos_de_carga, arvore_nos_de_carga, rnp_nos_de_carga, chaves) = poda if no_raiz is None: setor_inserir = setores[rnp_setores[1, 0]] else: setor_inserir = setores[no_raiz] setor_insersao = self.setores[no] # for identifica se existe alguma chave que permita a inserção do ramo na arvore # da subestação que ira receber a inserção. chaves_de_lig = dict() # for percorre os nos de carga do setor de insersão for i in self.setores[setor_insersao.nome].nos_de_carga.values(): # for percorre as chaves associadas ao no de carga for j in i.chaves: # for percorre os nos de carga do setor raiz do ramo a ser inserido for w in setores[setor_inserir.nome].nos_de_carga.values(): # se a chave pertence aos nos de carga i e w então é uma chave de ligação if j in w.chaves: chaves_de_lig[j] = (i, w) if not chaves_de_lig: print 'A insersao não foi possível pois nenhuma chave de fronteira foi encontrada!' return i = randint(0, len(chaves_de_lig) - 1) n1, n2 = chaves_de_lig[chaves_de_lig.keys()[i]] self.chaves[chaves_de_lig.keys()[i]].estado = 1 if setor_inserir.nome == setores[rnp_setores[1, 0]].nome: super(Alimentador, self).inserir_ramo(no, (rnp_setores, arvore_setores)) else: super(Alimentador, self).inserir_ramo(no, (rnp_setores, arvore_setores), no_raiz) # atualiza setores da arvore da subestação atual self.setores.update(setores) self.nos_de_carga.update(nos_de_carga) self.chaves.update(chaves) self.atualiza_arvore_da_rede() #self.arvore_nos_de_carga.inserir_ramo_1() self.gera_arvore_nos_de_carga()
14: [15], 8: [9, 7, 13], 13: [8], 7: [8] } nos_arvore_3 = { 3: [27], 27: [3, 21, 26], 21: [27, 20], 20: [21], 26: [27, 25, 19], 25: [26, 24], 24: [25], 19: [26, 18], 18: [19, 17], 17: [18] } nos_arvore_4 = {28: [29, 30], 29: [28], 30: [28]} arvore_1 = Arvore(nos_arvore_1) arvore_1.ordena(raiz=1) arvore_2 = Arvore(nos_arvore_2) arvore_2.ordena(raiz=2) arvore_3 = Arvore(nos_arvore_3) arvore_3.ordena(raiz=3) arvore_4 = Arvore(nos_arvore_4) arvore_4.ordena(raiz=28)
14: [15], 8: [9, 7, 13], 13: [8], 7: [8]} nos_arvore_3 = {3: [27], 27: [3, 21, 26], 21: [27, 20], 20: [21], 26: [27, 25, 19], 25: [26, 24], 24: [25], 19: [26, 18], 18: [19, 17], 17: [18]} nos_arvore_4 = {28:[29,30], 29:[28], 30:[28]} arvore_1 = Arvore(nos_arvore_1) arvore_1.ordena(raiz=1) arvore_2 = Arvore(nos_arvore_2) arvore_2.ordena(raiz=2) arvore_3 = Arvore(nos_arvore_3) arvore_3.ordena(raiz=3) arvore_4 = Arvore(nos_arvore_4) arvore_4.ordena(raiz=28)
class Alimentador(Arvore): def __init__(self, nome, setores, chaves): assert isinstance(nome, str), 'O parâmetro nome da classe Alimentador' \ 'deve ser do tipo string' assert isinstance(setores, list), 'O parâmetro setores da classe' \ 'Alimentador deve ser do tipo list' assert isinstance(chaves, list), 'O parâmetro chaves da classe' \ 'Alimentador deve ser do tipo list' self.nome = nome self.setores = dict() for setor in setores: self.setores[setor.nome] = setor self.chaves = dict() for chave in chaves: self.chaves[chave.nome] = chave self.nos_de_carga = dict() for setor in setores: for no in setor.nos_de_carga.values(): self.nos_de_carga[no.nome] = no for setor in self.setores.values(): print 'Setor: ', setor.nome setores_vizinhos = list() for chave in self.chaves.values(): if chave.n1 is setor: setores_vizinhos.append(chave.n2) elif chave.n2 is setor: setores_vizinhos.append(chave.n1) for setor_vizinho in setores_vizinhos: print 'Setor Vizinho: ', setor_vizinho.nome nos_de_ligacao = list() for i in setor.nos_de_carga.values(): for j in setor_vizinho.nos_de_carga.values(): if i.nome in j.vizinhos: nos_de_ligacao.append((j, i)) for no in nos_de_ligacao: setor.ordena(no[1].nome) setor.rnp_associadas[setor_vizinho.nome] = (no[0], setor.rnp) print 'RNP: ', setor.rnp self.trechos = dict() _arvore_da_rede = self._gera_arvore_da_rede() super(Alimentador, self).__init__(_arvore_da_rede, str) # def _gera_arvore_da_rede(self): # # for percorre os setores da subestação # arvore_da_rede = dict() # for i, j in self.setores.iteritems(): # setores_outra_subest = set() # # # for percorre os vizinhos do setor analisado # for w in j.vizinhos: # # se o setor vizinho ainda nao esta entre os vizinhos do # # setor vizinho este setor é setado na lista da vizinhança # # do setor analisado # if w in self.setores.keys(): # if i not in self.setores[w].vizinhos: # self.setores[w].vizinhos.append(i) # else: # # armazena os setores que pertencem a outra subestação # setores_outra_subest.add(w) # # print '%-12s vizinhos %s' % (str(j), j.vizinhos) # # # atualiza a arvore de setores # arvore_da_rede[i] = list(set(j.vizinhos) - setores_outra_subest) # # return arvore_da_rede def ordena(self, raiz): super(Alimentador, self).ordena(raiz) for setor in self.setores.values(): caminho = self.caminho_no_para_raiz(setor.nome) if setor.nome is not raiz: setor_jusante = caminho[1, 1] setor.rnp = setor.rnp_associadas[setor_jusante][1] def _gera_arvore_da_rede(self): arvore_da_rede = {i: list() for i in self.setores.keys()} for chave in self.chaves.values(): if chave.n1.nome in self.setores.keys() and chave.estado == 1: arvore_da_rede[chave.n1.nome].append(chave.n2.nome) if chave.n2.nome in self.setores.keys() and chave.estado == 1: arvore_da_rede[chave.n2.nome].append(chave.n1.nome) return arvore_da_rede def gera_arvore_nos_de_carga(self): # define os nós de carga do setor raiz da subestação como os primeiros # nós de carga a povoarem a arvore nós de carga e a rnp nós de carga setor_raiz = self.setores[self.rnp[1][0]] self.arvore_nos_de_carga = Arvore( arvore=setor_raiz._gera_arvore_do_setor(), dtype=str) self.arvore_nos_de_carga.ordena(raiz=setor_raiz.rnp[1][0]) # define as listas visitados e pilha, necessárias ao processo recursivo de visita # dos setores da subestação visitados = [] pilha = [] # inicia o processo iterativo de visita dos setores # em busca de seus respectivos nós de carga self._gera_arvore_nos_de_carga(setor_raiz, visitados, pilha) def _gera_arvore_nos_de_carga(self, setor, visitados, pilha): # atualiza as listas de recursão visitados.append(setor.nome) pilha.append(setor.nome) # for percorre os setores vizinhos ao setor atual # que ainda não tenham sido visitados vizinhos = setor.vizinhos for i in vizinhos: # esta condição testa se existe uma ligação entre os setores de uma mesma # subestação, mas que possuem uma chave normalmente aberta entre eles. # caso isto seja constatado o laço for é interrompido. if i not in visitados and i in self.setores.keys(): for c in self.chaves.values(): if c.n1.nome == setor.nome and c.n2.nome == i: if c.estado == 1: break else: pass elif c.n2.nome == setor.nome and c.n1.nome == i: if c.estado == 1: break else: pass else: continue prox = i setor_vizinho = self.setores[i] no_insersao, rnp_insersao = setor_vizinho.rnp_associadas[ setor.nome] arvore_insersao = setor_vizinho._gera_arvore_do_setor() setor_vizinho.no_de_ligacao = no_insersao setor_vizinho.rnp = rnp_insersao self.arvore_nos_de_carga.inserir_ramo( no_insersao.nome, (rnp_insersao, arvore_insersao), no_raiz=rnp_insersao[1, 0]) break else: continue else: pilha.pop() if pilha: anter = pilha.pop() return self._gera_arvore_nos_de_carga(self.setores[anter], visitados, pilha) else: return return self._gera_arvore_nos_de_carga(self.setores[prox], visitados, pilha) def atualiza_arvore_da_rede(self): _arvore_da_rede = self._gera_arvore_da_rede() self.arvore = _arvore_da_rede def gera_trechos_da_rede(self): print self.arvore_nos_de_carga.rnp j = 0 for i in range(1, size(self.arvore_nos_de_carga.rnp, axis=1)): prof_1 = int(self.arvore_nos_de_carga.rnp[0, i]) prof_2 = int(self.arvore_nos_de_carga.rnp[0, j]) while abs(prof_1 - prof_2) is not 1: if abs(prof_1 - prof_2) == 0: j -= 1 elif abs(prof_1 - prof_2) == 2: j = i - 1 prof_2 = int(self.arvore_nos_de_carga.rnp[0, j]) else: n_1 = str(self.arvore_nos_de_carga.rnp[1, j]) n_2 = str(self.arvore_nos_de_carga.rnp[1, i]) setor_1 = None setor_2 = None for setor in self.setores.values(): if n_1 in setor.nos_de_carga.keys() and n_1 != str( setor.rnp[1, 0]): setor_1 = setor if n_2 in setor.nos_de_carga.keys() and n_2 != str( setor.rnp[1, 0]): setor_2 = setor if setor_1 is not None and setor_2 is not None: break else: if setor_1 is None: n = n_1 else: n = n_2 for setor in self.setores.values(): if n in setor.nos_de_carga.keys() and size( setor.rnp, axis=1) == 1: if setor_1 is None: setor_1 = setor else: setor_2 = setor break if setor_1 != setor_2: for chave in self.chaves.values(): if chave.n1 in (setor_1, setor_2) and chave.n2 in (setor_1, setor_2): self.trechos[n_1 + n_2] = Trecho( nome=n_1 + n_2, n1=self.nos_de_carga[n_1], n2=self.nos_de_carga[n_2], chave=chave) else: self.trechos[n_1 + n_2] = Trecho(nome=n_1 + n_2, n1=self.nos_de_carga[n_1], n2=self.nos_de_carga[n_2]) def podar(self, no, alterar_rnp=False): poda = super(Alimentador, self).podar(no, alterar_rnp) rnp_setores = poda[0] arvore_setores = poda[1] if alterar_rnp: # for povoa dicionario com setores podados setores = dict() for i in rnp_setores[1, :]: setor = self.setores.pop(i) setores[setor.nome] = setor # for povoa dicionario com nos de carga podados nos_de_carga = dict() for setor in setores.values(): for j in setor.nos_de_carga.values(): if j.nome in self.nos_de_carga.keys(): no_de_carga = self.nos_de_carga.pop(j.nome) nos_de_carga[no_de_carga.nome] = no_de_carga # for atualiza a lista de nós de carga da subestação # excluindo os nós de carga podados for setor in self.setores.values(): for no_de_carga in setor.nos_de_carga.values(): self.nos_de_carga[no_de_carga.nome] = no_de_carga if no_de_carga.nome in nos_de_carga.keys(): nos_de_carga.pop(no_de_carga.nome) # poda o ramo na arvore da subetação poda = self.arvore_nos_de_carga.podar(setores[no].rnp[1, 0], alterar_rnp=True) rnp_nos_de_carga = poda[0] arvore_nos_de_carga = poda[1] # for povoa dicionario de chaves que estao nos trechos podados # e retira do dicionario de chaves da arvore que esta sofrendo a poda # as chaves que não fazem fronteira com os trechos remanescentes chaves = dict() for chave in self.chaves.values(): if chave.n1.nome in setores.keys(): if not chave.n2.nome in self.setores.keys(): chaves[chave.nome] = self.chaves.pop(chave.nome) else: chave.estado = 0 chaves[chave.nome] = chave elif chave.n2.nome in setores.keys(): if not chave.n1.nome in self.setores.keys(): chaves[chave.nome] = self.chaves.pop(chave.nome) else: chave.estado = 0 chaves[chave.nome] = chave return (setores, arvore_setores, rnp_setores, nos_de_carga, arvore_nos_de_carga, rnp_nos_de_carga, chaves) else: return rnp_setores def inserir_ramo(self, no, poda, no_raiz=None): (setores, arvore_setores, rnp_setores, nos_de_carga, arvore_nos_de_carga, rnp_nos_de_carga, chaves) = poda if no_raiz is None: setor_inserir = setores[rnp_setores[1, 0]] else: setor_inserir = setores[no_raiz] setor_insersao = self.setores[no] # for identifica se existe alguma chave que permita a inserção do ramo na arvore # da subestação que ira receber a inserção. chaves_de_lig = dict() # for percorre os nos de carga do setor de insersão for i in self.setores[setor_insersao.nome].nos_de_carga.values(): # for percorre as chaves associadas ao no de carga for j in i.chaves: # for percorre os nos de carga do setor raiz do ramo a ser inserido for w in setores[setor_inserir.nome].nos_de_carga.values(): # se a chave pertence aos nos de carga i e w então é uma chave de ligação if j in w.chaves: chaves_de_lig[j] = (i, w) if not chaves_de_lig: print 'A insersao não foi possível pois nenhuma chave de fronteira foi encontrada!' return i = randint(0, len(chaves_de_lig) - 1) n1, n2 = chaves_de_lig[chaves_de_lig.keys()[i]] self.chaves[chaves_de_lig.keys()[i]].estado = 1 if setor_inserir.nome == setores[rnp_setores[1, 0]].nome: super(Alimentador, self).inserir_ramo(no, (rnp_setores, arvore_setores)) else: super(Alimentador, self).inserir_ramo(no, (rnp_setores, arvore_setores), no_raiz) # atualiza setores da arvore da subestação atual self.setores.update(setores) self.nos_de_carga.update(nos_de_carga) self.chaves.update(chaves) self.atualiza_arvore_da_rede() #self.arvore_nos_de_carga.inserir_ramo_1() self.gera_arvore_nos_de_carga()