8数码问题(1)

使用dfs, 果然效率很低,生成的遍历树很deep啊,所以有时间实现bfs和a*的,使用java编写。。

贴上代码

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Stack;

/**
 * 
 * @author earthgee
 *
 *八数码(1),使用dfs
 */

public class EightNum {
    public static Stack<List<Integer>> path=new Stack<List<Integer>>();    //记录路径
    public static HashSet<List<Integer>> old=new HashSet<List<Integer>>();    //记录访问过的路径,用于去重
    public static List<Integer> target=new ArrayList<Integer>();    //目标路径
    
    static{
        target.add(1);
        target.add(2);
        target.add(3);
        target.add(8);
        target.add(0);
        target.add(4);
        target.add(7);
        target.add(6);
        target.add(5);
    }
    
    //0代表空格,此交换函数实现了0的移动
    public static List<Integer> swap(List<Integer> num,int num1,int num2)
    {
        List<Integer> tmp=new ArrayList<Integer>();
        for(int i=0;i<num.size();i++)
        {
            if(i==num1)
            {
                tmp.add(num.get(num2));
            }
            else if(i==num2)
            {
                tmp.add(num.get(num1));
            }
            else
            {
                tmp.add(num.get(i));
            }
        }
        return tmp;
    }
    
    //不解释
    public static boolean equalToTarget(List<Integer> num)
    {
        for(int i=0;i<9;i++)
        {
            if(!(num.get(i)==target.get(i)))
            {
                return false;
            }
        }
        return true;
    }
    
    /**
     * 主函数
     * @param num 每一次dfs的路径
     * @param k    0的位置
     * @return    是否到达目标,用于回溯
     */
    public static boolean calculate(List<Integer> num,int k)
    {
        int tmpp=0;
        
        if(equalToTarget(num))
        {
            path.push(num);
            return true;
        }
        
        old.add(num);
        
        //可以看出顺序为:上-左-下-右
        if(k-3>=0)
        {
            path.push(num);
            List<Integer> tmp=swap(num,k,k-3);
            if(old.contains(tmp))
            {
                path.pop();
            }
            else
            {
                tmpp=k-3;
                if(calculate(tmp, tmpp))
                {
                    return true;
                }
                else
                {
                    path.pop();
                }
            }
        }
        
        if(k-1>=0&&(k/3==(k-1)/3))
        {
            path.push(num);
            List<Integer> tmp=swap(num,k,k-1);
            if(old.contains(tmp))
            {
                path.pop();
            }
            else
            {
                tmpp=k-1;
                if(calculate(tmp, tmpp))
                {
                    return true;
                }
                else
                {
                    path.pop();
                }
            }
        }
        
        
        if(k+3<=8)
        {
            path.push(num);
            List<Integer> tmp=swap(num,k,k+3);
            if(old.contains(tmp))
            {
                path.pop();
            }
            else
            {
                tmpp=k+3;
                if(calculate(tmp, tmpp))
                {
                    return true;
                }
                else
                {
                    path.pop();
                }
            }
        }
        
        if(k+1<=8&&(k/3==(k+1)/3))
        {
            path.push(num);
            List<Integer> tmp=swap(num,k,k+1);
            if(old.contains(tmp))
            {
                path.pop();
            }
            else
            {
                tmpp=k+1;
                if(calculate(tmp, tmpp))
                {
                    return true;
                }
                else
                {
                    path.pop();
                }
            }
        }
        
        return false;
    }
    
    public static void printList(List<Integer> list)
    {
        for(int i=0;i<list.size();i++)
        {
            System.out.print(list.get(i)+"-");
        }
        System.out.println();
    }
    
    //测试实例
    public static void main(String[] args) {
        List<Integer> num=new ArrayList<Integer>();
        num.add(1);
        num.add(0);
        num.add(3);
        num.add(7);
        num.add(2);
        num.add(4);
        num.add(6);
        num.add(8);
        num.add(5);
        calculate(num, 1);
        for(int i=0;i<path.size();i++)
        {
            List<Integer> list=path.get(i);
            printList(list);
        }
    }
}

测试的深度达到了200多,可怕,这个还是不要用dfs的好