practical session

publicité
TP – Problème du sac à dos
27 mai 2008
1
Introduction
L’objectif de ce TP vise à implémenter les heuristiques et algorithmes de
bases pour le problème du sac à dos et de les confronter via un ensemble de
tests commun. Dans une deuxième partie, on utilisera un solveur de programme
linéaire et on statuera sur les avantages et inconvénients des différentes approches.
On dispose d’un ensemble de classes de base (accessible ici http://www.
loria.fr/~canon/pepites/base.zip). Les classes principales sont :
KnapsackTest définit les donnés d’un problème (nombre d’item, poids, profits
et capacité du sac à dos) ;
KnapsackSolution définit une solution (booléen pour chaque item et problème associé) ;
AlgorithmRandomSimple contient une fonction qui génère une solution aléatoire (tous les algorithmes devront reprendre le même modèle) ;
Evaluator contient la fonction principale et permet de tester les algorithmes
générés sur un même ensemble de tests (il est possible de définir la taille
maximale des problèmes et le temps maximal passé dans chaque algorithme).
La documentation est disponible ici http://www.loria.fr/~canon/pepites/
doc/. En cas de doute, le code est commenté et accessible. Il est impératif
de ne pas tout comprendre (uniquement ce qui vous servira à construire vos
méthodes).
Le cours est accessible ici http://www.loria.fr/~canon/pepites/slideshow/
(temps de chargement long).
2
Approche algorithmique
Tester le code en l’important dans un projet Eclipse et en lançant la classe
Evaluator.
1
2.1
Génération aléatoire
En repartant de la méthode de génération aléatoire donnée, proposer une
nouvelle méthode aléatoire plus performante. L’idée consiste à disposer du plus
grand nombre possible d’items dans la solution finale (à l’inverse, la méthode
actuelle peut s’arrêter même s’il reste de la place).
Insérer le nouvel algorithme dans la fonction main de la classe Evaluator
et relancer le programme.
2.2
Heuristique gloutonne
Réaliser une heuristique gloutonne (construction itérative en réalisant le
meilleur choix à chaque étape).
2.3
Recherche exhaustive
Réaliser une exploration exhaustive des solutions (par récursion).
Comment de comporte cette méthode vis-à-vis des méthodes précédentes sur
l’ensemble de tests ?
2.4
Méthode de branch and bound
Repartir de la méthode précédente en y ajoutant des méthodes bornant
supérieurement et inférieurement les solutions afin d’éliminer les branches de
l’arbre de recherche qu’il est inutile d’explorer. Les bornes peuvent être obtenues
grâce à l’heuristique gloutonne.
Le gain est-il significatif dans sur l’ensemble de tests ?
2.5
Programmation dynamique
Réaliser l’algorithme de programmation dynamique proposé en cours. L’article de Wikipedia http://en.wikipedia.org/wiki/Knapsack_problem fournit un complément d’informations.
Quelle méthode se comporte le mieux sur l’ensemble de tests ?
3
Programmation linéaire
On utilisera dans cette partie le solveur GLPK (GNU Linear Programming
Kit) qui est libre, multiplateforme, dispose de méthodes pour la programmation
en variables mixtes et d’une interface Java.
La documentation de GLPK est disponible ici http://bjoern.dapnet.de/
glpk/refman48.pdf, et celle de l’interface Java, ici http://bjoern.dapnet.
de/glpk/javadoc/index.html.
2
3.1
Importation et exemple simple
Importer les bibliothèques (disponible ici http://bjoern.dapnet.de/glpk/
windows.zip) dans votre projet (Project -> Properties -> Java Build Path ->
Libraries). Il faut importer le fichier jar et la bibliothèque dll.
L’exemple (disponible ici http://www.loria.fr/~canon/pepites/ExempleMIP.
java) consiste à résoudre le problème suivant (avec x1 , x2 et x3 entiers) :
maximiser
sujet à
bornes
Z = 10x1 + 6x2 + 4x3
x1 + x2 + x3
≤ 100
10x1 + 4x2 + 5x3
≤ 600
2x1 + 2x2 + 6x3
≤ 300
x1 ≥ 0, x2 ≥ 0, x3 ≥ 0
Lancer l’exemple et observer le résultat.
Il existe deux manières d’utiliser le solveur : soit par l’usage de primitive
(comme dans l’exemple), soit par la lecture d’un fichier respectant un format
donné (le fichier généré au format CPLEX exemple.pl peut ainsi être lu pas la
primitive readCpxlp).
3.2
Résolution du problème du sac à dos
Choisir une méthode pour utiliser le solveur (se reporter à la documentation
adéquate pour la description de chaque primitive ou la spécification du format
de fichier CPLEX) et résoudre le problème du sac à dos.
Vérifier que le résultat est optimal (identique aux précédentes méthodes
optimales). Statuer sur l’efficacité de cette méthode.
4
Sac à dos quadratique
Étendre les classes existantes de manière à prendre en compte les profits pij .
Adapter les algorithmes qui le nécessitent. Proposer une formulation linéaire
pour le problème qui minimise le nombre de contraintes.
3
Téléchargement