Java 使用堆栈和无递归的深度优先背包

Java 使用堆栈和无递归的深度优先背包,java,algorithm,Java,Algorithm,我需要使用深度优先和堆栈解决问题,而没有递归调用。我使用列表和递归解决了这个问题。我不知道如何使用堆栈和递归来解决这个问题 这就是我现在拥有的: private int knapsackDepthFirst(List<KnapsackObject> list, int weight, int price, int maxWeight) { if (list.size() == 0) return price; int max = Integer.MIN_

我需要使用深度优先堆栈解决问题,而没有递归调用。我使用列表和递归解决了这个问题。我不知道如何使用堆栈和递归来解决这个问题

这就是我现在拥有的:

   private int knapsackDepthFirst(List<KnapsackObject> list, int weight, int price, int maxWeight) {
      if (list.size() == 0) return price;
      int max = Integer.MIN_VALUE;
      for (KnapsackObject item : list) {
         int best;
         if (weight + item.getWeight() > maxWeight) {
            best = Integer.MIN_VALUE;
         } else if (weight + item.getWeight() == maxWeight) {
            best = price + item.getPrice();
         } else {
            best = knapsackDepthFirst(list.subList(1, list.size()), weight + item.getWeight(), price + item.getPrice(), maxWeight);
         }
         if (best > max) max = best;
      }
      return max;
   }
private int-knapsackDepthFirst(列表、int-weight、int-price、int-maxWeight){
如果(list.size()==0)返回价格;
int max=整数的最小值;
用于(背包对象项:列表){
int最佳;
if(重量+项目.getWeight()>最大重量){
最佳=整数.MIN_值;
}else if(weight+item.getWeight()==maxWeight){
最佳=价格+项目。getPrice();
}否则{
best=背包深度优先(list.subList(1,list.size()),weight+item.getWeight(),price+item.getPrice(),maxWeight);
}
如果(最佳>最大)最大=最佳;
}
返回最大值;
}

背包对象
保存物品的价格和重量。

您需要的是自己维护堆栈。在堆栈中,您需要保留函数调用参数和局部变量(您还需要减少它们的计数)。从代码中不太清楚背包语句中是否允许携带多个相同类型的物品。所以我假设这是被禁止的(重写代码很容易,但事实并非如此)。检查c#中的以下解决方案:

公共类背包对象
{
公共权重;
公共价格;
}
公共静态Int32背包求解(int maxWeight,列表项)
{
Int32 max=Int32.MinValue;
Int32计数=项目数;
//实际上,堆栈包含当前迭代的权重参数。
Int32[]权重=新的Int32[计数+2];
//实际上,它的堆栈包含当前迭代的价格参数。
Int32[]价格=新的Int32[计数+2];
//实际上,它的堆栈包含一个标志,指定我们是否已经尝试获取not的项步骤[current]。
//如果允许获取相同类型的多个项,则必须是存储索引变量(int)而不是bool标志。
Boolean[]itemGetted=新布尔值[count+2];
//指示我们需要在返回到当前迭代时离开它。
Boolean[]finishIteration=新布尔值[count+2];
//表示当前迭代的深度。
Int32电流=0;
//将第一个“调用”放入堆栈。当前权重=0,价格=0。
权重[当前]=0;
价格[当前]=0;
itemGetted[当前]=false;
完成迭代[当前]=错误;
而(当前>=0)
{
//我们已经在这里做了一切,回溯。
if(完成迭代[当前])
{
//从堆栈中弹出当前调用。
--电流;
继续;
}
//我们已经对所有项目类型做出了决定。
//比较和回溯。
如果(当前==计数)
{
如果(最大值<价格[当前])
最大值=价格[当前];
//从堆栈中弹出当前调用。
--电流;
继续;
}
//如果我们没有尝试获取当前项目
如果(!itemGetted[当前])
{
itemGetted[当前]=真;
//我们可以把它放在背包里,试试看。

if(重量[当前]+项目[当前].weight解决方案要求您手动实现编译器在使用递归函数调用时为您生成的数据结构。基本上,对于每个调用,您都需要保存过程调用本地的所有变量的值,并将它们保存在适当的数据结构中。然后,这些值保存在堆栈上,然后保存到程序中当调用返回时,通过复制周围的内容在不同调用之间进行调解。这样做很乏味,但实际上并不困难…这就是为什么递归首先被发明的原因,当然!Kilian,请添加注释作为答案,以便我们可以对其进行投票!
    public class KnapsackObject
    {
        public int weight;
        public int price;
    }

    public static Int32 KnapsackSolve(int maxWeight, List<KnapsackObject> items)
    {
        Int32 max = Int32.MinValue;
        Int32 count = items.Count;
        // Its actually a stack contains a weight parameter for current iteration.
        Int32[] weights = new Int32[count + 2];
        // Its actually a stack contains a price parameter for current iteration.
        Int32[] prices = new Int32[count + 2];
        // Its actually a stack contains a flag which specify whether we already try to get item steps[current] of not.
        // If it's allowed to get multiple item of same type, it must be store index variable (int) instead of bool flag.
        Boolean[] itemGetted = new Boolean[count + 2];
        // Indicates that we need to leave current iteration when back track to it.
        Boolean[] finishIteration = new Boolean[count + 2];
        // Represents depth of current iteration.
        Int32 current = 0;

        // Put the first "call" into stack. Current weight = 0, price = 0.
        weights[current] = 0;
        prices[current] = 0;
        itemGetted[current] = false;
        finishIteration[current] = false;

        while (current >= 0)
        {
            // we already have done everything here, back tracking.
            if (finishIteration[current])
            {
                // Pop current call from stack.
                --current;
                continue;
            }

            // we already make our decision about all item types. 
            // Compare and back track.
            if (current == count)
            {
                if (max < prices[current])
                    max = prices[current];
                // Pop current call from stack.
                --current;
                continue;
            }

            // if we haven't tried to get current item
            if (!itemGetted[current])
            {
                itemGetted[current] = true;
                // and we can put it in knapack, try it.
                if (weights[current] + items[current].weight <= maxWeight)
                {
                    weights[current + 1] = weights[current] + items[current].weight;
                    prices[current + 1] = prices[current] + items[current].price;
                    itemGetted[current + 1] = false;
                    finishIteration[current + 1] = false;
                    // Push new call into stack.
                    current++;
                    continue;
                }
            }

            // and try not to put current item. 
            finishIteration[current] = true;
            weights[current + 1] = weights[current];
            prices[current + 1] = prices[current];
            itemGetted[current + 1] = false;
            finishIteration[current + 1] = false;
            // Push new call into stack.
            current++;
        }

        return max;
    }