前言
概念
蛮力法(brute force):直接基于问题的描述和所涉及的概念定义的进行算法设计,简单而直接。
蛮力法应用特点
- 蛮力法所能解决的问题跨越的领域非常广泛。
- 对于一些重要的问题,运用蛮力策略可以设计出具备一定实用价值的算法,并且不用限制实例的规模。
- 当要解决的问题实例不多并且可以接受蛮力法的运算速度时,蛮力法的设计代价通常较为低廉。
- 蛮力算法可以作为衡量其它算法的准绳,服务于研究或教学。
枚举法
算法框架
- 依据问题,设定枚举范围;
- 找出约束条件,建立计算模型;
- 利用计算模型在枚举范围内搜索可能的解。
例题1
输入n个数字(在0与9之间),然后统计出这组数中相邻两个数字组成的链环数字对出现的次数。如:n=20,输入为0 1 5 9 8 7 2 2 2 3 2 7 8 7 8 7 9 6 5 9,则输出为(7,8)=2,(8,7)=3,(7,2)=1,(2,7)=1,(2,2)=2,(2,3)=1,(3,2)=1。
问题分析
可以利用一个二维数组a[10][10]存储出现的数字队。
首先,将二维数组初始化a[i][j]=0(0≤i<10,≤j<10)
然后,每输入一个数字对,则把对应下标的数组元素加1,如数据输入的序列为x,则a[xk][xk+1]=a[xk][xk+1]+1
如题目中的例子可以构建出如下的二维数组:

计算模型
输入序列:x
初始化:a[i][j]=0(0≤i<10,≤j<10)
a[xk][xk+1]=a[xk][xk+1]+10≤k<n
最后,统计完毕后,输出a
算法设计与描述

算法分析

例题2
解数字谜,如下

问题分析
一共可以采用三种方式
- 枚举测试:五位数的范围为30000-99999。时间复杂度为99999-30000 + 1 = 70000次
- 采用构造式的枚举法:A取值从3-9,B-C取值0-9。时间复杂度为71010 = 700
- 构造式的枚举法——除法:D的值从1-9,而A的取值仍然从3-9。两重循环,时间复杂度为7*9=63。
计算模型
主要针对第三种进行分析
设Ai∈[3,9],Dj∈[1,9]
⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧D=Dj∗105+⋯+DjDmodAi==0Si=D/AiB1=Simod10A1=(Si/10)mod10C=(Si/102)mod10B2=(Si/103)mod10A2=(Si/104)mod10上一步算得的D可以被Ai整除
判断D是否可以被Ai整除,A1与A2是否相等,B1和B2是否相等,上述条件均成立,则找到一个解。
算法设计与描述
输出:五位数ABCAB,六位数DDDDDD

例题3
输出玫瑰矩阵,其为n*n的方阵,特征如下所示对应下标的数组元素加1

问题分析
设矩阵为a[n,n]可以采用两种思路
- 用i代表圈数(从0开始),j代表圈内下标变化量:
⎩⎪⎪⎨⎪⎪⎧a[j,i]←ka[n−i−1,j]←ka[j,n−i−1]←ka[i,j]←kk←k+1k←k+1k←k+1k←k+1j←j+1j←j+1j←j−1j←j−1左侧底侧右侧顶侧
若n为奇数,还需要最后处理,令a[(n−1)/2,(n−1)/2]=n2
- 可以看出每半圈元素值增长规律变换一次
设增量t=1,每半圈变换一次t←−t
设矩阵边长为i,每半圈的元素就是2∗i−1个,hc为半圈内计数变量,0≤hc<2∗i−1,前1/4圈是0≤hc<i,后1/4圈是i≤hc<2∗i−1。
其中i从n开始变换,每过半圈 i=i−1
计算模型

算法设计与描述

算法分析

穷举查找
有一些求最优解的问题经过抽象,可以转换为组合优化问题,使用蛮力法来求解是一种简单的方法,称之为穷举查找(exhaustive search)。
例题4
旅行商问题(traveling salesman problem,TSP) 有一个旅行商由某市出发,经过所有给定的n个城市后,再回到出发的城市。除了出发的城市外,其它城市只经过一回。这样的回路可能有多个,求其中路径成本最小的回路。
问题分析
给出一个问题实例,如下

可以通过遍历a - d的全排列来实现问题求解。
计算模型
- 存储 利用图G(V,E)。边以临界矩阵形式存储,如下
- 计算 列出所有路径
a - b - c - d - a
a - b - d - c - a
a - c - b - d - a
a - c - d - b - a
a - d - b - c - a
a - d - c - b - a
- 计算路径代价
算法设计与描述

算法分析
T(n)=i=0∑n−1T(i+1)+C
例题5
背包问题。给定n个重量为w1,w2,…wn,价值为v1,v2,…vn的物品和一个承重为W的背包,求将这些物品中的某些装入背包中,在不超出重量W的情况下,价值最高的装法。
问题分析

计算模型

算法设计与描述

图的搜索
图的两个重要的遍历算法:深度优先查找(depth-first search, DFS)和广度优先查找(breadth-frist search, BFS),是穷举查找的重要应用之一。
深度优先查找

广度优先查找

例题6
迷宫问题。如图所示,图中方格内标为0的为通路,标为1墙。(0,0)为迷宫入口,(7,7)为迷宫出口,请查出由(0,0)到(7,7)的路径。

问题分析
- 存储
- 移动
计算模型
- 存储
采用二维矩阵maze[n][n],进行存储
其中maze[x][y] = 0表示通路,maze[x][y]=1表示墙,maze[x][y]=2表示死路,maze[x][y] = 3表示已经走过。
- 行走相对路径
行走方向:fx[]={-1,1,0,0 },fy[]={0,0, -1,1}
行走过程:nextx=x+fx[i],nexty=y+fy[i]
其中,i=0, 1, 2, 3。
算法设计与描述

算法分析
- 迷宫矩阵:maze[n][n]
- 依据不同的行走方向,可知T(n,n)=T(n−1,n)+T(n+1,n)+T(n,n−1)+T(n,n+1)。然而,这公式并不准确,因为墙的布局对算法的影响很大,所以,最坏情况下,所有顶点都测试过,这时,时间复杂度为
T(n)=O((n∗n−1)∗4)
- 存储空间中包括递归时的所用的栈,所以,空间复杂度至少为O(2∗n2)。