微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我需要通过选择最接近的排序来减少节点之间的弧数

如何解决我需要通过选择最接近的排序来减少节点之间的弧数

我正在解决一个 tsp 问题,因为执行需要很长时间,我决定尝试通过为每个节点仅选择 5 个最近的位置来减少弧的数量。我开始使用 sort解决我的问题,但我不太了解如何使用它。我的代码是:

   import numpy as np
   import pandas as pd
   from numpy import random

   n = 21  # Houses
   N = [i for i in range(n)]
   
   arcs = [(i,j) for i in N for j in N if i != j]  

   # random coordenates 
   list_coord_x = [random.randint(100) for i in N]
   list_coord_y = [random.randint(100) for i in N]

   df = pd.DataFrame({
      "coord_x": list_coord_x,"coord_y": list_coord_y
    })

   # distances for each arc
   D = {(p,j): abs(df["coord_x"][p]-df["coord_x"][j]) + abs(df["coord_y"][p]-df["coord_y"][j]) for p,j in arcs}  

我的目标是将弧线减少到最接近的 5,以便程序运行得更快。我在这个例子中的弧是:

    arcs = [(0,1),(0,2),3),4),5),6),7),8),9),10),11),12),13),14),15),16),17),18),19),20),..................................,(20,19) ]

我想例如:

   reduced_arcs = [(0,(1,.....,12)]

因为这些弧是它们之间最接近的。

解决方法

首先,您可以使用 scipy.spatial.distance_matrix 来计算距离矩阵:

import numpy as np
from scipy.spatial import distance_matrix

points = [(x,y) for x,y in zip(list_coord_x,list_coord_y)]
D = distance_matrix(points,points)

然后,您可以使用距离矩阵 D 并提取每行(节点)的 5 个最小距离条目的索引:

x_indices,y_indices = np.where(np.argsort(D) < 5) 
reduced_arcs = [(i,j) for i,j in zip(x_indices,y_indices) if i != j]
,

我建议您处理 numpy 或 pandas 中的数据,因为在 dict 中这不是不必要的困难。由于示例中已有 Pandas 代码,因此无需新导入即可使用此代码。在您的示例中,您使用 Taxicab Geometry。如果您更愿意使用欧几里得,则必须先取平方,然后再取根或使用@joni 建议的函数。

pd_D = pd.DataFrame.from_dict(((k[0],k[1],v) for k,v in D.items())) # so you have 
pd_D.columns = ['from','to','distance']

pd_D_reduced = pd_D.groupby('from').apply(lambda x: x.nsmallest(n=5,columns='distance'))
pd_D_reduced.droplevel(0) # to ungroup

# back to dict if you want it
D_reduced = {(row['from'],row['to']):row['distance'] for index,row in pd_D_reduced.iterrows()}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。