Algorithm 线性时间的子集和

Algorithm 线性时间的子集和,algorithm,time-complexity,subset-sum,Algorithm,Time Complexity,Subset Sum,这是我们期末考试的一道题。这是逐字逐句的,因为教授让我们把考试的副本带回家 (20点)设I={r1,r2,…,rn}是一组n个任意正整数,I中的值是不同的。我没有按任何顺序给出。假设我们想要找到I的子集I’,使得I’中所有元素的总和正好是100*ceil(n^.5)(I的每个元素最多只能在I’中出现一次)。提出了一种求解该问题的O(n)时间算法 据我所知,这基本上是背包问题的一个特例,也就是所谓的子集和问题。。。这两个问题在NP中都是线性时间内理论上不可能解决的 所以。。。这是个骗人的问题吗

这是我们期末考试的一道题。这是逐字逐句的,因为教授让我们把考试的副本带回家

  • (20点)设I={r1,r2,…,rn}是一组n个任意正整数,I中的值是不同的。我没有按任何顺序给出。假设我们想要找到I的子集I’,使得I’中所有元素的总和正好是100*ceil(n^.5)(I的每个元素最多只能在I’中出现一次)。提出了一种求解该问题的O(n)时间算法
  • 据我所知,这基本上是背包问题的一个特例,也就是所谓的子集和问题。。。这两个问题在NP中都是线性时间内理论上不可能解决的

    所以。。。这是个骗人的问题吗



    基本上解释了如果权重有界,则可以进行伪多项式(线性)时间近似,但在考试问题中权重没有界,并且考虑到考试的总体难度,如果教授希望我们知道/想出一个模糊的动态优化算法,我会感到震惊

    确定以下是O(n)时间内的一个简单解决方案。

    由于所需的和
    S
    的顺序为
    O(n^0.5)
    ,如果我们制定一个复杂度
    S^2
    的算法,那么我们是好的,因为我们的算法将具有有效的复杂度
    O(n)

  • 在所有元素上迭代一次,检查值是否小于S。如果是,则将其推入新阵列。该阵列最多应包含S个元素(O(n^.5))


  • 按O(sqrt(n)*logn)时间(
  • 输入可以被截断为大小O(sqrt(n))。没有负输入,因此您可以丢弃任何大于100*sqrt(n)的数字,并且所有输入都是不同的,因此我们知道最多有100*sqrt(n)个重要输入
  • 运动场的大小为O(sqrt(n))。虽然有O(2^sqrt(n))种方法可以组合重要的O(sqrt(n))输入,但您不必关心离开100*sqrt(n)范围或冗余地命中您已经可以达到的目标的组合
  • 基本上,这个问题是一个动态规划问题,每个输入都会以某种方式与“到达数”空间的每个部分进行检查

    最终的解决方案是确保数字不会脱离自身(通过向正确的方向扫描),只看一次每个数字,并为我们自己提供足够的信息,以便随后重建解决方案

    下面是一些C代码,可以在给定的时间内解决问题:

    int[]FindSubsetToImpliedTarget(int[]输入){
    var目标=100*(int)数学上限(Math.Sqrt(inputs.Count));
    //建立联系方式表
    var达到=新整数?[目标+1];
    达到[0]=0;//空集达到0
    foreach(输入中的var e){
    //我们后退以避免脱离自己
    对于(变量i=目标;i>=e;i--){
    如果(达到[i-e].HasValue){
    达到[i]=e;
    }
    }
    }
    //达到目标了吗?
    如果(!reach[target].HasValue)返回null;
    //通过记录的到达值回溯生成结果
    var result=新列表();
    对于(变量i=目标;达到[i]!=0;i-=达到[i]。值){
    结果.Add(达到[i].值);
    }
    返回result.ToArray();
    }
    

    我还没有实际测试过上面的代码,所以要小心错字和逐个错字。

    使用典型的DP算法将获得
    O(N)
    耗时的算法。我们使用
    dp[i][k]
    (布尔值)来指示前i项是否有一个和为k的子集,过渡方程为:

    dp[i][k] = (dp[i-1][k-v[i] || dp[i-1][k]),
    

    它是
    O(NM)
    ,其中N是集合的大小,M是目标和。由于元素是不同的,总和必须等于<代码> 100×CEL(n ^ 5)< /> >,我们最多只需要考虑第一个100×CEL(n,5)项,然后得到<代码>,权重确实有界,可以忽略那些大于<代码> 100 *CEL(SqRT(n))< /> >的权重。因此,您可以使用链接到的算法。当没有解决方案时(例如,
    I={1,2,3,4}
    ),响应应该是什么?(a) “无解”(b)“最近的解是……”(c)不收敛于O(n)。