Я пытаюсь реализовать как непосредственный Dijkstra, так и его версию обратный (то есть поиск самого длинного пути вместо кратчайшего), но у меня возникают проблемы, потому что я получаю бесконечные расстояния для несвязанных узлов во взвешенном неориентированном графе (и ноль расстояния в обратном варианте).
До сих пор я доверял и модифицировал эту реализацию, которую нашел в Интернете: [http://note.yuhc.me/2015/03/graphx-pregel-shortest-path/]
Мои реализации для обеих функций следующие:
Директ Дийкстра:
// Implementation of Dijkstra algorithm using Pregel API
def computeMinDistance(u: VertexId, k1: VertexId): Double = {
val g: Graph[(Double, VertexId), Double] = this.uncertainGraph.mapVertices((id, _) =>
if (id == u) (0.0, id) else (Double.PositiveInfinity, id)
)
println("Computing Digkstra distance info fof id: " + u.toString)
val sssp: Graph[(Double, VertexId), Double] = g.pregel[(Double, VertexId)]((Double.PositiveInfinity, Long.MaxValue), Int.MaxValue, EdgeDirection.Either)(
(id, dist, newDist) => {
if (dist._1 < newDist._1) {
(dist._1, id)
} else {
(newDist._1, id)
}
},
triplet => { // Send Message
if (triplet.srcAttr._1 + triplet.attr < triplet.dstAttr._1) {
println("triplet.srcAttr._1 = " + triplet.srcAttr._1 .toString)
println("triplet.dstAttr._1 = " + triplet.dstAttr._1 .toString)
Iterator((triplet.dstId, (triplet.srcAttr._1 + triplet.attr, triplet.srcId)))
} else {
Iterator.empty
}
},
(a, b) => (math.min(a._1, b._1), a._2) // Merge Message
)
sssp.vertices.take(20).foreach(println(_))
sssp.vertices.filter(element => element._1 == k1).map(element => element._2._1).collect()(0)
}
Обратный Дейкстра:
def computeMaxDistance(node: VertexId, center: VertexId): Double = {
val g: Graph[(Double, VertexId), Double] = this.uncertainGraph.mapVertices((id, _) =>
if (id != node) (0.0, id) else (Double.PositiveInfinity, id)
)
val sslp: Graph[(Double, VertexId), Double] = g.pregel[(Double, VertexId)]((Double.PositiveInfinity, Long.MaxValue), Int.MaxValue, EdgeDirection.Either)(
(id, dist, newDist) => {
if (dist._1 > newDist._1) {
(dist._1, id)
} else {
(newDist._1, id)
}
},
triplet => { // Send Message
if (triplet.srcAttr._1 + triplet.attr > triplet.dstAttr._1) {
println("triplet.srcAttr._1 = " + triplet.srcAttr._1 .toString)
println("triplet.dstAttr._1 = " + triplet.dstAttr._1 .toString)
Iterator((triplet.dstId, (triplet.srcAttr._1 + triplet.attr, triplet.srcId)))
} else {
Iterator.empty
}
},
(a, b) => (math.max(a._1, b._1), a._2) // Merge Message
)
sslp.vertices.take(20).foreach(println(_))
sslp.vertices.filter(element => element._1 == center).map(element => element._2._1).collect()(0)
}
Любая помощь глубоко оценена. У меня нет такого опыта работы со Scala и Spark. Заранее спасибо.
Спасибо за внимание. Не могли бы вы объяснить, что вы подразумеваете под «полным рабочим примером»? Я бы обязательно это сделал, если бы это было необходимо.
Что SO называет минимальный полный проверяемый пример. Лично, если я не могу скопировать и вставить код в вопросе Scala в REPL и скомпилировать его (или увидеть соответствующую ошибку компиляции), есть вероятность 99%, что я закрываю вкладку.
Пожалуйста, оставьте его открытым. Кто-то даст совет, несмотря на то, что не соответствует вашим стандартам. Большое Вам спасибо. И, пожалуйста, не поймите меня неправильно.
Похоже, у вас здесь две проблемы (прямая и обратная). Не могли бы вы редактировать задать свой вопрос так, чтобы он задавал только одну проблему, а затем задавал другой вопрос по другой? Это облегчает людям задачу, если у них есть решение только одной проблемы; иначе они могут не ответить. См. Как спросить.
Что ж, спасибо, что потратили время на отзыв о Брайане. Я на самом деле не сторонник теории графов, но мой бывший учитель предложил бы в качестве упражнения вычислить самый длинный путь, инвертируя логику алгоритма Дейкстры. В любом случае, никто не является непогрешимым. Как насчет обращения алгоритма Дейкстры для нахождения хорошего жадного приближения? Они используют термин «длинный» в предоставленной вами ссылке. Может быть, я должен повторно опубликовать на SE. Как я уже говорил, граф неориентирован. Есть ли разница? Это реальный график PPI, предположительно безмасштабный. Судя по вашему ответу, я отредактирую или закажу его. Спасибо.
Я сделал прямой алгоритм в Scala на основе курса алгоритмов Принстонского университета, не уверен, что это может вам помочь: medium.com/se-notes-by-alexey-novakov/…





У вас гораздо больше шансов получить ответ с полным рабочим примером.