2009-05-11 4 views
10

큰 나무가 재귀를 사용하여 통과하는 보드 게임 알고리즘에서 작업하고 있지만 예상대로 작동하지 않습니다. 이 문제를 어떻게 처리하며 이러한 상황에서 어떤 경험이 있습니까?깊은 재귀를 디버깅하는 데 도움이되는 유용한 팁이 있습니까?

상황을 악화 시키려면 알파 베타 제거 기능을 사용합니다. 즉, 트리의 전체 부분을 방문하지 않고 특정 조건이 충족 될 때 재귀를 중지하는 것입니다. 결정 깊이있는 동안 검색 깊이에 따라 검색 결과가 달라질 수 있고 검색 깊이가 낮을 때 예상대로 작동 할 수 있기 때문에 검색 깊이를 더 낮은 숫자로 변경할 수 없습니다.

이제 "내 코드에서 문제가있는 곳은 어디입니까?"라고 묻지 않을 것입니다. 하지만 난 일반적인 팁, 도구, 시각화, 아무것도 이런 식으로 코드를 디버깅을 찾고 있습니다. 개인적으로 C#으로 개발 중이지만 모든 도구를 환영합니다. 비록 이것이 명령형 언어에 가장 잘 적용될 수 있다고 생각합니다.

답변

22

로깅 . 코드에 광범위하게 로그인하십시오. 내 경험상 로깅은 이러한 유형의 문제에 대한 해결책입니다. 코드에서 수행하는 작업을 파악하기 어려울 때 코드를 광범위하게 로깅하는 것은 매우 좋은 솔루션입니다. 내부 상태를 코드 내에서 출력 할 수 있으므로, 정말 완벽한 해결책은 아니지만 지금까지 내가 본 것만 큼 다른 방법을 사용하는 것보다 효과적입니다.

3

정상적으로 잘 정의 된 결과가있는 하나 이상의 사전 정의 된 데이터 세트로 이러한 알고리즘을 단위 테스트합니다. 일반적으로 복잡성이 증가하는 순서로 여러 가지 테스트를 수행합니다. 디버깅을 주장하는 경우

는, 주어진 값을 확인 계산서를 가진 코드를 의사에게 때때로 유용합니다, 그래서 당신은 코드에서 그 시간에 중단 점과 장소를 첨부 할 수 있습니다

if (depth = X && item.id = 32) { 
    // Breakpoint here 
    } 
+1

글쎄요,이 시점에서 단위 테스트는 제가 이미 알고있는 것은 작동하지 않는다고 말할 것입니다 : p – JulianR

+0

더 제어 된 방식으로 문제를 해결할 수있게 해주고, 제안. – krosenvold

+0

그리고 단위 테스트를 사용할 때 훨씬 간단한 문제 공간, 아마도 깊이가 2 인 문제를 재현 할 수 있습니다. 로깅이이 스레드의 기본 솔루션 인 것처럼 보이지만 아주 좋은 해결책은 아닙니다. 로깅은 미래에 유용한 정보를 많이 보유하지 않습니다. 테스트 커버리지가 좋으면 로그 범위가 대폭 줄어 듭니다. – krosenvold

4

내가 과거에 한 가지 한 가지는 재귀 깊이를 반영하도록 로그를 형식화하는 것입니다. 따라서 모든 재귀 또는 다른 구분 기호에 대해 새로운 들여 쓰기를 할 수 있습니다. 그런 다음 각 반복에 대해 알아야 할 모든 것을 기록하는 디버그 dll을 만듭니다. 둘 사이에서, 당신은 실행 경로를 읽을 수 있어야하고 잘하면 무엇이 잘못되었는지 말할 수 있어야합니다.

1

나는 이것이 얼마나 고통 스러운지 알고 있습니다. 제 직업에서는 기본적으로 블랙 박스처럼 작동하는 타사 응용 프로그램을 사용하고 있습니다. 따라서 문제를 해결할 수 있도록 몇 가지 흥미로운 디버깅 기술을 고안해야합니다.

대학에서 컴파일러 이론 과정을 수강 할 때 우리는 나무를 시각화하기 위해 소프트웨어 라이브러리를 사용했습니다. 나무가 어떻게 생겼는지를 알 수 있으므로 도움이 될 것입니다. 사실 TreeView 컨트롤에 트리의 내용을 덤프하는 WinForms/WPF 응용 프로그램을 직접 만들 수 있습니다. 지저분하지만 작업이 완료됩니다.

어떤 종류의 디버그 출력도 고려할 수 있습니다. 나는 당신이 당신의 나무가 크다고 언급 한 것을 알고 있지만, 실행 중에 디버깅이나 진술을 디버그하여 시각화하는데 문제가 있다면 손을 빌려 줄 것입니다.

Visual Studio를 사용하여 지능적인 디버깅을하면 이상하게 작동 할 수 있습니다. 여러 번 휴식을 통해 상태가 어떻게 변하는 지 알기는 어려울 지 모르지만 Visual Studio 2010이 실제로이 작업을 도와야합니다.

불행히도 추가 정보없이 디버그하는 것이 특히 쉽지는 않습니다. 그것이 깨지기 시작한 첫 깊이를 확인 했습니까? 높은 검색 심도로 계속 깨지나요? 업무 사례를 평가하고 그것이 어떻게 다른지 판단하려고 할 수 있습니다.

0

순회가 예상대로 작동하지 않는다고 말했기 때문에 상황이 잘못 될 수 있다는 것을 알고 있다고 생각합니다. 그런 다음 코드를 검사하여 기본적인 것을 간과하지 않았 음을 확인하십시오.

그런 다음 간단한 단위 테스트를 설정하는 것이 좋습니다. 통과하면 실패 할 때까지 계속 테스트를 추가하십시오. 실패 할 경우 통과하거나 간단한만큼 테스트를 줄이십시오. 그러면 문제를 정확히 찾아 낼 수 있습니다.

디버깅도 원하는 경우 조건부 중단 점을 사용하는 것이 좋습니다. Visual Studio에서는 중단 점을 수정할 수 있으므로 중단 점을 트리거해야하는 조건을 설정할 수 있습니다. 그것은 당신이 볼 필요가 반복의 수를 줄일 수 있습니다.

0

기능을 사용하여 시작하겠습니다. 각각의 재귀 호출 로그에는 문제를 식별하는 데 도움이되는 데이터 구조 및 기타 정보가 기록됩니다.

소스 코드와 함께 덤프를 출력 한 다음 컴퓨터에서 빠져 나와 커피 잔 위에 멋진 종이 기반 디버깅 세션을 갖습니다.

6

아마도 매개 변수에 대한 명시 적 스택을 사용하여 반복으로 반복을 변환 할 수 있습니다. 값을 직접 기록하고, 스택에 액세스 할 수 있으며, 각 자체 평가에서 데이터/변수를 전달하거나 범위를 벗어날 수 없기 때문에 이러한 방식으로 테스트가 더 쉽습니다.

+2

이것은 건강 함 보존 솔루션입니다. 또한 재귀 적 솔루션의 고유 한계를 제거합니다 (매개 변수 큐를 보유하는 동적 구조를 가정) –

2

테트리스 게임을하기 위해 AI 알고리즘을 개발할 때도 비슷한 문제가있었습니다. 많은 것들을 시도한 후 내 로그를 읽고 디버깅을하고, 기능을 단계적으로 실행하는 데 많은 시간을 할애 해 빠른 시각화 프로그램을 코딩하고 고정 코드로 코드를 테스트했습니다.

시간이 문제가 아니며 실제로 무슨 일이 벌어지고 있는지 이해하고 싶다면 고정 보드 상태를 얻고 디버그 로그/출력과 일종의 혼합을 사용하여 프로그램에서 수행중인 작업을 확인하십시오 각 단계에 대한 정보를 보여주는 도구.

이 문제를 일으키는 보드 상태를 찾았 으면 시작 지점의 기능을 정확히 지정하면 문제를 해결할 수 있습니다.

관련 문제