我需要一种通过邻接来遍历图并返回路径总权重的方法。我不确定如何在方法“ public double getPathWeight(List path)”中增加权重。另外,可能我感觉我的公共void addEdge方法可能包含一些错误,因此,如果我也能对该方法获取一些指针,那将极大地帮助我完成图形。我的图形是根据通用VertexType参数编写的。而且我正在处理邻接表数据结构。
import java.util.HashMap;
import java.util.HashSet;
import java.util.TreeMap;
import java.util.Map;
import java.util.Set;
import java.util.List;
public class Graph<VertexType> {
private Map<VertexType, TreeMap<VertexType, Double>> adjacency;
public Graph()
{
adjacency = new java.util.HashMap<>();
}
public void addEdge(VertexType v1, VertexType v2, double weight)
{
Set <VertexType> set = new HashSet<VertexType>();
if(adjacency.get(v1)!=null)
{
set = (Set<VertexType>) adjacency.get(v1);
set.add(v2);
adjacency.put(v1,(TreeMap<VertexType, Double>) set);
}
else //adds edge if adjacency is null
{
set.add(v2);
adjacency.put(v1,(TreeMap<VertexType, Double>) set);
}
}
public Set<VertexType> getVertices()
{
return adjacency.keySet();
}
public void dumpGraph()
{
for (Map.Entry<VertexType,TreeMap<VertexType,Double>> entry :
adjacency.entrySet())
{
System.out.println(entry.getKey() + " -> " +
entry.getValue());
}
}
public double getPathWeight(List<VertexType> path) throws
GraphPathException
{
//need help with this method
}
}
答案 0 :(得分:1)
在没有给您答案的情况下,让我概述一种方法。假设我们有以下数据:
{A -> {C -> 10, D -> 100}}
{C -> {D -> 10}}
{D -> {}}
因此A
已连接到C
和D
,C
已连接到D
。一个简单的DAG。
让我们计算路径A -> C -> D
的成本。
首先,我们计算顶点A -> C
的成本。我们需要从外部地图中获得A
,这给了我们{C -> 10, D -> 100}
。接下来,我们需要获得顶点的末端,因此我们从内部C
-Map
获得10
。
所以A -> C = 10
。
首先,我们计算顶点C -> D
的成本。我们需要从外部地图中获得C
,这给了我们{C -> {D -> 10}}
。接下来,我们需要获得顶点的末端,因此我们从内部D
-Map
获得10
。
所以C -> D = 10
。
总费用:20
用于此的算法是什么样的?用伪代码:
double weight = 0;
for (int i = 0; i < path.size() - 1; ++i) {
Map<> inner = adjacency[path[i]]
weight += inner[path[i + 1]]
}
我们遍历path
直到结束之前的一项。然后,我们从adjacency
获取起始顶点,并从inner
获取终止顶点。这给了我们这一优势的成本。我们将其加到总计中。
然后我们沿着path
移动一个-上一个结束边变为下一个开始边。
我们一直循环到path
结束之前的一个,因为我们总是在“向前看”一项;即最后一个边不能成为起始边,因为没有结束边。
答案 1 :(得分:1)
为简单起见,我希望您考虑一些事项:
为什么要在Set
方法中引入addEdge
?您可以完成没有边缘的添加任务吗?
如何计算路径的权重?
考虑简单地迭代getPathWeight
参数中给出的节点/顶点并在adjacency
中进行查找。
我认为这很容易,您只需要知道如何获取介于两个给定顶点之间的边缘权重(但首先,您需要从adjacency
中检查是否该边缘确实存在,或者path
给出的列表不正确,在这种情况下可能会引发异常)。
实际的代码看起来像这样,但是我建议您先自己思考,然后再尝试编写代码,然后再继续阅读。 :)(我认为,如果您可以确定图的数据结构-Map<VertexType, Map<VertexType, Double>>
,并且感觉足够好,那么您可以轻松地用正确的代码填充getPathWeight
方法自己)
您可以使用这种简单的addEdge
实现:
public void addEdge(VertexType v1, VertexType v2, double weight) {
adjacency.computeIfAbsent(v1, v -> new HashMap<>()).put(v2,weight);
}
getPathWeight
的简单实现:
public double getPathWeight(List<VertexType> path) throws GraphPathException {
VertexType previousVertex = path.get(0);
double resultWeight = 0.0;
for (int i = 1; i < path.size(); i++) {
VertexType currentVertex = path.get(i);
Map<VertexType, Double> adjacencyForPreviousVertex = adjacency.get(previousVertex);
if (adjacencyForPreviousVertex == null) {
throw new GraphPathException("Vertex " + previousVertex + " don't exist in graph");
}
Double currentEdgeWeight = adjacencyForPreviousVertex.get(currentVertex);
if (currentEdgeWeight == null) {
throw new GraphPathException(currentVertex + "Vertex don't exist as an adjacent Vertex of " + previousVertex);
}
resultWeight += currentEdgeWeight;
previousVertex = currentVertex;
}
return resultWeight;
}