回溯算法 Backtrack

典型问题, 01背包问题, 8皇后问题,

核心就是 找到 解空间,通常是个vector。然后穷举这个vector所有的可能值。从一条路往前走,能进则进,不能进则退回来,换条路再试

例如,在01背包问题中,解空间就是一个vector,每个element的可能值就是0或者1,所以只需要求出N!个解就行了。这种穷举解空间的过程用到了回溯。 BTW, 解空间还是个完全二叉树

import java.util.*;
public class Backtracking {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
            Scanner in = new Scanner(System.in);
            System.out.println("input a integer");
            int[] a = new int[in.nextInt()];
            Backtracking b = new Backtracking();
            b.search(0, a.length, a);
    }

    public void search(int m, int n, int[] a)
    {
        if(m >= n){
            for(int i = 0 ; i < a.length; i++)
                System.out.print(a[i]);
            System.out.print("\n");
        }else{

                a[m] = 0;
                search(m + 1, n, a);
                a[m] = 1;
                search(m + 1, n, a);
            }

        }
    }
}

if input 3
Output: 000 001 ………………….111

再拓展到8皇后问题,解空间也是一个vector,只不过每个element的可能值不再是0或者1两个值,而是所有可能的列号,并且选择每一个可能的列的时候,需要判断是否能够选择这一列,i.e. 加上了判断条件。所以同样的思路穷举即可。最后的结果就不是全排列的结果了,一些不满足条件的组合会被淘汰掉

import java.util.*;

public class Backtracking {

/**
 * @param args
 */

static int count = 0;

public static void main(String[] args) {
    // TODO Auto-generated method stub
        Scanner in = new Scanner(System.in);
        System.out.println("input a integer");
        int[] a = new int[in.nextInt()];
        for(int i = 0; i< a.length; i++)
            a[i] = -1;

        Backtracking b = new Backtracking();
        b.search(0, a.length, a);
        System.out.print("the number of queen arrangements is " +  b.count);
}

public void search(int m, int n, int[] a)
{
    int i,j;
    if(m >= n){
        for( i = 0 ; i < 8; i++){
            for( j = 0; j< 8; j++)
            {

                if(a[i] == j)
                    System.out.print("A");
                else
                    System.out.print("+");
            }
            System.out.print("\n");
        }
        this.count++;

    }else{

        for( j = 0; j < 8; j++){
            if(this.canplace(m, j, a)){
                a[m] = j;
                search(m + 1, 8, a);
                a[m] = -1;
            }
        }

    }
}

public boolean canplace(int m, int j, int[] a)
{

    for(int k = 0; k < m; k++)
        if(Math.abs(k-m) == Math.abs(a[k] - j) || a[k] == j) // the difference between rows and cols should be the same
            return false;
    return true;

}

}

if input 8
Output: 92

你可能感兴趣的:(算法复习)