Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.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,所以我为我的旅行推销员问题创建了一个排序,我用x坐标和y坐标进行排序 我试图实现一个贪婪的搜索,但无法实现 此外,每个点在矩阵城市中实例化,例如[0,3,4],其中0是标题,3是x坐标,4是y坐标 这是我的程序,你应该可以运行。主要的问题是我的算法不起作用,我需要帮助将其修复为一个有效的贪婪算法。您可以在代码末尾附近找到算法 这是您需要的文本文件,它从中获取输入 旅行商问题(TSP)是一个组合优化问题 问题,在给定一张地图(一组城市及其位置)的情况下 想要找到一个访问所有城市的订单 旅行距离很

所以我为我的旅行推销员问题创建了一个排序,我用x坐标和y坐标进行排序

我试图实现一个贪婪的搜索,但无法实现

此外,每个点在矩阵城市中实例化,例如[0,3,4],其中0是标题,3是x坐标,4是y坐标

这是我的程序,你应该可以运行。主要的问题是我的算法不起作用,我需要帮助将其修复为一个有效的贪婪算法。您可以在代码末尾附近找到算法

这是您需要的文本文件,它从中获取输入


旅行商问题(TSP)是一个组合优化问题 问题,在给定一张地图(一组城市及其位置)的情况下 想要找到一个访问所有城市的订单 旅行距离很短

我建议先解决tsp问题,然后再解决视觉问题

以下代码包含一组用于说明的函数: -TSP问题的构造启发式算法 -先前构造的解决方案的改进启发式算法 -本地搜索,并随机启动本地搜索

import math
import random


def distL2((x1,y1), (x2,y2)):
    """Compute the L2-norm (Euclidean) distance between two points.

    The distance is rounded to the closest integer, for compatibility
    with the TSPLIB convention.

    The two points are located on coordinates (x1,y1) and (x2,y2),
    sent as parameters"""
    xdiff = x2 - x1
    ydiff = y2 - y1
    return int(math.sqrt(xdiff*xdiff + ydiff*ydiff) + .5)


def distL1((x1,y1), (x2,y2)):
    """Compute the L1-norm (Manhattan) distance between two points.

    The distance is rounded to the closest integer, for compatibility
    with the TSPLIB convention.

    The two points are located on coordinates (x1,y1) and (x2,y2),
    sent as parameters"""
    return int(abs(x2-x1) + abs(y2-y1)+.5)


def mk_matrix(coord, dist):
    """Compute a distance matrix for a set of points.

    Uses function 'dist' to calculate distance between
    any two points.  Parameters:
    -coord -- list of tuples with coordinates of all points, [(x1,y1),...,(xn,yn)]
    -dist -- distance function
    """
    n = len(coord)
    D = {}      # dictionary to hold n times n matrix
    for i in range(n-1):
        for j in range(i+1,n):
            (x1,y1) = coord[i]
            (x2,y2) = coord[j]
            D[i,j] = dist((x1,y1), (x2,y2))
            D[j,i] = D[i,j]
    return n,D

def read_tsplib(filename):
    "basic function for reading a TSP problem on the TSPLIB format"
    "NOTE: only works for 2D euclidean or manhattan distances"
    f = open(filename, 'r');

    line = f.readline()
    while line.find("EDGE_WEIGHT_TYPE") == -1:
        line = f.readline()

    if line.find("EUC_2D") != -1:
        dist = distL2
    elif line.find("MAN_2D") != -1:
        dist = distL1
    else:
        print "cannot deal with non-euclidean or non-manhattan distances"
        raise Exception

    while line.find("NODE_COORD_SECTION") == -1:
        line = f.readline()

    xy_positions = []
    while 1:
        line = f.readline()
        if line.find("EOF") != -1: break
        (i,x,y) = line.split()
        x = float(x)
        y = float(y)
        xy_positions.append((x,y))

    n,D = mk_matrix(xy_positions, dist)
    return n, xy_positions, D


def mk_closest(D, n):
    """Compute a sorted list of the distances for each of the nodes.

    For each node, the entry is in the form [(d1,i1), (d2,i2), ...]
    where each tuple is a pair (distance,node).
    """
    C = []
    for i in range(n):
        dlist = [(D[i,j], j) for j in range(n) if j != i]
        dlist.sort()
        C.append(dlist)
    return C


def length(tour, D):
    """Calculate the length of a tour according to distance matrix 'D'."""
    z = D[tour[-1], tour[0]]    # edge from last to first city of the tour
    for i in range(1,len(tour)):
        z += D[tour[i], tour[i-1]]      # add length of edge from city i-1 to i
    return z


def randtour(n):
    """Construct a random tour of size 'n'."""
    sol = range(n)      # set solution equal to [0,1,...,n-1]
    random.shuffle(sol) # place it in a random order
    return sol


def nearest(last, unvisited, D):
    """Return the index of the node which is closest to 'last'."""
    near = unvisited[0]
    min_dist = D[last, near]
    for i in unvisited[1:]:
        if D[last,i] < min_dist:
            near = i
            min_dist = D[last, near]
    return near


def nearest_neighbor(n, i, D):
    """Return tour starting from city 'i', using the Nearest Neighbor.

    Uses the Nearest Neighbor heuristic to construct a solution:
    - start visiting city i
    - while there are unvisited cities, follow to the closest one
    - return to city i
    """
    unvisited = range(n)
    unvisited.remove(i)
    last = i
    tour = [i]
    while unvisited != []:
        next = nearest(last, unvisited, D)
        tour.append(next)
        unvisited.remove(next)
        last = next
    return tour



def exchange_cost(tour, i, j, D):
    """Calculate the cost of exchanging two arcs in a tour.

    Determine the variation in the tour length if
    arcs (i,i+1) and (j,j+1) are removed,
    and replaced by (i,j) and (i+1,j+1)
    (note the exception for the last arc).

    Parameters:
    -t -- a tour
    -i -- position of the first arc
    -j>i -- position of the second arc
    """
    n = len(tour)
    a,b = tour[i],tour[(i+1)%n]
    c,d = tour[j],tour[(j+1)%n]
    return (D[a,c] + D[b,d]) - (D[a,b] + D[c,d])


def exchange(tour, tinv, i, j):
    """Exchange arcs (i,i+1) and (j,j+1) with (i,j) and (i+1,j+1).

    For the given tour 't', remove the arcs (i,i+1) and (j,j+1) and
    insert (i,j) and (i+1,j+1).

    This is done by inverting the sublist of cities between i and j.
    """
    n = len(tour)
    if i>j:
        i,j = j,i
    assert i>=0 and i<j-1 and j<n
    path = tour[i+1:j+1]
    path.reverse()
    tour[i+1:j+1] = path
    for k in range(i+1,j+1):
        tinv[tour[k]] = k


def improve(tour, z, D, C):
    """Try to improve tour 't' by exchanging arcs; return improved tour length.

    If possible, make a series of local improvements on the solution 'tour',
    using a breadth first strategy, until reaching a local optimum.
    """
    n = len(tour)
    tinv = [0 for i in tour]
    for k in range(n):
        tinv[tour[k]] = k  # position of each city in 't'
    for i in range(n):
        a,b = tour[i],tour[(i+1)%n]
        dist_ab = D[a,b]
        improved = False
        for dist_ac,c in C[a]:
            if dist_ac >= dist_ab:
                break
            j = tinv[c]
            d = tour[(j+1)%n]
            dist_cd = D[c,d]
            dist_bd = D[b,d]
            delta = (dist_ac + dist_bd) - (dist_ab + dist_cd)
            if delta < 0:       # exchange decreases length
                exchange(tour, tinv, i, j);
                z += delta
                improved = True
                break
        if improved:
            continue
        for dist_bd,d in C[b]:
            if dist_bd >= dist_ab:
                break
            j = tinv[d]-1
            if j==-1:
                j=n-1
            c = tour[j]
            dist_cd = D[c,d]
            dist_ac = D[a,c]
            delta = (dist_ac + dist_bd) - (dist_ab + dist_cd)
            if delta < 0:       # exchange decreases length
                exchange(tour, tinv, i, j);
                z += delta
                break
    return z


def localsearch(tour, z, D, C=None):
    """Obtain a local optimum starting from solution t; return solution length.

    Parameters:
      tour -- initial tour
      z -- length of the initial tour
      D -- distance matrix
    """
    n = len(tour)
    if C == None:
        C = mk_closest(D, n)     # create a sorted list of distances to each node
    while 1:
        newz = improve(tour, z, D, C)
        if newz < z:
            z = newz
        else:
            break
    return z


def multistart_localsearch(k, n, D, report=None):
    """Do k iterations of local search, starting from random solutions.

    Parameters:
    -k -- number of iterations
    -D -- distance matrix
    -report -- if not None, call it to print verbose output

    Returns best solution and its cost.
    """
    C = mk_closest(D, n) # create a sorted list of distances to each node
    bestt=None
    bestz=None
    for i in range(0,k):
        tour = randtour(n)
        z = length(tour, D)
        z = localsearch(tour, z, D, C)
        if z < bestz or bestz == None:
            bestz = z
            bestt = list(tour)
            if report:
                report(z, tour)

    return bestt, bestz


if __name__ == "__main__":
    """Local search for the Travelling Saleman Problem: sample usage."""

    #
    # test the functions:
    #

    # random.seed(1)    # uncomment for having always the same behavior
    import sys
    if len(sys.argv) == 1:
        # create a graph with several cities' coordinates
        coord = [(4,0),(5,6),(8,3),(4,4),(4,1),(4,10),(4,7),(6,8),(8,1)]
        n, D = mk_matrix(coord, distL2) # create the distance matrix
        instance = "toy problem"
    else:
        instance = sys.argv[1]
        n, coord, D = read_tsplib(instance)     # create the distance matrix
        # n, coord, D = read_tsplib('INSTANCES/TSP/eil51.tsp')  # create the distance matrix

    # function for printing best found solution when it is found
    from time import clock
    init = clock()
    def report_sol(obj, s=""):
        print "cpu:%g\tobj:%g\ttour:%s" % \
              (clock(), obj, s)


    print "*** travelling salesman problem ***"
    print

    # random construction
    print "random construction + local search:"
    tour = randtour(n)     # create a random tour
    z = length(tour, D)     # calculate its length
    print "random:", tour, z, '  -->  ',   
    z = localsearch(tour, z, D)      # local search starting from the random tour
    print tour, z
    print

    # greedy construction
    print "greedy construction with nearest neighbor + local search:"
    for i in range(n):
        tour = nearest_neighbor(n, i, D)     # create a greedy tour, visiting city 'i' first
        z = length(tour, D)
        print "nneigh:", tour, z, '  -->  ',
        z = localsearch(tour, z, D)
        print tour, z
    print

    # multi-start local search
    print "random start local search:"
    niter = 100
    tour,z = multistart_localsearch(niter, n, D, report_sol)
    assert z == length(tour, D)
    print "best found solution (%d iterations): z = %g" % (niter, z)
    print tour
导入数学
随机输入
def distL2((x1,y1),(x2,y2)):
“”“计算两点之间的L2范数(欧几里德)距离。
为了兼容性,距离四舍五入为最接近的整数
根据TSPLIB公约。
这两点位于坐标(x1,y1)和(x2,y2)上,
作为参数“”发送
xdiff=x2-x1
ydiff=y2-y1
返回int(math.sqrt(xdiff*xdiff+ydiff*ydiff)+.5)
def distL1((x1,y1),(x2,y2)):
“”“计算两点之间的L1范数(曼哈顿)距离。
为了兼容性,距离四舍五入为最接近的整数
根据TSPLIB公约。
这两点位于坐标(x1,y1)和(x2,y2)上,
作为参数“”发送
返回整数(abs(x2-x1)+abs(y2-y1)+.5)
def mk_矩阵(协调,区):
“”“计算一组点的距离矩阵。
使用函数“dist”计算
任意两点。参数:
-coord—具有所有点的坐标的元组列表,[(x1,y1),…,(xn,yn)]
-距离函数
"""
n=长(坐标)
D={}#保存n次n矩阵的字典
对于范围(n-1)内的i:
对于范围(i+1,n)内的j:
(x1,y1)=坐标[i]
(x2,y2)=坐标[j]
D[i,j]=dist((x1,y1),(x2,y2))
D[j,i]=D[i,j]
返回n,D
def read_tsplib(文件名):
“用于读取TSPLIB格式的TSP问题的基本函数”
“注意:仅适用于二维欧几里德距离或曼哈顿距离”
f=打开(文件名为“r”);
line=f.readline()
而line.find(“边缘重量类型”)==-1:
line=f.readline()
if line.find(“EUC_2D”)!=-1:
dist=distL2
elif line.find(“MAN_2D”)!=-1:
dist=distL1
其他:
打印“无法处理非欧几里德距离或非曼哈顿距离”
引发异常
而line.find(“节点协调部分”)==-1:
line=f.readline()
xy_位置=[]
而1:
line=f.readline()
if line.find(“EOF”)!=-1:休息
(i,x,y)=行分割()
x=浮动(x)
y=浮动(y)
xy_位置追加((x,y))
n、 D=mk_矩阵(xy_位置,距离)
返回n,xy_位置,D
def mk_最近(D,n):
“”“计算每个节点距离的排序列表。
对于每个节点,条目的形式为[(d1,i1),(d2,i2),…]
其中每个元组是一对(距离、节点)。
"""
C=[]
对于范围(n)中的i:
dlist=[(D[i,j],对于范围(n)内的j,如果j!=i]
dlist.sort()
C.append(数据列表)
返回C
def长度(行程,D):
“”“根据距离矩阵'D'计算巡更的长度。”
z=D[巡更[-1],巡更[0]]#从巡更的最后一个城市到第一个城市的边缘
对于范围(1,len(tour))中的i:
z+=D[tour[i],tour[i-1]]#将城市i-1到i的边长度相加
返回z
def randtour(n):
“”“构造大小为'n'的随机巡更。”
sol=范围(n)#将解设置为等于[0,1,…,n-1]
随机。随机(sol)#按随机顺序放置
返回溶胶
def最近(最后一次,未访问,D):
“”“返回最接近‘last’的节点的索引。”
近距离=未访问[0]
最小距离=D[最后,近距离]
对于未访问的[1:]中的我:
如果D[最后,i]<最小距离:
近=i
最小距离=D[最后,近距离]
回程
def最近邻(n,i,D):
“”“从城市“i”出发,使用最近的邻居进行回程游览。
使用最近邻启发式构造解决方案:
-开始参观城市i
-虽然有未游览的城市,但请跟随最近的城市
-返回城市i
"""
未访问=范围(n)
未访问。删除(i)
last=i
旅游=[i]
未经访问时!=[]:
下一个=最近的(最后一个,未访问,D)
tour.append(下一步)
未访问。删除(下一个)
最后一个=下一个
回程
def交换成本(巡回赛、i、j、D):
“”“计算一次巡更中交换两个圆弧的成本。
如果需要,确定行程长度的变化
圆弧(i,i+1)和(j,j+1)被删除,
并替换为(i,j)和(i+1,j+1)
(请注意最后一个弧的例外情况)。
参数:
-旅游
-i——第一条弧的位置
-j> i——第二条弧的位置
"""
n=len(巡回赛)
a、 b=巡更[i],巡更[(i+1)%n]
c、 d=巡更[j],巡更[(j+1)%n]
返回(D[a,c]+D[b,D])-(D[a,b]+D[c,D])
def交换(巡回、tinv、i、j):
“”“用(i,j)和(i+1,j+1)交换弧(i,i+1)和(j,j+1)。
对于给定的巡更“t”,删除圆弧(i,i+1)和(j,j+1)以及
插入(i,j)和(i+1,j+1)。
这是通过反转i和j之间的城市子列表来实现的。
"""
n=len(巡回赛)
如果i>j:
i、 j=j,i
断言i>=0和i=dist_ab:
打破