1. 实验内容
背包问题的求解
使用语言:Java语言
编译环境:openJDk-1.8
2. 问题描述
求装入哪些物品后恰好背包装满。
3. 需求分析
经过分析,本系统需完成的主要功能如下:
- 通过图形化界面输入物品重量组和背包最大承重
- 通过图形化界面输出背包装入物品组合
- 通过图形化界面重置内容
- 使用递归方法解决问题
- 重置内容
4. 概要设计
-=ADT=-
{
void recursionSolution (); //使用递归规划解决问题入口
void dfs(int V, int index); //实际递归方法
void output(); //递归的输出函数输出最终结果
void DPSolution(); //使用动态规划解决问题入口
void findAnswer(); //找出件数为1的满足条件的解决办法的入口方法
void find(int start, int[] nums, int count, int tempSum); //找出件数为1的满足条件的解决办法的实际方法
void logAnswer(); //输出最终结果
}
5. 存储结构
通过 ArrayList 和数组进行存储
6. 算法流程图
- 如果 nums 序号集合对应的物体总重量大于背包重量直接返回。(因为如果 nums 序号对应的物品总重量大于背包重量的话,再加其他物品的重量了肯定也大于背包重量)
- 判断 nums 序号集合对应的物体总重量是否等于背包重量,等于的话将序号集合加入到解决办法集合中,否则执行第 3 步
- 从 i = start + 1 开始搜索,看 i 是否在 nums 序号集合中,如果不在的话,执行下一步操作,否则继续下一次循环。
- 从第 i 间开始搜索,找出件数为 count+1 的满足条件的解决办法。
7. 算法时间复杂度分析
- 递归实现时间复杂度位 O(2n)
8. 调试分析
本程序的代码实现皆与递归有关调试难度较大,在图形化界面搭建时发现 Javafx 的部分原生问题:
【问题一】
现象:出现栈溢出错误。
原因:出口的判断出现问题。在递归问题中递归方法的出口应该清晰明确,避免栈溢出问题的发生。
【问题二】
现象:Spinner 组件数字读取失败。
原因:Javafx 中存在的原生问题。带微调器的 Spinner 组件在文本框输入文本后应以回车结束,方可正确放入到文本框中可以读取。此外在 fxml 文件中还需定义 Spinner 的最大值与最小值,在 Controller 中定义 Spinner 的的 id 时应加入 Integer 的泛型。