码迷,mamicode.com
首页 > 其他好文 > 详细

8数码问题(2)

时间:2015-04-03 14:57:52      阅读:149      评论:0      收藏:0      [点我收藏+]

标签:

抽空写了八数码问题的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 }

 

8数码问题(2)

标签:

原文地址:http://www.cnblogs.com/earthgee/p/4389860.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!