旅行推销员问题:
在一个无向图中找到一个经过每一个顶点的最短路径
1. 贪心算法
对于旅行推销员问题而言,贪心算法是最简单的,即在每次迭代时选择最接近的最短边,但不做进一步搜索
2. 贪心算法优化
贪心算法可在不用增加太多代码的情况下,用不同的起始顶点重新运行整个算法,不断迭代,挑选出一个到达所有顶点并且最短的解决方案,用这种方法可以改善贪心算法。
3. 贪心算法scala代码实现:
def greedy[VD](g:Graph[VD,Double], origin:VertexId) = {
var g2 = g.mapVertices((vid,vd) => vid == origin).mapTriplets(et => (et.attr,false))
var nextVertexId = origin
var edgesAreAvailable = true
do {
type tripletType = EdgeTriplet[Boolean,Tuple2[Double,Boolean]]
val availableEdges =
g2.triplets.filter(et => !et.attr._2
&& (et.srcId == nextVertexId && !et.dstAttr
|| et.dstId == nextVertexId && !et.srcAttr))
edgesAreAvailable = availableEdges.count > 0
if (edgesAreAvailable) {
val smallestEdge = availableEdges.min()(new Ordering[tripletType]() {
override def compare(a:tripletType, b:tripletType) = {
Ordering[Double].compare(a.attr._1,b.attr._1)
}
})
nextVertexId = Seq(smallestEdge.srcId, smallestEdge.dstId).filter(_ != nextVertexId)(0)
g2 = g2.mapVertices((vid,vd) => vd || vid == nextVertexId).mapTriplets(et => (et.attr._1, et.attr._2
|| (et.srcId == smallestEdge.srcId
&& et.dstId == smallestEdge.dstId)))
}
} while(edgesAreAvailable)
g2
}
greedy(myGraph,1L).triplets.filter(_.attr._2).map(et=>(et.srcId, et.dstId)).collect
参考书籍:Spark GraphX 实战