package com.ronnie.concurrent.part8;
import java.util.Set;
public interface Puzzle<P,M> {
/*
* 初始化位置信息
*/
P initialPositon();
/*
* 判断是否得到正确的答案
*/
boolean isGoal(P position);
/*
* 对于位置position,可能的所有移动.
*/
Set<M> legalMoves(P position);
/*
* 从position位置进行move移动,得到一个新的位置.
*/
P move(P position,M move);
}
package com.ronnie.concurrent.part8;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
/**
* 并行解题..
* 2016-3-12
* @author sima
*
* @param <P>
* @param <M>
*/
public class ConcurrentPuzzleSolver<P,M> {
/**
* 移动的信息..
*/
static class Node<P,M> {
final P position;
//如果move为null,表示不可以再移动.
final M move;
//上一个节点根据move动作得到节点信息.
final Node<P,M> prev;
Node(P pos,M move,Node<P,M> node){
this.position = pos;
this.move = move;
this.prev = node;
}
/*
* 该节点走过的所有路程..
*/
List<M> asMoveList(){
List<M> solution = new LinkedList<>();
//从一个节点出发.根据相关的规则,得到所有的移动信息.
for(Node<P, M> n = this;n.move != null ; n = n.prev){
solution.add(0,n.move);
}
return solution;
}
}
private final Puzzle<P, M> puzzle;
private final ExecutorService executor;
private final ConcurrentMap<P, Boolean> seen = new ConcurrentHashMap<P, Boolean>();
final ValueLatch<Node<P, M>> solution = new ValueLatch<Node<P,M>>();
public ConcurrentPuzzleSolver(Puzzle<P, M> p,ExecutorService exec) {
this.puzzle = p;
this.executor = exec;
}
public List<M> solve() throws InterruptedException{
try{
P p = puzzle.initialPositon();
executor.execute(newTask(p, null, null));
Node<P, M> solnNode = solution.getValue();
return (solnNode == null) ? null : solnNode.asMoveList();
}finally{
executor.shutdown();
}
}
protected Runnable newTask(P p,M m,Node<P,M> node){
return new SolveTask(p, m, node);
}
class SolveTask extends Node<P, M> implements Runnable{
SolveTask(P pos, M move, Node<P, M> node) {
super(pos, move, node);
}
@Override
public void run() {
// 判断是否已经找到满足条件的节点或该节点是否已经被遍历过.
if(solution.isSet() || seen.putIfAbsent(position, true) != null )
return;
if(puzzle.isGoal(position))
solution.setValue(this);
else
for(M m : puzzle.legalMoves(position))
executor.execute(newTask(puzzle.move(position, m),m,this));
}
}
}
class ValueLatch<T>{
private T value = null;
private final CountDownLatch done = new CountDownLatch(1);
public boolean isSet(){
return done.getCount() == 0;
}
public synchronized void setValue(T newValue){
if(!isSet()){
this.value = newValue;
done.countDown();
}
}
public T getValue() throws InterruptedException{
done.await();
synchronized (this) {
return value;
}
}
}
<pre name="code" class="java">package com.ronnie.concurrent.part8;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
/**
* 串行解题...
* 2016-3-11
* @author sima
* @param <P>
* @param <M>
*/
public class SequentialPuzzleSolve<P,M>{
/**
* 移动的信息..
*/
static class Node<P,M> {
final P position;
//如果move为null,表示不可以再移动.
final M move;
//上一个节点根据move动作得到节点信息.
final Node<P,M> prev;
Node(P pos,M move,Node<P,M> node){
this.position = pos;
this.move = move;
this.prev = node;
}
/*
* 一个节点的所有可移动的步骤.
*/
List<M> asMoveList(){
List<M> solution = new LinkedList<>();
//从一个节点出发.根据相关的规则,得到所有的移动信息.
for(Node<P, M> n = this;n.move != null ; n = n.prev){
solution.add(0,n.move);
}
return solution;
}
}
private final Puzzle<P, M> puzzle;
//已经遍历过的节点..
private final Set<P> seen = new HashSet<>();
public SequentialPuzzleSolve(Puzzle<P, M> p) {
this.puzzle = p;
}
public List<M> solve(){
P pos = puzzle.initialPositon();
return search(new Node<P,M>(pos, null, null));
}
private List<M> search(Node<P, M> node) {
if(!seen.contains(node.position)){
seen.add(node.position);
if(puzzle.isGoal(node.position))
return node.asMoveList();
for(M move : puzzle.legalMoves(node.position)){
P pos = puzzle.move(node.position, move);
// 得到一个新的节点信息.再进行递归遍历即可.
Node<P,M> child = new Node<P, M>(pos, move, node);
List<M> result = search(child);
if(result != null)
return result;
}
}
return null;
}
}