蛮力法又称为枚举法,穷举法,暴力法。蛮力算法是一种简单直接地解决问题,但不一定是最高效的方法
蛮力法所具有的优点:
蛮力法所具有的缺点:
蛮力法是指采用遍历(扫描)技术,即采用一定的策略将待求解问题的所有元素依次处理一次,从而找出问题的解。依次处理所有元素是蛮力法的关键,为了避免陷入重复试探,应保证处理过的元素不再被处理。
问题描述:
给定一个可排序的n元序列,将它们按照非降序方法重新排序
使用蛮力法的思路(递归描述):
算法设计(伪代码):
//非递归
Algorithm SS(A[0..n-1]) //SelectionSort
//输入:n元数组
//输出:n元数组
for i=0 to n-2 do
min:=i;
for j:=i+1 to n-1 do
if A[j]<A[min] then min->j;
swap A[i] and A[min]
算法分析:
输入规模(空间复杂度)
因为输入的是n元数组,故空间复杂度是:O(n)
算法的基本操作:
比较A[j] < A[min],数据交换swap
比较次数C(n)
C ( n ) = ∑ i = 0 n − 2 ∑ j = i + 1 n − 1 1 = ∑ i = 0 n − 2 ( n − 1 − i ) = n ( n − 1 ) 2 C(n)={\sum_{i=0}^{n-2}\sum_{j=i+1}^{n-1}1}={\sum_{i=0}^{n-2}(n-1-i)}=\frac{n(n-1)}{2} C(n)=i=0∑n−2j=i+1∑n−11=i=0∑n−2(n−1−i)=2n(n−1)
于是C(n)属于O(n2)
问题描述:
给定一个可排序的n元序列,将它们按照非降序方法重新排序
使用蛮力法的解决思路:
算法设计:
Algorithm BS(A[0..n-1]) //BubbleSort
//输入:n元数组
//输出:n元数组
for i:=0 to n-2 do
for j:=0 to n-2-i do
if A[j+1]<A[j] then swap A[j] and A[j+1]
算法分析:
输入规模(空间复杂度)
因为输入的是n元数组,故空间复杂度是:O(n)
算法的基本操作:
比较A[j] < A[j+1],数据交换swap
比较次数C(n)
C ( n ) = ∑ i = 0 n − 2 ∑ j = 0 n − 2 − i 1 = ∑ i = 0 n − 2 ( n − 1 − i ) = n ( n − 1 ) 2 C(n)={\sum_{i=0}^{n-2}\sum_{j=0}^{n-2-i}1}={\sum_{i=0}^{n-2}(n-1-i)}=\frac{n(n-1)}{2} C(n)=i=0∑n−2j=0∑n−2−i1=i=0∑n−2(n−1−i)=2n(n−1)
于是C(n)属于O(n2)
问题描述:
已知有n个元素的数组A[0…n],给定元素K,要求找出一个下标i,,使得A[i]=K.。输出第一个值等于K的元素的位置,找不到返回-1。
使用蛮力法解决问题的思路:
遍历数组
算法设计:
Algorithm SequentialSearch(A[0..n-1],K)
//输入:n元数组,给定元素k
//输出:所寻找到的元素k的下标
i:=0;
while A[i]≠K and i<n do
i:=i+1;
if A[i]=K then return i
else return -1
算法分析:
输入规模
因为输入的是n元数组,故空间复杂度是:O(n)
算法的基本操作
比较A[i]与k是否相同
比较次数
问题描述:
从文本中寻找匹配模式的子串,即求出第一个匹配模式的子串在文本中的开始位置(子串最左元素的下标)。
使用蛮力法解决问题的思路:
将模式对准文本的前m个字符从左往右进行比对,如果其中有一个字符不匹配,模式往右移动一位继续下一个m个字符的比对。
算法设计:
Algorithm BFSM (T[0..n-1], P[0..m-1])// Brute Force String Match
//输入:文本数组T[0..n-1],模式数组P[0..m-1] (n>m)
//输出:所寻找的的位置的下标,查找不成功时返回-1
for i :=0 to n-m do
j := 0
while j<m and P[j]=T[i+j] do
j := j+1
if j=m return i
return -1
算法分析:
输入规模
输入了两个数组,长度分别为n和m,故空间复杂度是:O(n+m)
算法的基本操作
比较
比较次数
最坏情况:
模式需要移动n-m+1次,模块每次移动前,都要做m次对比,此时的时间复杂度属于nm级别
最好情况:
模式不需要移动,只需要比较m次,时间复杂度属于m级别
平均时间复杂度属于n级别的
问题描述:
给定平面S上n个点,找其中的一对点,使得在n(n-1)/2个点对中,该点对的距离最小。
使用蛮力法解决问题的思路:
把所有的点两两组合,比较它们之间的距离即可以得到距离最小的一对
算法设计:
Algorithm BFCP ( P ) // Brute Force Closest Points
// 输入:n个点的数组P,Pi(xi , yi), i=1, 2, …, n
// 输出:两个最近点的下标index1和index2
dmin := ∞;
for i := 1 to n-1 do
for j := i+1 to n do
d := sqrt((xi-xj)2+(yi-yj)2);
if d < dmin then
dmin := d;
index1 := i; index2 := j;
return index1, index2
算法分析:
输入规模
算法的基本操作
平方操作
比较次数C(n)
C ( n ) = ∑ i = 1 n − 1 ∑ j = i + 1 n 2 = 2 ∑ i = 0 n − 2 ( n − i ) = n ( n − 1 ) C(n)={\sum_{i=1}^{n-1}\sum_{j=i+1}^{n}2}=2{\sum_{i=0}^{n-2}(n-i)}=n(n-1) C(n)=i=1∑n−1j=i+1∑n2=2i=0∑n−2(n−i)=n(n−1)
于是C(n)属于O(n2)
问题描述:
凸集定义:
设S是平面点集,如果S中任意两点的连线都属于该集合,则称S是凸的
凸包定义:
一个点集S的凸包是指包含S的最小凸集。显然,如果S是凸的,则S的凸包就是S本身(橡皮筋圈解释)。
给定一个n个点的点集S,求S的凸包。
使用蛮力法解决问题的思路:
极点:
凸集的极点是指不会出现在集合中任何线段的中间的点。
设点集大小为n,首先将其中的点两两配对,得到直线段条。
然后对每一条直线段检查其余的n-2个点的相对于该直线段的正负性,如果它们都有相同的正负性,那么这条直线段属于凸多边形的边,其顶点是极点。
穷举法是一种简单的蛮力方法,它要求生成所有可能的可行解,再从中选择最优解。
目前没有已知的效率可以用多项式来表示的算法,需要通过穷举法去解决,下面是两个经典问题:
给定n个城市相互之间的距离,求一条能走遍n个城市的最短路径,使我们能从任一城市开始,访问每个城市只一次后回到起点。
给定n个重量为w1、w2…wn,价值为v1、v2、…、vn的物品和一个承重为W的背包,如何将物品装入背包使背包所获的价值最大。
有n个任务需要分配给n个人执行,一人一个任务。将第j个任务分配给第i个人的成本是C[i, j],求总成本最小的分配方案。
可用穷举法列出n的阶乘个可能的解决方案