TA的每日心情 | 开心 2021-3-12 23:18 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
两个小孩去打油,一人带了一个一斤的空瓶,另一个带了一个七两、一个三两的空瓶。原计划各打一斤油,可是由于所带的钱不够,只好两人合打了一斤油,在回家的路上,二人想平分这一斤油,可是又没有其它工具。试仅用三个瓶子(一斤、七两、三两)精确地分出两个半斤油来。
- import java.util.*;
- class Bottle { //瓶子类
- int volume = 0; //总容量
- int oil = 0; //瓶中油的量
- public Bottle(int v, int o) {
- if( o <= v) {
- volume = v;
- oil = o;
- }
- else
- System.out.println("Bottle init error oil > volume");
- }
- public boolean isEmpty() { //瓶子是否空
- if(oil == 0)
- return true;
- else
- return false;
- }
- public boolean isFull() { //瓶子是否满
- if(oil == volume)
- return true;
- else
- return false;
- }
- public int needForFull() { //还需多少才能满
- return volume - oil;
- }
- public String toString() {
- return "Bottle_v="+ volume+" Oil="+oil;
- }
- }
- class StateNode { //状态节点类
- Bottle bottle1;
- Bottle bottle2;
- Bottle bottle3;
- StateNode parentState; //父节点
- public StateNode(int b1, int b2, int b3, StateNode parent) {
- bottle1 = new Bottle(10, b1); //容量为10的瓶子
- bottle2 = new Bottle(7, b2); //容量为7的瓶子
- bottle3 = new Bottle(3, b3); //容量为3的瓶子
- parentState = parent;
- }
- public String toString() {
- return "[" + bottle1.oil +" "+ bottle2.oil +" "+ bottle3.oil + "]";
- }
- public boolean isTargetState() { //判断是否为目标节点
- if(bottle1.oil == 5 && bottle2.oil == 5 )
- return true;
- else
- return false;
- }
- public boolean eqauls(StateNode s) { //判断是否为同一状态
- if( s.bottle1.oil == this.bottle1.oil &&
- s.bottle2.oil == this.bottle2.oil &&
- s.bottle3.oil == this.bottle3.oil)
- return true;
- else
- return false;
- }
- public void printStep(){ //打印从起始状态到当前状态的转换步骤
- if(parentState != null)
- parentState.printStep();
-
- System.out.println(toString());
- }
- public StateNode expandStateNode(int n) { //广度优先扩展状态节点
- StateNode newState = null;
- boolean isExpand = false;
-
- //分六种情况扩展节点状态
- //可以扩展则返回扩展后的新状态节点
- //如不能扩展则返回null
-
- switch(n) {
- case 1: //瓶子1向瓶子2倒油
- if(!bottle1.isEmpty() && !bottle2.isFull()) {
- n = bottle2.needForFull() <= bottle1.oil ? bottle2.needForFull() : bottle1.oil;
- newState = new StateNode(bottle1.oil-n, bottle2.oil+n, bottle3.oil, this);
- }
- break;
- case 2: //瓶子1向瓶子3倒油
- if(!bottle1.isEmpty() && !bottle3.isFull()) {
- n = bottle3.needForFull() <= bottle1.oil ? bottle3.needForFull() : bottle1.oil;
- newState = new StateNode(bottle1.oil-n, bottle2.oil, bottle3.oil+n, this);
- }
- break;
- case 3: //瓶子2向瓶子1倒油
- if(!bottle2.isEmpty() && !bottle1.isFull()) {
- n = bottle1.needForFull() <= bottle2.oil ? bottle1.needForFull() : bottle2.oil;
- newState = new StateNode(bottle1.oil+n, bottle2.oil-n, bottle3.oil, this);
- }
- break;
- case 4: //瓶子2向瓶子3倒油
- if(!bottle2.isEmpty() && !bottle3.isFull()) {
- n = bottle3.needForFull() <= bottle2.oil ? bottle3.needForFull() : bottle2.oil;
- newState = new StateNode(bottle1.oil, bottle2.oil-n, bottle3.oil+n, this);
- }
- break;
- case 5: //瓶子3向瓶子1倒油
- if(!bottle3.isEmpty() && !bottle1.isFull()) {
- n = bottle1.needForFull() <= bottle3.oil ? bottle1.needForFull() : bottle3.oil;
- newState = new StateNode(bottle1.oil+n, bottle2.oil, bottle3.oil-n, this);
- }
- break;
- case 6: //瓶子3向瓶子2倒油
- if(!bottle3.isEmpty() && !bottle2.isFull()) {
- n = bottle2.needForFull() <= bottle3.oil ? bottle2.needForFull() : bottle3.oil;
- newState = new StateNode(bottle1.oil, bottle2.oil+n, bottle3.oil-n, this);
- }
- break;
- }
- return newState;
- }
- }
- public class PartitionOil {
- public static void main(String[] args) {
- Queue< StateNode> stateQueue = new LinkedList< StateNode>(); //存放要扩展的状态节点的队列
- //存放所有出现过的状态的数组 用来判断某个状态是否出现过
- ArrayList< StateNode> stateList = new ArrayList< StateNode>();
-
- StateNode initialState = new StateNode(10, 0, 0, null); //初始状态10 0 0
-
- stateQueue.offer(initialState);
- stateList.add(initialState);
-
- while(!stateQueue.isEmpty()) {
- StateNode temp = stateQueue.poll(); //取队列头节点
- for(int i = 1; i <= 6; i++) { //每个节点分六种情况进行扩展
- StateNode newState = temp.expandStateNode(i); //扩展节点
- if(newState != null) {
- if(newState.isTargetState()){ //是否为目标状态
- System.out.println("----------Find target!!!---------");
- newState.printStep();
- return;
- }
-
- boolean tag = false; //判断状态是否出现过
- for(int j = 0; j < stateList.size(); j++){ //如出现过 跳过
- if(newState.eqauls(stateList.get(j))){
- tag = true;
- break;
- }
- }
-
- if(!tag) { //如没出现过 加入状态队列和数组
- stateQueue.offer(newState);
- stateList.add(newState);
- }
- }
- }
- }
- }
- }
复制代码 C:java>java PartitionOil
----------Find target!!!---------
[10 0 0]
[3 7 0]
[3 4 3]
[6 4 0]
[6 1 3]
[9 1 0]
[9 0 1]
[2 7 1]
[2 5 3]
[5 5 0]
源码下载:http://file.javaxxz.com/2014/12/7/000715921.zip |
|