Dijkstra递归java.lang.StackOverflowError

时间:2013-10-05 15:53:13

标签: java recursion dijkstra stack-overflow

我试图以递归方式编写Dijkstra的算法。但我一直得到这个java.lang.StackOverflowError

它使用具有灰度值和PixelNode坐标的x,y s。邻居函数返回最大3 PixelNode s,即当前像素s下方3个像素。

public PixelNode Dijkstra(PixelNode s, PriorityQueue<PixelNode> leads) {
  s.visited = true;
  if (s.isEndNode) {
    return s;
  }
  ArrayList<PixelNode> nbs = s.neighbors();
  for (PixelNode nb : nbs) {
    if (!nb.visited) {
      float new_distance = s.distance + nb.val();
      if (new_distance < nb.distance) {
        nb.distance = new_distance;
        nb.via = s;
      }
      if (!nb.addedToLeads) {
        nb.addedToLeads=true;
        leads.add(nb);
      } else {
        leads.remove(nb);
        leads.add(nb);
      }
    }
  }
  return Dijkstra(leads.poll(), leads);
}

如果有人愿意帮助我,我将不胜感激!

编辑: leads.remove(nb)不起作用。没有正确覆盖PixelNode的equals功能。现在我已经适当地覆盖了它,但仍然没有删除......

编辑: 我开始认为它达到了最大递归深度。如果我将图像裁剪成小的,它会找到正确的路径...对于21x19的图像,它需要374次递归。大致是图像中的nr像素。真实图像是396x366。我想它需要396x366 = 144936递归函数调用。它打破了3257个电话。

该功能的新版本现在是:

public PixelNode dijkstra(PixelNode s, PriorityQueue<PixelNode> leads) {
  s.visited=true;
  if(s.isEndNode) {
    return s;
  }
  ArrayList<PixelNode> nbs = s.neighbors();
  for(PixelNode nb : nbs) {
    if(!nb.visited) {
      float new_distance = s.distance + nb.val();
      if(new_distance < nb.distance) {
        nb.distance = new_distance;
        nb.via = s;
        nb.addedToLeads = true;
        leads.add(nb);
      }
    }
  }
  return dijkstra(leads.poll(), leads);
}

1 个答案:

答案 0 :(得分:0)

虽然我没有源代码来重现问题,但我必须猜测:

public PixelNode Dijkstra(PixelNode s, PriorityQueue<PixelNode> leads) {
  s.visited = true;
  if (s.isEndNode) {
    return s;
  }
  ArrayList<PixelNode> nbs = s.neighbors();
  for (PixelNode nb : nbs) {
    if (!nb.visited) {
      float new_distance = s.distance + nb.val();
      if (new_distance < nb.distance) {
        if (nb.addedToLeads) {
          // already in leads with higher distance value
          // Note: remove is done before distance update
          leads.remove(nb);
        }
        nb.distance = new_distance;
        nb.via = s;
      } else if (nb.addedToLeads) {
        // already in leads with lower or equal distance value
        continue;
      }
      nb.addedToLeads=true;
      leads.add(nb);
    }
  }
  return Dijkstra(leads.poll(), leads);
}

另外,请确保您的Comparator for PriorityQueue返回正确的equals值。