结构和图形优化问题 - 贪婪算法

1,057 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第23天,点击查看活动详情

结构和图形优化问题

优化问题的概念提供了一种结构化的方式来思考解决许多计算问题。每当您开始解决涉及查找最大,最小,最多,最少,最快,最便宜等的问题时,您很有可能将问题映射到具有已知计算解决方案的经典优化问题上。

通常,优化问题分为两部分:要最大化或最小化的目标函数。例如,波士顿和伊斯坦布尔之间的机票。

·必须遵守的一组约束(可能为空)。例如,行程时间的上限。

在本章中,我们将介绍优化问题的概念,并给出一些示例。我们还提供了一些简单的算法来解决这些问题。在第15章中,我们讨论了解决一类重要的优化问题的有效方法。

从本章中可以带走的主要内容是:

许多真正重要的问题可以用一种简单的方式提出,自然而然地导致计算解决方案。

通过将看似新的问题简化为已知问题的实例,可以使用预先存在的解决方案。

结构问题和图形问题是其他问题通常可以减少的问题类别。

穷举枚举算法提供了一种简单但通常难以计算的方法来搜索最佳解决方案。贪婪算法通常是一种实用的方法,可以找到一个相当好的,但并不总是最佳的优化问题解决方案。

像往常一样,我们将用一些Python和一些关于编程的技巧来补充有关计算思维的材料。

结构问题

成为窃贼并不容易。除了明显的问题(确保房屋是空的,撬锁,绕过警报,处理道德困境等),窃贼还必须决定偷什么。问题在于,大多数房屋包含的价值比普通窃贼可以带走的要多。可怜的窃贼该怎么办?他(或她)需要找到一组提供最大价值的东西,而不会超过他或她的承载能力。

例如,假设一个窃贼有一个结构&7,最多可以容纳20磅的战利品,他闯入一所房子,并在Eigure 14-1中找到了这些物品。显然,他无法把它们都装进结构里,所以他需要决定拿走什么,留下什么。

image.png

贪婪算法

找到此问题的近似解决方案的最简单方法是使用贪婪算法。小偷会先选择最好的物品,然后再选择下一个最好的物品,然后继续,直到达到极限。当然,在这样做之前,小偷必须决定“最好”应该是什么意思。最好的物品是最有价值的,最不重的,还是价值重量比最高的物品?如果他选择最高价值,他将只带电脑离开,他可以花200美元。如果他选择重量最低,他会按顺序拿走书,花瓶,收音机和绘画 - 总共价值170美元。最后,如果他决定最好意味着最高的价值重量比,他会从拿花瓶和时钟开始。这将使三件物品的价值重量比为10,但其中只有书仍然适合结构。拿完这本书后,他会拿走剩下的东西,收音机。他的战利品总价值为255美元。

尽管按密度贪婪(值与重量比)碰巧为此数据集产生最佳结果,但不能保证逐密度贪婪算法始终找到比按重量或值贪婪更好的解决方案。更一般地说,不能保证贪婪算法发现的这种结构问题的任何解决方案都是最佳的。

接下来三个图中的代码实现了所有这三个贪婪算法。在图 14-2 中,我们定义了类 Item。每个项目都有一个名称、值和权重属性。我们还定义了三个函数,这些函数可以绑定到我们实现贪婪的参数key_function;见艾古雷14=3。

image.png

image.png

通过引入参数key_function,我们使贪婪独立于考虑列表元素的顺序。所需要的只是key_function定义对项目中元素的顺序。然后,我们使用此排序来生成排序包含与项相同的元素的列表。我们使用排序的内置Python函数来执行此操作。(我们使用排序而不是排序,因为我们想要生成一个新列表,而不是改变传递给函数的列表。我们使用反向参数来指示我们希望列表从最大(尊重到key_function)到最小进行排序。

贪婪的算法效率是多少?有两件事需要考虑:内置函数排序的时间复杂度,以及贪婪主体中通过for循环的次数。循环的迭代次数由项中的元素数限制,即它是 θ(n),其中 n 是项的长度。然而,Python内置排序函数的最坏情况时间大致是顺序θ(n log n),其中n是要排序的列表的长度。图 14-4 中的代码构建一个项列表,然后使用不同的列表排序方式测试函数 greedy。

image.png

执行test_greedys () 时,它会打印

image.png