避免在dijkstra算法中出现ConcurrentModificationException

时间:2017-12-07 05:06:07

标签: java exception dijkstra

对于这个程序,我读了一个excel文件,其中列出了与他们相邻的城镇,城镇和他们之间的距离,如下所示:

Bourke  Nyngan  200
Brewarrina  Walgett 134
Broken Hill Mildura 266
Broken Hill Wilcannia   195
Bungendore  Queanbeyan  54
etc.

这很有效。一切似乎都很完美。 我试图制作一个程序,如果我给它两个城镇,它会返回两者之间最短的路径。

我可以让我的程序在文件中正确读取,并设置所有内容,所以我知道这个问题与设置无关。据我所知,我的程序的这部分工作,因为我的程序可以通过它而不会抛出错误:

   //returns the Vertex with the smallest distance from a list of Vertices
   public static Vertex minDist(List<Vertex> Q){
  int min = 2147483647;
  Vertex closest = new Vertex("Closest");

  for(Vertex v : Q){
     if(v.distance < min){
        closest = v;
     }
  }   
  return closest;
  }


 //used to relax (change the distance of a town)
 public static void relax(Vertex u, Vertex v, int w){
  if(v.distance > u.distance + w){
     v.distance = u.distance + w;
     v.predecessor = u;
    } 
   }



public static void Dijkstra(Graph G, Vertex s){
  Vertex u = new Vertex("not good");
  List<Vertex> Q = V;
  Vertex v = new Vertex("oh no");

//while Q is not empty:
  while(!Q.isEmpty()){

  //the vertex in Q that has the smallest distance (at first s with 0, then we relax and that changes things)
     u = minDist(Q);

     if(u.name.equals("Closest")){
        //Q.remove(u);
        return;
     }
     Q.remove(u);

     S.add(u);


  //for each edge e in u's adjacencyList:
     for(Edge e : u.roadList){

        if(e != null && !e.finish.name.equals(u.name) ){
           v = e.finish;

           relax(u,v,w(u,v)); //w(u,v) returns the distance between u and v
        }

     }
  } 

  System.out.println("Q is null");  
}

所以我有这个,事情看起来没问题。我知道它有点弗兰肯斯坦在一起,但我至少运行没有错误,因为ConcurrentModificationException在我的main方法返回此方法之后被抛出。

这是我的主方法中调用Dijkstra方法的地方。我从来没有在我的代码中找到打印出来的行#34;应该在这里找到&#34;因为程序抛出ConcurrentModificationException。

        //if both towns exist and are unique, find the shortest route between them.
        if(isTown(town1,V) && isTown(town2,V) && !town1.equals(town2)){

           for(Vertex f : V){
              if(f.name.equals(town2)){
                 destination  = f;
              }
           }

           System.out.println("Traveling...");

           Graph G = new Graph(V,E);

           for(Vertex s : V){

              if(s.name.equals(town1)){
              //////////////////DIJKSTRA STUFF GOES HERE///////////////////
                 initialize(G,s);

                 Dijkstra(G, s);
                 System.out.println("FINISHED DIJKSTRA");

                 //Print out the things in the vertex array S with their distances.
                 for(Vertex b : S){
                    System.out.println(b.name + " (" + b.distance + ")");
                 }

               ///////////////////////////////////////////////
              }

           }
           System.out.println("SHOULD REACH HERE");
        }

我从未见过ConcurrentModificationException,我的实验TA从未见过ConcurrentModificationException,甚至我的教授从未见过ConcurrentModificationException。我可以帮助避免这种情况吗?一个更高级别的人说他只是在使用多个线程时才看到这种情况发生,我甚至不知道这意味着什么,所以我认为我的程序没有这样做。

如果我使用town1 = Grafton和town2 = Bathurst运行程序,那么输出应为:

First town: Grafton
Second town: Bathurst
Bathurst (820)
Lithgow (763)
Windsor (672)
Singleton (511)
Muswellbrook (463)
Tamworth (306)
Bendemeer (264)
Uralla (218)
Armidale (195)
Ebor (106)
Grafton

但是

First town: Grafton
Second town: Bathurst
Grafton (0)
Glen Innes (158)
Inverell (225)
Warialda (286)
Coffs Harbour (86)
I/O error: java.util.ConcurrentModificationException

1 个答案:

答案 0 :(得分:0)

你得到这个是因为你在迭代它时从Q中移除它。见Iterating through a Collection, avoiding ConcurrentModificationException when removing in loop