- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
用 BFS 解决算法问题时发生超时。但是,有一个问题可以用 DFS 解决。为什么会出现这种差异?
问题是计算从(1,1)到(N,N)通过水平、垂直或对角线移动到达的次数。
如果问题由 BFS 解决(最坏情况),则需要 1331.0ms,而由 DFS 解决则需要 62.0ms。 (我创建并测试了 16 * 16 个数组。)
附上问题 URL。 (但请理解它是韩语。)网址> https://www.acmicpc.net/problem/17070
我想听到的答案是...
实现
类(class)位置{
int x;
int y;
int dir;
public Location(int x, int y, int dir) {
super();
this.x = x;
this.y = y;
this.dir = dir;
}
公共(public)课主要{
static int[][] map;
static int Answer;
static int N;
public static void main(String args[]) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
N = Integer.parseInt(br.readLine());
map = new int[N + 1][N + 1];
for (int i = 1; i <= N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 1; j <= N; j++)
map[i][j] = Integer.parseInt(st.nextToken());
}
DFS(1, 2, 0);
System.out.println(Answer);
Answer = 0;
BFS(1, 2, 0);
System.out.println(Answer);
br.close();
}
static void DFS(int x, int y, int pre) {
if (x == N && y == N) {
Answer++;
return;
}
if (pre == 0) {
if (y + 1 <= N && map[x][y + 1] == 0)
DFS(x, y + 1, 0);
if (y + 1 <= N && map[x][y + 1] == 0 && x + 1 <= N && map[x + 1][y] == 0 && map[x + 1][y + 1] == 0)
DFS(x + 1, y + 1, 1);
} else if (pre == 1) {
if (y + 1 <= N && map[x][y + 1] == 0)
DFS(x, y + 1, 0);
if (x + 1 <= N && map[x + 1][y] == 0)
DFS(x + 1, y, 2);
if (y + 1 <= N && map[x][y + 1] == 0 && x + 1 <= N && map[x + 1][y] == 0 && map[x + 1][y + 1] == 0)
DFS(x + 1, y + 1, 1);
} else {
if (x + 1 <= N && map[x + 1][y] == 0)
DFS(x + 1, y, 2);
if (y + 1 <= N && map[x][y + 1] == 0 && x + 1 <= N && map[x + 1][y] == 0 && map[x + 1][y + 1] == 0)
DFS(x + 1, y + 1, 1);
}
}
static void BFS(int startX, int startY, int dir) {
ArrayDeque<Location> arrayDeque = new ArrayDeque<>();
arrayDeque.add(new Location(startX, startY, dir));
Location location;
int x, y, pre;
while(!arrayDeque.isEmpty()) {
location = arrayDeque.remove();
x = location.x;
y = location.y;
pre = location.dir;
if(x == N-1 && y == N-1) {
Answer++; continue;
}
if (pre == 0) {
if (y + 1 <= N && map[x][y + 1] == 0)
arrayDeque.add(new Location(x, y + 1, 0));
if (y + 1 <= N && map[x][y + 1] == 0 && x + 1 <= N && map[x + 1][y] == 0 && map[x + 1][y + 1] == 0)
arrayDeque.add(new Location(x + 1, y + 1, 1));
} else if (pre == 1) {
if (y + 1 <= N && map[x][y + 1] == 0)
arrayDeque.add(new Location(x, y + 1, 0));
if (x + 1 <= N && map[x + 1][y] == 0)
arrayDeque.add(new Location(x + 1, y, 2));
if (y + 1 <= N && map[x][y + 1] == 0 && x + 1 <= N && map[x + 1][y] == 0 && map[x + 1][y + 1] == 0)
arrayDeque.add(new Location(x + 1, y + 1, 1));
} else {
if (x + 1 <= N && map[x + 1][y] == 0)
arrayDeque.add(new Location(x + 1, y, 2));
if (y + 1 <= N && map[x][y + 1] == 0 && x + 1 <= N && map[x + 1][y] == 0 && map[x + 1][y + 1] == 0)
arrayDeque.add(new Location(x + 1, y + 1, 1));
}
}
}
最佳答案
BFS 和 DFS 都有 O(|V| + |E|)
时间复杂度,而您遇到的时间差很可能是 BFS 实现中的错误造成的,该错误打破了循环不变性。
实现 BFS 时最常见的错误之一是多次将相同的元素添加到队列中。应该只添加一个顶点 v
到队列一次,这样你就可以确保它被删除一次。除非你这样做,否则渐近运行时(即它的复杂性)将不再是线性的。可以看到相关CLRS基于他们引入的循环不变概念,这一章的证明。
也就是说,BFS是一种遍历算法。它找出哪些 顶点是可达的,而不是到达每个顶点的路由数 v
.如果您尝试计算方式的数量 K<sub>v</sub>
到达每个 v
来自 (1, 1)
通过 BFS,复杂度变得比线性更大。 如果问题要求您查找K<sub>v</sub>
,那么您的方法应该是使用记忆化和动态规划,而不是 BFS。
具体来说,根据您提供的代码,您的算法似乎没有跟踪先前是否探索过顶点(即网格中的单元格)。这导致顶点被多次探索,这超过了使用 BFS 和 DFS 等图遍历算法的意义。使用我上面提到的术语,您将违反 BFS 的循环不变量,它声明每个顶点仅从队列中弹出一次。这会导致代码的复杂性远高于线性。
您应该查看术语memoization 并找出一种方法来找到(N, N)
的解决方案| ,使用您为 (N-1, N-1)
计算仅一次的解决方案, (N-1, N)
和 (N, N-1)
.
关于algorithm - BFS 和 DFS 算法有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55528606/
我正在寻找我的代码的复杂度计算。简单来说就是DFS中的DFS(depth first search)。 DFS 从头到尾(向后搜索)在图(状态机)上运行。每当到达开始时,它都会累积使其到达开始的字符串
我通过实现堆栈编写了一个迭代 DFS。现在我试图递归地编写相同的 DFS,但我遇到了问题。 我的问题是,当我迭代编写它时,我可以保留某些全局变量,例如 paths=[] 并在找到新路径时添加到其中。
此程序用于图的 dfs 遍历,一个函数是迭代方法,另一个函数是递归方法,但两者给出的答案不同从迭代中我得到 01234从递归我得到 02341 谁能解释我为什么? NOTE -> User is en
这个问题在这里已经有了答案: Iterative DFS vs Recursive DFS and different elements order (4 个答案) 关闭 8 年前。 我试图了解 D
首先请原谅我的英语这可能不太可能,或者以前没有人经历过这种情况,我真的非常需要帮助。这可能是我第一次在这里提问 我正在尝试在 azure 订阅中的两台服务器(LIVE1 和 LIVE2)上设置 dfs
我以迭代方式和递归方式实现了深度优先搜索算法。它们对于小尺寸(小于 1 MB)的文件都可以正常工作。然而,当我尝试在 50 MB 的文件上运行它们时,递归 DFS(9 秒)似乎比使用迭代方法(至少几分
我正在解决这个 dfs/bfs问题。 我编写了 DFS 的迭代版本和递归版本。 节点访问的顺序不同,我不明白为什么。 迭代 DFS: static void DFS (Integer root, Gr
我遇到了一个问题,我要在图中寻找一种特殊类型的节点。该算法按以下方式工作: bool findSpecial(Node n) { if(isSpecial(n)) return
我写了一个递归DFS算法来遍历一个图: void Graph::DFS(Node n) { std::cout void Graph::IterativeDFS(Node n) {
在我的算法中,我将通过 DFS 方法创建频繁模式,例如,我生成 A-A, A-A-B, A-A-B-C, .. .顺序。(这三种模式为频繁子图模式,A,B,C为节点,- 表示两个节点之间存在一条边。)
我对 hadoop 中的 dfs 有疑问。有人知道如何解决我的问题吗? [hduser@evghost ~]$ start-dfs.sh Starting namenodes on [evghost]
据说在未加权的图中不能用DFS求最短路径。我已阅读多篇文章和博客,但并不满意,因为对 DFS 稍加修改就可以实现。 我认为如果我们以这种方式使用改进的 DFS,那么我们可以找到距源的最短距离。 Ini
考虑到一个具有 14,000 个顶点和 14,000 个边的图,我想知道为什么 GraphX 比图的 java 实现花费更多的时间来获取从顶点到叶子的所有路径? java 实现:几秒钟 Graphx
我已按照 Apache“单节点设置”说明在单节点上设置 dfs.replication。 但是后来我按照“Cluster Setup”进行操作,但它没有提到这个属性,所以我不知道这是要在 Nameno
有没有办法修改 pd.read_html 使其返回数据帧而不是数据帧列表? 语境: 我正在尝试使用 pandas read_html 从网站导入表格。我知道 pd.read_html 返回一个 dfs
为什么 hdfs dfs -ls 指向与 hdfs dfs -ls/ 不同的位置? 从下面的截图中可以清楚地看到两个命令给出不同的输出: 以上输出的主要原因是什么? 最佳答案 来自官方源码org.ap
我没有在 hdfs-site.xml 文件中设置 dfs.name.dir 和 dfs.data.dir 值没有设置。他们会怎样?有趣的是,他们默认接受什么值? (如何接收他们的当前值?) 最佳答案
我试图用一个名称节点和四个数据节点配置 hadoop。我能够在一台机器上成功配置名称节点和作业跟踪器并将其启动。 但是在我要配置数据节点的机器上,我做了以下操作: 我将 hadoop-2.0.0-cd
我正在尝试在 ec2-instance 上安装 Hadoop-2.6.0。 我下载并安装了 Hadoop。我还设置了环境变量。尝试启动 hdfs 服务时出现以下错误。 [ec2-user@ip-10-
我是 hadoop 框架的新手,目前我正在处理大数据项目,在 Windows 7 中使用 cygwin、hadoop-0.19.1、eclipse-3.3.1 (Europa)。现在我正在尝试从 ha
我是一名优秀的程序员,十分优秀!