[Quiz#15] Thomas Darimont (OPL (CPLEX ) )

Thomas Darimont

Erfahrenes Mitglied
Hallo,

hier mal eine beispielhafte Lösung mit OPL. Nachspielen kann man die Geschichte mit der Trial Version des Analyst Studios:
http://www-01.ibm.com/software/websphere/products/optimization/opl-cplex-teaching-edition/

Neben der Formulierung von Optimierungsproblemen in einer problemnahen Sprache (OPL)
erlaubt der CPLEX Optimierer auchdie Aufbereitung von Eingabe / Ausgabe-Daten mit JavaScript.

Javascript:
/*********************************************
 * OPL 6.3 Model
 * Author: thomas.darimont
 * Creation Date: 09.04.2010 at 18:30:49
 *********************************************/
 
 tuple Sweet{
 	key int index;
 	string name;
 	float weightInGramm;
 	float kcal;
 }
 
 int maxWeightInGramm = 0; 
 
 int numberOfSweets = 0;
 {Sweet} sweets = {};
 
//exotisches Eingabeformat lesen
execute{
    //mit großen Dataset von http://www.tutorials.de/forum/diskussion/357969-quiz-15-lisas-osternest-3.html#post1855627
	var inputFileLocation = "C:/Users/thomas.darimont/opl/training/100k.txt";
	//var inputFileLocation = "C:/Users/thomas.darimont/opl/training/easterEggs.dat";
 	var inputFile = new IloOplInputFile();
 	inputFile.open(inputFileLocation);
 	
 	maxWeightInGramm = parseInt(inputFile.readline());
 	while(!inputFile.eof){
 	   var line = inputFile.readline();
 	   if(line ==""){
 	      break;
 	   }
 	   var currentSweetName = line;
 	   line = inputFile.readline();
 	   var weightAndKcal = line.split(" ");
 	   var currentSweetWeight = parseInt(weightAndKcal[0]);
 	   var currentSweetKcal = parseInt(weightAndKcal[1]);
 	   sweets.add(numberOfSweets++,currentSweetName,currentSweetWeight,currentSweetKcal);
 	}
 	inputFile.close();
 }
  
//eigentliche Optimierung
range sweetsRange = 1..numberOfSweets;
dvar int take[sweetsRange] in 0..1;

dexpr float currentWeight = sum(s in sweetsRange) item(sweets,s-1).weightInGramm * take[s];
dexpr float currentKcal = sum(s in sweetsRange) item(sweets,s-1).kcal * take[s];

maximize currentKcal;
    
subject to{
	ctMaxWeight: currentWeight <= maxWeightInGramm;
}

//Ergebnis Aufbereitung
execute{
	var sweetNames = "";

	for(var i = 1; i < numberOfSweets+1;i++){
		if(take[i] == 1){
			var sweet = sweets.get(i-1);
			if(i > 1){
				sweetNames += ", "
			}
			sweetNames += sweet.name ; 
		}
	}
	
	writeln("Optimale Auswahl: " + sweetNames);
	writeln("Masse: " + currentWeight);
	writeln("Nährwert: " + cplex.getObjValue());
}

Ausgabe für Standard Beispiel:
Code:
Optimale Auswahl: Nougat-Eier, Spannungs-Eier, Melker Runzelhase, Lynt Platinhase
Masse: 467
Nährwert: 2488

Ausgabe für OnlyFoos 100k.txt Eingabe:
Code:
Optimale Auswahl: , ei-2383, ei-8465, ei-23359, ei-40669, ei-47555, ei-62142, ei-62736, ei-66390, ei-77632, ei-79046
Masse: 500
Nährwert: 9983


Gruß Tom
 
Hi Tom,

das ist ja schon fast geschummelt :p Ich könnte noch eine Lösung in Mosel nachreichen, aber die würde wohl auch nicht recht viel anders ausschauen.

Grüße,
Matthias
 
Zurück