Java 加权有向图的宽度优先搜索

Java 加权有向图的宽度优先搜索,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

我需要帮助为我的BFS算法添加边缘成本。我不知道如何为添加到路径的每个顶点添加边成本。我将张贴代码供您参考。给我一些建议

Graph.java

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();
}