거대한 이진 트리 (각 노드에 통과 및 실패 노드가 있음)가 있으며이 트리를 통과하여 DFS를 사용하여 가능한 모든 경로를 얻으려고합니다. 트리가 크기 때문에 DFS가 단일 스레드를 사용하는 데 걸리는 시간은 매우 오래 걸립니다. 그래서이 문제를 해결하기 위해 병렬 DFS를 고려하고 있습니다. 기본 아이디어는 다음과 같습니다. 이 노드 안타깊이 우선 병렬 검색
- 단일 스레드로 시작하고 정상적인 DFS를 할 수는 시작 노드로 실패 노드로 시작하는 새로운 스레드를 생성하고 전달할 호출 노드는 지금까지
- 여행 초기 스레드는 패스 패스에서 계속됩니다.
- 결국 모든 스레드는 이동 한 노드 목록을 반환합니다. 나는 여러개의 Thread를 가지고 전체 Tree를 가로 질렀을 것입니다. 소위 부모 스레드가 자식 스레드로 여행 한 노드의 정보를 전달하기 때문에, 각 스레드는 그래서이를 구현하기 위해 자급 자족
라고,이
-
을하고 생각하고
- newCachedThreadPool을 사용하십시오.
- 메인에서는 풀을 만들고 호출 가능 DFS 클래스에 대한 초기 호출을 시작합니다.
public class DFS implements Callable<List<List<TestNode>>> { private Node node = null; private List<TestNode> testNodeList = new ArrayList<TestNode>(); private List<List<TestNode>> returnNodeList = new ArrayList<List<TestNode>>(); private ExecutorService service = null; public DFS(ExecutorService service, Node node, List<TestNode> initList) { this.node = node; this.service = service; if (initList != null && initList.size() > 0) { testNodeList.addAll(initList); } } public List<List<TestNode>> call() throws Exception { performDFS(this.node); returnNodeList.add(testNodeList); return returnNodeList; } private void performDFS(Node node) { TestNode testNode = new TestNode(); testNode.setName(node.getName()); Thread t = Thread.currentThread(); testNode.setThreadName(t.getName()); testNodeList.add(testNode); if (node.getPass() != null) { performDFS(node.getPass()); } if (node.getFail() != null) { Callable<List<List<TestNode>>> task = new DFS(service, node.getFail(), this.testNodeList); Future<List<List<TestNode>>> returnList = service.submit(task); try { returnNodeList.addAll(returnList.get()); } catch (InterruptedException e) { } catch (ExecutionException e) { } } }
}
DFS의
코드 구현 전술 한 바와 같이, 새로 만들어지는 스레드는 규칙을 사용하여 새 스레드를 생성 할 수 있도록 DFS 클래스의 생성자는 또한 ExecutorService에 걸릴 것입니다
메인 클래스
public static void main(String[] args) {
Main main = new Main();
Node root = main.createTree();
ExecutorService service = Executors.newCachedThreadPool();
Callable<List<List<TestNode>>> task = new DFS(service, root, null);
Future<List<List<TestNode>>> returnList = null;
try {
returnList = service.submit(task);
}
catch (Exception e) {
}
try {
main.displayTestNode(returnList.get());
service.shutdown();
}
catch (InterruptedException e) {
}
catch (ExecutionException e) {
}
}
,개 질문
- 이 메이크업 감각을합니까? 이것은 가능한가? 내가 다시 같은 스레드를 볼 수 있습니다 다시
트리가 완벽하게 균형 잡혀 있지 않거나 트리를 트래버스하기 전에 트리에 대해 많이 알지 못하는 경우 트래버스 수준에서 DFS를 병렬 처리하여 속도를 향상시킬 수 있다고 보장 할 수 없습니다. 극단적 인 예는 트리가 링크 된 목록이되도록 퇴화 된 경우입니다. 각 노드를 처리하는 데 시간이 오래 걸리면 각 노드 처리 작업을 병렬 처리하는 것이 좋습니다. –
@ MerlynMorgan-Graham : 밸런싱 인수는 순진한 병렬 알고리즘에만 해당됩니다. 각 노드의 탐색이 별도의 작업으로 간주 될 때 불균형 한 트리에서도 작동합니다. –
@larsmans : 내가 그에게 제안한 것은 무엇입니까. 그러나 각 작업에 대한 처리가 없다면 작업을 생성하는 오버 헤드는 아마도 유익보다 많은 해를 끼칠 것입니다. 그가 어떻게 든 나무의 큰 덩어리를 일괄 처리하지 않는다면 말이죠. 문제 : 나무의 덩어리가 얼마나 큰 덩어리를 가로지 않고 있는지 어떻게 알 수 있습니까? –