prefácio
Pensei sobre esta questão antes, sem sucesso reflete a maneira antiga: ajuda on-line
depois de navegar numerosos blog, tem algumas ideias sobre este registro. Como observa o estudo, apenas
se errado, desculpe-me salientar que você, seu conselho é o meu prazer.
Nota: A principal referência desde este é um blog , que também é um blog
solução
Título:
Suponha total de caverna e, d, c, b, um tesouro cinco (5 tipos de tesouro não), os seus pesos são 4,5,6,2,2, o seu valor é 6,4, 5,3,6, e agora a dar-lhe a carga mochila a 10, como mochila carregada pode levar embora a maior parte da riqueza?
pensamento
Aqui por Vi representa um valor do i-ésimo ponto; o Wi representa o i-ésimo peso do produto;
F. (i, j) representa a corrente , a seleção pode ser alcançado a partir do i-ésimo elemento na sequência mochila capacidade j quando o valor máximo
o terceiro exemplo refere-se a artigos C, e assim por diante.
Adicionar um novo item na mochila quando há duas opções:
- Novos itens adicionados peso maior do que a capacidade atual da mochila, naturalmente, não pode ser adicionado à mochila;
- Por peso do artigo recém-adicionado é menor do que a capacidade atual da mochila, para que possamos escolher um novo item adicionado a uma mochila ou não fazer parte de mochila.
NOTA: Os exemplos a seguir são independentes do assunto supra frente citada.
A primeira opção
No primeiro caso, o peso do artigo recentemente adicionado é maior do que a capacidade de corrente da embalagem, não é necessário mudar a sequência do artigo original mochila (por exemplo, a sequência original de artigos: a, b), a saber: Depois de encontrar um novo artigo, que valor permanece V (a) + V (b ) , pode-se convertê-lo em: sim na face de um i-th itens: F. (i, J) = F. (i- 1, J.); (PS: este é um cessão)
Por exemplo:
no caso em que a capacidade da mochila 5, mochila tem dois itens: a, b, quando confrontados com o terceiro item de C, a qual foi encontrada maior do que o peso actual do peso mochila (Wc> 5), assim existem F (3,5) = F (2,5 )
pode ser desenhada: quando o Wi> j; com um F (i, j) = F (i-1, j)
A segunda opção
No segundo caso, o peso dos itens recém-adicionado mochila menos do que a capacidade atual, somos confrontados com uma escolha: você quer a mudança em uma mochila
Mudança e não mudam:
Por exemplo, no caso de uma capacidade de 9 mochila, mochila desta vez há três itens: a, b, c, desta vez ele encontra os quatro primeiros itens D, para se transformar em, de fato, uma outra idéia é que tacitamente: na capacidade 9 é um caso em que, a partir de a, b, c, d quatro artigos item seleccionado na sequência com o valor mais alto tem uma certa d, mas se é após a mudança para o valor mais alto, e também precisam de ser Va + VB + Vc comparação (na verdade, . F. (1-i, j) )
Isto é: quando o Wi <= j quando não é: F (i, j) = max {F (i-1, j), F (i-1, j- o Wi) + Vi}
F (i-1, j) é o maior valor obtido sem mudança de
F (i-1, j- Wi) + Vi meios que se alterar o padrão, que é conseguir o mais alto valor mais excelente uma sequência após a d, capacidade mochila de j-Wi, mas desta vez havia um novo problema a: mochila de origem em b, c se não precisar fazer alterações? Isso é algo que nós não sabemos, que só pode ser calculado.
Mas para o problema A, não somos capazes de compreender: No caso da capacidade mochila de j-Wi, como escolher a partir do a, b, c três itens, a fim de alcançar o maior valor (independentemente de tudo espera, a b , c), então como é que vamos chegar capacidade mochila sequência ótima de j-Wi é? Será anunciado ...
Programação dinâmica
A tabela da FIG: linha superior para a "corrente" Capacidade Mochila (j), a primeira coluna representa o item de sequência (i)
, por exemplo: e (I = 1), d (i = 2), c (i = 3), b (i = 4), um (i = 5)
Nota: O exemplo que se segue vai ser: c-1, 3-1 = 2, de facto, refere-se também a d
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
---|---|---|---|---|---|---|---|---|---|---|
e | 0 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 6 | 6 |
d | 0 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 10 | 10 |
c | 0 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 10 | 11 |
b | 0 | 3 | 3 | 6 | 6 | 9 | 9 | 9 | 10 | 11 |
uma | 0 | 6 | 6 | 9 | 9 | 12 | 12 | 15 | 15 | 15 |
Como entender essa forma ele ??
E linha da tabela de uma célula para a coluna de sucesso para preencher.
B-th fileira 0 representa: quando a capacidade mochila de 1, a partir de e, d, c, b quatro tipos de itens para escolher a forma de alcançar o maior valor?
O d-line 7 representa: quando a capacidade mochila de 7, de como escolher e, d dois bens, a fim de alcançar o maior valor?
.
.
.
Baseado nesta tabela,
por exemplo, quando se calcula a linha c 8 coluna quando:
Wc de <J; F. (C, J) = max {F. (. C-1, J), F. (. C-1, J-Wc de) + Vc de }
a saber:
.. 6 <8; F. (3,8) = max {F. (2,8), F (2,8-6) 5}
= "F (3,8) = max {F. (2, . 8), F. (2,2 &) 5}
= "F (3,8) = max {6,0} +. 5
. 6 =" F (3,8) =
previamente calculamos F (3,8) temos calculado o F (2,2), ele pode ser diretamente referenciado. Esta é a solução para o problema da A.
Nota: O
método de programação dinâmica para resolver a seqüência cuidadosamente estruturado, para resolver o problema apenas uma vez para cada criança, e salvou o resultado. Se a solução para esta criança problema, novamente, apenas para descobrir que os resultados salvos sem ter que recalcular. Portanto, o algoritmo de programação dinâmica é dar espaço de memória adicional para economizar tempo de computação, é um exemplo típico do espaço-tempo trade-off. ----- "Introdução aos Algoritmos"
implementação de código Assunto
/**
* 使用动态规划解决01背包问题
*/
public class finalDemo01 {
/**
* 假设山洞里共有e d c b a这5件宝物(不是5种宝物),它们的重量分别是4,5,6,2,2,它们的价值分别是6,4,5,3,6
* 现在给你个承重为10的背包, 怎么装背包,可以才能带走最多的财富
*
* @param args
*/
public static void main(String[] args) {
//定义矩阵
//假设有5个物品e d c b a背包容量为10
//其重量分别为:4,5,6,2,2
//价值为:6,4,5,3,6
//定义价值矩阵,横坐标为背包的容量
int[][] valueMartix = new int[6][11];
//为了方便后面的取值,将没有意义的行列置0,这样取值就不必考虑行列为0的情况
for (int a = 0; a < 11; a++) {
valueMartix[0][a] = 0;
}
for (int a1 = 0; a1 < 5; a1++) {
valueMartix[a1][0] = 0;
}
//定义物品的重量数组
int[] weight = {0, 4, 5, 6, 2, 2};
//定义价值数组
int[] value = {0, 6, 4, 5, 3, 6};
int capacity = 10;
//开始填写价值矩阵
int i = 1;
int j = 1;
while (j <= capacity) {
for (; i < weight.length; i++) {
if (j < weight[i]) {
valueMartix[i][j] = valueMartix[i - 1][j];
} else {
valueMartix[i][j] = max(valueMartix[i - 1][j], valueMartix[i - 1][j - weight[i]] + value[i]);
}
}
i = 1;
j++;
}
//输出最佳方案对应的最大价值
System.out.println(valueMartix[5][10]);
}
public static int max(int v1, int v2) {
if (v1 >= v2) {
return v1;
} else {
return v2;
}
}
}
execução total código
A expansão adicional:
/**
* 最终版本,删减了一些不必要的注释
* 使用动态规划方法解决01背包问题
* 自底向上
*/
public class finalDemo02 {
public static void main(String[] args) {
//定义货物的数量
int goodsNumber;
//定义背包的容量
int capacity;
//输入货物的数量和背包的总容量
Scanner sc = new Scanner(System.in);
System.out.print("请输入货物的数量");
goodsNumber = sc.nextInt();
System.out.print("请输入背包的总容量");
capacity = sc.nextInt();
//定义矩阵
//定义价值矩阵,横坐标为背包的容量
int[][] valueMartix = new int[goodsNumber + 1][capacity + 1];
//为了方便后面的取值,将没有意义的行列置0,这样取值就不必考虑行列为0的情况
for (int a = 0; a < capacity; a++) {
valueMartix[0][a] = 0;
}
for (int a1 = 0; a1 < goodsNumber; a1++) {
valueMartix[a1][0] = 0;
}
//定义重量数组
List weight = new ArrayList();
//定义价值数组
List value = new ArrayList();
//将首为置为0
weight.add(0);
value.add(0);
//用户输入货物的重量和其对应的价值
for (int goods = 1; goods <= goodsNumber; goods++) {
//输入重量
weight.add(sc.nextInt());
//输入价值
value.add(sc.nextInt());
}
//开始填写价值矩阵
int i = 1;
int j = 1;
while (j <= capacity) {
for (; i < weight.size(); i++) {
if (j < (Integer) weight.get(i)) {
valueMartix[i][j] = valueMartix[i - 1][j];
} else {
valueMartix[i][j] = max(valueMartix[i - 1][j], valueMartix[i - 1][j - (Integer) weight.get(i)] + (Integer) value.get(i));
}
}
i = 1;
j++;
}
myPrint(valueMartix,goodsNumber,capacity);
}
//比较换与不换两种情况下的价值,返回价值高的数字
public static int max(int v1, int v2) {
if (v1 >= v2) {
return v1;
} else {
return v2;
}
}
//输出最佳方案能得到的最大价值
public static void myPrint(int[][] valueMartix,int goodsNumber,int capacity){
System.out.println(valueMartix[goodsNumber][capacity]);
}
}