fuzzle

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;
	}
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值