freeCodeCamp/guide/chinese/algorithms/greedy-algorithms/index.md

89 lines
6.9 KiB
Markdown
Raw Normal View History

---
title: Greedy Algorithms
localeTitle: 贪心算法
---
## 什么是贪婪算法
在筛选一些文章时,你一定听说过很多算法设计技巧。他们之中有一些是
* 蛮力
* 分而治之
* 贪心编程
* 动态编程 仅举几例。在本文中,您将了解贪婪算法是什么以及如何使用此技术来解决许多编程问题,否则这些问题似乎并不重要。
想象一下,你要去远足,你的目标是达到最高峰。您在开始之前已经拥有了地图,但地图上显示了数千条可能的路径。你太懒了,根本没有时间评估每一个。拧地图!你开始用简单的策略徒步旅行 - 贪婪和近视。只需走最多向上倾斜的路径。这似乎是徒步旅行的好策略。但它总是最好的吗?
旅行结束后,你的整个身体酸痛和疲惫,你第一次看远足地图。哦,我的上帝!我应该穿过一条泥泞的河流,而不是继续向上走。这意味着贪婪的算法选择了最佳的直接选择,并且从不重新考虑其选择。在优化解决方案方面,这仅仅意味着贪婪的解决方案将尝试找到本地最优解决方案 - 可能很多 - 并且可能错过全球最优解决方案。
## 正式定义
假设您有一个需要在给定点优化(最大化或最小化)的目标函数。贪婪算法在每一步都做出贪婪的选择,以确保优化目标函数。 Greedy算法只有一次计算最佳解决方案因此它永远不会返回并反转决策。
### 贪心算法有一些优点和缺点:
* 对于一个问题,很容易想出一个贪心算法(甚至是多个贪婪算法)。 分析贪婪算法的运行时间通常比其他技术(如分而治之)更容易。对于分而治之技术,尚不清楚该技术是快还是慢。这是因为在每个递归级别,大小变小,子问题的数量增加。
* 困难的部分是,对于贪婪的算法,你必须更加努力地去理解正确性问题。即使使用正确的算法,也很难证明它为什么是正确的。证明贪婪算法是正确的更多是艺术而不是科学。它涉及很多创造力。通常,提出一种算法似乎是微不足道的,但证明它实际上是正确的,这是一个完全不同的问题。
## 区间调度问题
让我们深入探讨几乎任何行业或任何行业中都会遇到的有趣问题。该问题的一些实例如下:
* 您将获得一组N个大学课程的N个课程表。特定讲座的时间表是形式 _时间_时间其中s _时间表示该讲座的开始时间类似地f_时间表示结束时间。给出N个讲座时间表的列表我们需要选择在白天举行的最大讲座集以使得**所有讲座都不相互重叠即如果讲座Li和Lj包含在我们的选择中那么j的开始时间> =完成i的时间反之亦然** 。
* 你的朋友正在担任营地辅导员他负责组织一系列露营者的活动。他的一个计划是下面的迷你铁人三项运动每个参赛者必须游泳20圈然后骑自行车10英里然后跑3英里。
* 计划是通过以下规则以交错方式发送参赛者参赛者必须一次使用一个游泳池。换句话说第一个参赛者在20圈游泳下车并开始骑自行车。
* 一旦第一个人离开游泳池第二个参赛者就开始游泳20圈;一旦他或她开始骑自行车,第三名选手开始游泳,依此类推。
* 每位参赛者都有预计的游泳时间,预计的骑行时间和预计的跑步时间。你的朋友想要决定铁人三项的时间表:一个顺序来排列参赛者的开始。
* 假设时间预测是准确的,假设时间表的完成时间是所有参赛者完成铁人三项全部三条腿的最早时间。如果想让整个比赛尽快结束,那么派出人员的最佳顺序是什么?更准确地说,提供一种有效的算法,该算法产生一个完成时间尽可能小的时间表
### 讲座调度问题
让我们看看解决这个问题的各种方法。
1. **最早的开始时间首先,**即选择具有最早开始时间的间隔。请看下面打破此解决方案的示例。此解决方案失败,因为可能会有一个很早开始的间隔,但这个间隔很长。这意味着我们可以尝试的下一个策略是首先考虑较小的间隔。 ![最早的开始时间](https://algorithmsandme.files.wordpress.com/2015/03/f268b-jobs.png?w=840)
2. **最小的间隔首先,**即你最终按照他们的整体间隔顺序选择讲座,这只是他们的`finish time - start time` 。同样,这个解决方案不正确。请看以下案例。 ![最短间隔优先](https://cdn-media-1.freecodecamp.org/imgr/4bz2N.png)
您可以清楚地看到最短的间隔讲座是中间讲座,但这不是最佳解决方案。让我们看看这个问题的另一个解决方案,从这个解决方案中获得见解。
3. **最小冲突间隔首先,**即您应该查看导致冲突次数最少的间隔。然而,我们再次举例说明这种方法无法找到最佳解决方案。 ![最小冲突间隔优先](https://cdn-media-1.freecodecamp.org/imgr/5LZ9V.png)
该图表显示冲突间隔最小的区间是中间只有2个冲突的区间。之后我们只能在最后两个区间选择两个区间每个区间有3个冲突。但最佳解决方案是在最顶层选择4个区间。
4. **最早的完成时间** 。这种方法始终为我们提供了解决此问题的最佳解决方案。我们从以前的方法中获得了很多见解,并最终得出了这种方法。我们根据完成时间的递增顺序对间隔进行排序,然后我们从一开始就选择间隔。请查看以下伪代码以获得更清晰的信息。
```
function interval_scheduling_problem(requests)
schedule \gets \{\}
while requests is not yet empty
choose a request i_r \in requests that has the lowest finishing time
schedule \gets schedule \cup \{i_r\}
delete all requests in requests that are not compatible with i_r
end
return schedule
end
```
## 我们什么时候使用贪婪算法
贪婪算法可以帮助您找到许多看似棘手的问题的解决方案。它们唯一的问题是您可能会提出正确的解决方案,但您可能无法验证它是否正确。所有贪婪的问题都有一个共同的特性,一个地方的最终可以最终导致全球最小化而不重新考虑已经考虑过的一系列选择。
贪婪算法帮助我们解决许多不同类型的问题。请继续关注其中每一个的即将发布的教程。
1. 最短路径问题。
2. 图中的最小生成树问题。
3. 霍夫曼编码问题。
4. K中心问题
#### 更多信息:
[![贪心问题](http://img.youtube.com/vi/HzeK7g8cD0Y/0.jpg)](https://www.youtube.com/watch?v=HzeK7g8cD0Y)
[![贪心问题](http://img.youtube.com/vi/poWB2UCuozA/0.jpg)](https://www.youtube.com/watch?v=poWB2UCuozA)