Vamos a resolver el problema de la mochila utilizando Enfriamiento Simulado. Para ello, supongamos que
la capacidad de la mochila es q = 180 y que puede insertar hasta 100 elementos, con pesos aleatorios
comprendidos entre [1, 100], esto es, considere el siguiente vector P = {p1, p2, …, p100}, con pi = [1,100]. Se
permite que dos elementos pesen lo mismo.
Solución al Problema de la Mochila con Enfriamiento Simulado
Una posible solución es la siguiente:
public class Ej2 {
public static void main(String[] args) {
double temp = 1000.0;
double tempFinal = 10;
int objetosMax = 100;
int pesoMax = 180;
int[] sol = generarSolInicial(objetosMax);
int[] pesos = generarPesos(objetosMax, pesoMax);
while (temp > tempFinal) {
int[] mejorVecino = new int[sol.length];
// Copiamos el Mejor vecino actual que es nuestra solución inicial
System.arraycopy(sol, 0, mejorVecino, 0, sol.length);
//Calculo el coste (peso) de la funcion con el vecino actual
int costeActual = costeFuncion(mejorVecino, pesos);
//Copiamos el vecino actual para ir modificando
int[] copiaVecino = new int[sol.length];
System.arraycopy(sol, 0, copiaVecino, 0, sol.length);
boolean encontrado = false;
for (int i = 0; i < sol.length && encontrado == false; i++) {
// Hallamos los vecinos con una función que altera los bits
// Por ejemplo los vecinos de {0,0,1,0,1} serían:
// {1,0,1,0,1}, {0,1,1,0,1}, {0,0,0,0,1}, {0,0,1,1,1} y {0,0,1,0,0}
if (copiaVecino[i] == 1) {
copiaVecino[i] = 0;
} else {
copiaVecino[i] = 1;
}
// Comparamos el coste del vecino actual con el nuevo vecino
// y si es menor o igual que el peso maximo y tiene mayor coste
// o probabilidad de aceptacion es mayor que 1 lo acepto
if (costeFuncion(copiaVecino, pesos) <= pesoMax &&
((costeActual < costeFuncion(copiaVecino, pesos) ||
probabilidadAceptacion(costeActual, costeFuncion(copiaVecino, pesos), temp) > 1 ))) {
mejorVecino = copiaVecino;
costeActual = costeFuncion(copiaVecino, pesos);
encontrado = true;
// Si no se cumple la condición, dejamos el array como estaba
} else {
copiaVecino = new int[sol.length];
System.arraycopy(sol, 0, copiaVecino, 0, sol.length);
}
}
sol = mejorVecino; //Igualamos la solucion al mejor vecino
temp *= 0.9; // Enfriamos la temperatura un 10%
}
System.out.print("Objetos que llevamos en la mochila (1, si) (0, no) : ");
for (int i = 0; i < sol.length; i++) {
System.out.print(sol[i]);
if (i != pesos.length - 1)
System.out.print(",");
}
System.out.print("\nPesos: ");
for (int i = 0; i < pesos.length; i++) {
System.out.print(pesos[i]);
if (i != pesos.length - 1)
System.out.print(",");
}
System.out.println("\nLa mochila lleva: " + costeFuncion(sol, pesos) + "kg de peso");
}
// Calculamos el coste (peso) sumando los objetos cogidos
// es decir, los que tienen 1 en el array de binarios
// dicha suma nos dará el peso total de los objetos que llevamos
// en la mochila
public static int costeFuncion(int[] mejorVecino, int[] pesos) {
int peso = 0;
for (int i = 0; i < mejorVecino.length; i++) {
if (mejorVecino[i] == 1) {
peso += pesos[i];
}
}
return peso;
}
public static double probabilidadAceptacion(int costeActual, int costeVecino, double temperatura) {
return Math.exp((costeVecino - costeActual) / temperatura);
}
// Creamos un array de ceros de tamaño tam
// Suponiendo que la mochila en un principio está vacía
// 1 en el array significará que el objeto de dicha
// posición ha sido cogido
public static int[] generarSolInicial(int tam) {
int[] solInicial = new int[tam];
for (int i = 0; i < tam; i++) {
solInicial[i]=0;
}
return solInicial;
}
// Generamos pesos aleatorios de 0 a 100
public static int[] generarPesos(int size, int pesoMax) {
int[] pesos = new int[size];
for (int i = 0; i < size; i++) {
pesos[i] = (int) (Math.random() * 100);
}
return pesos;
}
}
Comentarios
Publicar un comentario