假设我们有一个加权无向图和边数| E |是节点数| V |的k倍,即| E | 〜= k * | V |。
现在,选择一个节点,比如说v,我们希望找到包含v的循环,其平均成本最低。 (即,平均成本是指沿循环的平均边缘重量。)
有没有有效的算法?
抱歉,我错过了一个点 - 该周期不需要包含此图中的所有节点。这使它与汉密尔顿循环问题不同。
答案 0 :(得分:1)
这相当于Hamiltonian cycle problem,这是NP完全的。除非P = NP,否则没有最坏情况多项式算法能够解决这个问题。
我们可以将哈密尔顿循环问题减少到这个问题:
n周期的平均成本为(n+2)/n
- 正为n
的递减序列。对于v-vertex图,如果图是哈密顿图,则存在(v+2)/v
的平均成本的周期。由于确定哈密顿图是否是NP完全的,这个问题是NP难的。
与此问题相关的决策问题(“是否存在通过顶点V的x的平均边缘成本的简单循环”)在NP中:如果存在该平均长度的路径,则验证周期是平均成本足够低的有效周期需要O(v)
时间(使用邻接矩阵表示)。
因此,你不能指望最坏情况多项式时间算法。但是,根据边缘成本的分布,分支定界算法或动态编程的分支绑定可以非常有效:
q
:
c_best
,请终止循环。否则,c_best
,请拒绝此路径。否则,c_best_path
设置为此路径,将c_path
设置为其成本。q
。c_best_path
+ :如果图形是一个多图,你需要两个最便宜的平行边,而不是两个相同的边。这可能最好在单独的步骤中处理。
动态编程检查可以非常便宜(只是使用顶点对顶点进行散列)但如果预期的保存很少(算法很可能提前结束),则可以省略 - 删除“完成”集并忽略队列中的任何重复项(具有相同签名的不同路径)。
只要您可以计算下限,此算法对任何路径成本度量都可以正常工作。对于平均边缘成本问题,我可以想到几种启发式方法:
在任何情况下,如果路径是一个循环,请计算并返回其确切的成本。
一个简单的启发式方法是假设您可以访问所有剩余的顶点,其边缘不比整个图形或2连通组件中最便宜的路径便宜。然后相应的预期成本为(cost + (v - edge_length) * c_min) / edge_length
。好处是计算速度快。不利的一面是,如果图表很大并且几乎没有最便宜的边缘那么便宜,那么这个算法可以扩展很多路径以达到它认为存在的“绿洲”。
如果边缘的边数与最便宜的边缘一样便宜,您可以在图表的所有边缘中准备v
最低成本的列表。然后要估算图表的成本,考虑:路径只用最便宜的边缘完成,路径用最便宜的两条边完成,路径用最便宜的三条边完成...... while(exp_cost_decreases && length < v) exp_cost = (exp_total_cost += best_edges.next) / ++length
。好处是它可以做出更好的猜测。缺点是,如果有很多边缘会降低估算值,则计算时间会更长。
您始终必须使用公共边到开始顶点和路径的结束顶点(如果存在)或其中一个边与每个顶点(min_cost_adjanced(V) + min_cost_adjanced(end)
)相邻。如果找到共同边缘,则可以在这里完成周期的处理。
在汉密尔顿周期减少的情况下,前两个启发式算法的表现同样糟糕。启发式(1 + 3)和(2 + 3)将同等地执行。最佳情况是线性的。最糟糕的情况是O(v*k*2^v)
动态编程或O(v*k*log(k)*k^v)
没有(假设优先级队列为O(log n)
push,pop-min和reduce-key)
请注意,用于测试哈密顿周期是否存在于一般图表中的最着名的算法是O(1.657^v)
(according to wikipedia, as of Aug 2013)
答案 1 :(得分:1)
实际上存在一种基于动态规划的O(| V || E |)算法,该算法首先由Karp于1978年(http://www.sciencedirect.com/science/article/pii/0012365X78900110描述),或者由Ahuja,Magnanti和“网络流”中的第5.7节描述。的Orlin)。
不幸的是,Jan给出的减少是不正确的,因为成本周期(v + 2)/ v通常不是最小平均成本周期。特别地,任何不包含起始点的循环将具有平均成本1 <1。 (n + 2)/ n代表任何n。
答案 2 :(得分:0)
在Karp的论文中,问题是&#34;在图表中找到最小平均成本周期&#34;在O(| V || E |)中求解。循环不需要通过任何特定的顶点。