I';我正在努力解决这个问题;背包;Java和递归的使用问题

I';我正在努力解决这个问题;背包;Java和递归的使用问题,java,debugging,recursion,Java,Debugging,Recursion,这是学校作业,教授规定必须使用递归,并且必须在gui框中输入单行,其中第一个数字是背包可以容纳的最大容量(重量),其余是物品重量。这不包括值,只包括重量 它部分工作,因为它正确地跟踪树并指示有多少解决方案(通过调试输出),但我无法记录有效的解决方案。由于从sack[]数组中存储和删除了项,在分支结束时,它似乎可以很好地处理递归调用的返回 从我对代码进行了一百万次的单步检查中,我可以看出当它返回到其他地方时失败了。这就使得零散的物品被放在袋子里,而不该放在那里。希望有人能看到我在做什么蠢事,帮助我

这是学校作业,教授规定必须使用递归,并且必须在gui框中输入单行,其中第一个数字是背包可以容纳的最大容量(重量),其余是物品重量。这不包括值,只包括重量

它部分工作,因为它正确地跟踪树并指示有多少解决方案(通过调试输出),但我无法记录有效的解决方案。由于从sack[]数组中存储和删除了项,在分支结束时,它似乎可以很好地处理递归调用的返回

从我对代码进行了一百万次的单步检查中,我可以看出当它返回到其他地方时失败了。这就使得零散的物品被放在袋子里,而不该放在那里。希望有人能看到我在做什么蠢事,帮助我朝着正确的方向前进。我已经多次删除和重写了这段代码,以至于我要把我的电脑扔出窗外。哈哈

我知道这是很多,但我想不出如何正确地描述我遇到的问题,而只是张贴整个程序。提前感谢任何人可能提供的任何帮助

import javax.swing.*;
import java.util.Arrays;

// Main Program
class n00868494 {

   static int itemCount = 0; // total number of items 
   static int pos = 0; // position indicator in the "sack" array
   static int sack[] = new int[25]; // sack to hold items on right branches

   public static void main(String[] args) {

   String sinput[] = new String[25]; // temp string array to hold parameters before     converting to integers
   int items[] = new int[25]; // array to hold the items
   int capacity = 0; // knapsack capacity
   String s = null; // temp string to hold user input

   while (true) { // infinite loop

      // Use a JOptionPane dialog to get the user's input
      s = JOptionPane.showInputDialog(new JFrame("Input Params"), "Please enter total weight, followed a list of item weights)","Run Parameters",JOptionPane.QUESTION_MESSAGE);

      if ((s == null) || (s.equals(""))) { // user pressed X, cancel or left it blank.
         System.exit(0);  // exit cleanly
      }

      sinput = s.split(" "); // split the parameters on the whitespace

      for (int i = 0; i < sinput.length; i++) { // iterate through the array and copy the elements to the correct variables
         if (i == 0) {
            capacity = Integer.parseInt(sinput[i], 10); // knapsack weight in the first position
         } else {
            items[i-1] = Integer.parseInt(sinput[i], 10); // the rest are item weights
         }
      }
     items = Arrays.copyOfRange(items, 0, sinput.length - 1); // truncate the items array to remove empty elements at the end

      knapSack(capacity, items); // call the knapsack method that will in turn call the recursive function
   }   
      }

   public static void knapSack(int capacity, int[] items) {

      itemCount = items.length; // keep track of original number of items

      recknapSack(capacity, items, 0); // start recursive calls
   }


   /*
      recursive knapsack method: called repeatedly to find the correct combinations of items such that their weights
  total to the max capacity that the knapsack can hold

      capacity: knapsack capacity
      items: array of items (weights)
      branch: flag indicating whether the call is a left branch (item not included) or right branch (item included)
         0 - initial call, non recursive
         1 - left branch, weight not included
         2 - right branch, weight included
   */
   public static void recknapSack(int capacity, int[] items, int branch) {

      System.out.print("\nCap: " + capacity + " Items: " + Arrays.toString(items)); // recursive call tracking debugging

      if (capacity == 0){ // debugging - for breaking at certain points in the tree
         assert Boolean.TRUE; // set breakpoint on this line
      }


      // base cases - ends of the branches
      if (capacity == 0){ // sack is exactly full, item weights = total weight
            System.out.print("\t  -> good tree"); // debugging
            //JOptionPane.showMessageDialog(new JFrame("Results"), "The valid combinations are: ");
            Arrays.fill(sack, 0); // clear the sack, this was a successful branch, will start again for another solution
            return;
      } else if (capacity < 0) { // bag overloaded
            System.out.print("\t  -> overload tree"); // debugging
            if (branch == 2) // if this is an "included" branch
               sack[--pos] = 0; // remove the last item placed in the sack
        return;
           } else if (items.length == 0){ // out of items and/or capacity not reached
        System.out.print("\t  -> empty src tree"); // debugging
        if (branch == 2)
           sack[--pos] = 0;
        return;
   } else {

     int firstItem; // this the first item, it will either be discarded (not included) or placed in the sack array (included)
     firstItem = items[0];

     items = Arrays.copyOfRange(items, 1, items.length); // for either recursive branch: remove the first item from the list

     recknapSack(capacity, items, 1); // call recursive function, left branch, where item is discarded and not placed in sack

     // prepare for right branch, where item is placed in sack
     capacity -= firstItem; // subtract the left most item weight from from capacity
     sack[pos++] = firstItem; // place the item in the sack
     recknapSack(capacity, items, 2); // recursive right branch call, item is placed in sack, weight subtracted from capacity

  }

  return;
   }
}
import javax.swing.*;
导入java.util.array;
//主程序
n00868494类{
静态int itemCount=0;//项目总数
static int pos=0;//在“sack”数组中的位置指示器
static int sack[]=new int[25];//用于在右分支上保存项目的sack
公共静态void main(字符串[]args){
String sinput[]=新字符串[25];//转换为整数之前保存参数的临时字符串数组
int items[]=new int[25];//用于保存项的数组
int capacity=0;//背包容量
字符串s=null;//保存用户输入的临时字符串
while(true){//无限循环
//使用JOptionPane对话框获取用户的输入
s=JOptionPane.showInputDialog(新建JFrame(“输入参数”),“请输入总重量,然后是项目重量列表”,“运行参数”,JOptionPane.QUESTION_消息);
如果((s==null)| |(s.equals(“”)){//用户按了X,则取消或将其留空。
System.exit(0);//干净地退出
}
sinput=s.split(“”;//在空白处拆分参数
对于(int i=0;igood tree”);//调试
//showMessageDialog(新JFrame(“结果”),“有效组合为:”);
Arrays.fill(sack,0);//清除sack,这是一个成功的分支,将为另一个解决方案重新启动
返回;
}否则,如果(容量<0){//行李过载
System.out.print(“\t->重载树”);//调试
if(branch==2)//如果这是一个“包含”的分支
sack[--pos]=0;//删除放置在袋子中的最后一项
返回;
}如果(items.length==0){//未达到项和/或容量
System.out.print(“\t->empty src tree”);//调试
如果(分支==2)
sack[--pos]=0;
返回;
}否则{
int firstItem;//这是第一项,它将被丢弃(不包括)或放入sack数组(包括)
firstItem=项目[0];
items=Arrays.copyOfRange(items,1,items.length);//对于任一递归分支:从列表中删除第一项
RecBackapsack(容量,项,1);//调用递归函数,左分支,其中项被丢弃,不放入sack中
//准备右分支,将物品放在袋子中
容量-=firstItem;//从容量中减去最左边的项目重量
sack[pos++]=firstItem;//将物品放入袋子中
Rec背包(容量,物品,2);//递归右分支调用,物品放在袋子中,重量从容量中减去
}
返回;
}
}

代码中发生的事情是,当它到达最后一个else语句时,它并没有删除放入的初始值。我对你的代码做了一个小小的修改,可能会让你得到结果
 public static int recknapSack(int capacity, int[] items, int branch) {
 return capacity;
 else {

             int firstItem; // this the first item, it will either be discarded (not included) or placed in the sack array (included)
             firstItem = items[0];

             items = Arrays.copyOfRange(items, 1, items.length); // for either recursive branch: remove the first item from the list

             recknapSack(capacity, items, 1); // call recursive function, left branch, where item is discarded and not placed in sack

             // prepare for right branch, where item is placed in sack
             capacity -= firstItem; // subtract the left most item weight from from capacity
             int temp = pos;
             sack[pos++] = firstItem; // place the item in the sack
             System.out.println("First item " + firstItem);
             int ret = recknapSack(capacity, items, 2); // recursive right branch call, item is placed in sack, weight subtracted from capacity
             if(ret != 0)
             {
                  System.out.println("Removing " + sack[temp] + " at position " + (temp));
                 sack[temp] = 0;
                 pos = temp;
             }


      }