TP 8 : Problème du bin packing
On s'intérèsse au problème BIN-PACKING :
- Instance : un ensemble d'entiers et une capacité .
- Solution admissible : une partition de en sous-ensembles telle que pour tout , .
- Objectif : minimiser .
Autrement dit, il faut répartir les entiers de dans des boîtes de capacité de façon à minimiser le nombre de boîtes utilisées.
- Donner une solution optimale pour l'instance suivante : et .
Théorie
On admet que le problème PARTITION est NP-complet :
- Instance : un ensemble d'entiers .
- Question : existe-t-il une partition de en deux sous-ensembles et telle que ?
-
Définir le problème de décision BPD associé à BIN-PACKING.
-
Montrer que BPD est NP-complet.
Algorithme glouton
On va considérer trois algorithmes gloutons (non optimales) pour BIN-PACKING, qui considèrent les objets un par un :
- Next-fit : Lorsque le prochain objet ne tient pas dans la boîte actuelle, fermer définitivement cette boîte et mettre l'objet dans une nouvelle boîte.
- First-fit : Ajouter le prochain objet à la première boîte (c'est-à-dire la boîte la plus ancienne) dans laquelle il rentre. Si l'objet ne rentre dans aucune boîte, créer une nouvelle boîte et mettre l'objet dedans.
- First-fit decreasing : Trier les objets par ordre décroissant et appliquer l'algorithme First-fit.
-
Définir un type pour
instance
pour représenter une instance de BIN-PACKING, en C. Utiliser ce type pour définir l'instance donnée en question 1. -
Définir une fonction
int next_fit(instance *inst)
renvoyant le nombre de boîtes utilisées par l'algorithme Next-fit en C. -
Définir une fonction
int first_fit(instance *inst)
renvoyant le nombre de boîtes utilisées par l'algorithme First-fit en C. -
Définir une fonction
int first_fit_decr(instance *inst)
renvoyant le nombre de boîtes utilisées par l'algorithme First-fit decreasing en C. On pourra implémenter le tri par sélection. -
Vérifier ces trois algorithmes sur l'instance donnée en question 1.
next_fit: 5
first_fit: 4
first_fit_decr: 3
- Écrire une fonction
instance* random_instance(int n, int c)
qui génère une instance aléatoire de BIN-PACKING avec objets et une capacité . On utiliserasrand(time(0));
pour initialiser le générateur aléatoire dans lemain
etrand() % c
pour obtenir un entier uniformément au hasard entre0
etc - 1
.
Utiliser cette fonction pour comparer les trois algorithmes sur des instances aléatoires. On pourra aussi les comparer en temps d'exécution :
#include <time.h>
...
int t = clock();
... // exécution d'un algorithme
printf("Temps d'exécution : %f\n", (double)(clock() - t) / CLOCKS_PER_SEC);
Algorithme exact par Branch and Bound
-
Écrire une fonction récursive
int branch_and_bound(instance *inst, int i, int *bins, int nb_bins, int best)
qui renvoie le nombre minimum de boîtes possible pour l'instanceinst
. On utilisera un algorithme de Branch and Bound oùi
est l'indice de l'objet courant,bins
est un tableau contenant le poids dans chaque boîte,nb_bins
est le nombre de boîtes utilisées pour l'instant etbest
est le nombre minimum de boîtes trouvé jusqu'à présent. On arrêtera les appels récursifs lorsque tous les objets sont placés ou quand le nombre de boîtes utilisées dépassebest
. -
Vérifier avec l'instance suivante :
instance inst = {
.n = 30,
.w = {31, 18, 63, 28, 56, 1, 55, 74, 45, 10, 9, 24, 15, 61, 11, 38, 37, 71, 52, 38, 40, 26, 38, 72, 69, 96, 26, 5, 100, 78, },
.c = 100
};
// next_fit: 18
// first_fit: 15
// first_fit_decr: 14
//branch_and_bound: 13