贪心算法 ppt_第1页
贪心算法 ppt_第2页
贪心算法 ppt_第3页
贪心算法 ppt_第4页
贪心算法 ppt_第5页
已阅读5页,还剩72页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第四章 贪心算法 Greedmethod 例题 算法设计与分析 贪心算法 顾名思义 贪心算法总是作出在当前看来最好的选择 也就是说贪心算法并不从整体最优考虑 它所作出的选择只是在某种意义上的局部最优选择 当然 希望贪心算法得到的最终结果也是整体最优的 虽然贪心算法不能对所有问题都得到整体最优解 但对许多问题它能产生整体最优解 如单源最短路经问题 最小生成树问题等 在一些情况下 即使贪心算法不能得到整体最优解 其最终结果却是最优解的很好近似 目的 用以求解最优化问题 将问题的求解过程看作是一系列选择 每次选择一个输入 每次选择都是当前状态下的最好选择 局部最优解 每作一次选择后 所求问题会简化为一个规模更小的子问题 从而通过每一步的最优解逐步达到整体的最优解 4 1基本思想 算法优点 求解速度快 时间复杂性有较低的阶 算法缺点 需证明是最优解 常见应用 背包问题 最小生成树 最短路径 作业调度等等 适用问题 具备贪心选择和最优子结构性质的最优化问题贪心选择性质 整体的最优解可通过一系列局部最优解达到 即贪心选择到达 贪心算法通常以自顶向下的方式进行 以迭代的方式作出相继的贪心选择 每做一次贪心选择就将所求解的问题化简为规模更小的问题对于一个具体问题 要确定它是否具有贪心选择的性质 我们必须证明每一步所作的贪心选择最终导致问题的最优解 通常可以首先证明问题的一个整体最优解 是从贪心选择开始的 而且作了贪心选择后 原问题简化为一个规模更小的类似子问题 然后 用数学归纳法证明 通过每一步作贪心选择 最终可得到问题的一个整体最优解 最优子结构性质 当一个问题的最优解包含其子问题的最优解时 称此问题具有最优子结构性质 某一问题的n个输入 该问题的一种解 可行解 是A的一个子集 满足一定的条件 约束条件 目标函数 取极值 最优解 算法设计与分析 贪心算法 4 2 活动安排问题 算法设计与分析 贪心算法 活动安排问题就是要在所给的活动集合中选出最大的相容活动子集合 是可以用贪心算法有效求解的很好例子 该问题要求高效地安排一系列争用某一公共资源的活动 贪心算法提供了一个简单 漂亮的方法使得尽可能多的活动能兼容地使用公共资源 问题陈述 设有n个活动的集合E 1 2 n 其中每个活动都要求使用同一资源 如演讲会场等 而在同一时间内只有一个活动能使用这一资源 每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi 且si fi 如果选择了活动i 则它在半开时间区间 si fi 内占用资源 若区间 si fi 与区间 sj fj 不相交 则称活动i与活动j是相容的 也就是说 当si fj或sj fi时 活动i与活动j相容 1234567891011 例 130535688212 4567891011121314 i s i f i 设待安排的11个活动起止时间按结束时间的非减序排列 最大相容活动子集 1 4 8 11 也可表示为等长n元数组 1 0 0 1 0 0 0 1 0 0 1 算法思路 将n个活动按结束时间非减序排列 依次考虑活动i 若i与已选择的活动相容 则添加此活动到相容活动子集 活动安排问题贪心算法 templatevoidGreedySelector intn Types Typef boolA A 1 true intj 1 从第二个活动开始检查是否与前一个相容for inti 2 i f j A i true j i elseA i false 算法设计与分析 贪心算法 各活动的起始时间和结束时间存储于数组s和f中且按结束时间的非减序排列 算法greedySelector的计算过程如左图所示 图中每行相应于算法的一次迭代 阴影长条表示的活动是已选入集合A的活动 而空白长条表示的活动是当前正在检查相容性的活动 由于输入的活动以其完成时间的非减序排列 所以算法greedySelector每次总是选择具有最早完成时间的相容活动加入集合A中 直观上 按这种方法选择相容活动为未安排活动留下尽可能多的时间 也就是说 该算法的贪心选择的意义是使剩余的可安排时间段极大化 以便安排尽可能多的相容活动 算法greedySelector的效率极高 当输入的活动已按结束时间的非减序排列 算法只需O n 的时间安排n个活动 使最多的活动能相容地使用公共资源 如果所给出的活动未按非减序排列 可以用O nlogn 的时间重排 T n O nlogn 未排序时 算法分析 T n O n 排序时 算法证明 算法达到最优解 问题描述 输入 x1 x2 xn xi 0 货箱i不装船 xi 1 货箱i装船可行解 满足约束条件 c的输入优化函数 最优解 使优化函数达到最大值的一种输入 4 3最优装载 算法设计与分析 贪心算法 算法思路 将装船过程划为多步选择 每步装一个货箱 每次从剩下的货箱中选择重量最轻的货箱 如此下去直到所有货箱均装上船或船上不能再容纳其他任何一个货箱 例 设n 8 w1 w8 100 200 50 90 150 50 20 80 c 400 所考察货箱的次序为 7 3 6 8 4 1 5 2 货箱7 3 6 8 4 1的总重量为390个单位且已被装载 剩下的装载能力为10 小于任意货箱 所以得到解 x1 x8 1 0 1 1 0 1 1 1 1 最优装载的贪心算法 算法设计与分析 贪心算法 templatevoidLoading intx Typew Typec intn int t newint n 1 Sort w t n 按货箱重量排序 for inti 1 i n i x i 0 for inti 1 i n 调整剩余空间 2 贪心选择性质可以证明最优装载问题具有贪心选择性质 3 最优子结构性质最优装载问题具有最优子结构性质 算法证明 由最优装载问题的贪心选择性质和最优子结构性质 容易证明算法loading的正确性 算法分析 算法loading的主要计算量在于将集装箱依其重量从小到大排序 故算法所需的计算时间为O nlogn 最优化描述 找一个n元向量 x1 xn 0 xi 1使得且 其中C Wi vi 0 1 i n 4 4背包问题 KnapsackProblem 问题描述 设有n个物体和一个背包 物体i的重量为wi 价值为vi 背包的容量为C 若将物体i的xi部分 1 i n 0 xi 1 装入背包 则具有价值为vixi 目标是找到一个方案 使放入背包的物体总价值最高 约束条件 优化函数 算法设计与分析 贪心算法 背包问题实例 考虑下列情况的背包问题n 3 M 20 v1 v2 v3 25 24 15 w1 w2 w3 18 15 10 其中的4个可行解是 算法设计与分析 贪心算法 贪心方法的数据选择策略 1 1 用贪心策略求解背包问题时 首先要选出最优的度量标准 可以选取目标函数为量度标准 每装入一件物品就使背包获得最大可能的效益值增量 在这种量度标准下的贪心方法就是按效益值的非增次序将物品一件件放到背包中 如上面的实例所示 可将物品按效益量非增次序排序 v1 v2 v3 25 24 15 先装入物品1重量为18 即x1 1 然后再装物品2 由于约束条为 wixi M 20 所以物品2只能装入重量为2的一小部分 即x2 2 15 按上述的数据选择策略 装入顺序是按照物品的效益值从大到小的输入 由刚才的方法可得这种情况下的总效益值为 vixi 25 24 2 15 28 2 显然是一个次优解 原因是背包容量消耗过快 算法设计与分析 贪心算法 贪心方法的数据选择策略 2 2 若以容量作为量度 可让背包容量尽可能慢地被消耗 这就要求按物品重量的非降次序来把物品放入背包 即 w3 w2 w1 10 15 18 先装入物品3 x3 1 p3x3 15 再装入重量为10的物品2 vixi 15 24 10 15 31 由刚才的方法可得这种情况下的总效益值为31 仍是一个次优解 原因是容量在漫漫消耗的过程中 效益值却没有迅速的增加 算法设计与分析 贪心算法 贪心方法的数据选择策略 3 3 采用在效益值的增长速率和容量的消耗速率之间取得平衡的量度标准 即每一次装入的物品应使它占用的每一单位容量获得当前最大的单位效益 这就需使物品的装入次序按vi wi比值的非增次序来考虑 这种策略下的量度是已装入物品的累计效益值与所用容量之比 v2 w2 v3 w3 v1 w1 24 15 15 10 25 18 先装入重量为15的物品2 在装入重量为5的物品3 pixi 24 15 5 10 31 5 此结果为最优解 算法设计与分析 贪心算法 算法思路 1 将各物体按单位价值由高到低排序 2 取价值最高者放入背包 3 计算背包剩余空间 4 在剩余物体中取价值最高者放入背包 若背包剩余容量 0或物体全部装入背包为止 例 n 3 c 20 v1 v2 v3 25 24 15 w1 w2 w3 18 15 10 x1 x2 x3 0 2 3 1 0 1 1 2 1 2 15 0 20 20 20 28 2 31 31 5 算法设计与分析 贪心算法 voidKnapsack intn floatM floatv floatw floatx Sort n v w t 按单位价值排序 inti for i 1 ic break x t i 1 c w t i if i n x t i c w t i 背包问题的贪心算法 算法设计与分析 贪心算法 算法分析 排序为主要算法时间 所以T n O nlogn 背包问题中的物体不能分拆 只能整个装入称为0 1背包问题 算法证明 该算法能得到在最优解 用贪心算法能得到0 1背包的最优解吗 首先计算每种物品单位重量的价值Vi Wi 然后 依贪心选择策略 将尽可能多的单位重量价值最高的物品装入背包 若将这种物品全部装入背包后 背包内的物品总重量未超过C 则选择单位重量价值次高的物品并尽可能多地装入背包 依此策略一直地进行下去 直到背包装满为止 具体算法可描述如下页 voidKnapsack intn floatM floatv floatw floatx Sort n v w inti for i 1 ic break x i 1 c w i if i n x i c w i 算法knapsack的主要计算时间在于将各种物品依其单位重量的价值从大到小排序 因此 算法的计算时间上界为O nlogn 为了证明算法的正确性 还必须证明背包问题具有贪心选择性质 对于0 1背包问题 贪心选择之所以不能得到最优解是因为在这种情况下 它无法保证最终能将背包装满 部分闲置的背包空间使每公斤背包空间的价值降低了 事实上 在考虑0 1背包问题时 应比较选择该物品和不选择该物品所导致的最终方案 然后再作出最好选择 由此就导出许多互相重叠的子问题 这正是该问题可用动态规划算法求解的另一重要特征 实际上也是如此 动态规划算法的确可以有效地解0 1背包问题 思考题 0 1背包问题 在杂货店比赛中你获得了第一名 奖品是一车免费杂货 店中有n种不同的货物 规则规定从每种货物中最多只能拿一件 车子的容量为c 物品i需占用wi的空间 价值为pi 你的目标是使车中装载的物品价值最大 当然 所装货物不能超过车的容量 且同一种物品不得拿走多件 如何选择量度标准才能找到最优解 算法设计与分析 贪心算法 思考题 找零钱问题 一个小孩买了价值为33美分的糖 并将1美元的钱交给售货员 售货员希望用数目最少的硬币找给小孩 假设提供了数目不限的面值为25美分 10美分 5美分 及1美分的硬币 使用贪心算法求解最优结果 并证明找零钱问题的贪心算法总能产生具有最少硬币数的零钱 算法设计与分析 贪心算法 问题 通讯过程中需将传输的信息转换为二进制码 由于英文字母使用频率不同 若频率高的字母对应短的编码 频率低的字母对应长的编码 传输的数据总量就会降低 要求找到一个编码方案 使传输的数据量最少 见P109 表4 1 算法设计与分析 贪心算法 1 前缀码为能正确译码 编码需采用前缀码 对每一个字符规定一个0 1串作为其代码 并要求任一字符的代码都不是其它字符代码的前缀 这种编码称为前缀码 表示最优前缀码的二叉树总是一棵完全二叉树 即树中任一结点都有2个儿子结点 平均码长定义为 使平均码长达到最小的前缀码编码方案称为给定编码字符集C的最优前缀码 4 4哈夫曼编码 算法思路 1 以n个字母为结点构成n棵仅含一个点的二叉树集合 字母的频率即为结点的权 2 每次从二叉树集合中找出两个权最小者合并为一棵二叉树 增加一个根结点将这两棵树作为左右子树 新树的权为两棵子树的权之和 3 反复进行步骤2 直到只剩一棵树为止 2 构造哈夫曼编码哈夫曼提出构造最优前缀码的贪心算法 由此产生的编码方案称为哈夫曼编码 哈夫曼算法以自底向上的方式构造表示最优前缀码的二叉树T 算法以 C 个叶结点开始 执行 C 1次的 合并 运算后产生最终所要求的树T 算法设计与分析 贪心算法 哈夫曼编码 templateBinaryTreeHuffmanTree Tf intn 根据权f 1 n 构造霍夫曼树 创建一个单节点树的数组Huffman W newHuffman n 1 BinaryTreez zero for inti 1 i Q 1 Q Initialize w n n 将堆中的树不断合并Huffmanx yfor i 1 i n i Q DeleteMin x Q DeleteMin y z MakeTree 0 x tree y tree x weight y weight x tree z Q Insert x Q DeleteMin x 最后的树Q Deactivate delete w returnx tree 哈夫曼树算法 算法设计与分析 贪心算法 哈夫曼编码 在书上给出的算法huffmanTree中 编码字符集中每一字符c的频率是f c 以f为键值的优先队列Q用在贪心选择时有效地确定算法当前要合并的2棵具有最小频率的树 一旦2棵具有最小频率的树合并后 产生一棵新的树 其频率为合并的2棵树的频率之和 并将新树插入优先队列Q 经过n 1次的合并后 优先队列中只剩下一棵树 即所要求的树T 算法huffmanTree用最小堆实现优先队列Q 初始化优先队列需要O n 计算时间 由于最小堆的removeMin和put运算均需O logn 时间 n 1次的合并总共需要O nlogn 计算时间 因此 关于n个字符的哈夫曼算法的计算时间为O nlogn 最优子结构 设T为带权w1 w2 wt的最优树 若将以带权w1和w2的树叶为儿子的分枝点改为带权w1 w2的树叶 得到一棵新树T 则T 也是最优树 贪心选择性 设T为带权w1 w2 wt的最优树 a 带权w1和w2的树叶vw1和vw2是兄弟 b 以vw1和vw2为儿子的分枝点 其通路长度最长 算法证明 算法分析 HuffmanTree初始化优先队列Q需要O n DeleteMin和Insert需O logn n 1次的合并总共需要O nlogn 所以n个字符的哈夫曼算法的计算时间为O nlogn 算法设计与分析 贪心算法 哈夫曼编码 4 5单源最短路径问题 给定带权有向图G V E 其中每条边的权是一个非负实数 要计算从V的一点v0 源 到所有其他各顶点的最短路长度 路长指路上各边权之和 算法设计与分析 贪心算法 算法思路 Dijkstra 设最短路长已知的终点集合为S 初始时v0 S 其最短路长为0 然后用贪心选择逐步扩充S 每次在V S中 选择路径长度值最小的一条最短路径的终点x加入S 例题 构造路长最短的最短路径 设已构造i条最短路径 则下一个加入S的终点u必是V S中具有最小路径长度的终点 其长度或者是弧 v0 u 或者是中间只经过S中的顶点而最后到达顶点u的路径 例题 已知一个n结点的有向图G V E 和边的权函数c e 求由G中某指定结点v0到其他各个结点的最短路径 v0 v2 v1 v3 v4 v5 20 45 50 10 15 15 20 10 35 30 3 算法设计与分析 贪心算法 产生最短路径的贪心方法 逐条构造这些最短路径 使用迄今已生成的所有路径长度之和作为一种量度标准 为了使这一量度达到最小 其单独的每一条路径都必须具有最小长度 使用这标准时 假定已构造了i条最短路径 则下面要构造的路径应该是下一条最短的最小长度路径 生成从v0到所有其它结点的最短路径的贪心方法就是按照路径长度的非降次序生成这些路径 算法设计与分析 贪心算法 产生最短路径的贪心方法 设S表示对其已经生成了最短路径的那些结点 包括v0 的集合 扩张S的过程 对于不在S中的结点w 设DIST w 是从v0开始只经过S中的结点而在结点w结束的那条最短路径的长度 则有 如果下一条最短路径是到结点u 则这条路径是从v0处开始而在u处终止 并且只通过那些在S中的结点 所生成的下一条路径的终点u必定是所有不在S内的结点中具有最小距离DIST u 的结点 算法设计与分析 贪心算法 产生最短路径的贪心方法 选出了结点u并生成了从v0到u的最短路径之后 结点u就成为S中的一个成员 此时 那些从v0开始 只通过S中的结点并且在S外的结点w处结束的最短路径可能会减小 如果长度改变了 则它必定是由一条从v0开始 经过u然后到w的更短路径所造成的 其中从v0到u的路径是一条最短路径 从u到w的路径是边 于是这条路径的长度就是 DIST u c u w 算法设计与分析 贪心算法 算法设计与分析 贪心算法 算法描述 1 用带权的邻接矩阵c来表示带权有向图 c i j 表示弧上的权值 若 V 则置c i j 为 设S为已知最短路径的终点的集合 它的初始状态为空集 从源点v到图上其余各点vi的当前最短路径长度的初值为 dist i c v i vi V 2 选择vj 使得dist j Min dist i vi V S vj就是长度最短的最短路径的终点 令S SU j 更新S 3 修改从v到集合V S上任一顶点vk的当前最短路径长度 如果dist j c j k dist k 则修改dist K dist j c j k 更新dist和prev 4 重复操作 2 3 共n 1次 算法设计与分析 贪心算法 单源最短路径 例题 1 v1 v2 10 2 v1 v3 50 3 v1 v4 30 4 v1 v5 60 算法设计与分析 贪心算法 voidDijkstra intn intv Typedist intprev Type c bools maxint for inti 1 i n i dist i c v i s i false if dist i maxint prev i 0 elseprev i v dist v 0 s v true for inti 1 i n i inttemp maxint intu v for intj 1 j n j if s j 单源最短路径问题的Dijkstra算法 分析 用带权邻接矩阵表示有n个顶点和e条边的带权有向图 主循环体需要O n 时间 循环需要执行n 1次 所以完成循环需要O n2 算法设计与分析 贪心算法 单源最短路径 例题 1 v1 v2 10 2 v1 v3 50 3 v1 v4 30 4 v1 v5 60 算法实例 求下图中v1到其余各结点的最短路径 v1 v4 v2 v3 v6 v7 v5 20 30 50 40 55 25 70 50 25 10 70 50 0205030 025 70 0402550 055 01070 050 0 算法设计与分析 贪心算法 算法实例 SHORTEST PATHS执行踪迹 算法设计与分析 贪心算法 算法设计与分析 贪心算法 最小生成树 问题陈述 设G V E 是一个无向连通带权图 E中每条边 v w 的权为c v w 若G的一个子图G 是一棵包含G的所有顶点的树 则称G 为G的生成树 生成树各边权的总和称为该生成树的耗费 在G的所有生成树中 耗费最小的生成树称为G的最小生成树 抽象描述 输入 任一连通生成子图 该子图的边集合 可行解 图的生成树 优化函数 生成树的各边权值之和最优解 使优化函数达到最小的生成树 4 6最小生成树 算法设计与分析 贪心算法 最小生成树 应用领域与图模型 算法思路 首先置S 1 T 若S V 就作如下的贪心选择 选取满足条件i S j V S 且c i j 最小的边 i j 将顶点j添加到S中边 i j 添加到T中 这个过程一直进行到S V时为止 T中的所有边构成G的一棵最小生成树 voidPrim intn Type c T S 1 while S V i j i S且j V S的最小权边 T TU i j S SU j 算法描述 Prim算法 设G V E 是一个连通带权图 y l 2 n 例题 算法设计与分析 贪心算法 最小生成树 问题 如何选取满足条件i S j V S 且c i j 最小的边 i j 成了算法难点问题 解决方法 设置两个数组closest和lowcost 对于每个j V S closest j 是j在S中的邻接顶点 它与j在S中的其他邻接顶点k相比较有c j closet j c j k lowcost j 的值就是c j closest j 图 Prim算法的执行过程 注 灰色部分表示集合S每个结点的上的数字表示S中的结点到该结点的最小消耗 即lowcost用图示的边的连接表示closest 图Prim算法的执行过程 图 Prim算法的执行过程 图 Prim算法的执行过程 图4 16 Prim算法的执行过程 图4 16 Prim算法的执行过程 templatevoidPrim intn Type c Typelowcost maxint intclosest maxim bools maxint s 1 true for inti 2 i n i lowcost i c l i closest i 1 s i false for inti 1 i n i Typemin inf intj 1 for intk 2 k n k if lowcost k min Prim算法 算法分析 O n2 算法设计与分析 贪心算法 最小生成树 算法思路 首先将G的n个顶点看成n个孤立的连通分支 将所有的边按权从小到大排序 然后从第一条边开始 依边权递增的顺序查看每一条边 并按下述方法连接两个通分支 当查看到第k条边 v w 时 如果端点u和w分别是当前两个不同的连通分支T1 T2中的顶点时 就用边 u w 将TI和T2连接成一个连通分支 然后继续查看第k 1条边 如果端点v和w在当前的同一个连通分支中 就直接再查看第k十1条边 直到只剩下一个连通分支为止 此时 这个连通分枝就是G的一颗最小生成树 Kruskal算法 G V E V 1 2 n 例题 算法设计与分析 贪心算法 最小生成树 e1 1 e2 6 e8 9 e6 2 e9 4 e5 5 e4 7 e10 8 e11 3 e7 10 e3 11 1 以G中全部点为点作图 2 按权的大小次序依次添加各边 若出现回路则忽略此边 3 加入n 1条边后就得到最小生成树 1 2 5 3 7 求最小生成树 Kruscal 最优解 e1 e6 e11 e5 e4 例题 算法设计与分析 贪心算法 最小生成树 优先队列 定义 优先队列中元素出队列的顺序由元素的优先级决定 从优先队列中删除元素是根据优先权高或低的次序 而不是元素进入队列的次序 可以利用堆数据结构来高效地实现优先队列 实现 优先队列 priorityqueue 是0个或多个元素的集合 每个元素都有一个优先权或值 对优先队列执行的操作有1 查找 2 插入一个新元素 3 删除 在最小优先队列 minpriorityqueue 中 查找操作用来搜索优先权最小的元素 删除操作用来删除该元素 对于最大优先队列 maxpriorityqueue 查找操作用来搜索优先权最大的元素 删除操作用来删除该元素 处理 优先权队列中的元素可以有相同的优先权 查找与删除操作可根据任意优先权进行 Initialize函数 使用数组a中的元素对最大堆进行初始化 DeleteMin x 从队列中删除具有最小优先权的元素 并将该元素返回至xInsert x 将x插入队列 并查集 在一些应用问题中 我们需要划分n个不同的元素成若干组 每一组的元素构成一个集合 这种问题的一个解决办法是 在开始时 让每个元素自成一个单元素集合 然后按一定顺序将属于同一组的元素所在的集合合并 其间要反复用到查找一个元素在哪一个集合的运算 适合于描述这类问题的抽象数据类型称为并查集 给出各个元素之间的联系 要求将这些元素分成几个集合 每个集合中的元素直接或间接有联系 在这类问题中主要涉及的是对集合的合并和查找 因此将这种集合称为并查集 并查集的数学模型 并查集的数学模型是若干不相交的动态集合的集合S A B C 它支持以下的运算 1 INITIAL A x 构造一个取名为A的集合 它只包含一个元素x 2 MERGE A B 将集合A和B合并 其结果取名为A或B 3 FIND x 找出元素x的所在集合 并返回该集合的名字 templateboolKruskal intn inte EdgeNodeE EdgeNodet MinHeap H 1 H Initialize E e e UnionFindU n ihtk 0 while e e inta U Find x u intb U Eind x v if a b t k x U Union a b H Deactivate renturn k n 1 Kruska算法 算法设计与分析 贪心算法 最小生成树 A 选出的边 E h g 1 g f 2 c i 2 a b 4 c f 4 g I 6 c d 7 a h 8 b c 8 d e 9 e f 10 b h 11 d f 14 原图中的边 初始状态森林由9棵树组成 A h g E g f 2 c i 2 a b 4 c f 4 g I 6 c d 7 a h 8 b c 8 d e 9 e f 10 b h 11 d f 14 接受边 h g UNION g h 森林由8棵树组成 a b 图Kruskal算法的执行过程 E c i 2 a b 4 c f 4 g I 6 c d 7 a h 8 b c 8 d e 9 e f 10 b h 11 d f 14 c E c i 2 a b 4 c f 4 g I 6 c d 7 a h 8 b c 8 d e 9 e f 10 b h 11 d f 14 d 接受边 c i UNION c i 森林由6棵树组成 接受边 g f UNION g f 森林由7棵树组成 图Kruskal算法的执行过程 E c f 4 g I 6 c d 7 a h 8 b c 8 d e 9 e f 10 b h 11 d f 14 接受边 a b UNION a b 森林由5棵树组成 图Kruskal算法的执行过程 E g I 6 c d 7 a h 8 b c 8 d e 9 e f 10 b h 11 d f 14 E a h 8 b c 8 d e 9 e f 10 b h 11 d f 14 接受边 c f UNION c f 森林由4棵树组成 选取边 g I 6 但因为g和i在一个连通子图中 即U Find g 和U Find i 相同 所以拒绝边 g i 接受边 c d UNION c d 森林由3棵树组成 图Kruskal算法的执行过程 续 拒绝边 h i 接受边 a h UNION a h 森林由2棵树组成 拒绝边 b c 接受边 d e UNION d e 森林由1棵树组成 图Kruskal算法的执行过程 续 正确性证明 1 需要证明以下两点 1 只要存在生成树 Kruskal算法总能产生一棵生成树 2 产生的生成树具有最小耗费 2 证明1 令G为任意加权无向图 即G是一个无向网络 从12 11 3节可知当且仅当一个无向图连通时它有生成树 而且在Kruskal算法中被拒绝 丢弃 的边是那些会产生环路的边 删除连通图环路中的一条边所形成的图仍是连通图 因此如果G在开始时是连通的 则T与E中的边总能形成一个连通图 也就是若G开始时是连通的 算法不会终止于E 和 T n 1 3 证明2 现在来证明所建立的生成树T具有最小耗费 由于G具有有限棵生成树 所以它至少具有一棵最小生成树 令U为这样的一棵最小生成树 T与U都刚好有n 1条边 如果T U 则T就具有最小耗费 那么不必再证明下去 因此假设T U 令k k 0 为在T中而不在U中的边的个数 当然k也是在U中而不在T中的边的数目 通过把U变换为T来证明U与T具有相同的耗费 这种转化可在k步内完成 每一步使在T而不在U中的边的数目刚好减1 而且U的耗费不会因为转化而改变 经过k步的转化得到的U将与原来的U具有相同的耗费 且转化后U中的边就是T中的边 由此可知 T具有最小耗费 算法分析 当图的边数为e时 将其组成优先队列需要时间O e while循环中 DeleteMin需要O loge 时间因此关于优先队列所作运算需时间O eloge 实现UnionFind所需的时间为O eloge 所以Kruska的时间是O eloge 适合求边数较少的最小生成树 反之 用Prim算法 最小代价通讯网络 在N城市之间架设通讯线路 要求造价最低 城市之间所有可能的通讯连接视作一个无向图G G中每边的权值表示建成这段线路的代价 问题转化为求一棵最小生成树 问题描述 输入 任一连通图G 该图的边集合 可行解 图G的生成树优化函数 生成树的各边权值之和最优解 使优化函数达到最小值的生成树 最优化问题 optimizationproblem 问题可描述为有n个输入 x1 x2 xn 一组约束条件和一个优化 目标 函数 满足约束条件的输入称为可行解 它是输入的一个子集 使优化函数取得极值的可行解称为最优解 算法设计与分析 贪心算法 例1 旅行商问题 货郎担问题 问题 设一个由N个城市v1 v2 vn组成的网络 ci j为从vi到vj的代价不妨设ci j cj i 且ci i 一推销员要从某城市出发经过每城市一次且仅一次后返回出发地问如何选择路线使代价最小 5 1 4 3 1 7 3 4 2 2 算法设计与分析 贪心算法 抽象描述 将城市以及之间的道路抽象为一个无向图G G中每边的权值表示这段线路的代价 问题转化为求一条最佳周游路线 从一点出发 经过每点一次且仅一次并返回原点 且该路线的总代价最小 v1 v5 v2 v4 v3 C 输入 城市的数目n 代价矩阵c c 1 n 1 n 输出 最小代价路线1 tour 0 tour纪录路线 2 cost 0 cost纪录到目前为止的花费 3 v N N为起点城市 v为当前出发城市 4 fork 1toN 1do5 tour tour v w

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论