Algorithm 带障碍物的图算法DFS/BFS的实现
我想问你是否可以给我一个关于基于图算法的任务的建议-DFS或BFS。 这项任务背后有一个故事。在宇宙中,有很多行星。这些行星中的一些受到一种危险病毒的感染,这种病毒会杀死所有人。 我们的任务是找到一条从一个星球到一个有药物的星球的路径,这样就有可能治愈人类的病毒。 由于病毒的存在,找到路径是相当危险的。机组人员可能会去病毒所在的星球(他们知道病毒在哪个星球),但他们去那里是因为他们没有其他选择,因为他们必须找到药物。在被感染的星球上,机组人员被感染,并有一段时间可以生存(时间是从一个星球到另一个星球的一种方式)。这个任务的结果应该是一条从起始行星到有药物的行星的路径。它应该适用于任何已知宇宙的地图 一个已知的有行星的宇宙的例子。起始行星为0,终止行星为13。正如你所看到的,行星1,2,4都被感染了。在这个具体的例子中,机组人员感染后还有一天可以活。因此,如果机组人员前往行星1,他们会受到感染,然后在下一个行星(4或6)死亡。如果他们去了行星2,他们会被感染,他们只有一天的生命,所以在下一个行星上死亡。。。其结果是路径0 3 10 11 12 5 13 另一个已知有行星的宇宙的例子。起始行星为0,终止行星为9。正如你所看到的,行星4,6,7都被感染了。在这个具体的例子中,机组人员感染后还有两天的生命。因此,如果机组人员前往行星4,他们会受到感染,两天后(一天=从一个行星到另一个行星的一条路)死亡。其结果是路径01 2 3 5 7 6 9或01 2 3 5 7 8 9。正如您所看到的,在某些情况下,可能会有更多的路径。任务是只找到一个,而不必是最短的。只有一条正确的路线,船员们从起点到终点。Algorithm 带障碍物的图算法DFS/BFS的实现,algorithm,graph,depth-first-search,breadth-first-search,Algorithm,Graph,Depth First Search,Breadth First Search,我想问你是否可以给我一个关于基于图算法的任务的建议-DFS或BFS。 这项任务背后有一个故事。在宇宙中,有很多行星。这些行星中的一些受到一种危险病毒的感染,这种病毒会杀死所有人。 我们的任务是找到一条从一个星球到一个有药物的星球的路径,这样就有可能治愈人类的病毒。 由于病毒的存在,找到路径是相当危险的。机组人员可能会去病毒所在的星球(他们知道病毒在哪个星球),但他们去那里是因为他们没有其他选择,因为他们必须找到药物。在被感染的星球上,机组人员被感染,并有一段时间可以生存(时间是从一个星球到另一个
我已经使用了迭代DFS算法,但我不知道如何实现这样一个部分:如果机组人员在一条路径上死亡,算法应该找到另一条路径。您可以从图形的图片中获得它。您可以使用最短路径算法,如查找两个节点之间的最短路径 边权重就是您可能要访问的节点的权重。在这种情况下,所有指向非病毒节点的边的权重都将为
1
。而到病毒节点的边的权重为节点数+1
。访问任何一个病毒行星都比访问所有其他行星成本更高。这样,病毒行星只有在没有其他选择的情况下才会被选择
它还处理了你必须访问多个病毒行星的情况,通过选择病毒行星数量最少的路径,而这在这种情况下并不重要。虽然如果你想列出所有同样有效的解决方案,你可以考虑任何额外的病毒行星重量为1,如果路径已经包括一个病毒行星。然后,如果它与最佳解决方案具有相同的权重,则只需将其显示为另一个有效解决方案
至于生存时间,我们称之为T
,只需检查当前路径即可。如果搜索中的当前节点不是结束节点,并且自第一个病毒行星穿过后它一直是T
行星。然后将该路径视为无效而拒绝
《生存时间》的另一种处理方法是使用数组权重,
[路径权重,病毒年龄]
。这意味着,给定相同的路径权重,它将扩展病毒龄最低的路径。病毒年龄仅为暴露于病毒后的#天
如果您不在乎它是否是最短路径,您可以使用DFS并进行一些调整,以合并死亡时间功能。和javascript代码:
function findPath(path, infectedNodes, nodesBeforeDeath, initialNode, targetNode, adjacentTable) {
const lastNode = path.visitedNodes[path.visitedNodes.length - 1];
if (lastNode === targetNode) {
return path;
}
if (path.nodesLeftBeforeDeath !== null && path.nodesLeftBeforeDeath !== undefined && path.nodesLeftBeforeDeath == 0) {
return;
}
const adjacentNodes = adjacentTable[lastNode];
for (const node of adjacentNodes) {
if (path.visitedNodes.indexOf(node) > -1) {
continue;
}
const newPath = {
visitedNodes: [...path.visitedNodes, node]
};
if (path.nodesLeftBeforeDeath !== null && path.nodesLeftBeforeDeath !== undefined) {
newPath.nodesLeftBeforeDeath = path.nodesLeftBeforeDeath - 1;
}
else if (infectedNodes.indexOf(node) > - 1) {
newPath.nodesLeftBeforeDeath = nodesBeforeDeath;
}
const nodeResult = findPath(newPath, infectedNodes, nodesBeforeDeath, initialNode, targetNode, adjacentTable);
if (nodeResult) {
return nodeResult;
}
}
}
const firstExampleResult = findPath({
visitedNodes: [0]
},
[1, 2, 4],
1,
0,
13,
[[1,2,3,4],
[0,4,6],
[0, 7, 8],
[0, 9, 10],
[0, 1, 11, 12],
[6, 12, 13],
[1, 5, 7],
[2,6,14],
[2,9,14],
[3,8],
[3, 11],
[4,10,12],
[4,5,11],
[5],
[7,8]]
);
console.log(firstExampleResult.visitedNodes);
const secondExampleResult = findPath({
visitedNodes: [0]
},
[4, 6, 7],
2,
0,
9,
[
[1],
[0,2],
[1,3],
[2,4,5],
[3,7],
[3,7],
[7,9],
[4,5,6,8],
[7,9],
[6,8]
]
);
console.log(secondExampleResult.visitedNodes);
您可以通过修改BFS来解决此问题。在进行BFS时,保持感染天数作为状态的一部分。然后,在遍历时,如果我们访问的受感染天数更好(即更少),则接受对以前访问过的节点的遍历 这也是最短路径,因为BFS将在非加权图中生成最短路径 下面是应用于第二个示例的Python快速草图:
from collections import deque
def bfs(graph, virus_nodes, start, target, survive_days):
survive_days = min(survive_days, len(graph))
visited = {start : 0}
queue = deque([(start, 0, (start,))]) # node, days infected, path
while queue:
node, days_infected, path = queue.popleft()
is_infected = days_infected > 0 or node in virus_nodes
nxt_days_infected = days_infected + 1 if is_infected else 0
if nxt_days_infected > survive_days:
continue
for nxt in graph[node]:
if nxt == target:
return path + (target,)
if nxt not in visited or visited[nxt] > nxt_days_infected:
queue.append((nxt, nxt_days_infected, path + (nxt,)))
visited[nxt] = nxt_days_infected
if __name__ == "__main__":
graph = {
0 : [1],
1 : [0, 2],
2 : [1, 3],
3 : [2, 4, 5],
4 : [3, 7],
5 : [3, 7],
6 : [7, 9],
7 : [4, 5, 6, 8],
8 : [7, 9],
9 : [6, 8],
}
virus_nodes = {4, 6, 7}
max_survive_days = 2
print(bfs(graph, virus_nodes, 0, 9, max_survive_days))
输出:
(0, 1, 2, 3, 5, 7, 6, 9)
解决这个问题最简单的方法是使用BFS,但你要从头开始 假设感染后的存活时间为TTL天
从目的地运行BFS,但你只能考虑在小于TTL长的路径上感染行星。一旦BFS到达TTL长度的路径,那么从那时起,你只能使用干净的行星,一直到开始
这是特别容易,如果你做的BFS一级一级。然后,您只需检查level
s
到目标t
,并且x
是一条路径。)