算法:n后问题_局部搜索算法

n后问题_局部搜索算法

题目

局部搜索解n皇后,并测试n的极限

回溯法难以求解更大规模的n皇后问题,但是基于概率的局部搜索算法可以解决一定规模上的 n 皇后问题

思路

根据课件上的局部搜索算法思路,n皇后具体流程为:

  1. 随机将 N 皇后分布在棋盘上,并保证每行每列仅有一个皇后
  2. 计算皇后间的冲突数 conflicts,注意这里只需要计算斜线的冲突,行列不需要
  3. 如果冲突为0则转(6)
  4. 对于棋盘上的任意两个皇后,交换位置,如果交换后冲突减少,则接受交换,更新冲突数 conflicts
  5. 如果陷入了局部极小,即交换了所有皇后后,冲突数不能下降,则转(1)
  6. 输出结果,结束

优化思路

对于上面的思路,现提供 QS2 算法思路,主要优化点在于交换策略不再是任意交换,而是选择陷入冲突的棋子进行交换

  1. 随机地将N 个皇后分布在棋盘上,每行、每列只有一个皇后。
  2. 计算皇后间的冲突数Conflicts
  3. 如果冲突数等于0等转(9)
  4. 获取棋盘上陷入冲突的所有棋子
  5. 将冲突棋子和其他棋子进行交换,冲突降低则更新棋盘
  6. 重新计算冲突,冲突为0则转(9)
  7. 加速: 若冲突数小于某个阈值,则更新阈值并重新获取冲突 棋子
  8. 如果陷入了局部极小(达到循环次数上限),即交换了所有的皇后后,冲突数仍不能下降,则转(1)
  9. 输出结果并结束

源代码

package main

import (
	"fmt"
	"math/rand"
	"time"
)

const (
	// 加速系数
	speedUpFactor = 0.25
	// 循环系数
	cycleFactor = 32
)

// n 后问题:局部搜索法
func NQueenLocalSearch(n int) {
   
	c := n
	downSlash, upSlash := make([]int, 2*n), make([]int, 2*n)
	var s []int
	// 从这里开始计时
	start := time.Now()
outer:
	for c > 0 {
   
		// 1. 随机生成棋盘
		s = RandomCreateNQByArray(n)
		// 2. 获取棋盘中的冲突
		c := GetConflictsByArray(s, downSlash, upSlash)
		// 3. 如果冲突为0,转 7
		if c == 0 {
   
			break outer
		}
		// 4. 获取棋盘上陷入冲突的所有棋子
		attacks := GetAttack(s, downSlash, upSlash)
		limit := int(speedUpFactor * float64(c))
		loopSteps := 0
		for loopSteps < cycleFactor*n {
   
			for k := 0; k < len(attacks); k++ {
   
				i := attacks[k]
				j := randInt(i, n)
				// 5. 对冲突棋子进行模拟交换的冲突计算,若冲突减少,则更新棋盘,否则继续取其他冲突棋子
				if c1 := calConflictBeforeSwap(s, downSlash, upSlash, i, j); c1 < 0 {
   
					c += c1
					// 更新交换后的棋盘
					updateQueen
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值