标签:
抽空写了八数码问题的bfs版本,数据结构方面可能还有很多欠缺
然后需要用一个map来保存所有的路径,因为是bfs所以map可能会比较大(是很大吧!),但是比dfs好的地方在于可以找到最短路径,妈妈再也不用怕我看dfs那么深的递归树了
恩。。。dfs和bfs的速度都不及dbfs和a*的,所以有空会补上这两个算法的版本,还打了一个判断是否可解的补丁,根据逆序数,感兴趣可以搜索之
贴上代码:
1 public class EightNum2 { 2 /** 3 * 存储路径 4 * 遍历树如下 5 * a 6 * / 7 * b c 8 * 则存储(b=a,c=a) 9 * 可以用一个路径类来代替 10 */ 11 public static Map<List<Integer>,List<Integer>> path=new HashMap<List<Integer>,List<Integer>>(); 12 //去重,同dfs版本 13 public static Set<List<Integer>> old=new HashSet<List<Integer>>(); 14 //存储目标 15 public static List<Integer> target=new ArrayList<Integer>(); 16 //用于bfs的队列 17 public static Queue<List<Integer>> queue=new LinkedList<List<Integer>>(); 18 19 static{ 20 target.add(7); 21 target.add(1); 22 target.add(5); 23 target.add(8); 24 target.add(2); 25 target.add(4); 26 target.add(6); 27 target.add(0); 28 target.add(3); 29 } 30 31 //用于计算是奇排列还是偶排列 32 public static int reverse(List<Integer> list) 33 { 34 int num=0; 35 int tmp=find(list); 36 for(int i=0;i<9;i++) 37 { 38 for(int j=0;j<i;j++) 39 { 40 if(j!=tmp&&list.get(i)>list.get(j)) 41 { 42 num++; 43 } 44 } 45 } 46 return num; 47 } 48 49 //判断是否有解 50 public static boolean isSolve(List<Integer> list1,List<Integer> list2) 51 { 52 int reverse1=reverse(list1); 53 int reverse2=reverse(list2); 54 55 return reverse1%2==reverse2%2; 56 } 57 58 //查找某一状态0的位置 59 public static int find(List<Integer> num) 60 { 61 for(int i=0;i<num.size();i++) 62 { 63 if(num.get(i)==0) 64 { 65 return i; 66 } 67 } 68 return -1; 69 } 70 71 //同dfs 72 public static List<Integer> swap(List<Integer> num,int num1,int num2) 73 { 74 List<Integer> tmp=new ArrayList<Integer>(); 75 for(int i=0;i<num.size();i++) 76 { 77 if(i==num1) 78 { 79 tmp.add(num.get(num2)); 80 } 81 else if(i==num2) 82 { 83 tmp.add(num.get(num1)); 84 } 85 else 86 { 87 tmp.add(num.get(i)); 88 } 89 } 90 return tmp; 91 } 92 93 //同dfs 94 public static boolean equalToTarget(List<Integer> num) 95 { 96 for(int i=0;i<9;i++) 97 { 98 if(!(num.get(i)==target.get(i))) 99 { 100 return false; 101 } 102 } 103 return true; 104 } 105 106 //simple 107 public static boolean equal(List<Integer> tmp1,List<Integer> tmp2) 108 { 109 for(int i=0;i<9;i++) 110 { 111 if(tmp1.get(i)!=tmp2.get(i)) 112 { 113 return false; 114 } 115 } 116 return true; 117 } 118 119 //主要函数,一状态出队列后会将所有没有重复的子状态加入到队列中(bfs) 120 public static boolean calculate(List<Integer> num) 121 { 122 if(!isSolve(num, target)) 123 { 124 return false; 125 } 126 127 queue.add(num); 128 while(!queue.isEmpty()) 129 { 130 List<Integer> tmp=queue.poll(); 131 132 if(equalToTarget(tmp)) 133 { 134 return true; 135 } 136 137 int position=find(tmp); 138 139 old.add(tmp); 140 141 if(position-3>=0) 142 { 143 List<Integer> top=swap(tmp, position, position-3); 144 if(!old.contains(top)) 145 { 146 queue.add(top); 147 path.put(top, tmp); 148 old.add(top); 149 } 150 } 151 152 if(position-1>=0&&(position-1)/3==position/3) 153 { 154 List<Integer> left=swap(tmp, position, position-1); 155 if(!old.contains(left)) 156 { 157 queue.add(left); 158 path.put(left, tmp); 159 old.add(left); 160 } 161 } 162 163 if(position+3<=8) 164 { 165 List<Integer> below=swap(tmp, position, position+3); 166 if(!old.contains(below)) 167 { 168 queue.add(below); 169 path.put(below, tmp); 170 old.add(below); 171 } 172 } 173 174 if(position+1<=8&&(position+1)/3==position/3) 175 { 176 List<Integer> right=swap(tmp, position, position+1); 177 if(!old.contains(right)) 178 { 179 queue.add(right); 180 path.put(right, tmp); 181 old.add(right); 182 } 183 } 184 } 185 186 return false; 187 } 188 189 public static void printList(List<Integer> list) 190 { 191 for(int i=0;i<list.size();i++) 192 { 193 System.out.print(list.get(i)+"-"); 194 } 195 System.out.println(); 196 } 197 198 //用一个栈来打印出路径 199 public static void printPath(List<Integer> num) 200 { 201 Stack<List<Integer>> stack=new Stack<List<Integer>>(); 202 List<Integer> tmp=new ArrayList<Integer>(); 203 stack.add(target); 204 List<Integer> tmppp=target; 205 do 206 { 207 tmp=path.get(tmppp); 208 stack.add(tmp); 209 tmppp=tmp; 210 }while(!equal(num, tmp)); 211 212 while(!stack.isEmpty()) 213 { 214 List<Integer> tmpp=stack.pop(); 215 printList(tmpp); 216 } 217 } 218 219 //测试实例 220 public static void main(String[] args) { 221 List<Integer> num=new ArrayList<Integer>(); 222 num.add(1); 223 num.add(2); 224 num.add(5); 225 num.add(0); 226 num.add(6); 227 num.add(4); 228 num.add(7); 229 num.add(8); 230 num.add(3); 231 if(calculate(num)) 232 { 233 printPath(num); 234 } 235 else 236 { 237 System.out.println("无解"); 238 } 239 } 240 }
标签:
原文地址:http://www.cnblogs.com/earthgee/p/4389860.html