Está en la página 1de 4

Para cada trabajador, elegimos el trabajo con el mínimo

coste de la lista de trabajos no asignados (tomamos la


entrada mínima de cada fila).

Solución con ramificación y poda:


#include <bits/stdc++.h>
#include <iostream>
#include <vector>

using namespace std;


#define N 4

// La coordenada trabajador representa un Trabajador


// La coordenada tarea representa una Tarea
int matrizCosto[N][N] =
{
{11, 12, 18, 40},
{14, 15, 13, 22},
{11, 17, 19, 23},
{17, 14, 20, 28}};
struct Vertice
{
// almacena el nodo padre del nodo actual ayuda a rastrear el camino
cuando se encuentra la respuesta
Vertice *padre;

// contiene el costo para los nodos antecesores incluyendo el nodo actual


int rutaCosto;

// Contiene el coste menos prometedor


int costo;

// contienen el número de trabajador


int trabajadorID;

// contiene el número de la tarea


int tareaID;

// La matriz booleana contendrá información sobre los trabajos asignados


a los trabajadores
bool asignado[N];
};

// Función para asignar un nuevo árbol de búsqueda Vértice


Vertice *nuevoVertice(int trabajador, int tarea, const bool asignado[],
Vertice *padre)
{
auto *vertice = new Vertice;

for (int j = 0; j < N; j++)


vertice->asignado[j] = asignado[j];
vertice->asignado[tarea] = true;

vertice->padre = padre;
vertice->trabajadorID = trabajador;
vertice->tareaID = tarea;

return vertice;
}

// Función para calcular el coste menos prometedor


// de Vértice después de que el trabajador trabajador sea asignado al trabajo
tarea
int calcularCosto(int matrizCosto[N][N], int trabajador, int tarea, const
bool asignado[])
{
int costo = 0;

// para almacenar los trabajos no disponibles


bool disponible[N] = {true};

// empezar desde el siguiente trabajador


for (int i = trabajador + 1; i < N; i++)
{
int min = INT_MAX, minIndex = -1;

// hacer para cada trabajo


for (int j = 0; j < N; j++)
{
// si el trabajo está sin asignar y es disponible y es menor que
el mínimo
if (!asignado[j] && disponible[j] &&
matrizCosto[i][j] < min)
{
// número de trabajo de la tienda
minIndex = j;

// costo almacenado
min = matrizCosto[i][j];
}
}

// añadir el coste del siguiente trabajador


costo += min;

// el trabajo no está disponible


disponible[minIndex] = false;
}

return costo;
}

// Objeto de comparación que se utilizará para ordenar el montón


struct comp
{
bool operator()(const Vertice *izq,
const Vertice *der) const
{
return izq->costo > der->costo;
}
};

// imprimir solucion
void imprimirSolucion(Vertice *min)
{
if (min->padre == nullptr)
return;

imprimirSolucion(min->padre);
cout << "Trabajador [" << char(min->trabajadorID + 'a') << "] asignado a
la tarea " << min->tareaID + 1 << " (costo: " << matrizCosto[min-
>trabajadorID][min->tareaID] << ")" << endl;
}

// Encuentra el coste mínimo utilizando Branch and Bound


int encontrarCostoMinimo(int matrizCosto[N][N])
{
// Crear una cp de prioridad para almacenar los nodos vivos de
// árbol de búsqueda;
priority_queue<Vertice *, vector<Vertice *>, comp> cp;

// inicializar la pila con un vértice de costo 0


bool asignado[N] = {false};
Vertice *root = nuevoVertice(-1, -1, asignado, nullptr);
root->rutaCosto = root->costo = 0;
root->trabajadorID = -1;

// Añade un vértice a la lista de nodos vivos;


cp.push(root);

// Encuentra un vértice vivo con el menor coste,


// añade sus hijos a la lista de nodos vivos tarea
// finalmente lo elimina de la lista.
while (!cp.empty())
{
// Encontrar un vértice vivo con el menor coste estimado
Vertice *min = cp.top();

// El vértice encontrado se elimina de la lista de nodos vivos


cp.pop();

// i almacena el siguiente trabajador


int i = min->trabajadorID + 1;

// si a todos los trabajadores se les asigna un trabajo


if (i == N)
{
// imprime la solución
imprimirSolucion(min);
return min->costo;
}
// hacer para cada trabajo
for (int j = 0; j < N; j++)
{
// Si no está asignado
if (!min->asignado[j])
{
// crear un nuevo árbol
Vertice *hijo = nuevoVertice(i, j, min->asignado, min);

// coste de los nodos predecesores, incluido el vértice


actual
hijo->rutaCosto = min->rutaCosto + matrizCosto[i][j];

// calcular su límite inferior


hijo->costo = hijo->rutaCosto +
calcularCosto(matrizCosto, i, j, hijo-
>asignado);

// Añadir hijo a la lista de nodos vivos


cp.push(hijo);
}
}
}
}

int main()
{
cout << "\nCosto optimo: "
<< encontrarCostoMinimo(matrizCosto) << endl;

return 0;
}

IMPRESIÓN:

También podría gustarte