4皇后的队列实现---分支限界法

import java.util.*;
public class aaa {
    private static int num=0;


    public boolean place(State s,int temp,int i,int n){
        for(int k=0;k<n;k++){
            if(k==temp){
                continue;
            }
            if(s.selected[k]==0){
                break;
            }
            if(s.selected[k]==i||Math.abs(k-temp)==Math.abs(s.selected[k]-i)){
                return false;
            }
        }
        return true;
    }

    public class State {
        int[] selected;

        public State(int[] selected) {
            this.selected = selected;
        }
    }
    public void bfs(int n) {
        Queue<State> queue = new LinkedList<>();
        int[] init = new int[n];
        State initstate = new State(init);
        queue.add(initstate);
        num++;
        while (!queue.isEmpty()) {
            State currentstate = queue.poll();
            boolean flag = true;
            int ivalue=-1;
            for (int i = 0; i < n; i++) {
                if (currentstate.selected[i] == 0) {
                    ivalue=i;
                    flag = false;
                    break;
                }
            }
            if(flag){
                for(int i=0;i<n;i++){
                    System.out.print(currentstate.selected[i]+" ");
                }
                System.out.println();
            }
            if(ivalue==-1){
                continue;
            }
            for (int j = 1; j < n + 1; j++) {
                int[] newcurrent = currentstate.selected.clone();
                newcurrent[ivalue] = j;
                State newcurrentstate = new State(newcurrent);
                if(place(newcurrentstate,ivalue,newcurrentstate.selected[ivalue],n)){
                    queue.add(newcurrentstate);
                    num++;
                }
            }
        }

    }

    public static void main(String[] args) {
        Scanner in=new Scanner(System.in);
        int n=in.nextInt();
        in.close();
        aaa test=new aaa();
        test.bfs(n);
        System.out.println(num);
    }
}

运行结果:

输入:
4

输出:

2 4 1 3 
3 1 4 2 
17

优先队列修改:

说到底,也就是修改一下队列实现,让其比较器自动按照优先值排一下序,也就是多这两个而已。

PriorityQueue<State> queue = new PriorityQueue<>((s1, s2) -> {
            int count1 = countNonZero(s1.selected);
            int count2 = countNonZero(s2.selected);
            return Integer.compare(count2, count1);
        });

private int countNonZero(int[] array) {
        int count = 0;
        for (int num : array) {
            if (num != 0) {
                count++;
            }
        }
        return count;
    }
import java.util.*;

public class aaa {
    private static int num = 0;

    public boolean place(State s, int temp, int i, int n) {
        for (int k = 0; k < n; k++) {
            if (k == temp) {
                continue;
            }
            if (s.selected[k] == 0) {
                break;
            }
            if (s.selected[k] == i || Math.abs(k - temp) == Math.abs(s.selected[k] - i)) {
                return false;
            }
        }
        return true;
    }

    public class State {
        int[] selected;

        public State(int[] selected) {
            this.selected = selected;
        }
    }

    public void bfs(int n) {
        PriorityQueue<State> queue = new PriorityQueue<>((s1, s2) -> {
            int count1 = countNonZero(s1.selected);
            int count2 = countNonZero(s2.selected);
            return Integer.compare(count2, count1);
        });

        int[] init = new int[n];
        State initstate = new State(init);
        queue.add(initstate);
        num++;
        while (!queue.isEmpty()) {
            State currentstate = queue.poll();
            boolean flag = true;
            int ivalue = -1;
            for (int i = 0; i < n; i++) {
                if (currentstate.selected[i] == 0) {
                    ivalue = i;
                    flag = false;
                    break;
                }
            }
            if (flag) {
                for (int i = 0; i < n; i++) {
                    System.out.print(currentstate.selected[i] + " ");
                }
                System.out.println();
            }
            if (ivalue == -1) {
                continue;
            }
            for (int j = 1; j < n + 1; j++) {
                int[] newcurrent = currentstate.selected.clone();
                newcurrent[ivalue] = j;
                State newcurrentstate = new State(newcurrent);
                if (place(newcurrentstate, ivalue, newcurrentstate.selected[ivalue], n)) {
                    queue.add(newcurrentstate);
                    num++;
                }
            }
        }
    }

    private int countNonZero(int[] array) {
        int count = 0;
        for (int num : array) {
            if (num != 0) {
                count++;
            }
        }
        return count;
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        in.close();
        aaa test = new aaa();
        test.bfs(n);
        System.out.println(num);
    }
}

结果还是一样,

4
3 1 4 2 
2 4 1 3 
17

但是如果不是找到全部,只是找到一个的话,肯定是优先队列快,

下面我们进行分析:

 优先队列:

4
3 1 4 2 
入队数量:14
出队数量:13

6
3 6 2 5 1 4 
入队数量:48
出队数量:43

普通队列:

4
2 4 1 3 
入队数量:17
出队数量:16

6
2 4 6 1 3 5 
入队数量:153
出队数量:150

现在我们再看找全部,如果是六皇后:

优先队列:

6
3 6 2 5 1 4 
5 3 1 6 4 2 
4 1 5 2 6 3 
2 4 6 1 3 5 
入队数量:153
出队数量:153

普通队列:

6
2 4 6 1 3 5 
3 6 2 5 1 4 
4 1 5 2 6 3 
5 3 1 6 4 2 
入队数量:153
出队数量:153

  • 16
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值