我有l = [[1,2,3],[3,4,6],...]
形式的列表列表。有m
个子列表,每个子列表代表一个玩家。每个玩家都可以执行许多任务(有n
个任务)。我想通过最小化玩家之间的切换次数来找到通过所有步骤的最短路径。所以基本上让同一个玩家尽可能经常地连续执行任务。我正在尝试编写一个算法来优化这个在多项式时间中运行的算法,但是我在制定一个好的方案时遇到了一些麻烦。我当时认为它可能像Dijkstra's algorithm,但我并不完全确定如何使其适应我的情况。下面是我想要的具体例子。
示例
n = 5且m = 3使得我们有一个列表列表l = [[1,2,5],[1,3,5],[2,3,4]]
该算法将返回[0,2,2,2,0]
即。首先选择玩家0然后交换给玩家2进行3个任务,而不是回到玩家0进行最后一个任务。
我只是在寻找伪代码或正确方向推动。真正的挣扎和蛮力不会为大数人工作!
答案 0 :(得分:3)
由于让玩家执行的连续任务少于他所能完成永远不会有益,一个简单的贪婪算法就足以找到最佳解决方案:
从任务1开始,找到可以执行从第一个任务开始的最大连续任务数的玩家。
从先前找到的玩家无法做的第一个任务开始,找到能够执行从该任务开始的最大连续任务数的玩家。
重复,直到完成所有任务。
以下是该算法最佳的证明:
假设有一个最佳解决方案,玩家 A 通过 j 执行任务 i ,然后玩家 B 通过 k 执行任务 j + 1 。
如果有任何玩家(包括 A )可以通过 j + 1 执行任务 i ,那么我们可以使用该玩家而是做那些任务,解决方案将好或更好。 B 将通过 k 执行任务 j + 2 ,并且播放器切换的数量将相同,或 j + 1 = k ,我们根本不需要玩家 B 。
因此,存在一种最佳解决方案,其中每个所选择的玩家最大化该玩家可以执行的连续移动的数量。实际上,由于每个这样的解决方案都是等价的,因此它们全部最优。
编辑:当我写这篇文章时,Pham建议使用一个分段树,但不需要这种复杂的数据结构。如果子列表已排序,并且您从每个任务编号创建索引到可以找到它的子列表位置,那么您可以在O(N)时间内执行此操作。