Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 在给定时间内可以完成的最大任务数_Algorithm_Data Structures_Graph_Time Complexity_Dynamic Programming - Fatal编程技术网

Algorithm 在给定时间内可以完成的最大任务数

Algorithm 在给定时间内可以完成的最大任务数,algorithm,data-structures,graph,time-complexity,dynamic-programming,Algorithm,Data Structures,Graph,Time Complexity,Dynamic Programming,我最近在一个论坛上遇到一个问题: 给您一条从0到10^9的直线。从零开始,可以执行n个任务。第i个任务位于线路的第i点,需要执行“t”时间。要执行任务,您需要到达点i并在该位置花费“t”时间 示例:(5,8)位于5,因此旅行距离为5,工作努力为8。 总工作量计算为行驶距离+完成工作所需的时间。 走一个单位的路程需要一秒钟 现在我们得到了总的T秒,我们需要完成尽可能多的任务并回到起始位置 找出您可以在时间T内完成的最大任务数 例如: 3 16-3项任务和16个总时间单位 2 8-任务1在直线位置2

我最近在一个论坛上遇到一个问题: 给您一条从0到10^9的直线。从零开始,可以执行n个任务。第i个任务位于线路的第i点,需要执行“t”时间。要执行任务,您需要到达点i并在该位置花费“t”时间

示例:(5,8)位于5,因此旅行距离为5,工作努力为8。 总工作量计算为行驶距离+完成工作所需的时间。 走一个单位的路程需要一秒钟

现在我们得到了总的T秒,我们需要完成尽可能多的任务并回到起始位置 找出您可以在时间T内完成的最大任务数

例如:

3 16-3项任务和16个总时间单位

2 8-任务1在直线位置2,需要8秒完成

4 5-任务2在队列中的位置4,需要5秒完成

5 1-任务3在直线位置5,需要1秒完成

​​​​​​​ 产出:2

说明: 如果我们在位置2完成任务1,需要8秒,那么到达位置2需要2秒,完成任务需要8秒,剩下的时间只有6秒,不足以完成其他任务

另一方面,跳过第一项任务会让我们有足够的时间完成另外两项任务

前往地点和返回的成本为2x5=10秒,在地点4和5执行任务的成本为5+1=6秒。花费的总时间为10s+6s=16s

我对图和DP是新手,所以我不确定使用哈密顿圈、背包还是最长路径。 有谁能帮我找到最有效的方法来解决这个问题。

建议:

对于每个任务,创建一个如下图

将所有任务的这些图连接起来

运行旅行商算法以找到执行所有任务的最短时间(=访问组合图中的所有节点)


按顺序删除任务。这将为您提供执行的不同任务数的结果集合。选择一个执行最多任务且仍在时间限制内的任务

由于您正在最大限度地增加所执行的任务数量,因此从删除最长的任务开始,这样您将有大量的短任务。

建议:

对于每个任务,创建一个如下图

将所有任务的这些图连接起来

运行旅行商算法以找到执行所有任务的最短时间(=访问组合图中的所有节点)


按顺序删除任务。这将为您提供执行的不同任务数的结果集合。选择一个执行最多任务且仍在时间限制内的任务


由于您正在最大限度地增加执行的任务数量,因此从删除最长的任务开始,这样您将剩下大量的短任务。

让我们根据距离从第一个任务迭代到最后一个任务。在我们进行的过程中,很明显,在减去
2*距离(i)+努力(i)
将当前任务视为我们的最后一项任务后,我们可以完成的大部分任务可以通过贪婪地将尽可能多的早期任务累积到剩余时间中,并通过增加努力来排序它们


因此,一个有效的解决方案可以将SEED元素插入到按工作顺序排列的数据结构中,从而动态更新迄今为止最好的解决方案。(我原本想使用一个和二进制搜索,但j_random_hacker在下面的评论中建议了一种更简单的方法。)

让我们根据距离从第一个任务迭代到最后一个任务。在我们进行的过程中,很明显,在减去
2*距离(i)+努力(i)
将当前任务视为我们的最后一项任务后,我们可以完成的大部分任务可以通过贪婪地将尽可能多的早期任务累积到剩余时间中,并通过增加努力来排序它们


因此,一个有效的解决方案可以将SEED元素插入到按工作顺序排列的数据结构中,从而动态更新迄今为止最好的解决方案。(我原本想使用a和二进制搜索,但j_random_hacker在下面的评论中建议了一种更简单的方法。)

也许有办法将这个问题重新解释为您列出的3个问题之一,但我认为最有用的方法是总是寻找方法将问题分解成子问题,这样子问题的解决方案就可以组合成更大的子问题的解决方案。一旦你有了它,你就可以递归地解决这个问题。您可能会立即得到一个分治,或者您可能会发现相同的子问题被多次解决,在这种情况下,您可以在顶部添加备忘录以获得DP算法。如果没有,请寻找子问题的不同细分。如果我遗漏了任何内容,请告诉我,如果不使用标准符号,很难描述此类问题。假设您有一组K任务,您可以或不可以在p_K时间单位的s_K时间点执行这些任务。你在寻找K的子集I,它最大化值V=2*max_K{s_K}+sum_K{p_K},其中V@PhM75的目标是最大化子集的大小。正如你提到的V=2*max_K{s_K}+sum_K{p_K}和V@Hari,首先看到问题是弱NP难的(我可能错了);你知道它的确切复杂性等级和/或最为人所知的复杂性是什么吗?@Hari,对不起,我误读了问题描述,下面基于2*距离(I)+努力(I)的解决方案看起来是正确的,也许有某种方法可以将问题重新解释为你列出的3个问题之一,但我认为最有用的方法是总是寻找方法将问题分解成子问题,这样子问题的解决方案就可以组合成更大的子问题的解决方案。一旦你有了这些,你就可以解决