排兵布阵问题-回溯算法

      某游戏中,不同的兵种处于不同的地形上时,其攻击能力也一样,现有n个不同兵种的角色(1;2;; n),需安排在某战区n个点上,角色i在j点上的攻击力为Aij,试设计一个布阵方案,使总的攻击力最大。注:个人决定A矩阵的初始化工作。该问题求解算法的输入数据形如图4–1所示。

图4–1排兵布阵问题求解算法的输入数据

排兵布阵问题-回溯算法_第1张图片


刚学算法设计,这应该是典型的八皇后问题了,回溯问题。

可是我不知道怎么剪枝。

思路核心在于那个BackTrace函数

原理和数据结构的深度优先搜索是一样的。其实来个那个我觉着也行。

光看代码难理解,那么来画个图.

排兵布阵问题-回溯算法_第2张图片

从角色1站到位置一开始,按照剪枝条件遍历,深度优先搜索。

isPosition是判断位置是否符合条件的。backTrace函数的思路是

如果传进的参数>n,那么就说明这个递归调用到头了,可以计算这条路径上的攻击力和了。

否则,将x[]数组,更新,核心代码是这几句。

	for(int i=1;i<=n;i++){
			x[t] = i;
			if(isPosition(t)){
				backTrack(t+1);
			}
		}

 我水平不够有点表达不清,这个for循环有点类似于横的循环,就是从t=1(角色1)的时候

位置从1-5遍历。

同理,在1中调用backTrack(t+1),就是进入了角色2搜索,同样角色2也是从位置1到5开始判断。

同理,,

这几句话光看文字可能有点难看懂,建议耐心画一个图,慢慢理解。

 

#include
#include
#include
#include
using namespace std;
#define N 20 
int x[N] = {0};//用来存储第n行的皇后位置,比如X[1]=2代表第一行的位置是二 
int n;
int maxPower = INT_MIN;
int arr[N][N];
//判断位置能不能放 
bool isPosition(int layer)
{
	for(int i=1;i n)
	{
		int power = 0;
		printf("<");
		for(int i=1;i<=n;i++){
			printf("%d",x[i]);
			if(i!=n) printf(",");
			power += arr[i][x[i]];
		}
		if(power > maxPower) maxPower = power;
		printf("> power=%d maxPower=%d\n",power,maxPower);
	}else {
		for(int i=1;i<=n;i++){
			x[t] = i;
			if(isPosition(t)){
				backTrack(t+1);
			}
		}
	}
}
int main()
{
	printf("Please input the Matrix Order:\n");
	scanf("%d",&n);
	printf("Please input the attrack orderly:\n");
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			scanf("%d",&arr[i][j]);
		}
	}
	backTrack(1);
	return 0;
}

/*
5
60 40 80 50 60
90 60 80 70 20
30 50 40 50 80
90 40 30 70 90
60 80 90 60 50


4
20 50 60 40
10 30 20 50
30 10 50 60
40 20 30 70



*/

排兵布阵问题-回溯算法_第3张图片

你可能感兴趣的:(排兵布阵问题-回溯算法)