2016-11-02 2 views
1

그래서 Othello 게임을위한 Monte Carlo 검색 트리를 구현하려고합니다. 나는 하나의 합법적 인 이동에서 'y'에서 'x'로 이동할 수있는 경우 'x'가 'y'의 하위 노드 인 루트 노드와 자식 노드가 있습니다.새로운 개체를 만들기 때문에 C++에서 메모리가 부족합니다.

각 노드마다 각 보드의 값과 같은 보드 정보를 모두 담는 '보드'객체를 저장합니다. 내가 가지고있는 첫 번째 문제는 자식 노드의 보드 객체를 변경하면 부모 노드의 값도 변경된다는 것입니다. 모든 하위 노드에 대해 '새'보드 객체를 만들어이 문제를 해결했지만, 메모리가 부족한 시점까지 시뮬레이션을 몇 천 번 실행했을 때 과도한 메모리가 사용되었습니다.

부모의 보드 정보를 변경하지 않고 자식 노드에서 보드 정보를 변경하는 방법이 있거나 각 노드에 보드 정보를 저장하는 더 좋은 방법이있는 경우 방황합니다. 모든 노드에 대해 새 Board 객체를 만듭니다.

아래에서 의견을 명확히 할 필요가있는 경우, 읽어 주셔서 감사합니다.

편집 :

 for (int x = 0; x < numberOfChildren; x += 1) { 

     // Resets *currentBoard to the same state as the node being expanded 
     Board *currentBoard = nodeToExpand->getCurrentBoard(); 

     // Retrives the board value information 
     int** temporaryBoardValues = currentBoard->getBoardValues(); 

     // Makes a new board object with the previous parameters 
     Board *temporaryBoard = new Board(blockSize, boardSize, offset); 

     // Sets the new board values to the same as the old ones 
     temporaryBoard->setBoardValues(temporaryBoardValues); 

     // Creates a clone of that board state 
     // Board *temporaryBoard = cloneBoard(*currentBoard); 

     // Creates a node with the cloned board state, setting the parent to be the node being expanded. 
     // Assigns it one of the available moves 
     // Produces the array of child nodes 
     myChildren[x] = new Node(nodeToExpand, temporaryBoard, availableMoves[x], currentPlayer); 

     //delete temporaryBoard; 
    } 

작은 코드. 그것은 내가 모든 메모리를 다 사용하는 새로운 Board 객체를 만드는 부분입니다.

+5

작은 코드 샘플을 게시 할 수 있습니까? –

+0

일종의 실행 취소 작업을 위해이 정보를 저장하고 있습니까? – NathanOliver

+3

'n'의 깊이로 분기 트리를 검색하려면 : 현재 최상의 이동 및 'n'노드 만 메모리 (1)에 유지하면됩니다.전체 트리는 현재의 검색/평가를 1 브랜치에서 깊이'n '까지만 유지할 필요가 없습니다. 스택에서 쉽게 유지할 수 있습니다. 힙에 많은 보드를 보유하고 있다면 아마도 잘못했을 것입니다. (알파 베타 알고리즘 참조). –

답변

0

몬테 카를로 트리 검색 (MCTS)의 일반적인 구현은 명시 적으로 메모리 부족을 방지하기 위해 어떤 트릭도 사용하지 않습니다. 이론적으로 시뮬레이션을 계속한다면 메모리가 부족할 것입니다.하지만 OP에서 언급 한 것보다 일반적으로 수천 가지 이상의 시뮬레이션이 필요합니다.

이제 MCTS의 대부분의 구현은 시뮬레이션 당 하나의 노드로 트리를 확장합니다. 귀하가 게시 한 코드는 b이 시뮬레이션 당 트리에 노드를 추가하는 것처럼 보입니다. 여기서 b은 분기 요인 (자식 수)입니다. 그래서 그것은 당신이 변화를 들여다 볼 수있는 것입니다.

또한 Board 클래스에 저장 한 것을 살펴보고 실제로 필요한 것만 가지고 있는지 확인할 수 있습니다. 게임 상태의 데이터 만 있으면됩니다. 예를 들어, GUI에만 필요한 데이터가 없는지 확인하십시오. (몇 년 전에 실수 한 것입니다.)

이 두 가지 사항을 살펴본 후에도 여전히 메모리에 문제가 있으면 jaggedSpire의 의견을 고려해 볼 수 있습니다. 보드 상태 대신 이동을 저장하고 시뮬레이션에서 노드를 실행할 때 보드 상태를 다시 작성할 수 있습니다. 이렇게하면 메모리 소비가 크게 줄어들지 만 시뮬레이션 당 처리 시간이 늘어납니다. 1 턴에 제한된 양의 사고 시간 만 있다면 약한 플레이어가 될 수 있습니다.

마지막으로, 당신은 당신이 게시 코드에서 볼 수있는 new 운영과 수동 메모리 관리를하고있는 고려, 항상 당신이 어딘가에 일치하는 delete에 대해 잊고 메모리 누수가 될 가능성이있다. 위의 사항을 살펴본 후에도 수천 번의 시뮬레이션으로 메모리 문제가 계속 발생하면 이것이 가장 큰 원인 일 것입니다. 왜냐하면 MCTS가 몇 천 개가 넘는 시뮬레이션 수에 도달 할 때까지 메모리 문제가 발생하지 않아야하기 때문입니다.

+0

여러 보드 객체를 만드는 메모리 누수 문제를 해결할 수 있었고 지금 언급 한대로 jaggedSpire가 액션을 저장하는 것에 대해 언급 한 작업을 수행합니다. MCTS에 대한 나의 일반적인 접근 방식은 루트에서 시작하여 확장 된 경우 상위 신뢰도에 기초하여 올바른 아이를 선택하는 것입니다. 확장되지 않았다면 확장하고 게임이 끝날 때까지 임의의 시뮬레이션을 재생하십시오. –

+0

하지만 컴퓨터에서 이동할 때마다 * NEW * 노드가 많이 생성되지만 각 노드가 이동할 때마다 메모리에 저장되므로 게임이 진행되면 메모리가 이전 노드 정보로 인해 막히게됩니다. , 그냥 그 메모리를 해제하는 방법을 잘 모르겠다 –

+0

@MatthewFennell '실제'게임에서 실제 이동을 한 후에 검색 트리를 정리하지 않기 때문에 메모리 사용량이 증가한다는 의미입니까? 그렇다면 실제 게임에서 실제 이동을 한 후에 전체 검색 트리를 삭제해야합니다. 또는, 한 이동에 해당하는 깊이 2의 노드와 상대 노드가 한 이동을 새 루트 노드로 설정할 수 있습니다. 그런 다음 검색 트리를 재사용 할 때 해당 새 루트 위의 노드를 삭제하고 해당 노드 아래의 도달 할 수없는 하위 노드 인 –