Esempio n. 1
0
def genera_instancia(textFile):

    #    leer poligono
    mex = open(MAPA, 'r')
    coordenadas = []
    for linea in mex:

        linea.strip()
        p = linea.split()
        if len(p) == 0:
            break

        coordenadas.append(((float(p[0]), float(p[1]))))
    mapa = Polygon(coordenadas)

    G = Grafo()
    datos = open(textFile, "w")

    ID = 0
    numSubE = int(PORSubE * n)
    X = []
    Y = []
    on = set()

    puntos = random_points_within(mapa, n)

    #generar subestaciones
    puesto = [randint(0, 1)
              for i in range(numSubE)]  #asegura al menos una subestacion on
    if 1 not in puesto:
        puesto[0] = 1
        shuffle(puesto)
    for i in range(numSubE):
        #        punto=random_points_within(mapa,1,1)
        #        print(punto)
        X.append(puntos[i].coords[0][0])
        Y.append(puntos[i].coords[0][1])
        G.agregaNodo(SubE([i, "%.2f" % X[-1], "%.2f" % Y[-1], puesto[i]]))
        #print("s:\t"+str(ID)+"\t"+str(X[-1])+"\t"+str(Y[-1])+"\t"+str(puesto[i])+'\t'+str(potencia),file=datos)
        ID += 1
        if puesto[i] == 1:
            on.add(i)

#generar nodos
    for i in range(numSubE, n):
        #n: ID  X   Y   puesto/posible(1/0) demanda
        #        punto=random_points_within(mapa,1)
        X.append(puntos[i].coords[0][0])
        Y.append(puntos[i].coords[0][1])
        puesto = choice([0, 1])
        if puesto == 1:
            on.add(ID)
        demanda = randint(DLOW, DUP)
        G.agregaNodo(
            Nodo([ID, "%.2f" % X[-1],
                  "%.2f" % Y[-1], puesto, demanda]))
        ID += 1

#generar matriz distancias
    D = []
    for i in range(0, n):
        D.append(
            [sqrt((X[i] - X[j])**2 + (Y[i] - Y[j])**2) for j in range(0, n)])

#generar arcos
    for inicio in range(n):
        final = np.array(
            D[inicio]).argsort()  #ordena por los nodos mas cercanos
        final = list(final)
        final.remove(inicio)  #para eliminar arco (i,i)
        final = [
            x for x in final if inicio not in G.lista[x]
        ]  #verifica que el arco (j,i) no exista antes de crear el (i,j)
        if inicio < numSubE:
            final2 = final[:int(
                DENARCOSSUBE *
                n)]  #selecciona el porcentaje de arcos estipulado
        else:
            final2 = final[:int(DENARCOS * n)]

#asegurar conectividad con nodos activos
        if inicio in on:
            if on.isdisjoint(
                    final2):  #si de los selccionados no hay uno activo :
                x = next(x for x in final
                         if x in on and inicio not in G.lista[x]
                         )  #agregar para asegurar conexidad
                final2.append(x)

#agregar arcos
        for f in final2:
            puesto = G.lista[inicio]['info'].on * G.lista[f]['info'].on
            longitud = D[i][f]
            topologia = choice(['Aerea', 'Subterranea'])
            G.agregaArco(
                Arco([inicio, f, puesto,
                      "%.2f" % longitud, topologia]))
            G.agregaArco(
                Arco([f, inicio, puesto,
                      "%.2f" % longitud, topologia]))

    #agrupar grupos desconexos de nodos activos

    grupos_ok = {}
    grupos_mal = []
    revisados = set()
    subestaciones = set([x for x in range(int(DENARCOSSUBE * n)) if x in on])

    for inicio in on:
        if inicio not in revisados:  #subestacion activa... buscar nodos conexos
            revisados.add(inicio)
            cola = [inicio]
            grupo = []
            while len(cola) > 0:
                #                print(cola,revisados)
                #                input()
                x = cola.pop(0)

                for final in G.lista[x]:
                    if final in on and final is not inicio and final not in grupo:
                        grupo.append(final)
                        cola.append(final)
                        revisados.add(final)
            interseccion = subestaciones.intersection(set(grupo))
            try:
                grupos_ok[interseccion.pop()] = grupo
            except:
                grupos_mal.append(grupo)
    print(grupos_ok, grupos_mal)

    #    if len(grupos_ok)<len(subestaciones):
    #        falt=0
    #        for c in grupos_ok:
    #            falt+=len(subestaciones.intersection(grupos_ok[c])) #hay varias subestaciones conectadas
    #        if falt<len(subestaciones):#hay subestaciones que no se agregaron

    for grupo in grupos_mal:
        #buscar el grupo mas cercano
        distancia = inf
        for cjto in grupos_ok:
            for x in grupo:
                for y in grupos_ok[cjto]:
                    if D[x][y] < distancia:
                        inicio, final, distancia = x, y, D[x][y]

        #agregar arco inicio--final
        G.agregaArco(
            Arco([
                inicio, final, 1,
                "%.2f" % distancia,
                choice(['Aerea', 'Subterranea'])
            ]))
        print("se agrego el arco %d -- %d" % (inicio, final))


#imprimir instancia
    for g in G.lista:
        if g < numSubE:
            print("s:\t" + str(G.lista[g]['info']), file=datos)
        else:
            print("n:\t" + str(G.lista[g]['info']), file=datos)
    for g in G.lista:
        for a in G.lista[g]:
            if a != 'info':
                print("a:\t" + str(G.lista[g][a]), file=datos)

    datos.close()

    graficaInstancia(textFile)

    return G