2012-03-29 3 views
0

내 코드는 내가 더 깊이의 나무를 호출 할 때 무한 재귀을 할 것으로 보인다. 나는 어쨌든 여기, 내가 나무 자체를 조작해야하기 때문에 어떻게 좀 어려운 먹으 렴 아니라 재귀없이 그것을 할 시도하고, m 코드입니다. 감사합니다유전 프로그래밍에 유래 오류

문제는 리프 노드에 도달하고,이 스택

는 내가 수 있도록 내 전체 코드를 게시 할 오히려 것 넘칠 때까지 잎 노드와 노드의 부모를 인쇄 앞뒤로 이동의 printPostOrder의 방법입니다 너는 내가하려고하는 것을 얻을 수있다.

노드 삽입 기회 그래프 순환되어 있는지가이

import java.util.*; 

public class IPG { 

    class Node { 

     private int arity; 
     private String label; 
     private int value; 
     private Node[] children; 
     protected int visit = 0; 
     protected boolean isVisited = false; 

     public Node(int arity, String label) { 
      this.arity = arity; 
      this.label = label; 
      this.children = new Node[3]; 
     } 

     public Node(Node another) { 
      this.label = another.label; 
      this.arity = another.arity; 
     } 

     @Override 
     public String toString() { 
      return label; 
     } 

     String getLabel() { 
      return label; 
     } 

     void insertChild(int pos, Node n) { 
      if (pos < arity) { 
       children[pos] = n; 
      } 
     } 

     Node getChildAt(int i) { 
      return children[i]; 
     } 

     void setValue(int value) { 
      this.value = value; 
     } 

     int getArity() { 
      return arity; 
     } 

     void replace(Node another) { 
      this.arity = another.arity; 
      this.children = another.children; 
      this.label = another.label; 
     } 

    } 

    private Node[] functions = { new Node(2, "AND"), new Node(2, "OR"), 
      new Node(1, "NOT"), new Node(3, "IF") }; 

    private Node[] terminals = { new Node(0, "A0"), new Node(0, "D1"), 
      new Node(0, "D0"), new Node(0, "A1"), new Node(0, "D2"), 
      new Node(0, "D3"), new Node(0, "A2"), new Node(0, "D4"), 
      new Node(0, "D5"), new Node(0, "D6"), new Node(0, "D7") }; 

    private Random random = new Random(); 

    private int multiplexerType = 3; 

    public Node getTerminal() { 
     return terminals[random.nextInt(multiplexerType)]; 
    } 

    public Node getFunction() { 

     return functions[random.nextInt(3)]; 
    } 

    public Node getAnyNode() { 
     return random.nextInt(2) == 1 ? getFunction() : getTerminal(); 
    } 

    public Node generateGrow(int depth) { 
     Node root; 

     if (depth > 1) 
      root = getAnyNode(); 

     else 
      root = getTerminal(); 

     for (int i = 0; i < root.getArity(); i++) 
      root.insertChild(i, generateGrow(depth - 1)); 

     return root; 
    } 

    public Node generateFull(int depth) { 
     Node root; 

     if (depth > 1) 
      root = getFunction(); 

     else 
      root = getTerminal(); 

     for (int i = 0; i < root.getArity(); i++) 
      root.insertChild(i, generateFull(depth - 1)); 

     return root; 
    } 

    public void printPostOrder() { 
     Node root = generateFull(3); 
     printPostOrder(root); 
    } 

    private void printPostOrder(Node n) { 
     if (n == null) { 
      return; 
     } else { 
      System.out.println(n + " "); 

      printPostOrder(n.children[0]); 
      printPostOrder(n.children[1]); 
      printPostOrder(n.children[2]); 
     } 
    } 

    public static void main(String[] args) { 
     new IPG().printPostOrder(); 
    } 
} 
+3

문제는 무엇인가? 오류가 무엇입니까? 어디에? – talnicolas

+2

마음을 짧게 잘라서 관련 부분을 보여주는 마음. http://sscce.org – Nishant

+0

팝이를 prettyify하십시오! 당신이 당신의 디버거에서 간단한 예제를 단계별로 때 – Coffee

답변

0

functions 배열을 생성 할 때 각 유형의 노드를 하나만 만들고 그 다음에 getFunction()을 다시 사용하면 문제가 발생합니다. 무슨 일 예를 들어, 당신은 "AND"노드를 삽입한다는 것입니다 그들이 실제로 같은 객체이기 때문에 자식은 사이클이 생성되고, 또한 "AND"노드입니다.

그것은 쉽게 수정, 당신은 너무 같은 예를 들어, getFunction()의 각 호출에 새 노드를 만들 수 있는지 확인해야합니다

private String [] functionNames = {"AND", "OR", "NOT", "IF"}; 
private int [] functionArities = {2,2,1,3}; 

public Node getFunction() { 
    int index = random.nextInt(3); // If you want to use "IF" nodes too this 
            // needs to be nextInt(4) 
    return new Node(functionArities[index],functionNodes[index]); 
} 
+0

고마워요 많은 브래지어 수정을 위해 – Pops

1

같다. 미리 만들어진 노드를 사용하고 무작위로 선택하기 만하면됩니다. 노드가 깊어 질수록 확률은 높아 지므로 한 노드가 한 번 이상 삽입됩니다. 그리고 그 경우주기가 있고 JVM은 SSO로 불평합니다.

문제의 루트는 functions 배열입니다 (터미널 노드에 자식이 없기 때문에 terminals은 정상입니다).

그 배열을 제거하고, 각 노드에 대한 새로운 함수 객체를 생성한다.

+1

(앞에서 언급 한 코드 부분은 전체 클래스가 표시된 이전 편집본입니다.이 경우 코드 줄이기는 나쁜 조언이었습니다) –

+0

감사합니다. 문제는 함수 터미널에 ..... 덕분에 많은이 날 괴롭혔다 – Pops