当前位置: 首页 > 知识库问答 >
问题:

用递归法求解背包问题

朱博实
2023-03-14

我试图在Scala中使用递归来解决背包问题,但我的要求是显示选择哪些项目保存在背包中。可用的钱表示背包大小。

我的代码如下:

def knapsack(availableMoney: Int,wt:List[Int],value :List[Int] ,n:Int) : Int= {

  if(n == 0 || availableMoney == 0)  
    return 0
  if (wt(n - 1) > availableMoney) {     
    return knapsack(availableMoney,wt,value, n - 1)
  }
  else {
    var element1 = value(n-1) + knapsack(availableMoney- wt(n-1), wt, value, n-1)
    var element2 = knapsack(availableMoney, wt, value, n-1)

    return max(element1,element2);
  }
}

如何知道选择哪些物品放在背包里?

共有2个答案

陶俊晤
2023-03-14

请考虑接受amit的解决方案作为答案,我只想在这里补充他的解决方案之上的附加说明。

在这个解决方案中,我还将考虑背包解决方案不是唯一的情况。

正如amit所指出的,修改代码以跟踪背包中的元素是很简单的。你的方法应该返回一个tuple,而不是背包值,其中第一个条目是背包的“最大值”,第二个条目是背包中元素列表,代表背包中项目的组合。

  • 第一个if对应于递归的终止条件,背包中只有一个可能的组合——没有任何元素的背包
  • 如果第二个If的条件为真,则无法选择项目n-1,因此我们返回到下一个项目
  • 另一方面,如果项目n-1的重量小于availableMoney,那么我们可以在构造中选择项目n-1(这对应于element1),或者在构造中保留项目n-1。然后,返回的解决方案应该是两者中更好的一个,或者如果它们给出相同的值,则将它们合并在一起

以下是代码的修改版本,供您参考:

def knapsack(availableMoney: Int, wt: List[Int], value: List[Int], n: Int): (Int, List[List[Int]]) = {

  if (n == 0 || availableMoney == 0)
    return (0, List[List[Int]](List[Int]()))

  if (wt(n - 1) > availableMoney) {
    return knapsack(availableMoney, wt, value, n - 1)
  } else {
    val recur = knapsack(availableMoney - wt(n - 1), wt, value, n - 1)
    val element1 = (recur._1 + value(n - 1), for (e <- recur._2) yield {e :+ wt(n - 1)})
    val element2 = knapsack(availableMoney, wt, value, n - 1)

    if (element1._1 > element2._1)
      return element1
    else if (element1._1 < element2._1)
      return element2
    else
      return (element1._1, element1._2 ::: element2._2)
  }
}
谭琛
2023-03-14

在代码中,您已经知道是否选择了当前元素。

如果选择了element1(高于element2),则最后一个(index=n-1)元素被选择。另外,你没有。

因此,您可以添加另一个要从递归调用返回的输出参数,这将指示所选元素。

你需要修改所有的返回 也要处理它:

  • 返回0将变成返回(0,[])

此外,如果您想实现is作为动态编程,这个问题讨论了如何返回元素而不仅仅是值:

如何使用背包算法(而不仅仅是包的值)找到包中的元素?

 类似资料:
  • 在我为0/1背包和无界背包签出的所有DP解决方案中,解决方案方法总是这样定义的: 0/1背包:取第n项或不取第n项,使总价值最大化。例如,0/1背包 无界背包:将第n个物品视为最后挑选的物品,或(n-1)个物品视为最后挑选的物品,使总价值最大化。例如,无界背包 但无界背包也可以使用0/1背包的逻辑来解决,只需稍加调整。我的意思是,对于0/1背包,我们执行以下操作(使用第一个链接中的代码): 请注意

  • 本文向大家介绍C#用递归算法解决经典背包问题,包括了C#用递归算法解决经典背包问题的使用技巧和注意事项,需要的朋友参考一下 1.引子   我们人类是一种贪婪的动物,如果给您一个容量一定的背包和一些大小不一的物品,裝到背包里面的物品就归您,遇到这种好事大家一定不会错过,用力塞不一定是最好的办法,用脑子才行,下面就教您如何解决这样的问题,以获得更多的奖品。 2.应用场景   在一个物品向量中找到一个子

  • 已知背包重量为S(正整数), 有给定的n个物品,其数量分别为N1,N2,..,Nn, 重量分别为s1,s2,..,sn(均为正整数),需要挑任意的物品将背包正好装满,求是否有解,如果有解,给出一个解(比如使用了3个1号物品,2个2号物品)。 可以用常见语言比如js,java,python都行

  • 给定一个填充了0和1的二维字符数组,其中0代表一堵墙,1代表一条有效路径,我开发了一个名为findPath(int r,int c)的递归方法,用于在标有“x”的迷宫中找到出口。该方法接收迷宫的当前行和列,并通过N、E、S、W方向,直到找到有效路径,并用“”标记该有效路径。假设所有方向都被一堵墙挡住,那么该方法假设是回溯,直到情况不再如此,然后用“F”标记该路径,以表示坏路径。 现在我不明白为什么

  • 我试图用Python解决背包问题,实现一个贪婪的算法。我得到的结果对我来说毫无意义。 背包: 结果:

  • 对于,我被赋予和。 现在给定N、A、B、C和X,如何有效地找到所有N个元素? 我需要把这N个元素分成2组,其中最大的元素在第一组,第二大的元素在第二组,第三大的元素在第一组,以此类推。。。最后需要找到两个集合元素之和的绝对差。 我可以在不计算所有元素的情况下找到这个差异吗?因为N可以大到最大值为100。