1

우리 선생님이 프로그램을 테스트해야하는 입력 파일이 있습니다. 작업은 파일에서 읽고, 유향 그래프를 만들고 출력을 인쇄하는 것입니다. 그러나주기가 있다면 우리는 프로그램을 종료해야합니다.토폴로지 정렬 및 순환

house1과 house2라는 파일이 있습니다. house1 파일에는 사이클이 없지만 house2에는 있습니다. 그러나 왜 내 프로그램이 그주기를 찾지 못하는지 알 수 없습니다. 여기 나는 모든 코드를 가지고 있고, 어떤 도움 내가 preciated됩니다 :)

import java.util.*; 
import java.io.*; 
import java.lang.*; 

class Input { 

    public static void main(String[] args) { 

    if (args.length == 0) { 
     System.out.println("enter a filename!"); 
     System.exit(1); 
    } else if (args.length == 1) { 
     String fil = args[0]+".txt"; 
     LesFraFil(fil); 
     // skrivUt(); 
     topSort(); 
    } else { 
     System.out.println("too many parameters, try again..."); 
    } 
    } 

    static int antTask; 
    static Task[] ids; 
    static int tTid; 
    static void LesFraFil(String fil) { 

    int i = 0; 
    int j; 
    try { 

     String lest; 

     Scanner in = new Scanner(new FileReader(fil)); 
     Edge til; 

     int counter = 0; 
     antTask = in.nextInt(); 
     ids = new Task[antTask]; 
     System.out.println(antTask); 
     while (in.hasNextLine()) { 

     lest = in.nextLine(); 
     // hvis tom linje, så hopper den over 
     if(lest.trim().length() == 0) continue; 

     String split[] = lest.split("\\s+"); 
     int id = Integer.parseInt(split[0]); 
     String act = split[1]; 
     int tid = Integer.parseInt(split[2]); 
     int staff = Integer.parseInt(split[3]); 
     int depA = Integer.parseInt(split[4]); 
     tTid += tid; 
     ids[i] = new Task(id, act, tid, staff); 
     j = 4; 

     /* 
     * Lesingen av inputen skal avbrytes når den leser 0. 
     * j er den som holder på hvor langt vi er i split arrayet 
     * når den møter på 0 
     */ 
     while(split[j].compareTo("0") != 0) { 
      int tmp = Integer.parseInt(split[j])-1; 

      // System.out.println(tmp+1 + " Aktivitetens navn : " + act); //+ " tiden aktiviteten tar tid: " + tid + " avhengihet: " + split[j]); 

      j++; 

      if (ids[tmp] == null) { 
      ids[tmp] = new Task(id, act, tid, staff); 
      ids[tmp].visited = true; 
      } 
      ids[i].cntPredecessors++; 
      if(ids[tmp].outEdge == null) { 
      ids[tmp].outEdge = new Edge(ids[tmp], ids[i]); 
      } else { 
      til = ids[tmp].outEdge; 

      while(til.neste != null) { 
       til = til.neste; 
      } 
      // til.neste = new Edge(ids[tmp], ids[i]); 
      } 
     } 
     counter++; 
     i++; 
     } 

     if (antTask == counter) { 
     System.out.println("Lesinga gikk som planlagt av fil: " + fil); 
     System.out.println("Total arbeidstid: " + tTid);// + antTask + " == " + counter); 
     } else { 
     System.out.println("Noe gikk galt avslutter!"); 
     System.out.println(antTask + " || " + counter); 
     System.exit(2); 
     } 
     in.close(); 
    } catch (Exception e) { 
     System.err.println("Dette gikk galt med lesinga: " + e.getMessage()); 
    } 
    } 

    static void topSort() { 
    LinkedList<Task> list = new LinkedList<Task>(); 
    ArrayList<Task> array = new ArrayList<Task>(); 

    Task temp; 
    int totalTime = 0; 
    int counter = 0; 

    for(Task t : ids) { 
     if (t.cntPredecessors == 0) { 
     list.add(t); 

     } 
    } 
    while (!list.isEmpty()) { 
     temp = list.pop(); 
     counter++; 
     array.add(temp); 
     System.out.println("Time " + totalTime + "\t Started task " + temp.id + "\t Staff: " + temp.staff + ", Task done " + temp.id); 
     totalTime += temp.time; 

     for (Task t : ids) { 
     if (--t.cntPredecessors == 0) 
     list.add(t); 
     } 
    } 


    if(counter < antTask) { // checking for loop 
     System.out.println(counter + " != " + antTask); 
     System.out.println("En løkke er funnet i grafen. Avslutter..."); 
     System.exit(0); 
    } 
    System.out.println("Topological sort: " + Arrays.toString(array.toArray()));// den sorterte "arraylisten" 
    System.out.println("Total tid brukt er: " + totalTime); 
    } 

} 

class Task { 

    int id, time, staff; 
    int depA, depB; 
    String name; 
    int eStart, lStart; 
    Edge outEdge; 
    int cntPredecessors; 
    boolean visited; 

    Task(int id, String name, int time, int staff) { 
    this.id = id; 
    this.name = name; 
    this.time = time; 
    this.staff = staff; 
    visited = false; 
    } 

    public String getName() { 
    return name; 
    } 
    public String toString() { 
    return name; 
    } 
} 

class Edge { 

    Task fra, til; 
    Task id, name, time, staff; 
    Edge neste; 
    // Task fra, til; 

    Edge(Task fra, Task til) { //, Task fra, Task til) {//, Task name, Task time, Task staff) { 
    this.fra = fra; 
    this.til = til; 

// this.id = id; 
    // this.fra = fra; 
    // this.til = til; 
    /* this.name = name; 
    this.time = time; 
    this.staff = staff;*/ 
    } 

    public Task getTil() { 
    return til; 
    } 
} 

답변

1

내가 여기에 간단한 알고리즘의 일종을 쓸 것이다는 무슨 일을하는 것은 위상 종류

입니다보고해야하는 위치를 말하는

중요한 것은 위상 종류의

은 당신이 할 일은 각 노드에 대한 추가 속성의 어떤 종류를 만드는 것입니다 DFS 알고리즘 O (V + E)를 사용하고 있다는 점이다 (의이 String color를 호출하고 흰색에 초기 값입니다 설정할 수 있습니다.

노드를 반복하면서 색상을 회색으로 설정하고 DFS를 계속하고, 끝나면 검정색으로 설정합니다.

요점은 - 당신이 color == gray와 노드를 방문하거나 color == black 당신이 Topological sort chapterIntroduction to Algorithms

에서주기

내가 읽어 보시기 바랍니다 발견 그리고 이제 코드를 보자 경우! 이런 식으로 말에 대한

 while (!list.isEmpty()) { 
      temp = list.pop(); 
      counter++; 
      array.add(temp); 
      System.out.println("Time " + totalTime + "\t Started task " + temp.id + "\t Staff: " + temp.staff + ", Task done " + temp.id); 
      totalTime += temp.time; 

      for (Task t : ids) { 
       if (--t.cntPredecessors == 0) { 
        list.add(t); 
       } 
      } 
     } 

아니라 죄송하지만, 코드 등, 영어 문서없이, 좀 지저분하지만 난 당신이 누락 생각 :

당신은 입력 파일과 중요한 부분에서 무언가를 읽어

는 여기 당신의 노드를 채색하는 부분은 당신이주기를 찾을 수없는 이유 일 수 있습니다. 그리고 당신이 결코 끝나지 않을 것이라고 생각합니다. 왜냐하면 당신이 당신의 노드를 "색칠"하지 못하기 때문에 아무도 당신이 이미 그들을 방문했다는 것을 아무도 모릅니다.

btw 내 "color"속성이 코드에서 방문되었습니다 (부울을 사용할 수는 있지만 책에서와 같이 회색/검정색으로 색칠 할 수는 없습니다). 나는/난 경우

// 죄송합니다) 노드를 방문

하면 초기화하는 동안 true로 설정 한 것 같아요 (당신이 false로 설정하고 이미 처리 한 경우 true로 설정해야합니다) 여기에 게시 잘못이지만 1A.M입니다. 여기에, 나는 이것이 문제 일 수 있다고 생각한다.

// 만약 당신이 그래프를 그린다면, 사이클을 감지하면 O (V) 시간에 cycle detection algorithm을 얻는다.