【问题标题】:Return elements of array in subset sum problem返回子集和问题中的数组元素
【发布时间】:2019-10-16 16:20:16
【问题描述】:

对于以下子集和问题的递归解决方案(see this link),如果a 中有任何子集的和等于sum 的值,则以下代码返回true

def isSubsetSum(set,n, sum) : 

    # Base Cases 
    if (sum == 0) : 
        return True
    if (n == 0 and sum != 0) : 
        return False

    # If last element is greater than sum, then ignore it 
    if (set[n - 1] > sum) : 
        return isSubsetSum(set, n - 1, sum); 

    # else, check if sum can be obtained by any of the following 
    # (a) including the last element 
    # (b) excluding the last element    
    return isSubsetSum(set, n-1, sum) or isSubsetSum(set, n-1, sum-set[n-1]) 

set = [2, 1, 14, 12, 15, 2] 
sum = 9
n = len(set) 
if (isSubsetSum(set, n, sum) == True) : 
    print("Found a subset with given sum") 
else : 
    print("No subset with given sum") 

我怎样才能返回满足suma 的索引?

另外,如何使函数对数组a 中的负整数起作用。

【问题讨论】:

    标签: python numpy dynamic-programming


    【解决方案1】:

    这是一种可能性:

    def isSubsetSum(numbers, n, x, indices):
        # Base Cases
        if (x == 0):
            return True
        if (n == 0 and x != 0):
            return False
        # If last element is greater than x, then ignore it
        if (numbers[n - 1] > x):
            return isSubsetSum(numbers, n - 1, x, indices)
        # else, check if x can be obtained by any of the following
        # (a) including the last element
        found = isSubsetSum(numbers, n - 1, x, indices)
        if found: return True
        # (b) excluding the last element
        indices.insert(0, n - 1)
        found = isSubsetSum(numbers, n - 1, x - numbers[n - 1], indices)
        if not found: indices.pop(0)
        return found
    
    numbers = [2, 1, 4, 12, 15, 3]
    x = 9
    n = len(numbers)
    indices = []
    found = isSubsetSum(numbers, n, x, indices)
    print(found)
    # True
    print(indices)
    # [0, 2, 5]
    

    编辑:为了更简洁的界面,您可以将前一个函数包装在另一个函数中,该函数返回成功时的索引列表,否则返回 None

    def isSubsetSum(numbers, x):
        indices = []
        found = _isSubsetSum_rec(numbers, len(numbers), x, indices)
        return indices if found else None
    
    def _isSubsetSum_rec(numbers, n, x, indices):
        # Previous function
    

    【讨论】:

      【解决方案2】:

      这是一种方法:如果找到,则返回子数组,而不是 TrueFalse,否则返回 None

      def isSubsetSum(sset,n, ssum) : 
      
          # Base Cases 
          if (ssum == 0) : 
              return []
          # not found
          if (n == 0 and ssum != 0) : 
              return None
      
          # If last element is greater than sum, then ignore it 
          if (sset[n - 1] > ssum) : 
              return isSubsetSum(sset, n - 1, ssum); 
      
          # else, check if sum can be obtained by any of the following 
          # (a) including the last element 
          # (b) excluding the last element    
          a1 = isSubsetSum(sset, n-1, ssum)
      
          # (b) excluding last element fails
          if a1 is None:
              a2 = isSubsetSum(sset, n-1, ssum-sset[n-1])
      
              # (a) including last element fails
              if a2 is None:
                  return None
      
              # (a) including last element successes
              else: return a2 + [sset[n-1]]
          else:
              return a1
      
      
      sset = [2, 1, 4, 12, 15, 2] 
      ssum = 9
      n = len(sset) 
      subset = isSubsetSum(sset, n, ssum) 
      if subset is not None : 
          print(subset) 
      else : 
          print("No subset with given sum") 
      
      # [2, 1, 4, 2]
      

      【讨论】:

        【解决方案3】:

        “简单”的方法是让索引列表成为函数的另一个参数。沿调用树向下移动时保持它。

        “干净”的方法是在您返回 back 并返回成功结果的树时构建它。不是返回布尔值,而是返回索引列表; None 表示失败。

        一个重要的注意事项:不要用变量名“遮蔽”一个内置类型; set 作为变量名 具有误导性,既危险又危险。例如,试试coins

        基本情况:

        if (sum == 0) : 
            return [n]
        if (n == 0 and sum != 0) : 
            return None
        

        递归:

        include = isSubsetSum(coins, n-1, sum-coins[n-1]):
        if include:
            return include.append(n-1)
        

        这些是对现有代码的直接添加。我强烈建议您在线研究这个问题,看看其他人是如何解决的。将整个列表和指针作为参数传递会浪费空间和时间;相反,您可以从最后一个元素开始,然后返回,在每次调用时从列表中剪掉结尾。这将使您的索引问题变得更加简单。

        【讨论】:

        • 您的建议会加快运行时间多少?
        • 如果您对问题有补充,请编辑问题。一般来说,试试看。它不会改变解决方案的复杂性,因此任何改变都应该可以忽略不计。
        猜你喜欢
        • 2022-11-21
        • 2011-09-05
        • 2021-04-11
        • 2011-07-07
        • 1970-01-01
        • 2020-01-12
        • 1970-01-01
        • 2020-03-20
        • 1970-01-01
        相关资源
        最近更新 更多