我正尝试在一个大图上执行广度优先搜索。我有一个顶点和它的每个邻居的列表。我将数据放入一个hashmap中,键是顶点,值是与键相邻的顶点列表。我尝试了以下方法,但由于我使用键/值对进行循环的方式,第二个"For Loop“正在无限期地运行。但我想不出另一种方法来正确地循环并命中每个节点。
public static void BFS(HashMap<Vertex, List<Vertex>> map) {
Queue<Vertex> myQ = new LinkedList<Vertex>();
for(HashMap.Entry<Vertex, List<Vertex>> entry : map.entrySet()) {
if(entry.getKey().getCount() == 0){
count++;
entry.getKey().setCount(count);
myQ.add(entry.getKey());
while(!myQ.isEmpty()) {
for(Vertex neighbor : entry.getValue()){
if(neighbor.getCount() == 0) {
count++;
neighbor.setCount(count);
myQ.add(neighbor);
}
}
myQ.remove(entry.getKey());
}
}
}
}count属性用于跟踪某个顶点是否已经被访问过。
任何帮助都将不胜感激,只要寻找一种新的方式来思考如何在HashMap中循环即可。或者如果我做了完全错误的事情:)
发布于 2015-02-11 05:57:57
如果我理解您的问题和示例代码,那么您要做的就是在不多次访问顶点的情况下迭代所有map的值。如果是这样,那么您可以使用Java 8执行以下操作:
map.values().stream().flatMap(List::stream).distinct()
.forEach(vertex -> {...});但是,如果您想从根节点开始并执行广度优先搜索(这是正常的机制),那么它就有点复杂了:
List<Vertex> completedList = new ArrayList<>();
for (List<Vertex> searchList = Arrays.toList(root);
!searchList.isEmpty();
searchList = searchList.stream().map(map::get).flatMap(List::steam)
.filter(v -> !completedList.contains(v))
.collect(Collectors.toList())) {
searchList.forEach(vertex -> {...});
completedList.addAll(searchList);
}发布于 2015-02-11 06:02:40
假设开始搜索的是一个顶点根,您的代码可能如下所示:
public static void BFS(Vertex root, HashMap<Vertex, List<Vertex>> map) {
Deque<Vertex> myQ = new LinkedList<Vertex>();
myQ.add(root);
while(!myQ.empty()) {
Vertex current = myQ.getFirst();
current.visited = true;
// Or you can store a set of visited vertices somewhere
List<Vertex> neighbors = map.get(current);
for (Vertex neighbor : neighbors) {
if (!neighbor.visited) {
myQ.addLast(neighbor);
}
}
}
}发布于 2015-02-11 06:04:29
在这里,我还没有真正尝试过这段代码,所以它可能甚至不会按原样编译,但让它工作起来应该不难。事实上,它应该让你对算法是如何工作的有一个很好的了解。
public void BFS( HashMap<Vertex, List<Vertex>> map )
{
if( map.isEmpty() )
return;
/* pick an arbitrary first vertex to start from */
Vertex start = null;
for( Vertex temp : map.getKeys() )
{
start = temp;
break;
}
/* visit first vertex */
visit( start );
/* start recursion */
BFS( start, map );
}
public void BFS( Vertex start, HashMap<Vertex, List<Vertex>> map )
{
/* mark the current vertex as visited */
int count = start.getCount();
assert count == 0;
count++;
start.setCount( count );
/* visit each unvisited neighboring vertex */
for( Vertex neighbor : map.get( start ) )
{
if( neighbor.getCount() != 0 )
continue;
visit( neighbor );
}
/* recurse into each unvisited neighboring vertex */
for( Vertex neighbor : map.get( start ) )
{
if( neighbor.getCount() != 0 )
continue;
BFS( neighbor, map );
}
}但是,在继续之前,我强烈建议您定义一个新的Graph类,封装顶点映射,并提供在图术语中有意义的操作,而不是java集合术语。
https://stackoverflow.com/questions/28442385
复制相似问题