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

是否可以递归检查java数组中所有组合的最大值

孙池暝
2023-03-14

我得到了岩石的价格和数组中每一块岩石的值。我必须递归地(仅使用列出的4个变量)检查所有可能的岩石组合,以找到低于或等于岩石组合允许的最大重量的最高价格。

例如:

price = {50, 10, 30, 40}
weight = {20, 5, 10, 30}
maxWeight = 25;
index = 4;

在这种情况下,可以找到的最高价格是50,因为20的重量低于25,值是50。这比5-10的权重高,5-10的权重也低于25,但它们的值加起来只有40,小于50。

示例2:

price = {50, 10, 30, 40}
weight = {20, 5, 10, 30}
maxWeight = 30;
index = 4;

在这种情况下,最高价格是80美元。这是因为权重20 10加起来等于最大权重30,其值加起来等于80。第二个最大值是重量20 5,其总和小于最大重量,其值为60。第三个最大值是40,可以使用5到10个重量或30个重量找到。

调用这些值的方法如下所示:

public static int maxValue(weight[], price[], maxWeight, index) {

}

是否有可能递归使用此方法来找到重量最大且价格最高的岩石的最佳组合?

如果您有任何困惑,请发表评论。

共有1个答案

常自怡
2023-03-14

你的问题是众所周知的背包问题,没有任何已知的有效算法来解决它。

您可能正在寻找递归解决方案:

static int naive_knapSack(int[] v, int[] w, int size, int index) {

    // no more items
    if (index >= v.length)
        return 0;

    // we cannot use the current item
    if (size < w[index])
        return naive_knapSack(v, w, size, index + 1);

    // the maximum value will be taking in account the current index OR not
    return Math.max(
            naive_knapSack(v, w, size, index + 1), // ignoring this item
            v[index] + naive_knapSack(v, w, size - w[index], index + 1) // using this item
    );

}

但是,如果背包大小适合内存(例如小于4G),则存在成本为O(n^2)的动态规划解决方案:

static int knapSack(int[] v, int[] w, int size) {
    int[][] m = new int[w.length + 1][size + 1];
    for (int i = 1; i <= w.length; i++)
        for (int j = 0; j <= size; j++)
            m[i][j] = w[i - 1] > j ? m[i - 1][j] : Math.max(m[i - 1][j], m[i - 1][j - w[i - 1]] + v[i - 1]);
    return m[w.length][size];
}

因为它基本上是相同的,但递归的每个选项都会被记忆(只计算一次)。如果记住前面的递归函数,将得到相同的结果。

我们可以比较两种输出

int[] v = new int[]{50, 10, 30, 40};
int[] w = new int[]{20, 5, 10, 30};

// specific cases
System.out.println(knapSack(v, w, 25));
System.out.println(knapSack(v, w, 30));

System.out.println(naive_knapSack(v, w, 25, 0));
System.out.println(naive_knapSack(v, w, 30, 0));

结果相同(注意第一个解决方案不是50是60)

60
80
60
80

但是,当动态规划算法是多项式时,递归算法的效率是指数的,仅使用34项进行比较

// efficiency
int ITEMS = 34;
int[] V = IntStream.range(0, ITEMS).map(i -> ThreadLocalRandom.current().nextInt(1, 50)).toArray();
int[] W = IntStream.range(0, ITEMS).map(i -> ThreadLocalRandom.current().nextInt(50, 150)).toArray();
int itemsWeight = Arrays.stream(W).sum();
int capacity = ThreadLocalRandom.current().nextInt(itemsWeight >> 2, itemsWeight >> 1);

long t0 = System.nanoTime();
int r1 = naive_knapSack(V, W, capacity, 0);
long t1 = System.nanoTime();
int r2 = knapSack(V, W, capacity);
long t2 = System.nanoTime();

System.out.printf("r1 = %d, t1 = %f%nr2 = %d, t2 = %f%n", r1, (t1 - t0) * 1e-9, r2, (t2 - t1) * 1e-9);

我们得到

r1 = 481, t1 = 11,11 seconds
r2 = 481, t2 = 0,004 seconds
 类似资料:
  • 在PHP中,检查数组是否为递归数组的最佳方法是什么? 给定以下代码: 从PHP手册: print\u r()在到达数组的第三个元素时将显示递归。 似乎没有其他方法可以扫描数组中的递归引用,因此如果需要检查它们,则必须使用print\u r()及其第二个参数来捕获输出并查找单词RECURSION。 还有更优雅的检查方式吗? 附:这就是我如何使用regex和print\u r()检查和获取递归数组键的

  • 我正在组装一个java小程序,使任务在工作中更快、更高效。 用户定义项目列表需要拆分成的三个组的大小。列表中的每个项目根据它被放入三个组中的哪个组具有不同的值。小程序需要显示哪个组合的总价值最高。 示例:带有列的二维整数数组;项目编号、第1组中的值、第2组中的值和第3组中的值。 这样,用户定义组1有3个插槽,组2有3个插槽,组3有2个插槽。 小程序应不按特定顺序显示以下解决方案 我可以管理一种效率

  • 问题内容: 对于需要解决的问题之一,我使用for循环找到了数组的最大值,因此我尝试使用递归找到它,这就是我想出的: 因此它可以正常工作并获取最大值,但是我的问题是:对于基本情况,返回a [head]以及对于在开头处的值大于最后一个值的情况,可以吗? 问题答案: 您只需一个计数器即可轻松完成此操作,只需使用您这次想要比较的值的索引即可: 这样可以更好地显示正在发生的情况,并使用默认的“递归”布局,例

  • 我正在尝试编写下一个程序: 仅包含正整数的二维方形数组。每个单元格只能在路径上出现一次,编写一个递归布尔静态方法,该方法接受一个包含数字(大于零)和任何正和的二维mat数组作为参数,该方法作为与mat大小相同的二维数组的参数给出,该方法应检查数组中是否有一个和为和的路径。否则,将返回false值,并使用路径标记路径和和:最初,当路径数组作为参数传递时,其所有单元格在方法末尾包含和,如果mat数组和

  • 问题内容: 我知道我可以这样做: 然后只需编写语句中所需的代码。 还有其他方法可以检查它们是否相等? 问题答案: 怎么了 if(!Arrays.equals(array1,array2)) 与相同,即是同一数组。这不是大多数人期望的。 比较数组的内容。

  • 问题内容: 我想找出$ all是否包含所有$ search_this值并返回true或false。有什么想法吗? 问题答案: 看一下array_intersect()。