Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 带遗传、变异、交叉的旅行商_Python_Algorithm - Fatal编程技术网

Python 带遗传、变异、交叉的旅行商

Python 带遗传、变异、交叉的旅行商,python,algorithm,Python,Algorithm,上学期上学时,我写了一个python程序来解决旅行推销员问题。对于那些不熟悉它是什么的人来说,wolfram alpha解释很好地解释了它 这是我最早用Python编写的程序之一,到目前为止,我喜欢这种语言,它来自C++/Java背景。无论如何,我使用了很多低效的方法/编程实践来让它工作,所以我想回去改进。我使用了一种带有突变和有序交叉的遗传算法。首先,我创建一个具有给定长度和给定策略数的随机唯一节点列表。遗传算法通过给定数量的这些策略,通过使用有序交叉和两个随机指数之间的反向变异来改变策略的随

上学期上学时,我写了一个python程序来解决旅行推销员问题。对于那些不熟悉它是什么的人来说,wolfram alpha解释很好地解释了它

这是我最早用Python编写的程序之一,到目前为止,我喜欢这种语言,它来自C++/Java背景。无论如何,我使用了很多低效的方法/编程实践来让它工作,所以我想回去改进。我使用了一种带有突变和有序交叉的遗传算法。首先,我创建一个具有给定长度和给定策略数的随机唯一节点列表。遗传算法通过给定数量的这些策略,通过使用有序交叉和两个随机指数之间的反向变异来改变策略的随机选择。每个策略都有一个给定的变异概率和另一个交叉概率。在此之后,算法随机选择两种策略,选择最佳策略,然后将其与迄今为止找到的最佳解决方案进行比较。该程序的最终目标是找到通过所有节点的最短距离

以下是我更新、高效、不起作用的代码:

import random
import math
import pprint
from matplotlib import pyplot as plt

def create_nodes(num_nodes, num_rows):
    elements = range(1, num_nodes + 1)
    return [random.sample(elements, num_nodes) for _ in range(num_rows)]

def mutate(table, node_table, mutate_probability, cross_probability):
    for next_id, row in enumerate(table, 1):
        nodes = len(row)
        # print
        # print "Original: ", row
        #mutation
        if random.random() > mutate_probability:
            mini, maxi = sorted(random.sample(range(nodes),2))
            row[mini:maxi+1] = row[mini:maxi+1][::-1]
            # print "After mutation: ", row
            # print "Between: ", mini, maxi

        #crossover
        if random.random() > cross_probability:
            try:
                next_row = table[next_id]
                # print "Parent: ", next_row
            except IndexError:
                pass
            else:
                half_length = nodes//2
                mini = random.randint(0, half_length)
                maxi = mini + half_length - 1 + (nodes % 2)

                crossed = [None] * nodes
                # print "Before crossed: ", row
                crossed[mini:maxi+1] = next_row[mini:maxi+1]
                # print "Cross with: ", crossed
                iterator = 0
                for element in row:
                    if element in crossed:
                        continue
                    while mini <= iterator <= maxi:
                        iterator += 1
                    crossed[iterator] = element
                    iterator += 1
                row[:] = crossed
                # print "After crossed: ", row
                # print "Between: ", mini, maxi
def sample_best(table, node_table):
    t1, t2 = random.sample(table[1:], 2)
    return distance(t1, t2, node_table)

def distance(s1, s2, node_table):
    distance1 = sum_distances(s1, node_table)
    distance2 = sum_distances(s2, node_table)

    if distance1 < distance2:
        return s1, distance1
    else:
        return s2, distance2

def sum_distances(strategy, node_table):
    dist = 0
    first_row, second_row = node_table

    for idx_next_node, node1 in enumerate(strategy, 1):
        try:
            node2 = strategy[idx_next_node]
        except IndexError:
            node2 = strategy[0]
        dist += math.hypot(
            first_row[node2-1] - first_row[node1-1],
            second_row[node2-1] - second_row[node1-1])

    return dist

def draw_graph(node_table, strategy):
    graphX = [node_table[0][index - 1] for index in strategy]
    graphY = [node_table[1][index - 1] for index in strategy]

    plt.scatter(graphX, graphY)
    plt.plot(graphX, graphY)
    plt.show()


def main(nodes=8, strategies=100, generations=10000, mutateP=.7, crossP=.7):
    #create node locations
    node_table = create_nodes(nodes, 2)
    # for i in range(2):
    #   print node_table[i]

    #create first generation
    table = create_nodes(nodes, strategies)
    # for i in range(strategies):
    #   print i
    #   print table[i]

    print "TOP MEN are looking through:"
    print strategies, "strategies in", generations, "generations with",
    print nodes, "nodes in each strategy..."

    best_score = None
    for count in range(generations):
        mutate(table, node_table, mutateP, crossP)
        # crossover(table, node_table, crossP)
        strategy, score = sample_best(table, node_table)

        if best_score is None or score < best_score:
            best_strategy = strategy
            best_score = score

        if count % 100 == 0:
            print "Foraged", count, "berries"
            print "Best we got so far:", best_score, "with: ", best_strategy

        # if count % 2 == 0:
        #   print count
        #   for i in range(strategies):
        #       print table[i]



    print "=========================================================================="
    print "Best we could find: ", best_score, "for strategy", best_strategy

    draw_graph(node_table, best_strategy)

main()
随机导入
输入数学
导入pprint
从matplotlib导入pyplot作为plt
def创建_节点(num_节点,num_行):
元素=范围(1,num_节点+1)
return[random.sample(elements,num_nodes)for u in range(num_rows)]
def mutate(表、节点表、变异概率、交叉概率):
对于下一个_id,枚举(表1)中的行:
节点=len(行)
#印刷品
#打印“原件:”,第行
#突变
如果random.random()>变异概率:
mini,maxi=sorted(random.sample(范围(节点),2))
行[mini:maxi+1]=行[mini:maxi+1][:-1]
#打印“变异后:”,第行
#打印“介于:”、mini、maxi之间
#交叉
如果random.random()>交叉概率:
尝试:
下一行=表[下一行id]
#打印“父项:”,下一行
除索引器外:
通过
其他:
半长=节点//2
mini=random.randint(0,半长)
最大=最小+半长-1+(节点%2)
交叉=[无]*节点
#打印“划线前:”,第行
交叉[mini:maxi+1]=下一行[mini:maxi+1]
#打印“带:”,划线
迭代器=0
对于行中的元素:
如果元素交叉:
持续

而mini的目标函数是什么?