![](/img/trans.png)
[英]Finding shortest path between two nodes in a weighted DAG with negative weights
[英]Finding shortest path between two nodes
我試圖弄清楚如何制作一種在兩個節點之間找到最短路徑的方法,但似乎無法弄清楚。 我得到了兩個文件,一個包含演員(將是節點)的文件和一個包含電影(將是邊緣)的文件。
我將一個圖表表示為一個 HashMap,其中鍵是一個演員,而值是一個 ArrayList,其中包含該演員出演過的電影:
HashMap<Actor, ArrayList[Movie]> graph;
現在我想找到兩個演員之間的最短路徑,但我不知道該怎么做。 我在考慮 DFS 或 BFS,但我不太確定如何使用這個哈希圖來做到這一點..
您可以使用您當前的結構( HashMap<Actor, ArrayList<Movie>>
)作為鄰接列表,但缺少一些東西:一種從電影回到主演的有效方法。 您可以構建一個Map<Movie, List<Actor>>
,這會起作用……但使用單個鄰接列表更簡單,而不是讓一個用於演員而另一個用於電影。 我會這樣做(假設Actor
和Movie
都實現了equals
和hashcode
,並且沒有演員等於任何電影):
Map<Object, List<Object>> edges = new HashMap<>();
for (Map.Entry<Actor, ArrayList<Movie>> e : graph.entries()) {
Actor a = e.getKey();
edges.put(a, new ArrayList<Object>(e.getValues()));
for (Movie m : e.getValues()) {
List<Actor> otherActors = edges.getOrDefault(m, new ArrayList<Object>());
otherActors.add(a);
edges.put(m, otherActors);
}
}
現在您可以使用edges
來執行標准的廣度優先搜索。 保證為您提供任意 2 個演員之間的最短路徑(可能有多個同樣短的路徑),並且該路徑將包含鏈接他們的電影。
僅僅為您指明方向並不是整個解決方案,您必須按照tucuxi 建議創建一個 Map<Movie, List> 。 您一個一個地遍歷每個角色並標記當前角色與參考角色的距離。
private static void fn(HashMap<Actor, List<Movie>> graph, Actor referenceActor) {
var movieMap = new HashMap<Movie, List<Actor>>();
graph.forEach((key, value) -> {
for (var movie : value) {
movieMap.compute(movie, (k, v) -> {
if (v == null) {
return new ArrayList<>(List.of(key));
}
v.add(key);
return v;
});
}
});
final var visited = new HashSet<Actor>();
var dq = new ArrayDeque<Actor>();
var map = new HashMap<Actor, Integer>();
dq.add(referenceActor);
int distance = 0;
while (!dq.isEmpty()) {
var size = dq.size();
for (int i = 0; i < size; i++) {
var actor = dq.poll();
visited.add(actor);
map.putIfAbsent(actor, distance);
for (Movie movie : graph.get(actor)) {
// adding every non visited actor in the same movie in the queue
dq.addAll(movieMap
.get(movie)
.stream()
.filter(x -> !visited.contains(x))
.collect(Collectors.toList()));
}
}
distance++;
}
System.out.println(map);
}
我在這里使用ArrayDeque
以 BFS 方式遍歷,如果您希望 DFS 記住,計算距離的邏輯也需要更改,您可以修改。 從評論中粘貼圖像,將節點 B 作為參考參與者。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.