我理解并且可以轻松实现BFS。
我的问题是,我们如何将这个BFS限制在某一个深度范围内?假设我只需要搜索10层深度。
我理解并且可以轻松实现BFS。
我的问题是,我们如何将这个BFS限制在某一个深度范围内?假设我只需要搜索10层深度。
timeToDepthIncrease
保持了队列中第一个元素所在层级上一层的节点数。如果我说错了,请纠正我。算法很棒。谢谢。 - canbaxtimeToDepthIncrease
这样的名称,不如使用cntElementsInQueueFromUpperLevel
这样更具说明性但不太美观的名称。 - canbax对于未来的读者,看一下上面描述的算法的示例。这个实现将监视以下级别包含的节点数。通过这样做,该实现能够跟踪当前深度。
void breadthFirst(Node parent, int maxDepth) {
if(maxDepth < 0) {
return;
}
Queue<Node> nodeQueue = new ArrayDeque<Node>();
nodeQueue.add(parent);
int currentDepth = 0,
elementsToDepthIncrease = 1,
nextElementsToDepthIncrease = 0;
while (!nodeQueue.isEmpty()) {
Node current = nodeQueue.poll();
process(current);
nextElementsToDepthIncrease += current.numberOfChildren();
if (--elementsToDepthIncrease == 0) {
if (++currentDepth > maxDepth) return;
elementsToDepthIncrease = nextElementsToDepthIncrease;
nextElementsToDepthIncrease = 0;
}
for (Node child : current.children()) {
nodeQueue.add(child);
}
}
}
void process(Node node) {
// Do your own processing here. All nodes handed to
// this method will be within the specified depth limit.
}
跟踪深度的简单方法是每当您进入一层时将“NULL”添加到队列中。 一旦您从队列中轮询了一个null,则将您的级别计数器增加1并将另一个“null”添加到队列中。 如果您连续获得两个null,则可以退出循环。
q.offer(user);
q.offer(null);
user.setVisited(true);
while(!q.isEmpty()){
User userFromQ = q.poll();
if(userFromQ == null){
level++;
q.offer(null);
if(q.peek()==null)
break;
else
continue;
}
map<Node,Depth>
来跟踪这两个信息(其中 Node 是类的实例、int、String 等,而 Depth 是从根节点开始计算的深度)。如果 map 包含一个节点(O(1) 成本),则说明它被访问过,否则请继续进行操作,并将其添加到 map 中,并将其深度设置为当前节点深度+1。public static void BfsToDepth(graph graphDb, Node rootNode, int depth) {
if(depth<1)
return;
Queue<Node> queue = new LinkedList<>();
ResourceIterator<Node> nodesIterator = graphDb.getAllNodes().iterator();
LinkedHashMap<Node, Boolean> visited = new LinkedHashMap<>();
LinkedHashMap<Node, Integer> distance = new LinkedHashMap<>();
// Start: Bfs Init Step
if (nodesIterator.hasNext() == true) {
while (nodesIterator.hasNext()) {
Node currentNode = nodesIterator.next();
visited.put(currentNode, false);
distance.put(currentNode, Integer.MAX_VALUE);
}
} else {
System.out.println("No nodes found");
}
// End: Bfs Init Step
distance.put(rootNode, 0);
visited.put(rootNode, true);
queue.add(rootNode);
Node current = null;
while (queue.isEmpty() == false) {
current = queue.poll();
if (distance.get(current) <= depth) {
Iterator<Relationship> relationships = current.getRelationships().iterator();
if (relationships.hasNext() == true) {
while (relationships.hasNext()) {
Relationship relationship = relationships.next();
Node adjacent = relationship.getOtherNode(current);
if (visited.get(adjacent) == false) {
/*if you want to print the distance of each node from root then
System.out.println("len: "+ (distance.get(current) + 1)+" to: "+ adjacent);*/
distance.put(adjacent, (distance.get(current) + 1));
visited.put(adjacent, true);
queue.add(adjacent);
}
}
}
}
}
}
from collections import deque
def bfs_maxdepth(graph, start, maxdepth):
queue = deque([start])
depths = {start: 0}
while queue:
vertex = queue.popleft()
if depths[vertex] == maxdepth:
break
for neighbour in graph[vertex]:
if neighbour in depths:
continue
queue.append(neighbour)
depths[neighbour] = depths[vertex] + 1
return depths
这个可以工作。假设节点中没有visited标志。如果isVisited可用,则不需要跟踪Map。
// k is depth, result should not contain initialNode.
public static Collection<Node> bfsWithK_Depth(Node initialNode, int k) {
if (initialNode == null || k <= 0) {
return new ArrayList<>();
}
Queue<Node> q = new LinkedList<>();
q.add(initialNode);
Map<Node, Node> tracker = new HashMap(); // no need if there is visited flag.
Collection<Node> result = new ArrayList<>();
while (!q.isEmpty()) { // Q will be filled only with eligible nodes
--k ;
Node node = q.remove();
List<Node> neighbor = node.getNeighbor();
for (Node n : neighbor) {
if (tracker.get(n) == null && k > 0) {
q.add(n);
}
if (tracker.get(n) == null) {
tracker.put(n, n);
result.add(n); // visit this node
}
}
}
return result;
}
这个解决方案对我很有效,它返回了在深度限制内可以访问的顶点的所有内容。
def bfs(graph,src,limit):
v = [src]
q = [src]
lastElement = src
while len(q) > 0 and limit > 0:
ele = q.pop(0)
for i in graph[ele]:
if i not in v:
q.append(i)
v.append(i)
if len(q) > 0 and ele == lastElement:
lastElement = q[-1]
limit -= 1
return v