eight-queen problem les veges probability algorithm

本文介绍了一种结合随机放置与回溯法解决八皇后问题的算法,并通过实验对比了不同随机放置数量对运行时间和成功率的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package csm.work;

import java.util.Random;

public class Question_9 {
    /*
     * 题目:Ex. 对8皇后问题,写一算法,求n=12~20时最优的StepVegas值(lasvegas Algorithm)。
     * 思路:求解规模为15的八皇后问题,随机放置k个八皇后,对余下的20-k个皇后用回溯法放置,找出一个解则结束 结果如下:
     *
            规模为15,随机放置0个,平均运行时间为:3506690ns
            找到解的成功率为1.0,随机算法的超时率为0.0
            
            规模为15,随机放置1个,平均运行时间为:2808510ns
            找到解的成功率为1.0,随机算法的超时率为0.0
            
            规模为15,随机放置2个,平均运行时间为:1695070ns
            找到解的成功率为1.0,随机算法的超时率为0.0
            
            规模为15,随机放置3个,平均运行时间为:1229860ns
            找到解的成功率为1.0,随机算法的超时率为0.0
            
            规模为15,随机放置4个,平均运行时间为:978460ns
            找到解的成功率为1.0,随机算法的超时率为0.0
            
            规模为15,随机放置5个,平均运行时间为:708120ns
            找到解的成功率为0.988,随机算法的超时率为0.0
            
            规模为15,随机放置6个,平均运行时间为:464840ns
            找到解的成功率为0.755,随机算法的超时率为0.0
            
            规模为15,随机放置7个,平均运行时间为:201980ns
            找到解的成功率为0.356,随机算法的超时率为0.0
            
            规模为15,随机放置8个,平均运行时间为:82830ns
            找到解的成功率为0.105,随机算法的超时率为0.0
            
            规模为15,随机放置9个,平均运行时间为:46240ns
            找到解的成功率为0.039,随机算法的超时率为0.0
            
            规模为15,随机放置10个,平均运行时间为:40850ns
            找到解的成功率为0.025,随机算法的超时率为0.0
            
            规模为15,随机放置11个,平均运行时间为:50650ns
            找到解的成功率为0.011,随机算法的超时率为0.01
            
            规模为15,随机放置12个,平均运行时间为:156030ns
            找到解的成功率为0.0060,随机算法的超时率为0.19
            
            规模为15,随机放置13个,平均运行时间为:1221120ns
            找到解的成功率为0.0040,随机算法的超时率为2.85
            
            规模为15,随机放置14个,平均运行时间为:3344020ns
            找到解的成功率为0.0030,随机算法的超时率为8.09
            
            从数据可以看出,放置5-6个时性能较优
     */
    public static Random r = new Random();
    public static int size = 15;
    // 放置20个皇后的坐标
    public int x[] = new int[size];
    public int y[] = new int[size];
    public int num = 0;
    public int k;

    // 检测两皇后是否符合规则
    static boolean check(int x1, int y1, int x2, int y2) {
        if (x1 != x2 && y1 != y2 && (x1 + y1) != (x2 + y2)
                && (x1 - y1) != (x2 - y2))
            return true;
        return false;
    }

    // 判断某点是否可放
    boolean isValid(int x1, int y1) {
        for (int i = 0; i < num; i++) {
            if (!check(x1, y1, x[i], y[i])) {
                return false;
            }
        }
        return true;
    }

    public boolean stepVegas(int k1) {
        k = k1;
        int limit = 10000;
        while (k1 != 0 && limit != 0) {
            int x1 = r.nextInt(size);
            int y1 = r.nextInt(size);

            /*
             * x1 = 0; y1 = 2; if(k1==1) { x1 = 3; y1 = 0; }
             */

            if (isValid(x1, y1)) {
                // System.out.println(x1+","+y1);
                x[num] = x1;
                y[num] = y1;
                num++;
                k1--;
            }

            limit--;
        }
        if (limit == 0)
            return false;
        return true;
    }

    // 回溯
    public boolean backTrace() {
        int validx[] = new int[size - k];
        int validy[] = new int[size - k];
        int flag[] = new int[size];
        for (int i = 0; i < k; i++) {
            flag[x[i]] = 1;
        }
        int index = 0;
        for (int i = 0; i < size; i++) {
            if (flag[i] == 0) {
                validx[index] = i;
                validy[index] = -1;
                index++;
            }
        }
        // show();
        for (int i = 0; i < index; i++) {
            int j;
            for (j = validy[i] + 1; j < size; j++) {
                if (isValid(validx[i], j)) {
                    x[num] = validx[i];
                    y[num] = j;
                    num++;
                    if (num == size)
                        return true;
                    validy[i] = j;
                    for (int m = i + 1; m < size - k; m++) {
                        validy[m] = -1;
                    }
                    // show();
                    break;
                }
            }
            if (j == size) {
                if (num == k)
                    return false;
                num--;
                i -= 2;
                // show();
            }
        }
        return false;
    }

    public void show() {
        System.out.println("****************************");
        int flag[][] = new int[size][size];
        for (int i = 0; i < num; i++) {
            flag[x[i]][y[i]] = 1;
        }
        for (int i = 0; i < size; i++) {

            for (int j = 0; j < size; j++) {
                System.out.print(flag[i][j]);
            }
            System.out.println();
        }
    }

    public static void main(String[] args) {
        // 规模为15,随机放置3、6、9个八皇后的性能比较,每个运行100次。
        long begin, end;
        int success, failed, timeout;
        int testCount = 1000;

        for (int j = 0; j < Question_9.size; j++) {
            success = 0;
            failed = 0;
            timeout = 0;
            begin = System.nanoTime();
            for (int i = 0; i < testCount; i++) {
                Question_9 q9 = new Question_9();
                if (q9.stepVegas(j)) {
                    if (q9.backTrace()) {
                        success++;
                    } else {
                        failed++;
                    }
                } else {
                    timeout++;
                }
            }
            end = System.nanoTime();
            System.out.println("规模为15,随机放置"+j+"个,平均运行时间为:" + (end - begin) / 100
                    + "ns");
            System.out.println("找到解的成功率为" + (success / (testCount * 1.0))
                    + ",随机算法的超时率为" + (timeout / 100.0));
            System.out.println();

        }
    }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值