Example #1
0
def opt2(solution=[], dist_matrix=[]):  #no puedo llamarle 2_opt
    """
        Implementacion del algoritmo 2-Optimo
        nota: nelson descubrio donde fallaba el algoritmo :P
    """
    n_vertex = len(solution)
    soluc = solution[:]
    for i in xrange(n_vertex - 3):
        for j in xrange(i + 2, n_vertex - 1):
            vi = soluc[i]
            vj = soluc[i + 1]
            vk = soluc[j]
            vl = soluc[j + 1]

            d1 = dist(vi, vj, dist_matrix) + dist(vk, vl, dist_matrix)
            d2 = dist(vi, vk, dist_matrix) + dist(vj, vl, dist_matrix)

            if d2 < d1:
                ini = soluc[:i + 1]
                med = soluc[i + 1:j + 1]
                med.reverse()
                fin = soluc[j + 1:]
                soluc = ini + med + fin

    return soluc
Example #2
0
def opt2(solution=[], dist_matrix=[]): #no puedo llamarle 2_opt
    """
        Implementacion del algoritmo 2-Optimo
        nota: nelson descubrio donde fallaba el algoritmo :P
    """
    n_vertex = len(solution)
    soluc = solution[:]
    for i in xrange(n_vertex-3):
        for j in xrange(i+2, n_vertex-1):
            vi = soluc[i]
            vj = soluc[i+1]
            vk = soluc[j]
            vl = soluc[j+1]

            d1 = dist(vi,vj,dist_matrix) + dist(vk,vl,dist_matrix)
            d2 = dist(vi,vk,dist_matrix) + dist(vj,vl,dist_matrix)

            if d2 < d1:
                ini = soluc[:i+1]
                med = soluc[i+1:j+1]
                med.reverse()
                fin = soluc[j+1:]
                soluc = ini + med + fin

    return soluc
Example #3
0
def nearest_vertex(distances, size):
    random.seed()
    tsp_sol = []
    number_of_vertex = size
    vertex_list = range(number_of_vertex)
    incoming_vertex = random.randint(0,number_of_vertex-1)
    min_distance = 0
    tsp_sol.append(incoming_vertex)
    vertex_list.remove(incoming_vertex)
    counter = 0
    echo("building solution.....")
    while counter < number_of_vertex-1:
        flag = 0
        vertex = tsp_sol[-1] #el ultimo elemento de tsp_sol
        for vertex_2 in vertex_list:
            if not flag:
                flag = 1
                min_distance=dist(vertex,vertex_2,distances)
                incoming_vertex = vertex_2
            else:
                temp_distance = dist(vertex,vertex_2,distances)
                if min_distance > temp_distance:
                    min_distance = temp_distance
                    incoming_vertex = vertex_2
        tsp_sol.append(incoming_vertex)
        vertex_list.remove(incoming_vertex)
        counter+=1
    echo("Done")
    return tsp_sol
Example #4
0
def nearest_vertex(distances, size):
    random.seed()
    tsp_sol = []
    number_of_vertex = size
    vertex_list = range(number_of_vertex)
    incoming_vertex = random.randint(0, number_of_vertex - 1)
    min_distance = 0
    tsp_sol.append(incoming_vertex)
    vertex_list.remove(incoming_vertex)
    counter = 0
    echo("building solution.....")
    while counter < number_of_vertex - 1:
        flag = 0
        vertex = tsp_sol[-1]  #el ultimo elemento de tsp_sol
        for vertex_2 in vertex_list:
            if not flag:
                flag = 1
                min_distance = dist(vertex, vertex_2, distances)
                incoming_vertex = vertex_2
            else:
                temp_distance = dist(vertex, vertex_2, distances)
                if min_distance > temp_distance:
                    min_distance = temp_distance
                    incoming_vertex = vertex_2
        tsp_sol.append(incoming_vertex)
        vertex_list.remove(incoming_vertex)
        counter += 1
    echo("Done")
    return tsp_sol
Example #5
0
def create_neighbor(solution_o, k, memory, maximum, probability, distances, invert_mode = False):
    """
    Crea un vecino de solution perteneciente al vecindario k, pero tomando
    en cuenta la memoria de largo plazo
    """
    if not invert_mode:
        a = 0
        b = -1
    else:
        a = 1
        b = 1
    random.seed()
    solution = solution_o[:]
    selected = []
    alredy_selected = [0]*len(solution_o)
    if k == len(solution):
        selected = solution
    else:
        for i in range(k):
            found = 0
            while not found:
                alredy_used = 0
                while not alredy_used:
                    vertex = random.choice(solution)
                    index = solution.index(vertex)
                    if alredy_selected[index] == 0:
                        alredy_used = 1
                vertex_a = solution[index-1]
                if index == (len(solution)-1):
                    index = -1
                vertex_p = solution[index+1]
                counter_a = dist(vertex_a, vertex, memory)
                counter_p = dist(vertex_p, vertex, memory)
                if counter_a > counter_p:
                    counter = counter_a
                else:
                    counter = counter_p
                prob = counter*probability/maximum
                prob = (a-prob)*b
                luck = random.random()
                #print prob, luck, maximum
                if luck >= prob:
                    selected.append(vertex)
                    alredy_selected[index] = 1
                    found = 1
    neighbor = solution_o[:]
    vertex = random.choice(selected)
    selected.remove(vertex)
    index = neighbor.index(vertex)
    while selected != []:
        vertex_b = random.choice(selected)
        selected.remove(vertex_b)
        index_b = neighbor.index(vertex_b)
        neighbor[index] = vertex_b
        neighbor[index_b] = vertex
        index = index_b
    return neighbor
Example #6
0
def nearest_neighbor_sort(graph: Graph) -> Node:
    def follow_path(n: Node):
        if len(n.edges) > 1:
            raise ValueError('Start {!r} has more than one edge'.format(n))
        if len(n.edges) == 0:
            return n
        last = n
        selected = next(iter(n.edges))
        while len(selected.edges) != 1:
            if len(selected.edges) != 2:
                raise ValueError('Inner {!r} does not have two edges'.format(selected))
            next_node = next(iter(selected.edges.difference({last})))
            last = selected
            selected = next_node
        return selected
    picked = set()
    # we only want to connect nodes on the end of a path, not in the middle
    end_nodes = set(filter(lambda n: len(n.edges) <= 1, graph.nodes))
    # pick a node to start from
    start = random.choice(list(end_nodes))  # TODO: find a better way to get a random element
    selected = follow_path(start)
    picked.add(selected)
    picked.add(start)
    remaining = end_nodes.difference(picked)
    while len(remaining) != 0:
        next_node = min(remaining, key=lambda n: dist(selected, n))
        # follow node to the end of its path
        end = follow_path(next_node)
        selected.connect(next_node)
        picked.add(next_node)
        picked.add(end)
        selected = end
        remaining = end_nodes.difference(picked)
    return start
Example #7
0
def vns_opt2(solution=[], dist_matrix=[]): #no puedo llamarle 2_opt
    """
        Implementacion del algoritmo 2-Optimo  que funciona como VNS
        el algoritmo es algo trucho pero es entre 10 y 20 veses mas rapido
        que 3opt y los resultados varian muy poco
    """
    n_vertex = len(solution)
    soluc = solution[:]

    loop=True
    while loop:
        i=0
        while i < n_vertex-3:
            j = i + 2
            while j < n_vertex-1:
                vi = soluc[i]
                vj = soluc[i+1]
                vk = soluc[j]
                vl = soluc[j+1]

                d1 = dist(vi,vj,dist_matrix) + dist(vk,vl,dist_matrix)
                d2 = dist(vi,vk,dist_matrix) + dist(vj,vl,dist_matrix)

                if d2 < d1:
                    ini = soluc[:i+1]
                    med = soluc[i+1:j+1]
                    med.reverse()
                    fin = soluc[j+1:]
                    soluc = ini + med + fin
                    i = 0
                    j = 1 #con esto remplazo el break de abajo
                    #break #los break no son muy elegantes por eso lo quito
                j += 1
            i += 1
            if i == n_vertex - 3:
                loop = False
    return soluc
Example #8
0
def vns_opt2(solution=[], dist_matrix=[]):  #no puedo llamarle 2_opt
    """
        Implementacion del algoritmo 2-Optimo  que funciona como VNS
        el algoritmo es algo trucho pero es entre 10 y 20 veses mas rapido
        que 3opt y los resultados varian muy poco
    """
    n_vertex = len(solution)
    soluc = solution[:]

    loop = True
    while loop:
        i = 0
        while i < n_vertex - 3:
            j = i + 2
            while j < n_vertex - 1:
                vi = soluc[i]
                vj = soluc[i + 1]
                vk = soluc[j]
                vl = soluc[j + 1]

                d1 = dist(vi, vj, dist_matrix) + dist(vk, vl, dist_matrix)
                d2 = dist(vi, vk, dist_matrix) + dist(vj, vl, dist_matrix)

                if d2 < d1:
                    ini = soluc[:i + 1]
                    med = soluc[i + 1:j + 1]
                    med.reverse()
                    fin = soluc[j + 1:]
                    soluc = ini + med + fin
                    i = 0
                    j = 1  #con esto remplazo el break de abajo
                    #break #los break no son muy elegantes por eso lo quito
                j += 1
            i += 1
            if i == n_vertex - 3:
                loop = False
    return soluc
Example #9
0
def min_(k, vertex_list, dist_matrix=[]):
    """
        Calcula el vertice perteneciente a vertex_list mas cercano a k.

        Retorna
            ady_vertex : vertice mas cercano a k
            cost: costo de agregar el nuevo vertice
    """
    ady_vertex = None #vertice adyacente que se agregara
    cost = 9999999999 #defino un costo inicial muy elevado
    for vert in vertex_list: #bobo un algoritmo de busqueda
        if vert != k:
            ncost = dist(k, vert, dist_matrix)
            if ncost < cost:
                ady_vertex = vert
                cost = ncost
    return ady_vertex, cost
Example #10
0
def min_(k, vertex_list, dist_matrix=[]):
    """
        Calcula el vertice perteneciente a vertex_list mas cercano a k.

        Retorna
            ady_vertex : vertice mas cercano a k
            cost: costo de agregar el nuevo vertice
    """
    ady_vertex = None  #vertice adyacente que se agregara
    cost = 9999999999  #defino un costo inicial muy elevado
    for vert in vertex_list:  #bobo un algoritmo de busqueda
        if vert != k:
            ncost = dist(k, vert, dist_matrix)
            if ncost < cost:
                ady_vertex = vert
                cost = ncost
    return ady_vertex, cost
Example #11
0
def opt3_(solution=[], d_m=[]):
    """
        Implementacion del Algoritmo 3-Optimo,

        optimizado en velocidad calculo
    """
    n_vertex = len(solution)
    soluc = solution[:]
    for i in xrange(n_vertex-5):
        for j in xrange(i+2, n_vertex-3):
            for k in xrange(j+2, n_vertex-3):
                va, vb = soluc[i], soluc[i+1]
                vc, vd = soluc[j], soluc[j+1]
                ve, vf = soluc[k], soluc[k+1]

                #calculo las distancias de todas las posibles conbinaciones
                #muchos calculos entre las conv se repiten y para no hacerlos
                #de nuevo los calculo una sola ves lo que reduce a la mitad la
                #cantida usos de la func dist
                d_ab = dist(va,vb,d_m)
                d_ac = dist(va,vc,d_m)
                d_ad = dist(va,vd,d_m)
                d_ae = dist(va,ve,d_m)

                d_ef = dist(ve,vf,d_m)
                d_df = dist(vd,vf,d_m)
                d_cf = dist(vc,vf,d_m)
                d_vf = dist(vb,vf,d_m)

                d_bd = dist(vb,vd,d_m) # d_bd = d_db
                d_cd = dist(vc,vd,d_m) # d_cd = d_dc
                d_be = dist(vb,ve,d_m) # d_be = d_eb
                d_ce = dist(vc,ve,d_m) # d_ce = d_ec

                distances = [
                    d_ab + d_cd + d_ef,
                    d_ac + d_bd + d_ef,
                    d_ab + d_ce + d_df,
                    d_ac + d_be + d_df,
                    d_ad + d_be + d_cf,
                    d_ae + d_bd + d_cf,
                    d_ad + d_ce + d_vf,
                    d_ae + d_cd + d_vf,
                ]

                ini = soluc[:i+1] #tramo hasta a includo
                t_bc = soluc[i+1:j+1] #tramo bc
                t_de = soluc[j+1:k+1] #tramo de
                fin = soluc[k+1:] #tramo desde f includo

                #d = distances[:]
                #d.sort()
                mini = distances.index(min(distances))

                #el primer caso es el original, no implica ningun cambio
                #por eso no hago nada, ahh aca no hay case pero lo mismo eso
                #se soluciona a como sigue :P
                if mini == 1:
                    t_bc.reverse()

                elif mini == 2:
                    t_de.reverse()

                elif mini == 3:
                    t_bc.reverse()
                    t_de.reverse()

                #cuando min = 4 solo invierte las posiciones de tramos bc y ef
                #osea intercambo ambos tramos bc -> ef y ef -> bc
                elif mini == 5:
                    t_de.reverse()

                elif mini == 6:
                    t_bc.reverse()

                elif mini == 7:
                    t_bc.reverse()
                    t_de.reverse()

                if mini < 4:
                    soluc = ini + t_bc + t_de + fin
                else:
                    soluc = ini + t_de + t_bc + fin
    return soluc
Example #12
0
def opt3(solution=[], d_m=[]):
    """
        Implementacion del Algoritmo 3-Optimo
    """
    n_vertex = len(solution)
    soluc = solution[:]
    for i in xrange(n_vertex-5):
        for j in xrange(i+2, n_vertex-3):
            for k in xrange(j+2, n_vertex-3):
                va, vb = soluc[i], soluc[i+1]
                vc, vd = soluc[j], soluc[j+1]
                ve, vf = soluc[k], soluc[k+1]

                #calculo las distancias de todas las posibles conbinaciones

                distances = [
                    dist(va,vb,d_m) + dist(vc,vd,d_m) + dist(ve,vf,d_m),
                    dist(va,vc,d_m) + dist(vb,vd,d_m) + dist(ve,vf,d_m),
                    dist(va,vb,d_m) + dist(vc,ve,d_m) + dist(vd,vf,d_m),
                    dist(va,vc,d_m) + dist(vb,ve,d_m) + dist(vd,vf,d_m),
                    dist(va,vd,d_m) + dist(ve,vb,d_m) + dist(vc,vf,d_m),
                    dist(va,ve,d_m) + dist(vd,vb,d_m) + dist(vc,vf,d_m),
                    dist(va,vd,d_m) + dist(ve,vc,d_m) + dist(vb,vf,d_m),
                    dist(va,ve,d_m) + dist(vd,vc,d_m) + dist(vb,vf,d_m),
                ]

                ini = soluc[:i+1] #tramo hasta a includo
                t_bc = soluc[i+1:j+1] #tramo bc
                t_de = soluc[j+1:k+1] #tramo de
                fin = soluc[k+1:] #tramo desde f includo

                d = distances[:]
                d.sort()
                min = distances.index(d[0])

                #el primer caso es el original, no implica ningun cambio
                #por eso no hago nada, ahh aca no hay case pero lo mismo eso
                #se soluciona a como sigue :P
                if min == 1:
                    t_bc.reverse()

                elif min == 2:
                    t_de.reverse()

                elif min == 3:
                    t_bc.reverse()
                    t_de.reverse()

                #cuando min = 4 solo invierte las posiciones de tramos bc y ef
                #osea intercambo ambos tramos bc -> ef y ef -> bc

                elif min == 5:
                    t_de.reverse()

                elif min == 6:
                    t_bc.reverse()

                elif min == 7:
                    t_bc.reverse()
                    t_de.reverse()

                if min < 4:
                    soluc = ini + t_bc + t_de + fin
                else:
                    soluc = ini + t_de + t_bc + fin
    return soluc
Example #13
0
def create_neighbor(solution_o,
                    k,
                    memory,
                    maximum,
                    probability,
                    distances,
                    invert_mode=False):
    """
    Crea un vecino de solution perteneciente al vecindario k, pero tomando
    en cuenta la memoria de largo plazo
    """
    if not invert_mode:
        a = 0
        b = -1
    else:
        a = 1
        b = 1
    random.seed()
    solution = solution_o[:]
    selected = []
    alredy_selected = [0] * len(solution_o)
    if k == len(solution):
        selected = solution
    else:
        for i in range(k):
            found = 0
            while not found:
                alredy_used = 0
                while not alredy_used:
                    vertex = random.choice(solution)
                    index = solution.index(vertex)
                    if alredy_selected[index] == 0:
                        alredy_used = 1
                vertex_a = solution[index - 1]
                if index == (len(solution) - 1):
                    index = -1
                vertex_p = solution[index + 1]
                counter_a = dist(vertex_a, vertex, memory)
                counter_p = dist(vertex_p, vertex, memory)
                if counter_a > counter_p:
                    counter = counter_a
                else:
                    counter = counter_p
                prob = counter * probability / maximum
                prob = (a - prob) * b
                luck = random.random()
                #print prob, luck, maximum
                if luck >= prob:
                    selected.append(vertex)
                    alredy_selected[index] = 1
                    found = 1
    neighbor = solution_o[:]
    vertex = random.choice(selected)
    selected.remove(vertex)
    index = neighbor.index(vertex)
    while selected != []:
        vertex_b = random.choice(selected)
        selected.remove(vertex_b)
        index_b = neighbor.index(vertex_b)
        neighbor[index] = vertex_b
        neighbor[index_b] = vertex
        index = index_b
    return neighbor
Example #14
0
def opt3_(solution=[], d_m=[]):
    """
        Implementacion del Algoritmo 3-Optimo,

        optimizado en velocidad calculo
    """
    n_vertex = len(solution)
    soluc = solution[:]
    for i in xrange(n_vertex - 5):
        for j in xrange(i + 2, n_vertex - 3):
            for k in xrange(j + 2, n_vertex - 3):
                va, vb = soluc[i], soluc[i + 1]
                vc, vd = soluc[j], soluc[j + 1]
                ve, vf = soluc[k], soluc[k + 1]

                #calculo las distancias de todas las posibles conbinaciones
                #muchos calculos entre las conv se repiten y para no hacerlos
                #de nuevo los calculo una sola ves lo que reduce a la mitad la
                #cantida usos de la func dist
                d_ab = dist(va, vb, d_m)
                d_ac = dist(va, vc, d_m)
                d_ad = dist(va, vd, d_m)
                d_ae = dist(va, ve, d_m)

                d_ef = dist(ve, vf, d_m)
                d_df = dist(vd, vf, d_m)
                d_cf = dist(vc, vf, d_m)
                d_vf = dist(vb, vf, d_m)

                d_bd = dist(vb, vd, d_m)  # d_bd = d_db
                d_cd = dist(vc, vd, d_m)  # d_cd = d_dc
                d_be = dist(vb, ve, d_m)  # d_be = d_eb
                d_ce = dist(vc, ve, d_m)  # d_ce = d_ec

                distances = [
                    d_ab + d_cd + d_ef,
                    d_ac + d_bd + d_ef,
                    d_ab + d_ce + d_df,
                    d_ac + d_be + d_df,
                    d_ad + d_be + d_cf,
                    d_ae + d_bd + d_cf,
                    d_ad + d_ce + d_vf,
                    d_ae + d_cd + d_vf,
                ]

                ini = soluc[:i + 1]  #tramo hasta a includo
                t_bc = soluc[i + 1:j + 1]  #tramo bc
                t_de = soluc[j + 1:k + 1]  #tramo de
                fin = soluc[k + 1:]  #tramo desde f includo

                #d = distances[:]
                #d.sort()
                mini = distances.index(min(distances))

                #el primer caso es el original, no implica ningun cambio
                #por eso no hago nada, ahh aca no hay case pero lo mismo eso
                #se soluciona a como sigue :P
                if mini == 1:
                    t_bc.reverse()

                elif mini == 2:
                    t_de.reverse()

                elif mini == 3:
                    t_bc.reverse()
                    t_de.reverse()

                #cuando min = 4 solo invierte las posiciones de tramos bc y ef
                #osea intercambo ambos tramos bc -> ef y ef -> bc
                elif mini == 5:
                    t_de.reverse()

                elif mini == 6:
                    t_bc.reverse()

                elif mini == 7:
                    t_bc.reverse()
                    t_de.reverse()

                if mini < 4:
                    soluc = ini + t_bc + t_de + fin
                else:
                    soluc = ini + t_de + t_bc + fin
    return soluc
Example #15
0
def opt3(solution=[], d_m=[]):
    """
        Implementacion del Algoritmo 3-Optimo
    """
    n_vertex = len(solution)
    soluc = solution[:]
    for i in xrange(n_vertex - 5):
        for j in xrange(i + 2, n_vertex - 3):
            for k in xrange(j + 2, n_vertex - 3):
                va, vb = soluc[i], soluc[i + 1]
                vc, vd = soluc[j], soluc[j + 1]
                ve, vf = soluc[k], soluc[k + 1]

                #calculo las distancias de todas las posibles conbinaciones

                distances = [
                    dist(va, vb, d_m) + dist(vc, vd, d_m) + dist(ve, vf, d_m),
                    dist(va, vc, d_m) + dist(vb, vd, d_m) + dist(ve, vf, d_m),
                    dist(va, vb, d_m) + dist(vc, ve, d_m) + dist(vd, vf, d_m),
                    dist(va, vc, d_m) + dist(vb, ve, d_m) + dist(vd, vf, d_m),
                    dist(va, vd, d_m) + dist(ve, vb, d_m) + dist(vc, vf, d_m),
                    dist(va, ve, d_m) + dist(vd, vb, d_m) + dist(vc, vf, d_m),
                    dist(va, vd, d_m) + dist(ve, vc, d_m) + dist(vb, vf, d_m),
                    dist(va, ve, d_m) + dist(vd, vc, d_m) + dist(vb, vf, d_m),
                ]

                ini = soluc[:i + 1]  #tramo hasta a includo
                t_bc = soluc[i + 1:j + 1]  #tramo bc
                t_de = soluc[j + 1:k + 1]  #tramo de
                fin = soluc[k + 1:]  #tramo desde f includo

                d = distances[:]
                d.sort()
                min = distances.index(d[0])

                #el primer caso es el original, no implica ningun cambio
                #por eso no hago nada, ahh aca no hay case pero lo mismo eso
                #se soluciona a como sigue :P
                if min == 1:
                    t_bc.reverse()

                elif min == 2:
                    t_de.reverse()

                elif min == 3:
                    t_bc.reverse()
                    t_de.reverse()

                #cuando min = 4 solo invierte las posiciones de tramos bc y ef
                #osea intercambo ambos tramos bc -> ef y ef -> bc

                elif min == 5:
                    t_de.reverse()

                elif min == 6:
                    t_bc.reverse()

                elif min == 7:
                    t_bc.reverse()
                    t_de.reverse()

                if min < 4:
                    soluc = ini + t_bc + t_de + fin
                else:
                    soluc = ini + t_de + t_bc + fin
    return soluc