用java实现一个动态规划矩阵连乘java,求大神帮忙!!!

页面已拦截
无锡网警提示您:
该网站已被大量用户举报,且存在未经证实的信息,可能会通过各种手段来盗取您的账号或骗取您的财产。Java通过动态规划法解决0-1背包问题代码
0人收藏此代码,
0/1背包问题的动态规划法求解,前人之述备矣,这里所做的工作,不过是自己根据理解实现了一遍,主要目的还是锻炼思维和编程能力,同时,也是为了增进对动态规划法机制的理解和掌握。 转自:
&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp值得提及的一个问题是,在用&nbspJAVA&nbsp实现时,&nbsp是按算法模型建模,还是用对象模型建模呢?&nbsp如果用算法模型,那么&nbsp背包的值、重量就直接存入二个数组里;如果用对象模型,则要对背包以及背包问题进行对象建模。思来想去,还是采用了对象模型,尽管心里感觉算法模型似乎更好一些。有时确实就是这样,对象模型虽然现在很主流,但也不是万能的,采用其它的模型和视角,或许可以得到更好的解法。&nbsp背包建模:
package algorithm.
public class Knapsack {
/** 背包重量
/** 背包物品价值
public Knapsack(int weight, int value) {
this.value =
this.weight =
public int getWeight() {
public int getValue() {
public String toString() {
return &[weight: & + weight + & & + &value: & + value + &]&;
//该代码片段来自于: /codes/java/7212
背包问题求解:
* 求解背包问题:
* 给定 n 个背包,其重量分别为 w1,w2,……,wn, 价值分别为 v1,v2,……,vn
* 要放入总承重为 totalWeight 的箱子中,
* 求可放入箱子的背包价值总和的最大值。
* NOTE: 使用动态规划法求解 背包问题
* 设 前 n 个背包,总承重为 j 的最优值为 v[n,j], 最优解背包组成为 b[n];
* 求解最优值:
* 1. 若 j & wn, 则 : v[n,j] = v[n-1,j];
j &= wn, 则:v[n,j] = max{v[n-1,j], vn + v[n-1,j-wn]}。
* 求解最优背包组成:
* 1. 若 v[n,j] & v[n-1,j] 则 背包 n 被选择放入 b[n],
* 2. 接着求解前 n-1 个背包放入 j-wn 的总承重中,
于是应当判断 v[n-1, j-wn] VS v[n-2,j-wn], 决定 背包 n-1 是否被选择。
* 3. 依次逆推,直至总承重为零。
重点: 掌握使用动态规划法求解问题的分析方法和实现思想。
分析方法: 问题实例 P(n) 的最优解S(n) 蕴含 问题实例 P(n-1) 的最优解S(n-1);
在S(n-1)的基础上构造 S(n)
实现思想: 自底向上的迭代求解 和 基于记忆功能的自顶向下递归
package algorithm.
import java.util.ArrayL
public class KnapsackProblem {
/** 指定背包 */
private Knapsack[]
/** 总承重
private int totalW
/** 给定背包数量
/** 前 n 个背包,总承重为 totalWeight 的最优值矩阵
private int[][] bestV
/** 前 n 个背包,总承重为 totalWeight 的最优值 */
private int bestV
/** 前 n 个背包,总承重为 totalWeight 的最优解的物品组成 */
private ArrayList&Knapsack& bestS
public KnapsackProblem(Knapsack[] bags, int totalWeight) {
this.bags =
this.totalWeight = totalW
this.n = bags.
if (bestValues == null) {
bestValues = new int[n+1][totalWeight+1];
* 求解前 n 个背包、给定总承重为 totalWeight 下的背包问题
public void solve() {
System.out.println(&给定背包:&);
for(Knapsack b: bags) {
System.out.println(b);
System.out.println(&给定总承重: & + totalWeight);
// 求解最优值
for (int j = 0; j &= totalW j++) {
for (int i = 0; i &= i++) {
if (i == 0 || j == 0) {
bestValues[i][j] = 0;
// 如果第 i 个背包重量大于总承重,则最优解存在于前 i-1 个背包中,
// 注意:第 i 个背包是 bags[i-1]
if (j & bags[i-1].getWeight()) {
bestValues[i][j] = bestValues[i-1][j];
// 如果第 i 个背包不大于总承重,则最优解要么是包含第 i 个背包的最优解,
// 要么是不包含第 i 个背包的最优解, 取两者最大值,这里采用了分类讨论法
// 第 i 个背包的重量 iweight 和价值 ivalue
int iweight = bags[i-1].getWeight();
int ivalue = bags[i-1].getValue();
bestValues[i][j] =
Math.max(bestValues[i-1][j], ivalue + bestValues[i-1][j-iweight]);
// 求解背包组成
if (bestSolution == null) {
bestSolution = new ArrayList&Knapsack&();
int tempWeight = totalW
for (int i=n; i &= 1; i--) {
if (bestValues[i][tempWeight] & bestValues[i-1][tempWeight]) {
bestSolution.add(bags[i-1]);
// bags[i-1] 表示第 i 个背包
tempWeight -= bags[i-1].getWeight();
if (tempWeight == 0) { }
bestValue = bestValues[n][totalWeight];
n 个背包, 总承重为 totalWeight 的背包问题的最优解值
* 调用条件: 必须先调用 solve 方法
public int getBestValue() {
return bestV
n 个背包, 总承重为 totalWeight 的背包问题的最优解值矩阵
* 调用条件: 必须先调用 solve 方法
public int[][] getBestValues() {
return bestV
n 个背包, 总承重为 totalWeight 的背包问题的最优解值矩阵
* 调用条件: 必须先调用 solve 方法
public ArrayList&Knapsack& getBestSolution() {
return bestS
//该代码片段来自于: /codes/java/7212
背包问题测试:
package algorithm.
public class KnapsackTest {
public static void main(String[] args) {
Knapsack[] bags = new Knapsack[] {
new Knapsack(2,13), new Knapsack(1,10),
new Knapsack(3,24), new Knapsack(2,15),
new Knapsack(4,28), new Knapsack(5,33),
new Knapsack(3,20), new Knapsack(1, 8)
int totalWeight = 12;
KnapsackProblem kp = new KnapsackProblem(bags, totalWeight);
kp.solve();
System.out.println(& -------- 该背包问题实例的解: --------- &);
System.out.println(&最优值:& + kp.getBestValue());
System.out.println(&最优解【选取的背包】: &);
System.out.println(kp.getBestSolution());
System.out.println(&最优值矩阵:&);
int[][] bestValues = kp.getBestValues();
for (int i=0; i & bestValues. i++) {
for (int j=0; j & bestValues[i]. j++) {
System.out.printf(&%-5d&, bestValues[i][j]);
System.out.println();
//该代码片段来自于: /codes/java/7212
动态规划法总结:1.&nbsp动态规划法用于求解非最优化问题:当问题实例P(n)的解由子问题实例的解构成时,比如&nbspP(n)&nbsp=&nbspP(n-1)&nbsp+&nbspP(n-2)&nbsp[斐波那契数列]&nbsp,而&nbspP(n-1)&nbsp和&nbspP(n-2)可能包含重合的子问题,可以使用动态规划法,通过自底向上的迭代,求解较小子问题实例的解,并作为求解较大子问题实例的解的基础。关键思想是:&nbsp避免对子问题重复求解。比如:&nbsp求斐波那契数&nbspF(5):F(5)&nbsp&nbsp=&nbspF(4)&nbsp+&nbspF(3);子问题:&nbspF(4)&nbsp=&nbspF(3)&nbsp+&nbspF(2)&&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbspF(3)&nbsp=&nbspF(2)&nbsp+&nbspF(1);&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbspF(2)&nbsp=&nbspF(1)&nbsp+&nbspF(0)&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbspF(2)&nbsp=&nbspF(1)&nbsp+&nbspF(0);子问题:&nbspF(3)&nbsp=&nbspF(2)&nbsp+&nbspF(1)&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbspF(2)&nbsp=&nbspF(1)&nbsp+&nbspF(0)由上面的计算过程可知,如果单纯使用递归式,则子问题&nbspF(2)&nbsp被重复计算了2次;当问题实例较大时,这些重复的子问题求解就会耗费大量不必要的时间。&nbsp若使用动态规划法,将&nbspF(2)&nbsp的值存储起来,当后续计算需要的时候,直接取出来,&nbsp就可以节省不少时间。&nbsp另一个比较典型的例子是:&nbsp求解二项式系数&nbsp&nbspC(n,&nbspk)&nbsp=&nbspC(n-1,&nbspk)&nbsp+&nbspC(n-1,&nbspk-1)&nbsp2.&nbsp动态规划法求解最优化问题:&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp当问题实例P(n)&nbsp的最优解&nbsp可以从&nbsp问题实例&nbspP(n-1)&nbsp的最优解&nbsp构造出来时,可以采用动态规划法,一步步地构造最优解。&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp关键是掌握动态规划法求解问题时的分析方法,如何从问题导出&nbsp解的递推式。&nbsp实际上,当导出背包问题的递归式后,后来的工作就简单多了,如何分析背包问题,导出其最优解的递推式,我觉得,这才是最关键的地方!问题分析很重要!
相关代码片段:
最新Java代码片段
合作网站:商品中每种商品都有标价。例如,一朵花的价格是2元,一个花瓶的价格是5元。为了吸引顾客,商品提供了一组优惠商品价。优惠商品是把一种或多种商品分成一组,并降价销售。如,三朵花的价格是5元不是6元。2个花瓶加1朵花的优惠价是10元。设计算法计算出某一顾客所购商品应付的最少费用,并用Java代码实现.
问题1:有多少种类的商品?问题2:这些商品是否都可以组合,,比如顾客买了200个50种类的商品,这50个种类是不是都可以互相组合?
你还没有登录,请先登录或注册慕课网帐号
你这个问题,我感觉就举得几个例子基本懂啊最后计算的时候都是整数,如三朵花+一个花瓶是10元,不是11元,我只能帮你到这了
你还没有登录,请先登录或注册慕课网帐号
69594人关注
Copyright (C)
All Rights Reserved | 京ICP备 号-2本帖子已过去太久远了,不再提供回复功能。背包问题具体例子:假设现有容量10kg的背包,另外有3个物品,分别为a1,a2,a3。物品a1重量为3kg,价值为4;物品a2重量为4kg,价值为5;物品a3重量为5kg,价值为6。将哪些物品放入背包可使得背包中的总价值最大?
首先想到的,一般是穷举法,一个一个地试,对于数目小的例子适用,如果容量增大,物品增多,这种方法就无用武之地了。
  其次,可以先把价值最大的物体放入,这已经是贪婪算法的雏形了。如果不添加某些特定条件,结果未必可行。
  最后,就是动态规划的思路了。先将原始问题一般化,欲求背包能够获得的总价值,即欲求前i个物体放入容量为m(kg)背包的最大价值c[i][m]&&使用一个数组来存储最大价值,当m取10,i取3时,即原始问题了。而前i个物体放入容量为m(kg)的背包,又可以转化成前(i-1)个物体放入背包的问题。下面使用数学表达式描述它们两者之间的具体关系。
  表达式中各个符号的具体含义。
  w[i] : &第i个物体的重量;
  p[i] : 第i个物体的价值;
  c[i][m] : 前i个物体放入容量为m的背包的最大价值;
  c[i-1][m] : 前i-1个物体放入容量为m的背包的最大价值;
  c[i-1][m-w[i]] : 前i-1个物体放入容量为m-w[i]的背包的最大价值;
  由此可得:
      c[i][m]=max{c[i-1][m-w[i]]+pi , c[i-1][m]}(下图将给出更具体的解释)
  根据上式,对物体个数及背包重量进行递推,列出一个表格(见下表),表格来自()&,当逐步推出表中每个值的大小,那个最大价值就求出来了。推导过程中,注意一点,最好逐行而非逐列开始推导,先从编号为1的那一行,推出所有c[1][m]的值,再推编号为2的那行c[2][m]的大小。这样便于理解。
  思路厘清后,开始编程序,Java代码如下所示:
public class BackPack {
public static void main(String[] args) {
int m = 10;
int n = 3;
int w[] = {3, 4, 5};
int p[] = {4, 5, 6};
int c[][] = BackPack_Solution(m, n, w, p);
for (int i = 1; i &=n; i++) {
for (int j = 1; j &=m; j++) {
System.out.print(c[i][j]+"\t");
System.out.println();
//printPack(c, w, m, n);
* @param m 表示背包的最大容量
* @param n 表示商品个数
* @param w 表示商品重量数组
* @param p 表示商品价值数组
public static int[][] BackPack_Solution(int m, int n, int[] w, int[] p) {
//c[i][v]表示前i件物品恰放入一个重量为m的背包可以获得的最大价值
int c[][] = new int[n + 1][m + 1];
for (int i = 0; i & n + 1; i++)
c[i][0] = 0;
for (int j = 0; j & m + 1; j++)
c[0][j] = 0;
for (int i = 1; i & n + 1; i++) {
for (int j = 1; j & m + 1; j++) {
//当物品为i件重量为j时,如果第i件的重量(w[i-1])小于重量j时,c[i][j]为下列两种情况之一:
//(1)物品i不放入背包中,所以c[i][j]为c[i-1][j]的值
//(2)物品i放入背包中,则背包剩余重量为j-w[i-1],所以c[i][j]为c[i-1][j-w[i-1]]的值加上当前物品i的价值
if (w[i - 1] &= j) {
if (c[i - 1][j] & (c[i - 1][j - w[i - 1]] + p[i - 1]))
c[i][j] = c[i - 1][j - w[i - 1]] + p[i - 1];
c[i][j] = c[i - 1][j];
c[i][j] = c[i - 1][j];
运行结果为:
Process finished with exit code 0
阅读(...) 评论()}

我要回帖

更多关于 java实现动态规划问题 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信