Java 加权有向图的宽度优先搜索
我需要帮助为我的BFS算法添加边缘成本。我不知道如何为添加到路径的每个顶点添加边成本。我将张贴代码供您参考。给我一些建议 Graph.javaJava 加权有向图的宽度优先搜索,java,algorithm,breadth-first-search,Java,Algorithm,Breadth First Search,我需要帮助为我的BFS算法添加边缘成本。我不知道如何为添加到路径的每个顶点添加边成本。我将张贴代码供您参考。给我一些建议 Graph.java package algo; import java.util.*; public class Graph { private static Map<String, LinkedHashSet<HashMap<String, Double>>> map; private ArrayList<S
package algo;
import java.util.*;
public class Graph
{
private static Map<String, LinkedHashSet<HashMap<String, Double>>> map;
private ArrayList<String> nodes = new ArrayList<String>();
private static ArrayList<String> shortestPath = new ArrayList<String>();
public Graph()
{
}
public Graph(String[] nodes)
{
map = new HashMap<String,LinkedHashSet<HashMap<String, Double>>>();
for(int i=0;i<nodes.length;++i)
map.put(nodes[i], new LinkedHashSet<HashMap<String, Double>>());
}
public void addNeighbor(String node1,String node2, Double edgeCost)
{
LinkedHashSet<HashMap<String, Double>> adjacent = map.get(node1);
HashMap<String, Double> innerMap = new HashMap<String, Double>();
if(map.get(node1)==null)
{
adjacent = new LinkedHashSet<HashMap<String, Double>>();
map.put(node1, adjacent);
}
innerMap.put(node2, edgeCost);
adjacent.add(innerMap);
}
public boolean memberOf(String node) {
return nodes.contains(node);
}
public LinkedList<HashMap<String, Double>> getNeighbours(String node) {
LinkedHashSet<HashMap<String, Double>> adjacent = map.get(node);
if(adjacent==null) {
return new LinkedList<HashMap<String, Double>>();
}
return new LinkedList<HashMap<String, Double>>(adjacent);
}
protected void storeNodes(String source, String destination)
{
if (!source.equals(destination))
{
if (!nodes.contains(destination))
{
nodes.add(destination);
}
}
if (!nodes.contains(source)) {
nodes.add(source);
}
}
public void getKeyValuePairs()
{
Iterator<String> iterator = map.keySet().iterator();
while (iterator.hasNext())
{
String key = iterator.next().toString();
LinkedHashSet<HashMap<String, Double>> value = map.get(key);
System.out.println(key + " " + value);
}
}
}
这是我的bfs代码的一部分,我在没有添加任何edgecost的情况下对其进行了测试
public static ArrayList<String> breadthFirstSearch(Graph graph,
String source,
String destination)
{
shortestPath.clear();
// A list that stores the path.
ArrayList<String> path = new ArrayList<String>();
// If the source is the same as destination, I'm done.
if (source.equals(destination) && graph.memberOf(source))
{
path.add(source);
return path;
}
// A queue to store the visited nodes.
ArrayDeque<String> queue = new ArrayDeque<String>();
// A queue to store the visited nodes.
ArrayDeque<String> visited = new ArrayDeque<String>();
queue.offer(source);
while (!queue.isEmpty()) {
String vertex = queue.poll();
visited.offer(vertex);
ArrayList<String> neighboursList = (ArrayList<String>) graph.getNeighbours(vertex);
int index = 0;
int neighboursSize = neighboursList.size();
while (index != neighboursSize) {
String neighbour = neighboursList.get(index);
path.add(neighbour);
path.add(vertex);
if (neighbour.equals(destination)) {
return processPath(source, destination, path);
} else {
if (!visited.contains(neighbour)) {
queue.offer(neighbour);
}
}
index++;
}
}
return null;
}
public static ArrayList<String> processPath(String src,
String destination,
ArrayList<String> path)
{
// Finds out where the destination node directly comes from.
int index = path.indexOf(destination);
String source = path.get(index + 1);
// Adds the destination node to the shortestPath.
shortestPath.add(0, destination);
if (source.equals(src)) {
// The original source node is found.
shortestPath.add(0, src);
return shortestPath;
} else {
// We find where the source node of the destination node
// comes from.
// We then set the source node to be the destination node.
return processPath(src, source, path);
}
}
publicstaticarraylistbreadthfirstsearch(图形,
字符串源,
字符串目的地)
{
最短路径。清除();
//存储路径的列表。
ArrayList路径=新建ArrayList();
//如果源与目标相同,则完成。
if(源相等(目标)和图成员(源))
{
添加路径(源);
返回路径;
}
//用于存储已访问节点的队列。
ArrayDeque队列=新的ArrayDeque();
//用于存储已访问节点的队列。
ArrayDeque=新建ArrayDeque();
排队。报价(来源);
而(!queue.isEmpty()){
字符串顶点=queue.poll();
访问。提供(顶点);
ArrayList邻居列表=(ArrayList)graph.GetNeights(顶点);
int指数=0;
int neighboursSize=neighboursList.size();
while(索引!=邻居大小){
String neighbor=neighboursList.get(索引);
添加(邻居);
添加(顶点);
if(邻居等于(目的地)){
返回processPath(源、目标、路径);
}否则{
如果(!visted.contains(邻居)){
排队。提供(邻居);
}
}
索引++;
}
}
返回null;
}
公共静态ArrayList进程路径(字符串src,
字符串目的地,
ArrayList路径)
{
//找出目标节点直接来自何处。
int index=path.indexOf(目的地);
stringsource=path.get(索引+1);
//将目标节点添加到最短路径。
最短路径。添加(0,目标);
if(source.equals(src)){
//找到原始源节点。
添加(0,src);
返回最短路径;
}否则{
//我们找到目标节点的源节点所在的位置
//来自。
//然后,我们将源节点设置为目标节点。
返回processPath(src、source、path);
}
}
我的问题是如何将edgecost添加到bfs部分的代码中,并在执行时提供从源到目标的路径成本 要返回路径和成本,您需要创建一个类来保存这两个值:
class CostedPath {
private final List<String> path = new ArrayList<>();
private double cost = 0.0;
public CostedPath(String start) {
path.add(start);
}
public CostedPath addNode(String node, Graph graph) {
this.cost += graph.getCost(path.get(0), node);
path.add(0, node);
return this;
}
}
如果将类进一步拆分,代码的可读性将大大提高
class Vertex {
private final String name;
private final Set<Edge> edges;
}
class Edge {
private final Vertex end;
private final double cost;
}
class Graph {
private final Set<Vertex> vertices;
}
class Path {
private final Vertex start;
private final List<Edge> edges;
}
这比必须传递原始图形才能找到边的成本要干净得多。虽然共享代码很好,但您能告诉我问题的确切含义吗?我猜您需要在带有加权边(或者可能是加权节点?)的图上运行BFS。请解释一下,请看这个:是的。现在我可以运行bfs给定的源和目标,而不包括成本,因此它为我提供了一条路径。同样地,我希望bfs也采用edgecost,并向我提供从源头到达目的地的成本。例如,如果city1->city3->city5是路径,则相关成本应为11这是否回答了您的问题?
class CostedPath {
private final List<String> path = new ArrayList<>();
private double cost = 0.0;
public CostedPath(String start) {
path.add(start);
}
public CostedPath addNode(String node, Graph graph) {
this.cost += graph.getCost(path.get(0), node);
path.add(0, node);
return this;
}
}
private CostedPath processPath(String start, String end, List<String> path, Graph graph) {
{
String previous = path.get(path.indexOf(end) + 1);
if (previous.equals(start))
return new CostedPath(start);
else
return processPath(start, previous, path, graph).addNode(end, graph);
}
class Vertex {
private final String name;
private final Set<Edge> edges;
}
class Edge {
private final Vertex end;
private final double cost;
}
class Graph {
private final Set<Vertex> vertices;
}
class Path {
private final Vertex start;
private final List<Edge> edges;
}
public double getCost() {
return edges.stream().mapToDouble(Edge::getCost).sum();
}