2016-05-13 2 views
2

У меня возникла проблема преобразования псевдокода алгоритма Дейкстры в фактический код. Я был указан и список смежности, такой как «Местоположение - смежное местоположение - расстояние до местоположения», пример для одного узла: AAA AAC 180 AAD 242 AAH 40. Моя задача состояла в том, чтобы прочитать файл, организованный как список смежности, как описано, и вычислить кратчайший путь от одного узла к другому. Вот Дейкстр псевдокод:Список смежности Dijkstra

void dijkstra(Vertex s) 
    { 
     for each Vertex v 
     { 
      v.dist = INFINITY; 
      v.known = false; 
     } 
     s.dist = 0; 
     while(there is an unknown distance vertex) 
     { 
      Vertex v = smallest unknown distance vertex; 
      v.known = true; 

     for each Vertex w adjacent to v 
      if(!w.known) 
      { 
      DistType cvw = cost of edge from v to w; 
      if(v.dist + cvw < w.dist) 
      { 
    // Update w 
      decrease(w.dist to v.dist + cvw); 
      w.path = v; 
      } 
      } 
      } 
    } 

им, имеющие наибольшие проблемы с линией «для каждой вершины ш рядом с V» Вот мой нерабочим код:

import java.io.BufferedReader; 
import java.io.FileReader; 
import java.io.IOException; 
import java.util.LinkedList; 
import java.util.List; 
import java.util.ListIterator; 

public class Dijkstra { 

    public static boolean isInteger(String s) { 
     return isInteger(s, 10); 
    } 

    public static boolean isInteger(String s, int radix) { 
     if (s.isEmpty()) 
      return false; 
     for (int i = 0; i < s.length(); i++) { 
      if (i == 0 && s.charAt(i) == '-') { 
       if (s.length() == 1) 
        return false; 
       else 
        continue; 
      } 
      if (Character.digit(s.charAt(i), radix) < 0) 
       return false; 
     } 
     return true; 
    } 

    public static void dijkstra(Vertex[] a, Vertex s, int lineCount) { 
     int i = 0; 
     while (i < (lineCount)) // each Vertex v 
     { 
      a[i].dist = Integer.MAX_VALUE; 
      a[i].known = false; 
      i++; 
     } 

     s.dist = 0; 
     int min = Integer.MAX_VALUE; // 

     while (!(a[0].known == true && a[1].known == true && a[2].known == true && a[3].known == true 
       && a[4].known == true && a[5].known == true && a[6].known == true && a[7].known == true 
       && a[8].known == true && a[9].known == true && a[10].known == true && a[11].known == true 
       && a[12].known == true)) { 
      System.out.println("here"); 
      for (int b = 0; b < lineCount; b++) { 

       if (a[b].dist < min && a[b].known == false) { 
        min = a[b].dist; 
       } 
      } 
      int c = 0; 
      while (c < lineCount) { 

       if (a[c].dist == min && a[c].known == false) { 
        break; 
       } 
       c++; 
      } 
      System.out.println(min); 

      a[c].known = true; 
      int adjSize = a[c].adj.size(); 

      int current = 0; 

      System.out.println(adjSize); 

      while (current < adjSize - 1) { 

       String currentAdjacent = (String) a[c].adj.get(current); 
       int p = 0; 

       while (p < lineCount) { 
        if (a[p].name.equals(currentAdjacent)) { 

         if (!a[p].known) { 
          String cvwString = (String) a[c].distance.get(current); 
          int cvw = Integer.parseInt(cvwString); 
          System.out.println(" This is cvw" + cvw); 
          System.out.println("Here2"); 

          if (a[c].dist + cvw < a[p].dist) { 
           a[p].dist = a[c].dist + cvw; 
           a[p].path = a[c]; 
          } 
         } 
        } 
        p++; 
       } 
       current++; 
      } 
     } 
    } 

    public static class Vertex { 
     public List adj; // Adjacency list 
     public List distance; 
     public boolean known; 
     public int dist; // DistType is probably int 
     public Vertex path; 
     public String name; 

     // Other fields and methods as needed 
    } 

    public static void printPath(Vertex v) { 
     if (v.path != null) { 
      printPath(v.path); 
      System.out.print(" to "); 
     } 
     System.out.print(v); 
    } 

    public static void main(String[] args) throws IOException { 

     int lineCounter = 0; 

     BufferedReader br = new BufferedReader(new FileReader("airport.txt")); 
     try { 
      StringBuilder sb = new StringBuilder(); 
      String line = br.readLine(); 

      while (line != null) { 

       sb.append(line); 
       sb.append(System.lineSeparator()); 
       line = br.readLine(); 

       lineCounter = lineCounter + 1; 
      } 

      Vertex[] arr = new Vertex[lineCounter]; 
      for (int i = 0; i < lineCounter; i++) { 
       arr[i] = new Vertex(); 
       arr[i].adj = new LinkedList<String>(); 
       arr[i].distance = new LinkedList<Integer>(); 
      } 
      ; 

      // 
      int arrayCounter = 0; 
      String everything = sb.toString(); 
      String[] lines = everything.split("\\s*\\r?\\n\\s*"); 

      for (String line1 : lines) { 
       arr[arrayCounter] = new Vertex(); 

       arr[arrayCounter].adj = new LinkedList<String>(); 
       arr[arrayCounter].distance = new LinkedList<Integer>(); 
       String[] result = line1.split("\\s+"); 

       for (int x = 0; x < result.length; x++) { 
        if (x == 0) { 
         arr[arrayCounter].name = result[0]; 
         continue; 
        } else if (isInteger(result[x])) { 
         arr[arrayCounter].distance.add(result[x]); 
         continue; 
        } else { 
         arr[arrayCounter].adj.add(result[x]); 
         continue; 
        } 
       } 

       arrayCounter++; 
      } 

      for (int i = 0; i < 12; i++) { 
       System.out.println(arr[i].name); 
      } 
      System.out.println(lineCounter); 
      dijkstra(arr, arr[3], lineCounter - 1); 
      printPath(arr[11]); 

     } finally { 
      br.close(); 
     } 
    } 
} 

Используя мой класс вершины, как Я использовал серию циклов while, пересекаю строки смежности, хранящиеся в связанном списке, сравнивая их с тем, какая вершина эквивалентна строке списка смежности. Есть ли лучший способ кодировать «для каждой вершины w, смежной с v», используя мой класс Vertex? И извиняюсь впереди за грязный код и любые другие грехи, которые я могу совершить. Благодаря!

+2

Наличие вложенных структур без отступов делает код почти нечитаемым. Пожалуйста, подумайте об исправлении форматирования первого блока кода. – ChiefTwoPencils

+0

Хорошо, теперь лучше отформатировать. – panzerschwein

+0

Почему бы просто не реализовать 'isInteger', используя' s.matches ("^ -? [0-9] +") '? Зачем вам нужно учитывать основание? (вы никогда не пропускаете ничего, кроме 10, неявно) –

ответ

1

Для решения этой проблемы вам понадобится куча объектов «Узла», хранящихся в HashMap, с ключом на Source Location.

В узле вам понадобится коллекция ссылок на соседние объекты «Узла» (или, по крайней мере, их «ключ», чтобы вы могли писать логику против него. «Узел» также должен знать, что это местоположение и расстояние до каждого «соседний» узел. Подумайте о подземных картах метро Lundon - каждая станция соединяется, по меньшей мере, с одной другой станцией. Обычно два или более. Поэтому соседние узлы на станциях метро являются ближайшими ближайшими остановками, с которых вы можете добраться с этой станции.

После того, как вы создадите эту структуру данных, вы можете использовать рекурсивную подпрограмму для итерации по каждому отдельному узлу. Затем она должна проходить через каждый дочерний узел (aka соседний узел) и отслеживать расстояния от исходного (исходного) узла до текущего узла, сохраняя эти данные в HashMap и используя текущий accu (или «хождение» по графику »). Эта информация отслеживания должна быть частью вашей сигнатуры метода при рекурсии. Вам также необходимо будет отслеживать текущий путь, который вы использовали при рекурсии, чтобы избежать круговых циклов (что в конечном итоге и по иронии судьбы вызывает StackOverflowError). Вы можете сделать это, используя HashSet. Этот набор должен отслеживать местоположение источника и текущего узла в качестве ключа ввода. Если вы видите это во время рекурсии, вы уже видели его, поэтому не продолжайте обработку.

Я не собираюсь кодировать решение для вас, потому что подозреваю, что вы задаете более конкретные вопросы по мере того, как вы прорабатываете свой ответ, понимая ответ, который, скорее всего, ответил в другом месте.

Смежные вопросы