Programación inicial dinámico: cómo resolver con habilidad para juntar un solo problema "doble Octubre" ir de compras?

Programación inicial dinámico: cómo resolver con habilidad para juntar un solo problema "doble Octubre" ir de compras?

Taobao "doble Octubre" actividades promocionales festival de compras, tales como "lleno 200 por 50", si hay algo que desea comprar n-novia carro de compras, elegir unos pocos, reducción total bajo la premisa presionó condiciones en las así elegido para maximizar la suma de la reducción de los precios de las materias primas cerca completo

estudio de planificación dinámica de rutas

La programación dinámica es más adecuado para la resolución de problemas de optimización, tales como la búsqueda de máximos, mínimos

Sección I: dos modelos clásicos de problema de programación dinámica, tenemos que mostrar la programación dinámica, la programación dinámica y métodos de resolución de problemas ¿Por qué es cómo la evolución cabo

Sección II: Resumen de la programación dinámica para las características de resolución de problemas, la programación dinámica e ideas para resolver problemas

Sección III: programación dinámica clásica para resolver problemas reales

0-1 problema de la mochila

//回溯算法实现。注意:把输入的变量都定义成了成员变量
private int maxW = Integer.MIN.VALUE;  //结果放到maxW中
private int[] weight = {2,3,4,6,3}  //物品重量
private int n = 5 ;//物品个数
private int w = 9 ;//背包承受的最大重量
public void f(int i , int cw){  //调用f(0,0)
	if(cw == w || i == n){   //cw == w 表示装满了,i == n表示物品都考察完了
		if(cw > maxW) maxW = cw ;
		return;
	}
	f(i+1,cw);  //选择不装第i个物品
	if(cw + weight[i] <= w){
		f(i+1,cw + weight[i]);  //选择装第i个物品
	}
}

Supongamos peso de la carga máxima mochila es 9, hay cinco elementos diferentes, a saber, 2,2,4,6,3, un ejemplo del proceso de solución por backtracking árbol recursivo dibujada, que es:

f (0,0)

f (1,0) f (1,2)

f (2,0) f (2,2) f (2,2) f (2,4)

f (3,0) f (3,4) f (3,2) f (3,6) f (3,2) f (3,6) f (3,4) f (3,8)

Cada nodo en el árbol de forma recursiva representado por un estado (i, CW) denota, i denota el número de elementos para tomar una decisión de si o no en la mochila, la mochila CW representa el peso total de la corriente, tal como (2,2) a ser representado Decisión dos artículos se cargan mochila, antes de la decisión, el peso total de la mochila es el artículo 2,

árbol recursivo, algunos temas fueron doble contado dos veces, que pueden hacer uso de la sección recursiva del "memorándum" se dirigió a varios de los registros y calcular f (i, cw), redundancia evitar

private int maxW = Integer.MIN_VALUE;  //结果放到maxW中
private int[]  weight = {2,2,4,6,3} ;   //物品重量
private int n = 5 ;//物品个数
private int w = 9;//背包承受的最大重量
private boolean[][] mem = new boolean[5][10];  //备忘录,默认值是false
public void f(int i , int cw){  //调用f(0,0)
	if(cw == w || i == n){   //cw == w表示装满了,i == n表示物品都考察完了
		if(cw > maxW) maxW = cw;
		return;
	}
	if(mem[i][cw])  return;   //重复状态
	mem[i][cw] = true;   //记录(i,cw)这个状态
	f(i+1,cw) ; //选择不装第i个物品
	if(cw +weight[i] <= w){
		f(i+1,cw +weight[i]);   //选择装第i个物品
	}
}

A continuación, el enfoque de programación dinámica es: todo el proceso de solución se divide en n etapas, cada etapa será una decisión de si los elementos en la mochila, después de cada elemento de la decisión (o no colocados en la mochila) terminado, artículos de mochila en peso tener muchos casos, es decir, alcanzar el estado de una pluralidad de diferentes, corresponden a un árbol recursiva, es decir, hay muchos nodos diferentes, el estado de cada capa de los registros duplicados combinados únicos estados diferentes, a continuación, basada en capa conjunto del estado, para derivar un conjunto de estados. El número se puede repetir para cada capa del estado combinado, el estado de cada capa son diferentes para asegurar que no más de W

Unidos con una matriz de dos dimensiones [n][w+1], cada uno de los estados registro diferente se pueden lograr, en peso de 0 (subíndice numeran empezando desde 0) el artículo es 2, o en una bolsa, mochila o no cargado, después de las decisiones de terminación, corresponderá a mochila dos estados, el peso total de la mochila artículo es 0 o 2, con los Estados [0][0]= true y Unidos [0][2]= true para indicar dos estados

En peso de un artículo es 2, según el estado anterior de la mochila, después de la decisión artículo completamente diferentes estados tienen tres, el peso total de los artículos en una mochila son 0 (0 + 0), 2 (0 + 2 o 2 0), 4 (2 + 2) Unidos [1][0]= true, Estados [1][2]= true, Estados [1][4]= true para indicar tres estados

Y así sucesivamente, hasta que todos los artículos Después de la inspección, toda la matriz se calcula estados, 0 representa falsa, 1 representa cierto, solo hay que encontrar el valor más cercano de los verdaderos valores de w = 9 en el peso final, total del artículo es una mochila máximo

weight:物品重量      n:物品个数 , w:背包可承载重量
public int knapsack(int[] weight , int n ,int w){
	boolean[][] states = new boolean[n][w+1];  //默认值false
	states[0][0] = true;   //第一行的数据要特殊处理,可以利用哨兵优化
	if(weight[0] <= w){
		states[0][weight[0]]  = true;
	}
	for(int i = 1; i < n ; ++i){  //动态规划状态转移
		for(int j = 0 ; j <= w ; ++j){   // 不把第i个物品放入背包
			if(states[i -1][j]  == true) states[i][j] = states[i -1][j];
		}
		for(int j = 0 ;j <= w-weight[i] ; ++j){   //把第i个物品放入背包
			if(states[i-1][j]  == true) states[i][j+weight[i]]  =true;
		}
	}
	for(int i = w ; i >= 0 ;--i) {   //输出结果
		if(states[n-1][i]  == true)  return i;
	}
	return 0 ;
}

El problema se divide en una pluralidad de etapas, cada una correspondiente a una decisión, para cada registro de un conjunto de estados fase alcanzable, a continuación, una etapa para derivar un conjunto de conjunto del estado por el estado de la fase actual

Aunque la eficiencia de la programación dinámica es relativamente alta, pero la necesidad de aplicación adicional n multiplicado por una matriz de dos dimensiones w + 1 puede reducir el consumo de espacio que?

Solamente un tamaño es matriz unidimensional w + 1 puede resolver este problema

public static int knapsack2(int[] items , int n , int w){
	boolean[] states = new boolean[w+1];//默认值false
	states[0] = true;   //第一行的数据要特殊处理,可以利用哨兵优化
	if(items[0] <= w){
		states[items[0]] = true;
	}
	for(int i = 1 ; i < n ; ++i){    //动态规划
		for(int j = w-items[i] ; j >= 0 ; --j){   //把第i个物品放入背包
			if(states[j] == true)  states[j+items[i]] = true;
		}
	}
	for(int i = w ; i >= 0 ; --i){   //输出结果
		if(states[i]  == true) return i ;
	}
	return 0 ;
}

0-1 mochila versión mejorada problema

El valor de esta variable se introduce elementos, seleccionar ciertos elementos en la mochila, el límite máximo de peso de la mochila para cumplir con la premisa de, la mochila se puede cargar en el valor total de los bienes es el número más grande?

El uso del algoritmo de vuelta atrás para resolver:

private int maxV = Integer.MIN_VALUE;//结果放到maxV中
private int[] items={2,2,4,6,3}; //物品的重量
private int[] value={3,4,8,9,6};//物品的价值
private int n = 5;//物品个数
private int w = 9 ;//背包承受的最大重量
public void f(int i , int cw,int cv){  //调用f(0,0,0)
	if(cw == w || i == n){//cw == w 表示装满了,i==n表示物品都考察完了
		if(cv > maxV) maxV = cv;
		return;
	}
	f(i+1,cw,cv);  //选择不装第i个物品
	if(cw + weight[i] <= w){
		f(i+1,cw +weight[i],cv+value[i];  //选择装第i个物品)
	}
}

Necesitan tres variables (i, cw, cv) para representar un estado, i denota el i-ésimo próxima decisión de si los elementos en la mochila, cw representa el peso total de la mochila en el artículo actual, cv representa el valor total de los tipos actuales de los objetos de la mochila

Hay pocos nodos i y cw son idénticos, (2,2,4) en este estado es la siguiente f (2,2,4) y f (2,2,3), como el peso total de la caja, f el valor total de los bienes más altos correspondientes a los descartes f (2,2,3), (2,2,4), este movimiento decisión f

Programación Dinámica:

O todo el proceso de solución se divide en n etapas, cada etapa será una decisión de si los elementos en la mochila, después de la finalización de cada etapa de la decisión, el peso total y el valor total de los artículos en la mochila, habrá una variedad de circunstancias, es decir, alcanzará muchos estados diferentes

Unidos con una matriz de dos dimensiones [n][w+1], cada uno para grabar diferentes estados se puede lograr, en donde la matriz se almacena en los corresponde estado actual a un valor máximo total, las que cada capa (i, cw) estado de combinación se repite, sólo los valores de CV registran el estado máximo, este estado luego se derivan en base al estado de la capa siguiente

public static int knapsack3(int[] weight,int[] value,int n ,int w){
	int[][] states = new int[n][w+1];
	for(int i = 0 ; i < n ; ++i){   //初始化states
		for(int j = 0 ; j < w+1;++j){
			states[i][j] = -1;
		}
	}
	states[0][0] = 0;
	if(weight[0] <= w){
		states[0][weight[0]] = value[0];
	}
	for(int i = 1;i < n ;++i){   //动态规划,状态转移
		for(int j = 0 ; j <= w;++j){   //不选择第i个物品
			if(states[i-1][j] >= 0) states[i][j] = states[i-1][j];
		}
		for(int j = 0;j <= w-weight[i] ;++j){   //选择第i个物品
			if(states[i-1][j] >= 0 ){
				int v = states[i-1][j] + value[i];
				if(v > states[i][j+weight[i]]){
					states[i][j+weight[i]] = v;
				}
			}
		}
	}
	
	//找出最大值
	int maxvalue = -1;
	for(int j = 0 ; j <= w ;++j){
		if(states[n-1][j] > maxvalue) maxvalue = states[n-1][j];
	}
	return maxvalue;
}

El triángulo de Pascal para alguna transformación, digital gratuita para llenar cada posición, después de un cierto número sólo puede llegar a dos números adyacentes a la capa de abajo, si se mueve hacia abajo en la primera capa, mover a los pases de más bajo nivel la suma de todos los números, que se define como la longitud de la ruta, el programa obtiene la longitud del camino más corto desde el fondo hasta la parte superior de movimiento

5

7 8

2 3 4

4 9 6 1

2 7 9 4 5

int[][] matrix={{5},{7,8},{2,3,4},{4,9,6,1},{2,7,9,4,5}};

public int yanghuiTriangle(int[][] matrix){
	int[][] state = new int[matrix.length][matrix.length];
	state[0][0] = matrix[0][0];
	for(int i = 1 ; i < matrix.length ; i++){
		for(int j =0 ; j < matrix[i].length;j++){
			if(j == 0)  state[i][j] = state[i -1][j] + matrix[i][j;]
			else if(j == matrix[i].length -1)  state[i][j ] = state[i -1][j - 1] + matrix[i][j];
			else{
				int top1 = state[i- 1][j -1];
				int top2 = state[i - 1][j];
				state[i][j] = Math.min(top1,top2) + matrix[i][j];
			}
		}
	}
	
	int minDis = Integer.MAX_VALUE;
	for(int i = 0 ; i < matrix[matrix.length - 1] . length;i++){
		int distance = state[matrix.length -1][i];
		if(distance < minDis)  minDis = distance;
	}
	return minDis;
}

Publicado 75 artículos originales · ganado elogios 9 · vistas 9181

Supongo que te gusta

Origin blog.csdn.net/ywangjiyl/article/details/104717901
Recomendado
Clasificación