英文:
Out of Memory error when implementing breadth first search algorithm
问题
以下是您的代码的翻译部分:
我遇到了以下错误:
```text
[error][1] (E/DartVM (14988): 耗尽堆空间,尝试分配 536870928 字节。
E/flutter (14988): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] 未处理的异常:内存不足)
当尝试实现广度优先搜索算法以找到图中的最短路径时,我找到了C#中的算法,现在正尝试将其重写为Dart/Flutter。
原始的C#代码在这里。
我的Dart代码:
import 'dart:collection';
import 'package:stack/stack.dart';
class Node<T> {
int id;
Node(this.id);
String toString() => '$id';
}
class Graph<T> {
final Map<Node, List<Node>> adj;
Graph(this.adj);
void AddEdge(Node node1, Node node2) {
if (!adj.containsKey(node1))
adj[node1] = List<Node>();
if (!adj.containsKey(node2))
adj[node2] = List<Node>();
adj[node1].add(node2);
adj[node2].add(node1);
}
Stack<Node> ShortestPath(Node source, Node dest) {
var path = Map<Node<T>, Node<T>>();
var distance = Map<Node<T>, int>();
for (var node in adj.keys) {
distance[node] = -1;
}
distance[source] = 0;
var q = Queue<Node<T>>();
q.add(source);
while (q.isNotEmpty) {
var node = q.removeFirst();
for (var adjs in adj[node].where((n) => distance[n] == -1)) {
distance[adjs] = distance[node] + 1;
path[adjs] = node;
q.add(adjs);
}
}
var res = Stack<Node>();
var cur = dest;
while (cur != res) {
res.push(cur);
cur = path[cur];
}
res.push(source);
return res;
}
}
void main() {
var g = new Graph({});
var n1 = new Node<int>(1);
var n2 = new Node<int>(2);
var n3 = new Node<int>(3);
var n4 = new Node<int>(4);
var n5 = new Node<int>(5);
var n6 = new Node<int>(6);
var n7 = new Node<int>(7);
g.AddEdge(n1, n2);
g.AddEdge(n1, n3);
g.AddEdge(n1, n4);
g.AddEdge(n4, n5);
g.AddEdge(n2, n6);
g.AddEdge(n4, n7);
g.AddEdge(n5, n6);
g.AddEdge(n6, n7);
var answ = g.ShortestPath(n1, n7);
print(answ);
}
这是您的代码的中文翻译,不包含问题的答案。如果您有其他问题或需要进一步帮助,请随时提出。
英文:
I got the following error:
[error][1] (E/DartVM (14988): Exhausted heap space, trying to allocate 536870928 bytes.
E/flutter (14988): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: Out of Memory)
When trying to implement a breadth_first search algorithm to find the shortest path in a graph. I found the algorithm written in C# and I am trying to rewrite it in dart/flutter.
The original code in C# can be found here.
My dart code:
import 'dart:collection';
import 'package:stack/stack.dart';
class Node<T>{
int id;
Node(this.id);
String toString() => '$id';
}
class Graph<T>{
final Map<Node, List<Node>> adj;
Graph(this.adj);
void AddEdge(Node node1,Node node2){
if(!adj.containsKey(node1))
adj[node1]=List<Node>();
if(!adj.containsKey(node2))
adj[node2]=List<Node>();
adj[node1].add(node2);
adj[node2].add(node1);
}
Stack<Node> ShortestPath(Node source, Node dest){
var path=Map<Node<T>,Node<T>>();
var distance=Map<Node<T>,int>();
//adj.keys.forEach(( node) => distance[node]=-1);
for(var node in adj.keys){
distance[node]=-1;
}
distance[source]=0;
var q=Queue<Node<T>>();
q.add(source);
while(q.isNotEmpty){
var node=q.removeFirst();
for(var adjs in adj[node].where((n) => distance[n]==-1)){
distance[adjs]=distance[node]+1;
path[adjs]=node;
q.add(adjs);
}
}
var res=Stack<Node>();
var cur=dest;
while(cur != res){
res.push(cur);
cur=path[cur];
}
res.push(source);
return res;
}
}
void main() {
var g = new Graph({});
var n1 = new Node<int>(1);
var n2 = new Node<int>(2);
var n3 = new Node<int>(3);
var n4 = new Node<int>(4);
var n5 = new Node<int>(5);
var n6 = new Node<int>(6);
var n7 = new Node<int>(7);
g.AddEdge(n1, n2);
g.AddEdge(n1, n3);
g.AddEdge(n1, n4);
g.AddEdge(n4, n5);
g.AddEdge(n2, n6);
g.AddEdge(n4, n7);
g.AddEdge(n5, n6);
g.AddEdge(n6, n7);
var answ=g.ShortestPath(n1, n7);
print(answ);
}
So what is the wrong with my program, and if anyone know better way to find shortest path in graph to use it in dart it will be great.
Thanks in advance
答案1
得分: 0
首先,您的主要问题可能是您的 while 循环与 C# 实现不正确:
var res = Stack<Node>();
var cur = dest;
while (cur != res) {
res.push(cur);
cur = path[cur];
}
res.push(source);
return res;
此循环永远不会结束,因为cur
和res
是完全不同的类型,其中cur
是一个Node
,而res
是一个Stack
。如果您查看 C# 实现,您会发现这是不正确的:
var res = new Stack<Node<T>>();
var cur = dest;
while (cur != source) {
res.Push(cur);
cur = path[cur];
}
res.Push(source);
return res;
因此,我认为通过与source
进行比较,将正确解决该问题。但是您的代码中还存在许多较小的问题,其中类型不太合适,并且可以在更多地方使用泛型来增加类型安全性。
因此,我已经向您的代码添加了更多的类型信息(这是为了捕捉类型错误)。我还放弃了Stack
类的使用,因为我认为这没有太多意义。此外,您获取的Stack
类没有toString
实现,因此我认为直接使用 List 并将其作为结果返回更容易:
import 'dart:collection';
class Node<T> {
int id;
Node(this.id);
@override
String toString() => '$id';
}
class Graph<T> {
final Map<Node<T>, List<Node<T>>> adj;
Graph(this.adj);
void AddEdge(Node<T> node1, Node<T> node2) {
if (!adj.containsKey(node1)) adj[node1] = <Node<T>>[];
if (!adj.containsKey(node2)) adj[node2] = <Node<T>>[];
adj[node1].add(node2);
adj[node2].add(node1);
}
List<Node<T>> ShortestPath(Node<T> source, Node<T> dest) {
final path = <Node<T>, Node<T>>{};
final distance = <Node<T>, int>{};
// adj.keys.forEach((node) => distance[node]=-1);
for (final node in adj.keys) {
distance[node] = -1;
}
distance[source] = 0;
final q = Queue<Node<T>>();
q.add(source);
while (q.isNotEmpty) {
final node = q.removeFirst();
for (final adjs in adj[node].where((n) => distance[n] == -1)) {
distance[adjs] = distance[node] + 1;
path[adjs] = node;
q.add(adjs);
}
}
final res = <Node<T>>[];
var cur = dest;
while (cur != source) {
res.add(cur);
cur = path[cur];
}
res.add(source);
return res;
}
}
void main() {
final g = Graph<int>({});
final n1 = Node<int>(1);
final n2 = Node<int>(2);
final n3 = Node<int>(3);
final n4 = Node<int>(4);
final n5 = Node<int>(5);
final n6 = Node<int>(6);
final n7 = Node<int>(7);
g.AddEdge(n1, n2);
g.AddEdge(n1, n3);
g.AddEdge(n1, n4);
g.AddEdge(n4, n5);
g.AddEdge(n2, n6);
g.AddEdge(n4, n7);
g.AddEdge(n5, n6);
g.AddEdge(n6, n7);
final answ = g.ShortestPath(n1, n7);
print(answ); // [7, 4, 1]
}
英文:
First, you main problem is properly that your while loop is not correct according to the C# implementation:
var res=Stack<Node>();
var cur=dest;
while(cur != res){
res.push(cur);
cur=path[cur];
}
res.push(source);
return res;
This loop will never finish res and cur are entirely different types where cur
are a Node
and res
are a Stack
. If you check the C# implementation you can see this is not correct:
var res = new Stack<Node<T>>();
var cur = dest;
while(cur != source) {
res.Push(cur);
cur = path[cur];
}
res.Push(source);
return res;
So I think by comparing against source
it will properly solve the problem. But there are a lot of smaller problems in you code where types are not really great and where you could make it a lot more type safe by using generics more places.
I have therefore added more typing information to you code (which I needed to do to catch the type error). I have also dropped the usage of the Stack
class since I don't think it makes much sense. Also, the Stack
class you got had no toString
implementation so I just thought it was easier to just use a List and return that as the result:
import 'dart:collection';
class Node<T> {
int id;
Node(this.id);
@override
String toString() => '$id';
}
class Graph<T> {
final Map<Node<T>, List<Node<T>>> adj;
Graph(this.adj);
void AddEdge(Node<T> node1, Node<T> node2) {
if (!adj.containsKey(node1)) adj[node1] = <Node<T>>[];
if (!adj.containsKey(node2)) adj[node2] = <Node<T>>[];
adj[node1].add(node2);
adj[node2].add(node1);
}
List<Node<T>> ShortestPath(Node<T> source, Node<T> dest) {
final path = <Node<T>, Node<T>>{};
final distance = <Node<T>, int>{};
//adj.keys.forEach(( node) => distance[node]=-1);
for (final node in adj.keys) {
distance[node] = -1;
}
distance[source] = 0;
final q = Queue<Node<T>>();
q.add(source);
while (q.isNotEmpty) {
final node = q.removeFirst();
for (final adjs in adj[node].where((n) => distance[n] == -1)) {
distance[adjs] = distance[node] + 1;
path[adjs] = node;
q.add(adjs);
}
}
final res = <Node<T>>[];
var cur = dest;
while (cur != source) {
res.add(cur);
cur = path[cur];
}
res.add(source);
return res;
}
}
void main() {
final g = Graph<int>({});
final n1 = Node<int>(1);
final n2 = Node<int>(2);
final n3 = Node<int>(3);
final n4 = Node<int>(4);
final n5 = Node<int>(5);
final n6 = Node<int>(6);
final n7 = Node<int>(7);
g.AddEdge(n1, n2);
g.AddEdge(n1, n3);
g.AddEdge(n1, n4);
g.AddEdge(n4, n5);
g.AddEdge(n2, n6);
g.AddEdge(n4, n7);
g.AddEdge(n5, n6);
g.AddEdge(n6, n7);
final answ = g.ShortestPath(n1, n7);
print(answ); // [7, 4, 1]
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论