佳礼资讯网

 找回密码
 注册

ADVERTISEMENT

搜索
查看: 1460|回复: 1

Farmer Wolf Goat Cabbage Problem 问题 In Java

[复制链接]
发表于 25-8-2009 02:51 PM | 显示全部楼层 |阅读模式
本人之前无聊的时候写了一个Java程序,来解决 Farmer Wolf Goat Cabbage 过桥问题。
大家应该听过这个问题吧?就是怎么样让农夫把所有东西都带到对岸去。
但是呢,一次农夫只能带一样东西过去。
有一些规则:
如果农夫不在的话,狼会吃羊,后者羊会吃白菜。

这个程序的主要用途,就是自动探索所有解决路线,然后最终目标是可以成功显示解题步骤。
就好像这样
Move Farmer, Wolf from here to there
Move Farmer from there to here

而这个程序,本人只花了三天来写,所以程序蛮乱的。
而且有个问题就是,最后一步,就会有错误。就只差最后一步就到终点了。

本人第一次把程序发表在这里,希望有高手可以帮忙看看。。。
感谢了!

程序太长,分两个帖子来

Main.java


  1. /**
  2. * To demonstrate the solution of Farmer Wolf Goat Cabbage Problem in Java
  3. *
  4. * @author (Khor Yong Hao)
  5. * @version (0.1)
  6. */
  7. import java.util.*;
  8. public class Main
  9. {
  10.     public static void main(String args[]) {
  11.         new Main().solve();
  12.     }
  13.    
  14.     final int FARMER = 1;
  15.     final int WOLF = 2;   
  16.     final int GOAT = 4;
  17.     final int CABBAGE = 8;
  18.     Side side1 = new Side("left side", new int[]{FARMER, WOLF, GOAT, CABBAGE});
  19.     Side side2 = new Side("right side", new int[]{});
  20.     LinkedHashSet states = new LinkedHashSet(); // insertion order unique element
  21.    
  22.     public void solve() {
  23.         // initialize
  24.         states.add(new State(side1, side2));
  25.         
  26.         reach_to(side1, side2);
  27.     }
  28.    
  29.     // reach side1 to side2
  30.     public void reach_to(Side side1, Side side2) {
  31.         printSides();
  32.         
  33.         
  34.         checkMove(side1, side2);
  35.         
  36.         // for testing purpose
  37.         /*
  38.         printStates(states);
  39.         System.out.println("state: " + checkRepeatState());
  40.         move_to(side1.getSlot(), side1, side2);
  41.         
  42.         printStates(states);
  43.         System.out.println("state: " + checkRepeatState());
  44.         
  45.         move_to(side2.getSlot(), side2, side1);
  46.         
  47.         printStates(states);
  48.         System.out.println("state: " + checkRepeatState());
  49.         
  50.         System.out.println(checkGoal());
  51.         
  52.         printStates(states);
  53.         */
  54.       
  55.         printSides();
  56.     }
  57.    
  58.     public void checkMove(Side side1, Side side2) {
  59.         if(checkGoal()) {
  60.             System.out.println("The Problem Solved");
  61.             System.exit(0);
  62.             return;
  63.         }
  64.         if(checkExist(FARMER, side1)) {
  65.             //System.out.println("farmer at side " + side1.getName());
  66.             try_move(side1, side2);
  67.         } else if(checkExist(FARMER, side2)) {
  68.             //System.out.println("farmer at side " + side2.getName());
  69.             try_move(side2, side1);
  70.         }
  71.     }
  72.    
  73.     public boolean checkGoal() {
  74.         
  75.         if(side1.getSlot().length == 0 && side2.getSlot().length == 4) {
  76.             return true;
  77.         }
  78.         return false;
  79.     }
  80.    
  81.     // check if target exist in that side
  82.     public boolean checkExist(int target, Side side) {
  83.         for(int i=0; i<side.getSlot().length; i++) {
  84.             if(side.getSlot()[i] == target) {
  85.                
  86.                 return true;
  87.             }
  88.         }
  89.         return false;
  90.     }
  91.    
  92.     public boolean checkTargetExist(int[] targets, Side side) {
  93.         boolean result = true;
  94.         String notExistTargets = "";
  95.         for(int i=0; i<targets.length; i++) {
  96.             if(!checkExist(targets[i], side)) {
  97.                 result = false;
  98.                 notExistTargets += getName(targets[i]) + " ";
  99.             }
  100.         }
  101.         if(!result) {
  102.             //System.out.println("Target: " + notExistTargets + "not existed in " + side.getName());
  103.         }
  104.         return result;
  105.     }
  106.    
  107.     public void try_move(Side side1, Side side2) {
  108.         //System.out.println("side1 slot length: " + side1.getSlot().length);
  109.         
  110.         for(int i=0; i<side1.getSlot().length; i++/*, System.out.println("i++")*/) {
  111.             //System.out.println("i: " + i);
  112.             
  113.             int successCount = 0;
  114.             if(side1.getSlot()[i] != FARMER) {
  115.                
  116.                 int[] moveTargets = new int[] {FARMER, side1.getSlot()[i]};
  117.                 // move side1 to side2 first
  118.                
  119.                
  120.                
  121.                 try_move_to(moveTargets, side1, side2);
  122.                
  123.                 // check eating rule
  124.                 // if break rule, move back (backtracking)
  125.                 // if repeat, go back
  126.                 //System.out.println("11111111111111");
  127.                 if(checkBreakRule(side1) || checkBreakRule(side2) || checkRepeatState()) {
  128.                     try_move_to(moveTargets, side2, side1);
  129.                     
  130.                     //System.out.println("22222222222222");
  131.                 } else {
  132.                     // this is success route, so print
  133.                     successCount++;
  134.                     
  135.                     addState();
  136.                     printMove(moveTargets, side1, side2);
  137.                     
  138.                     checkMove(side1, side2); // recursive continue to search
  139.                     //System.out.println("33333333333333");
  140.                 }
  141.                
  142.                 //System.out.println("successcount: " + successCount);
  143.                
  144.                 // move farmer only if other already try
  145.                 if(i == side1.getSlot().length - 1 && successCount == 0) {
  146.                     try_move_to(new int[]{FARMER}, side1, side2);
  147.                     if(checkBreakRule(side1) || checkBreakRule(side2) || checkRepeatState()) {
  148.                         
  149.                         try_move_to(new int[]{FARMER}, side2, side1);
  150.                     } else {
  151.                     
  152.                         addState();
  153.                         printMove(new int[]{FARMER}, side1, side2);
  154.                     
  155.                         checkMove(side1, side2);
  156.                     
  157.                         //System.out.println("44444444444444");
  158.                     }
  159.                 }
  160.                
  161.                 if(successCount > 0 && checkRepeatState()) {
  162.                     try_move_to(moveTargets, side2, side1);
  163.                     continue;
  164.                 }
  165.             }
  166.         }
  167.     }
  168.    
  169.     public boolean checkBreakRule(Side side) {
  170.         if(sum(side) == 12) {
  171.             // GOAT eat CABBAGE
  172.             //System.out.println("OOPS, goat eat cabbage");
  173.             return true;
  174.         } else if(sum(side) == 6) {
  175.             // WOLF eat GOAT
  176.             //System.out.println("OOPS, wolf eat goat");
  177.             return true;
  178.         }
  179.         return false;
  180.     }
  181.    
  182.     public boolean checkRepeatState() {
  183.         /*
  184.         if(states.contains(new State(side1.getSlot().clone(), side2.getSlot().clone()))) {
  185.             return true;
  186.         }
  187.         */
  188.       
  189.         Iterator it = states.iterator();
  190.         int t = 0;
  191.         int count = 0;
  192.         while(it.hasNext() && (count++ < states.size() - 1)) {
  193.             
  194.             State state = (State) it.next();
  195.             if(state.isSameState(side1, side2)) {
  196.                
  197.                 t++;
  198.             }
  199.         }
  200.         
  201.         return t>0;
  202.     }
复制代码
回复

使用道具 举报


ADVERTISEMENT

 楼主| 发表于 25-8-2009 02:53 PM | 显示全部楼层
  1. public int sum(Side side) {
  2.         int sum = 0;
  3.         for(int i=0; i<side.getSlot().length; i++) {
  4.             sum += side.getSlot()[i];
  5.         }
  6.         return sum;
  7.     }
  8.    
  9.     // move targets from side1 to side2
  10.     public void move_to(int[] targets, Side side1, Side side2) {
  11.         if(try_move_to(targets, side1, side2)) {
  12.             printMove(targets, side1, side2);
  13.         }
  14.     }
  15.    
  16.     public boolean try_move_to(int[] targets, Side side1, Side side2) {
  17.         
  18.         // check target exist or not
  19.         if(!checkTargetExist(targets, side1)) {
  20.             return false;
  21.             // out
  22.         }
  23.         
  24.         // give temporary storage
  25.         int[] temp1 = new int[side1.getSlot().length - targets.length];
  26.         int[] temp2 = new int[side2.getSlot().length + targets.length];
  27.         int m=0;
  28.         
  29.         // move side1 into temp1 first
  30.         // here got bug
  31.         for(int n=0; n<side1.getSlot().length; n++) {
  32.             // all targets not exists then add temp
  33.             int t = 0;
  34.             for(int p=0; p<targets.length; p++) {
  35.             
  36.                
  37.                 if(targets[p] == side1.getSlot()[n]) {
  38.                     t++; // target exist
  39.                 }
  40.                
  41.             }
  42.             if(t == 0) {
  43.                
  44.                 temp1[m++] = side1.getSlot()[n];
  45.                
  46.             }
  47.             
  48.         }
  49.         
  50.         
  51.         // move side2 into temp2 first
  52.         
  53.         for(m=0; m<side2.getSlot().length; m++) {
  54.             temp2[m] = side2.getSlot()[m];
  55.         }
  56.         
  57.         for(int i=0; i<targets.length; i++) {
  58.             
  59.             temp2[m++] = targets[i];
  60.         }
  61.         
  62.         // update new data
  63.         side1.setSlot(temp1);
  64.         side2.setSlot(temp2);
  65.         
  66.         addState();
  67.         //printSides();
  68.         return true;
  69.     }
  70.    
  71.     public void printMove(int[] targets, Side side1, Side side2) {
  72.         System.out.print("Move ");
  73.         
  74.         for(int i=0; i<targets.length; i++) {
  75.             
  76.             System.out.print(getName(targets[i]) + " ");
  77.         }
  78.         
  79.         System.out.println("from " + side1.getName() + " to " + side2.getName());
  80.     }
  81.    
  82.     public String getName(int obj) {
  83.         String output = null;
  84.         switch(obj) {
  85.             case FARMER:
  86.             output = "farmer";
  87.             break;
  88.             
  89.             case WOLF:
  90.             output = "wolf";
  91.             break;
  92.             
  93.             case GOAT:
  94.             output = "goat";
  95.             break;
  96.             
  97.             case CABBAGE:
  98.             output = "cabbage";
  99.             break;
  100.         }
  101.         return output;
  102.     }
  103.    
  104.     public void printSide(Side side) {
  105.         
  106.         System.out.print(side.getName() + ": ");
  107.         for(int i=0; i<side.getSlot().length; i++) {
  108.             System.out.print(getName(side.getSlot()[i]) + " ");
  109.         }
  110.         System.out.println();
  111.         
  112.     }
  113.    
  114.     public void printSides() {
  115.         System.out.println("--------------------------------");
  116.         printSide(side1);
  117.         printSide(side2);
  118.         System.out.println("--------------------------------");
  119.     }
  120.    
  121.     public void printArray(Side side) {
  122.         int[] array = side.getSlot();
  123.         System.out.print("Array: ");
  124.         for(int i=0; i<array.length; i++) {
  125.             System.out.print(getName(array[i]) + " ");
  126.         }
  127.         System.out.println();
  128.     }
  129.    
  130.     public void printStates(LinkedHashSet states) {
  131.         Iterator it = states.iterator();
  132.         System.out.println("States: ");
  133.         while(it.hasNext()) {
  134.             State state = (State) it.next();
  135.             System.out.print("side 1 ");
  136.             printArray(state.getSide1());
  137.             System.out.print("side 2 ");
  138.             printArray(state.getSide2());
  139.             
  140.         }
  141.         System.out.println();
  142.             
  143.     }
  144.    
  145.     public void addState() {
  146.         // insert state
  147.         
  148.         State state = new State(side1, side2);
  149.         states.add(state);
  150.     }
  151.       
  152. }

  153. class Side extends Object implements Cloneable {
  154.     public static int count = 0;
  155.     private int counter = ++count;
  156.     private int[] slot = new int[4];
  157.     private String name;
  158.    
  159.     public Side(String name, int[] slot) {
  160.         this.name = name;
  161.         this.slot = slot;
  162.     }
  163.    
  164.     public int[] getSlot() {
  165.         return slot;
  166.     }
  167.    
  168.     public void setSlot(int[] slot) {
  169.         
  170.         java.util.Arrays.sort(slot);
  171.         this.slot = slot;
  172.     }
  173.    
  174.     public String getName() {
  175.         return name;
  176.     }
  177.    
  178.    
  179.    
  180.    
  181.     public boolean equals(Object obj) {
  182.       
  183.         int[] sideObj = (int[])(((Side) obj).getSlot());
  184.         
  185.         
  186.         
  187.         if(sideObj.length + slot.length == 0) {
  188.            
  189.             return true;
  190.         } else if(slot.length == 0 || sideObj.length == 0) {
  191.             
  192.             return false;
  193.         }
  194.         
  195.         for(int i=0; i<sideObj.length; i++) {
  196.             try {
  197.                 if(sideObj[i] != slot[i]) {
  198.                     //System.out.println("side obj: " + sideObj[i] + " :::: slot[i]: " + slot[i]);
  199.                     return false;
  200.                 }
  201.             } catch (ArrayIndexOutOfBoundsException e) {
  202.                 System.err.println(e);
  203.                 return false;
  204.             }
  205.         }
  206.         
  207.         
  208.         
  209.             
  210.         
  211.         return true;
  212.     }
  213.    
  214.    
  215.     public Side clone() {
  216.         Side side = null;
  217.         try {
  218.             side = (Side) super.clone();
  219.         } catch (CloneNotSupportedException e) {
  220.             System.err.println(e);
  221.         }
  222.         return side;
  223.     }
  224.    
  225. }

  226. class State {
  227.     Side side1;
  228.     Side side2;
  229.     public State(Side side1, Side side2) {
  230.         this.side1 = side1.clone();
  231.         this.side2 = side2.clone();
  232.     }
  233.    
  234.     public boolean isSameState(Side sideA, Side sideB) {
  235.         /*
  236.         System.out.print("same state side1 ");
  237.         printArray(side1);
  238.         System.out.print("same state side2 ");
  239.         printArray(side2);
  240.         System.out.print("same state sideA ");
  241.         printArray(sideA);
  242.         System.out.print("same state sideB ");
  243.         printArray(sideB);
  244.         System.out.println("same state end");
  245.         System.out.println("side1.equals(sideA) = " + side1.equals(sideA) + " :::: " + "side2.equals(sideB) = " + side2.equals(sideB));
  246.         //return true;
  247.         */
  248.       
  249.         if(side1.equals(sideA) && side2.equals(sideB)) {
  250.             return true;
  251.         }
  252.         return false;
  253.         
  254.     }
  255.    
  256.    
  257.     public Side getSide1() {
  258.         return side1;
  259.     }
  260.    
  261.     public Side getSide2() {
  262.         return side2;
  263.     }
  264.    
  265.     public void printArray(Side side) {
  266.         int[] array = side.getSlot();
  267.         System.out.print("Array: ");
  268.         for(int i=0; i<array.length; i++) {
  269.             System.out.print(array[i] + " ");
  270.         }
  271.         System.out.println();
  272.     }
  273.    
  274.    
  275.    
  276. }
复制代码
希望各位高手能帮忙看看。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

 

ADVERTISEMENT


本周最热论坛帖子本周最热论坛帖子

ADVERTISEMENT



ADVERTISEMENT

ADVERTISEMENT


版权所有 © 1996-2026 Cari Internet Sdn Bhd (483575-W)|IPSERVERONE 提供云主机|广告刊登|关于我们|私隐权|免控|投诉|联络|脸书|佳礼资讯网

GMT+8, 5-5-2026 07:32 PM , Processed in 0.072998 second(s), 11 queries , Gzip On, Redis On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表