【问题标题】:What is an efficient way to go beyond a greedy algorithm超越贪心算法的有效方法是什么
【发布时间】:2009-05-19 14:15:58
【问题描述】:

这个问题的领域是在受限硬件上调度操作。结果的分辨率是时间表适合的时钟周期数。搜索空间增长非常迅速,早期的决策限制了未来的决策,并且可能的调度总数快速且呈指数增长。许多可能的调度是等价的,因为只是交换两条指令的顺序通常会导致相同的时序约束。

基本上,问题是在不花费太多时间的情况下探索广阔的搜索空间的好策略是什么。我希望只搜索一小部分,但希望在此过程中探索搜索空间的不同部分。

当前的贪心算法有时会在早期做出愚蠢的决定,并且分支定界的尝试速度非常慢。

编辑: 想要指出结果是非常二元的,可能贪心算法最终使用 8 个周期,而存在使用分支定界仅使用 7 个周期的解决方案。

第二点是指令之间的数据路由和指令之间的依赖关系有很大的限制,这限制了解决方案之间的通用性。将其视为具有大量排序约束的背包问题以及由于路由拥塞而导致某些解决方案完全失败的问题。

澄清: 在每个循环中,每种类型的操作数量都有限制,并且某些操作有两种可能的类型。有一组路由约束可以变化为相当严格或相当宽容,并且限制取决于路由拥塞。

【问题讨论】:

  • 请添加更多关于您的侧面约束的详细信息:这将确定哪些算法可能适用。
  • 无论您选择哪种方法,我建议尝试通过对等价选择执行命令来消除问题“对称性”(例如指令 A 然后 B 等同于 B 然后 A)——例如要求每当一组指令 A、...、Z 可以按任何顺序执行时,只检查将按字母顺序执行的部分解决方案。这会稍微限制搜索空间。

标签: algorithm non-greedy


【解决方案1】:

NP-hard问题的整数线性优化

根据您的限制,您可以使用critical path method 或 (如上一个答案中所建议)dynamic programming。但是许多调度问题是 NP 难题,就像经典的旅行推销员一样——精确的解决方案具有指数搜索时间的最坏情况,正如您在问题中所描述的那样。

重要的是要知道,虽然 NP-hard 问题仍然有一个非常糟糕的最坏情况解决时间,但有一种方法通常可以通过非常短的计算得出准确的答案(平均情况 是可以接受的,您通常看不到最坏的情况)。

这种方法是将您的问题转换为具有整数变量的线性优化问题。有免费软件包(如 lp-solve)可以有效地解决此类问题。

这种方法的优点是它可以在可接受的时间内为您提供 NP 难题的准确答案。我在几个项目中使用了这种方法。

由于您的问题陈述未包含有关侧面约束的更多详细信息,因此我无法详细说明如何应用该方法。

编辑/添加:示例实现

以下是有关如何在您的情况下实施此方法的一些详细信息(当然,我做了一些可能不适用于您的实际问题的假设 --- 我只知道您问题的详细信息):

假设您有 50 条指令 cmd(i) (i=1..50) 被安排在 10 个或更少的周期 cycle(t) (t=1..10) 内。我们引入了 500 个二进制变量 v(i,t) (i=1..50; t=1..10),它们表示指令 cmd(i) 是否在周期 (t) 执行。这个基本设置给出了以下线性约束:

v_it integer variables
0<=v_it; v_it<=1;       # 1000 constraints: i=1..50; t=1..10
sum(v_it: t=1..10)==1   # 50 constraints:   i=1..50

现在,我们必须指定您的附带条件。假设操作 cmd(1)...cmd(5) 是乘法运算,并且您恰好有两个乘法器 --- 在任何循环中,您最多可以并行执行这些操作中的两个:

sum(v_it: i=1..5)<=2    # 10 constraints: t=1..10

对于你的每一个资源,你需要添加相应的约束。

另外,假设操作 cmd(7) 依赖于操作 cmd(2) 并且需要在它之后执行。为了让方程更有趣一点,我们还要求它们之间有两个周期的间隙:

sum(t*v(2,t): t=1..10) + 3 <= sum(t*v(7,t): t=1..10)   # one constraint

注意:sum(t*v(2,t): t=1..10) 是循环 t,其中 v(2,t) 等于 1。

最后,我们希望尽量减少循环次数。这有点棘手,因为您按照我建议的方式获得了相当大的数字:我们为每个 v(i,t) 分配一个随时间呈指数增长的价格:将操作推迟到未来比尽早执行要昂贵得多:

sum(6^t * v(i,t): i=1..50; t=1..10) --> 最小值。 # 一个目标函数

我选择 6 大于 5 以确保向系统添加一个周期比将所有内容压缩成更少的周期更昂贵。一个副作用是程序会尽可能早地安排操作。您可以通过执行两步优化来避免这种情况:首先,使用这个目标函数来找到最少的必要循环数。然后,用不同的目标函数再次问同样的问题 --- 一开始就限制可用周期的数量,并为以后的操作施加更温和的价格惩罚。你必须玩这个,我希望你明白了。

希望您可以将所有要求表达为二进制变量中的线性约束。当然,可能有很多机会可以利用您对特定问题的洞察力来减少约束或减少变量。

然后,将您的问题交给 lp-solve 或 cplex,让他们找到最佳解决方案!

【讨论】:

    【解决方案2】:

    乍一看,听起来这个问题可能适合dynamic programming solution。多个操作可能需要相同的时间,因此您最终可能会遇到重叠的子问题。

    【讨论】:

      【解决方案3】:

      如果您可以将您的问题映射到“旅行推销员”(例如:找到在最短时间内运行所有操作的最佳序列),那么您就有一个 NP 完全问题。

      解决这个问题的一个非常快速的方法是ant algorithm(或蚁群优化)。

      这个想法是你在每条路径上都派一只蚂蚁。蚂蚁在路径上散布有气味的物质,随着时间的推移会蒸发。较短的部分意味着当下一只蚂蚁出现时,这条路会更臭。蚂蚁更喜欢臭而不是干净的路径。通过网络运行成千上万的蚂蚁。最臭的路径是最佳路径(或至少非常接近)。

      【讨论】:

        【解决方案4】:

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-02-27
          • 1970-01-01
          • 2023-04-02
          • 2022-12-07
          • 1970-01-01
          • 1970-01-01
          • 2021-12-20
          • 2012-12-11
          相关资源
          最近更新 更多