我正在研究一个看起来很容易出问题的算法,但我找不到一个有效的算法.问题如下:
我有一个数字列表(0-50)和一个起始位置,并且必须访问其中的每一个,同时最小化行进的总距离.一些位置要求我先访问另一个位置(所以要访问29我必须首先在26处选择一些东西).但是,如果不生成每个选项,我似乎无法弄清楚如何做到这一点.有任何想法吗?
例如,我们有以下内容
startLocation=25;
targetPairs=[[1,5],[7,12],[22,23]]
visitLocations=[4,6,8,2]
这意味着我们必须在5之前的7,之前的12和之前的22之前访问.我们还必须访问位置4,6,8和2.
开始的一个选择是去1(距离24)然后去4(距离3总共27)然后去5(距离1总共28)然后我们可以继续到6(距离1总共29)或者为全套(7(30),8(31),12(35),22(45),23(46)).
从逻辑上讲,我们要访问的位置数量限制为50对和50个位置.
最佳答案 问题可以通过以下潜在的指数时间算法来解决,如果它是NP-hard(我怀疑)那么你将无法做得更好(其中“很多”,我的意思是找到一个多项式的算法时间复杂度 – 很可能减少指数时间算法的基础.
基本上,在状态空间中进行最佳优先搜索,其中每个状态由两个部分组成:当前位置和一组已访问过的位置. (遗憾的是,仅仅跟踪已经访问过的城市的数量是不够的.)在这个状态空间中,我们每个点最多只有以下2个移动:
>向左移动到最近的可访问位置
>向右移动到最近的可访问位置
这是因为总有一个最佳解决方案,在我们第一次访问或访问它之后访问每个位置.这里,“可访问”意味着已经访问过所有位置的前任(包括前辈的前辈等).
任何已经访问过所有位置的州都是目标国家.使用最佳优先搜索(可在优先级队列中实现,或者在这种情况下,只需要大小为50的数组),找到的第一个此类状态将对应于最佳解决方案.该算法将需要时间指数的需要访问的位置数量.
可以通过使用A *算法来加速这种搜索 – 也就是说,通过使用一些可接受的启发式来确定从给定状态剩余的距离的下限.在这里提出合理的东西应该相当容易 – 例如令x为最左边的未访问位置,y为最右边的位置,如果我们当前位置z在它们之间,则至少需要min(2(z-x)y-z,z-x 2(y-z))从z访问它们. (如果z代替所有未访问城市的左侧或右侧,则至少需要y-z或至少z-x.)考虑前辈可以大大改善边界.