前言 大家好吖,欢迎来到 YY 滴算法不挂科系列 ,热烈欢迎! 本章主要内容面向接触过C++的老铁
A、运⾏速度快 B、占⽤空间少 C、时间复杂度低 D、代码短
A、蒙特卡罗算法 B、拉斯维加斯算法 C、舍伍德算法 D、数值概率算法
A、数值概率算法 B、舍伍德算法 C、拉斯维加斯算法 D、蒙特卡罗算法
A. 贪⼼算法 B. 回溯法 C.动态规划算法 D.舍伍德算法
A、分⽀界限算法 B、概率算法 C、贪⼼算法 D、回溯算法
A. 蒙特卡罗算法 B. 拉斯维加斯算法 C.动态规划算法 D.舍伍德算法
A.不⾼于 B.不低于 C.等价于 D.逼近
A .(1)(2)(3) B.(1)(2)(4) C.(1)(3)(4) D.(1)(2)(3)(4)
A. 2n B. 32n C. nlogn D. 10nlogn
A NP问题都是不可能解决的问题 B P类问题包含在NP类问题中 C NP完全问题是P类问题的⼦集 D NP类问题包含在P类问题中
A.满⾜显约束的值的个数 B. 计算约束函数的时间 C. 计算限界函数的时间 D. 确定解空间的时间
A.递归函数 B.剪枝函数 C.随机数函数 D.搜索函数
A、⼦集树 B、排列树 C、深度优先⽣成树 D、⼴度优先⽣成树
A.深度优先 B.⼴度优先 C.最⼩耗费优先 D.活结点优先
A.有序树 B.⼦集树 C.排列树 D.⽆序树
A、O(n*2n) B、O(nlogn) C、O(2的n次方) D、O(n)
A、分治策略 B、动态规划法 C、贪⼼法 D、回溯法
A、备忘录法 B、动态规划法 C、贪⼼法 D、回溯法
A、找出最优解的性质 B、构造最优解 C、算出最优解 D、定义最优解
A、分⽀界限法 B、动态规划法 C、贪⼼法 D、回溯法
A、分⽀界限算法 B、动态规划算法 C、贪⼼算法 D、回溯算法
A、分治法 B、动态规划法 C、贪⼼法 D、回溯法
A、定义最优解 B、构造最优解 C、算出最优解 D、⼦问题重叠性质
A、重叠⼦问题 B、最优⼦结构性质 C、贪⼼选择性质 D、定义最优解
A.logn B.n C.n2 D.nlogn
A、棋盘覆盖问题 B、选择问题 C、归并排序 D、0/1背包问题
A、分治策略 B、动态规划法 C、贪⼼法 D、回溯法
A、贪⼼法 B、动态规划法 C、分治策略 D、回溯法
A、分治策略 B、动态规划法 C、贪⼼法 D、回溯法
A、分治法 B、动态规划法 C、贪⼼法 D、回溯法
A、分治策略 B、动态规划法 C、贪⼼法 D、回溯法
A、分治策略 B、动态规划法 C、贪⼼法 D、回溯法
A、分治策略 B、动态规划法 C、贪⼼法 D、回溯法
A、⼦问题必须是⼀样的 B、⼦问题不能够重复 C、⼦问题的解可以合并 D、原问题和⼦问题使⽤相同的⽅法解
A、单源最短路径问题 B、N皇后问题 C、最⼩花费⽣成树问题 D、背包问题
A、贪⼼法 B、动态规划 C、回溯法 D、分⽀限界法
A、重叠⼦问题 B、构造最优解 C、贪⼼选择性质 D、最优⼦结构性质
A、最优⼦结构 B、贪⼼选择性质 C、构造最优解 D、定义最优解
A.分治 B.贪⼼ C.动态规划 D.穷举
A、O(n2n) B、O(nlogn) C、O(2n) D、O(n)
A、O(n×2的n次方) B、O(nlogn) C、O(2的n次方) D、O(n)
A、O(n*2n) B、O(nlogn) C、O(2的n次方) D、O(n)
A、O(n*2n) B、O(nlogn) C、O(2n) D、O(n)
A.有序树 B.⼦集树 C.排列树 D.⽆序树
A、分⽀界限法 B、动态规划法 C、贪⼼法 D、回溯法
A、⼴度优先 B、最⼩耗费优先 C、最⼤效益优先 D、深度优先
A、分⽀界限法 B、动态规划法 C、贪⼼法 D、回溯法
A、先进先出 B、后进先出 C、结点的优先级 D、随机
A、最⼩堆 B、最⼤堆 C、栈 D、数组
A 、最⼩堆 B 、最⼤堆 C 、栈 D、数组
A.队列式分⽀限界法 B.优先队列式分⽀限界法 C.栈式分⽀限界法 D.FIFO分⽀限界法
A.回溯法 B.分⽀限界法 C.回溯法和分⽀限界法 D.回溯法求解⼦集树问题
A.有序树 B.⼦集树 C.排列树 D.⽆序树
void Knapsack(int n, float M, float v[], float w[], float x[])
{
Sort(n, v, w);
int i;
for (i = 1; i <= n; i++)
x[i] = 0;
float c = M;
for (i = 1; i <= n; i++)
{
if (w[i] > c)
break;
x[i] = 1;
c -= w[i];
}
if (i <= n)
x[i] = c / w[i];
}
int MaxSum(int n, int a[]) { int sum=0, b=0; //sum存储当前最⼤的b[j], b存储b[j] for(int j=1; j<=n; j++) { if (b>0) b+= a[j] ; else b=a[i]; ; //⼀旦某个区段和为负,则从下⼀个位置累和 if(b>sum) sum=b; } return sum; }
template <typename Type>
void QuickSort(Type a[], int p, int r)
{
if (p < r) {
int q = Partition(a, p, r);
QuickSort(a, p, q - 1); // 对左半段排序
QuickSort(a, q + 1, r); // 对右半段排序
}
}
#include <iostream>
#include <algorithm> // 为了使用 std::swap
template <class Type>
void perm(Type list[], int k, int m)
{
// 产生 [list[k:m]] 的所有排列
if (k == m)
{
// 只剩下一个元素,打印排列
for (int i = 0; i <= m; ++i)
std::cout << list[i];
std::cout << std::endl;
}
else
{
// 还有多个元素待排列,递归产生排列
for (int i = k; i <= m; ++i)
{
std::swap(list[k], list[i]); // 交换 list[k] 和 list[i]
perm(list, k + 1, m); // 递归调用 perm 函数
std::swap(list[k], list[i]); // 恢复 list[k] 和 list[i] 的原始顺序(回溯)
}
}
}
int main()
{
// 示例数组
int arr[] = {1, 2, 3};
int n = sizeof(arr) / sizeof(arr[0]);
// 生成并打印所有排列
perm(arr, 0, n - 1);
return 0;
}
template <class Type>
int BinarySearch(Type a[], const Type& x, int l, int r)
{
while (l <= r)
{
// 计算中间索引,注意使用整数除法
// 为了避免 (l + r) 可能的整数溢出,使用 l + (r - l) / 2
int m = l + (r - l) / 2;
if (x == a[m])
{
return m; // 找到元素,返回索引
}
else if (x < a[m])
{
r = m - 1; // 元素在左半部分,更新右边界
}
else
{
l = m + 1; // 元素在右半部分,更新左边界
}
}
return -1; // 未找到元素,返回 -1
}
template void Mergesort(Type a[ ], int left, int right) { if (left<right){ int i=( left+right)/2; Mergesort(a, left, i ); Mergesort(a, i+1, right); Merge(a,b, left,i,right);//合并到数组b Copy(a,b, left,right ); //复制到数组a } }
int power ( x, m ) { //计算xm 的值并返回。 y=( 1 );i=m; While(i- - >0) y=y*x; (return y) ; }
1、问题分析2、数学模型建⽴3、算法设计与选择4、算法指标5、算法分析 6、算法实现7、程序调试8、结果整理⽂档编制
算法是指在解决问题时,按照某种机械步骤⼀定可以得到问题结果的处理过 程
1、操作2、控制结构3、数据结构
有穷性:⼀个算法必须总是在执⾏有穷步之后结束,且每⼀步都在有穷时 间内完成。 确定性:算法中每⼀条指令必须有确切的含义。不存在⼆义性。只有⼀个 ⼊⼝和⼀个出⼝ 可⾏性:⼀个算法是可⾏的就是算法描述的操作是可以通过已经实现的基 本运算执⾏有限次来实现的。 输⼊:⼀个算法有零个或多个输⼊,这些输⼊取⾃于某个特定对象的集 合。 输出:⼀个算法有⼀个或多个输出,这些输出同输⼊有着某些特定关系的 量。
正确性:算法应满⾜具体问题的需求; 可读性:算法应该好读,以有利于读者对程序的理解; 健壮性:算法应具有容错处理,当输⼊为⾮法数据时,算法应对其作出反 应,⽽不是产⽣莫名其妙的输出结果。 效率与存储量需求:效率指的是算法执⾏的时间;存储量需求指算法执⾏ 过程中所需要的最⼤存储空间。⼀般这两者与问题的规模有关。 经常采⽤的算法主要有迭代法、分治法、贪婪法、动态规划法、回溯法、分⽀ 限界法
也称“辗转法”,是⼀种不断⽤变量的旧值递推出新值的解决问题的⽅法。 7.利⽤迭代算法解决问题,需要做好以下三个⽅⾯的⼯作: 1)、确定迭代模型。在可以⽤迭代算法解决的问题中,⾄少存在⼀个直接 或间接地不断由旧值递推出新值的变量,这个变量就是迭代变量。 2)、建⽴迭代关系式。所谓迭代关系式,指如何从变量的前⼀个值推出其 下⼀个值的公式(或关系)。迭代关系式的建⽴是解决迭代问题的关键,通常 可以使⽤递推或倒推的⽅法来完成。 3)、对迭代过程进⾏控制。在什么时候结束迭代过程?这是编写迭代程序 必须考虑的问题。不能让迭代过程⽆休⽌地重复执⾏下去。迭代过程的控制通 常可分为两种情况:⼀种是所需的迭代次数是个确定的值,可以计算出来;另 ⼀种是所需的迭代次数⽆法确定。对于前⼀种情况,可以构建⼀个固定次数的 循环来实现对迭代过程的控制;对于后⼀种情况,需要进⼀步分析出⽤来结束 迭代过程的条件。
将⼀个规模为n的问题分解为k个规模较⼩的⼦问题,这些⼦问题互相独⽴且 与原问题相同。递归地解这些⼦问题,然后将各个⼦问题的解合并得到原问题 的解。
(1)该问题的规模缩⼩到⼀定的程度就可以容易地解决; (2)该问题可以分解为若⼲个规模较⼩的相同问题,即该问题具有最优⼦ 结构性质; (3)利⽤该问题分解出的⼦问题的解可以合并为该问题的解; (4)该问题所分解出的各个⼦问题是相互独⽴的,即⼦问题之间不包含公 共的⼦⼦问题。
分治法在每⼀层递归上都有三个步骤: (1)分解:将原问题分解为若⼲个规模较⼩,相互独⽴,与原问题形式相 同的⼦问题; (2)解决:若⼦问题规模较⼩⽽容易被解决则直接解,否则递归地解各个 ⼦问题; (3)合并:将各个⼦问题的解合并为原问题的解。
前⽂主要介绍了动态规划的⼀些理论依据,我们将前⽂所说的具有明显的 阶段划分和状态转移⽅程的动态规划称为标准动态规划,这种标准动态规划是 在研究多阶段决策问题时推导出来的,具有严格的数学形式,适合⽤于理论上 的分析。在实际应⽤中,许多问题的阶段划分并不明显,这时如果刻意地划分 阶段法反⽽麻烦。⼀般来说,只要该问题可以划分成规模更⼩的⼦问题,并且 原问题的最优解中包含了⼦问题的最优解(即满⾜最优⼦化原理),则可以考 虑⽤动态规划解决。 动态规划的实质是分治思想和解决冗余,因此,动态规划是⼀种将问题实 例分解为更⼩的、相似的⼦问题,并存储⼦问题的解⽽避免计算重复的⼦问 题,以解决最优化问题的算法策略。 由此可知,动态规划法与分治法和贪⼼法类似,它们都是将问题实例归纳 为更⼩的、相似的⼦问题,并通过求解⼦问题产⽣⼀个全局最优解。 贪⼼法的当前选择可能要依赖已经作出的所有选择,但不依赖于有待于做 出的选择和⼦问题。因此贪⼼法⾃顶向下,⼀步⼀步地作出贪⼼选择; ⽽分治法中的各个⼦问题是独⽴的(即不包含公共的⼦问题),因此⼀旦递归 地求出各⼦问题的解后,便可⾃下⽽上地将⼦问题的解合并成问题的解。 不⾜之处:如果当前选择可能要依赖⼦问题的解时,则难以通过局部的贪 ⼼策略达到全局最优解;如果各⼦问题是不独⽴的,则分治法要做许多不必要 的⼯作,重复地解公共的⼦问题。 解决上述问题的办法是利⽤动态规划。该⽅法主要应⽤于最优化问题,这 类问题会有多种可能的解,每个解都有⼀个值,⽽动态规划找出其中最优(最 ⼤或最⼩)值的解。若存在若⼲个取最优值的解的话,它只取其中的⼀个。在 求解过程中,该⽅法也是通过求解局部⼦问题的解达到全局最优解,但与分治 法和贪⼼法不同的是,动态规划允许这些⼦问题不独⽴,(亦即各⼦问题可包 含公共的⼦问题)也允许其通过⾃身⼦问题的解作出选择,该⽅法对每⼀个⼦ 问题只解⼀次,并将结果保存起来,避免每次碰到时都要重复计算。 因此,动态规划法所针对的问题有⼀个显著的特征,即它所对应的⼦问题 树中的⼦问题呈现⼤量的重复。动态规划法的关键就在于,对于重复出现的⼦ 问题,只在第⼀次遇到时加以求解,并把答案保存起来,让以后再遇到时直接 引⽤,不必重新求解。
设计⼀个标准的动态规划算法,通常可按以下⼏个步骤进⾏: (1)划分阶段:按照问题的时间或空间特征,把问题分为若⼲个阶段。注意这 若⼲个阶段⼀定要是有序的或者是可排序的(即⽆后向性),否则问题就⽆法 ⽤动态规划求解。 (2)选择状态:将问题发展到各个阶段时所处于的各种客观情况⽤不同的状态 表示出来。当然,状态的选择要满⾜⽆后效性。 (3)确定决策并写出状态转移⽅程:之所以把这两步放在⼀起,是因为决策和 状态转移有着天然的联系,状态转移就是根据上⼀阶段的状态和决策来导出本 阶段的状态。所以,如果我们确定了决策,状态转移⽅程也就写出来了。但事 实上,我们常常是反过来做,根据相邻两段的各状态之间的关系来确定决策。 (4)写出规划⽅程(包括边界条件):动态规划的基本⽅程是规划⽅程的通⽤ 形式化表达式。 ⼀般说来,只要阶段、状态、决策和状态转移确定了,这⼀步还是⽐较简单 的。动态规划的主要难点在于理论上的设计,⼀旦设计完成,实现部分就会⾮ 常简单。根据动态规划的基本⽅程可以直接递归计算最优值,但是⼀般将其改 为递推计算。实际应⽤当中经常不显式地按照上⾯步骤设计动态规划,⽽是按 以下⼏个步骤进⾏: (1)分析最优解的性质,并刻划其结构特征。 (2)递归地定义最优值。 (3)以⾃底向上的⽅式或⾃顶向下的记忆化⽅法(备忘录法)计算出最优值。 (4)根据计算最优值时得到的信息,构造⼀个最优解。 步骤(1)~(3)是动态规划算法的基本步骤。在只需要求出最优值的情形, 步骤(4)可以省略,若需要求出问题的⼀个最优解,则必须执⾏步骤(4)。 此时,在步骤(3)中计算最优值时,通常需记录更多的信息,以便在步骤 (4)中,根据所记录的信息,快速地构造出⼀个最优解。 总结:动态规划实际上就是最优化的问题,是指将原问题的⼤实例等价于 同⼀最优化问题的较⼩实例,⾃底向上的求解最⼩实例,并将所求解存放起 来,存放的结果就是为了准备数据。与递归相⽐,递归是不断的调⽤⼦程序求 解,是⾃顶向下的调⽤和求解。
将待求解的问题分解成若⼲个⼦问题,先求解⼦问题,然后从这些⼦问题 的解得到原问题的解。 两者的不同点是:适合于⽤动态规划法求解的问题,经分解得到的⼦问题 往往不是互相独⽴的。⽽⽤分治法求解的问题,经分解得到的⼦问题往往是互 相独⽴的。
回溯法也称为试探法,该⽅法⾸先暂时放弃关于问题规模⼤⼩的限制,并将 问题的候选解按某种顺序逐⼀枚举和检验。当发现当前候选解不可能是解时, 就选择下⼀个候选解;倘若当前候选解除了还不满⾜问题规模要求外,满⾜所 有其他要求时,继续扩⼤当前候选解的规模,并继续试探。如果当前候选解满 ⾜包括问题规模在内的所有要求时,该候选解就是问题的⼀个解。在回溯法 中,放弃当前候选解,寻找下⼀个候选解的过程称为回溯。扩⼤当前候选解的 规模,以继续试探的过程称为向前试探。
这是⼀种⽤于求解组合优化问题的排除⾮解的搜索算法。类似于回溯法, 分枝定界法在搜索解空间时,也经常使⽤树形结构来组织解空间。然⽽与回溯 法不同的是,回溯算法使⽤深度优先⽅法搜索树结构,⽽分枝定界⼀般⽤宽度 优先或最⼩耗费⽅法来搜索这些树。因此,可以很容易⽐较回溯法与分枝定界 法的异同。相对⽽⾔,分枝定界算法的解空间⽐回溯法⼤得多,因此当内存容 量有限时,回溯法成功的可能性更⼤。 算法思想:分枝限界(branch and bound)是另⼀种系统地搜索解空间的⽅ 法,它与回溯法的主要区别在于对E-节点的扩充⽅式。每个活节点有且仅有⼀ 次机会变成E-节点。当⼀个节点变为E-节点时,则⽣成从该节点移动⼀步即可 到达的所有新节点。在⽣成的节点中,抛弃那些不可能导出(最优)可⾏解的 节点,其余节点加⼊活节点表,然后从表中选择⼀个节点作为下⼀个E-节点。 从活节点表中取出所选择的节点并进⾏扩充,直到找到解或活动表为空,扩充 过程才结束。 有两种常⽤的⽅法可⽤来选择下⼀个E-节点(虽然也可能存在其他的⽅ 法):
问题解的算法。 不同点:(1)求解⽬标不同; (2)搜索⽅式不同; (3)对扩展结点的扩展⽅式不同; (4)存储空间的要求不同。
(1)该问题的规模缩⼩到⼀定的程度就可以容易地解决; (2)该问题可以分解为若⼲个规模较⼩的相同问题,即该问题具有最优⼦ 结构性质; (3)利⽤该问题分解出的⼦问题的解可以合并为该问题的解; (4)原问题所分解出的各个⼦问题是相互独⽴的,即⼦问题之间不包含公 共的⼦问题。
(1)针对所给问题,定义问题的解空间(对解进⾏编码); (2)确定易于搜索的解空间结构(按树或图组织解) ; (3)以⼴度优先或以最⼩耗费(最⼤收益)优先的⽅式搜索解空间,并在搜 索过程中⽤剪枝函数避免⽆效搜索。
(1)队列式(FIFO)分⽀限界法:按照队列先进先出(FIFO)原则选取下⼀ 个节点为扩展节点。 (2)优先队列式分⽀限界法:按照优先队列中规定的优先级选取优先级最 ⾼的节点成为当前扩展节点。
当所给的问题是从n个元素的集合S中找出满⾜某种性质的⼦集时,相应 的解空间树称为⼦集树。这类⼦集树通常有2n个叶结点,遍历⼦集树需O(2n)计 算时间 。 当所给的问题是确定n个元素满⾜某种性质的排列时,相应的解空间树称 为排列树。这类排列树通常有n!个叶结点。遍历排列树需要O(n!)计算时间。
在扩展结点处,先⽣成其所有的⼉⼦结点(分⽀),然后再从当前的活结 点表中选择下⼀个扩展结点。为了有效地选择下⼀扩展结点,加速搜索的进 程,在每⼀个活结点处,计算⼀个函数值(限界),并根据函数值,从当前活 结点表中选择⼀个最有利的结点作为扩展结点,使搜索朝着解空间上有最优解 的分⽀推进,以便尽快地找出⼀个最优解。
共同点: 都需要最优⼦结构性质, 都⽤来求有优化问题。 不同点: 动态规划:每⼀步作⼀个选择—依赖于⼦问题的解。 贪⼼⽅法:每⼀步作⼀个选择—不依赖于⼦问题的解。 动态规划⽅法的条件:⼦问题的重叠性质。 可⽤贪⼼⽅法的条件:最优⼦结构性质;贪⼼选择性质。 动态规划:⾃底向上求解; 贪⼼⽅法: ⾃顶向下求解。 可⽤贪⼼法时,动态规划⽅法可能不适⽤; 可⽤动态规划⽅法时,贪⼼法可能不适⽤。
答: 最优⼦结构性质是指⼤问题的最优解包含⼦问题的最优解。 动态规划⽅法是⾃底向上计算各个⼦问题的最优解,即先计算⼦问题的最优 解,然后再利⽤⼦问题的最优解构造⼤问题的最优解,因此需要最优⼦结 构.
(1)优先队列可⽤什么数据结构实现? (2)优先队列插⼊算法基本思想? (3)优先队列插⼊算法时间复杂度? 答:(1)堆。 (2)在⼩根堆中,将元素x插⼊到堆的末尾, 然后将元素x的关键字与其双亲的关键字⽐较, 若元素x的关键字⼩于其双亲的关键字, 则将元素x与其双亲交换,然后再将元素x与其新双亲的关键字相 ⽐,直到元素x的关键字⼤于双亲的关键字,或元素x到根为⽌。 (3)O( log n) 25. 衡量算法时间效率的⽅法有哪两种?请叙述。 答:有事前分析法和事后分析法两种。 事后分析法:先将算法⽤程序设计语⾔实现,然后度量程序的运⾏时间。 事前分析法:算法的时间效率是问题规模的函数,假如,随着问题规模n的增 ⻓,算法执⾏时间的增⻓率和函数f(n)的增⻓率相同,则可记作: T(n)=○(f(n)) 称T(n)为算法的渐进时间复杂度。简称时间复杂度。 26. 在算法复杂性分析中,O、Ω、Θ这三个记号的意义是什么?在忽略常数因 ⼦的情况 下,O、Ω、Θ分别提供了算法运⾏时间的什么界? 答: 如果存在两个正常数c和N0,对于所有的N≥N0,有|f(N)|≤C|g(N)|,则记作:f(N)= O(g(N))。这时我们说f(N)的阶不⾼于g(N)的阶。 若存在两个正常数C和⾃然数N0,使得当N ≥ N0时有|f(N)|≥C|g(N)|,记为 f(N)=Ω(g(N))。这时我们说f(N)的阶不低于g(N)的阶。 如果存在正常数c1,c2和n0,对于所有的n≥n0,有c1|g(N)| ≤|f(N)| ≤ c2|g(N)| 则记作 f(N)= (g,(N)) O、Ω、Θ分别提供了算法运⾏时间的上界、下界、平均
很多算法的每⼀个计算步骤都是固定的,⽽概率算法允许算法在执 ⾏的过程中随机选择下⼀个计算步骤。许多情况下,当算法在执⾏过程中⾯临 ⼀个选择时,随机性选择常⽐最优选择省时。因此概率算法可在很⼤程度上降 低算法的复杂度。
是对所求解问题的同⼀实例⽤同⼀概率算法求解两次可能得到完全不同的 效果。这两次求解问题所需的时间甚⾄所得到的结果可能会有相当⼤的差别。
数值概率算法,蒙特卡罗(Monte Carlo)算法,拉斯维加斯(Las Vegas) 算法和舍伍德(Sherwood)算法。
常⽤于数值问题的求解。这类算法所得到的往往是近似解。⽽且近似解的 精度随计算时间的增加不断提⾼。在许多情况下,要计算出问题的精确解是不 可能或没有必要的,因此⽤数值概率算法可得到相当满意的解。
⽤于求问题的准确解。对于许多问题来说,近似解毫⽆意义。例如,⼀个判 定问题其解为“是”或“否”,⼆者必居其⼀,不存在任何近似解答。⼜如,我们 要求⼀个整数的因⼦时所给出的解答必须是准确的,⼀个整数的近似因⼦没有 任何意义。⽤蒙特卡罗算法能求得问题的⼀个解,但这个解未必是正确的。求 得正确解的概率依赖于算法所⽤的时间。算法所⽤的时间越多,得到正确解的 概率就越⾼。蒙特卡罗算法的主要缺点就在于此。⼀般情况下,⽆法有效判断 得到的解是否肯定正确。
不会得到不正确的解,⼀旦⽤拉斯维加斯算法找到⼀个解,那么这个解肯定 是正确的。但是有时候⽤拉斯维加斯算法可能找不到解。与蒙特卡罗算法类 似。拉斯维加斯算法得到正确解的概率随着它⽤的计算时间的增加⽽提⾼。对 于所求解问题的任⼀实例,⽤同⼀拉斯维加斯算法反复对该实例求解⾜够多 次,可使求解失效的概率任意⼩。
总能求得问题的⼀个解,且所求得的解总是正确的。当⼀个确定性算法在最 坏情况下的计算复杂性与其在平均情况下的计算复杂性有较⼤差别时,可以在 这个确定算法中引⼊随机性将它改造成⼀个舍伍德算法,消除或减少问题的好 坏实例间的这种差别。舍伍德算法精髓不是避免算法的最坏情况⾏为,⽽是设 法消除这种最坏⾏为与特定实例之间的关联性。 Θ舍伍德算法 sherwood algorithm 舍伍德算法 ⼀类概率算法的代称。此类算法总能给出所求问题的正确的解。… 当解决某⼀问题的确定性算法的平均情形复杂性⽐最坏情形复杂性低得多时, 通过引⼊随机性来试图减少甚⾄消除“好”、“坏”实体之间这种时间上的差别, 以期望较⼩的运⾏时间。例 …