Optimization 类似旅行商的优化问题-需要更好的启发式

Optimization 类似旅行商的优化问题-需要更好的启发式,optimization,graph-theory,traveling-salesman,Optimization,Graph Theory,Traveling Salesman,我有一个优化问题,我正在寻找一个算法,执行比我的天真的方法更好 问题 考虑一个图,G(N,E),其中N是节点集,E是边集。n中的每个节点n\u i都有一个关联状态s\u i。我使用字典D来存储它,节点作为键,相应的状态作为值。相邻节点可以使用交换操纵器交换状态。具体而言,掉期操纵器的定义如下: def swap(G, D, n_i, n_j): if n_i not in neighbors(G, n_j): print('Cannot swap between dis

我有一个优化问题,我正在寻找一个算法,执行比我的天真的方法更好

问题

考虑一个图,
G(N,E)
,其中
N
是节点集,
E
是边集。
n
中的每个节点
n\u i
都有一个关联状态
s\u i
。我使用字典
D
来存储它,节点作为键,相应的状态作为值。相邻节点可以使用交换操纵器交换状态。具体而言,掉期操纵器的定义如下:

def swap(G, D, n_i, n_j):
    if n_i not in neighbors(G, n_j):
         print('Cannot swap between disconnected nodes')
    else:
         s_i = D[n_i]
         s_j = D[n_j]
         D[n_i] = s_j
         D[n_j] = s_i
    return D
每个状态现在必须按给定顺序“访问”其他状态的列表,其中访问意味着两个状态必须位于
G(N,E)
上的任何一对相邻节点上。例如
su1
必须访问
[su3,su5,su2]
su2
必须访问
[su1,su3]
su3
必须访问
[su1,su2,su4]
等等必须保留访问顺序。但是,允许状态位于相邻节点上,而不将其标记为访问。例如,如果
s_1
开始时与
s_5
相邻,则必须首先与
s_3
相邻,将访问标记为完成,然后再次与
s_5
相邻。访客列表是这样的:如果
sui
必须访问
suj
,那么这也意味着
suj
必须访问
sui
,即一切都是自洽的

典型尺寸

该图通常约为20-30个节点,每个节点通常连接到2-4个其他节点。访问列表原则上没有长度限制,但实际上不超过10

目标

目标是完成访问列表,同时最小化交换操作的总数。这个问题的有效算法/启发式是什么

我天真的解决方案

我目前的算法做的是最简单的事情。我首先根据以下功能查看哪些VIST是
(0,0)
访问,即两个州必须在访问其他州之前访问对方

def interaction_priority(s1, s2):
    if s2 in visitors_of_s1:
       b = visitors_of_s1.index(s2)
       a = visitors_of_s2.index(s1)
    return (a, b)
对于这些状态,我获取当前节点,并使用
networx
函数在
G
上查找这些节点之间的最短路径。我进行互换,直到它们相邻。让我们假设前面的函数为
s_1和s_3
返回
(0,0)
。然后我找到
s_1
s_3

inv_D = {s : n for n, s in D.items()} #Invert the dictionary of nodes and states
def get_shortest_path(s1, s3):
    n1 = inv_D[s1]
    n3 = inv_D[s3]
    path_nodes = get_shortest_path(G, n1, n3)
    return path_nodes
现在,我沿着这条路径进行交换

if len(path_nodes)> 0:
    for i in path_nodes:
         D = swap(G, D, n1, i)

visitors_of_s1.remove(s3)
visitors_of_s3.remove(s1)

我知道我可能会优化一些东西,例如,使最后一个方法对称等等,但基本思想仍然不是很聪明。是否有一种更聪明的算法可以优化状态在图形中的移动方式,但仍然可以完成它们的所有访问。

在您天真的解决方案中,您不也需要避免在交换序列中与其他状态相邻吗?对不起,如果我误解了这个问题。@justhalf,good point-我忘了添加那个。你可以在不访问的情况下相邻,但要访问,你必须相邻。你能描述数据集的大小和性质吗?具体来说,图表有多大,需要访问列表的州的百分比是多少,访问列表相对于州总数的长度通常是多少?由于这可能是一个O(2^n)或更糟的问题,因此了解类似的信息对于优化策略非常重要。@RBarryYoung通常在20-30个节点左右,每个节点通常连接到2-4个其他节点。访问名单原则上没有长度限制,但实际上不超过10。