均匀调度多个周期性任务的算法
问题:
假设你有一堆需要定期做的任务,知道每个任务需要多长时间,以及它们多久要做一次,目标是制定一个时间表,让这些任务的时间分配得尽量均匀。
举个例子,我需要每两天做一次“运行杀毒软件”、“碎片整理硬盘”和“更新电脑”,每三天做一次“更新硬件”、“清理内部”,每五天做一次“更换硬盘”、“更换显卡”、“更换CPU”。每个任务需要的时间是以分钟计算的。
根据这些信息,我应该在这个月的哪几天做每个任务呢?
尝试:
我已经“解决”过这个问题两次,但每次的解决方案计算起来都需要超过一百万年。
我用的第一个算法生成了所有可能的“天数”,也就是可以执行的任务组合。然后,对于每一个可能的月份组合,我检查这个月是否符合要求(任务每隔x天执行一次,时间分配要均匀)。这是最简单的方法,但用Python来检查这些组合的时间比宇宙的年龄还长。
我现在正在运行的算法也能工作。它生成了每个任务在一个月内的所有可能的“日程计划”,也就是说,我可以选择在第1天、第2天、第3天、第4天或第5天开始执行每五天的任务。然后,对于每一个日程计划的组合,我把这些日程计划加起来形成一个月的计划。接着,我计算这个月中每一天的任务所需时间,看看效果如何。这个算法需要处理1e14种组合,如果用编译语言编写并在一个大型集群上并行执行几天,可能有希望完成……
总结
我想知道有没有更好的方法来解决这个问题。简单来说,我有一些任务,需要每隔x天重复一次,想把它们分散到一个月中,让每一天在这些任务上花费的时间尽量相同。
谢谢。
2 个回答
我第一次尝试这个问题时,意识到这个时间表是周期性的,所以要先确定这个周期有多长(也就是所有周期的最小公倍数)。接下来,你可以把所有任务想象成一个甘特图。对于每个任务,你需要选择一个阶段偏移量,这样可以让不同任务的开始时间之间的间隔最大。我不太确定能不能用数学公式计算出来,但你可以试着用梯度下降的方法来解决。
你可以试试一些本地搜索算法,比如爬山算法或者模拟退火。
简单来说,你从一个候选解决方案开始(比如随机分配任务),然后对这个方案进行评估(你需要想出一个评估函数来判断好坏)。接着,你检查一下周围的状态值,选择一个值最高的状态来移动。这里的“周围状态”指的是把某个任务往前或往后移动一天的所有可能状态。你一直重复这个过程,直到状态值不再有提升为止。
这样,你应该能找到一个评估函数的局部最大值,但这可能还不是最优解。不过,由于这个算法运行得很快,你可以多次尝试不同的起始分配,最终找到一个不错的解决方案。你还可以通过加入一些随机步骤来“放松”算法的贪婪程度。