Solve Exercise 13

This commit is contained in:
Manuel Thalmann 2022-12-20 14:25:40 +01:00
parent c99b0817c0
commit 39a1585a4b
No known key found for this signature in database
GPG key ID: 5FD9AD3CCDDBD27B
3 changed files with 243 additions and 0 deletions

View file

@ -0,0 +1,162 @@
package ch.nuth.zhaw.exbox;
import java.util.Random;
import java.util.stream.Stream;
public class BakeryCookieServer implements CommandExecutor {
private Ingredient mehl, zucker, salz, eier, butter, milch, zitrone, konfituere, schokolade;
private Ingredient[] stockOfIngredients;
private Cookie mailaenderli, spitzbuben, brownies;
private Cookie[] cookiesOfBakery;
private float temperature;
private Random heatGenerator = new Random();
public String execute (String input) {
initialiseIngredients();
initialiseCookies();
return simulatedAnnealing();
}
/**
* initializes the ingredients and their quantity in stock
*/
private void initialiseIngredients() {
mehl = new Ingredient("Mehl", 20000);
zucker = new Ingredient("Zucker", 25000);
salz = new Ingredient("Salz", 5000);
eier = new Ingredient("Eier", 2000);
butter = new Ingredient("Butter", 10000);
milch = new Ingredient("Milch", 5000);
zitrone = new Ingredient("Zitrone", 10000);
konfituere = new Ingredient("Konfitüre", 2000);
schokolade = new Ingredient("Schokolade", 1000);
stockOfIngredients = new Ingredient[] { mehl, zucker, salz, eier, butter, milch, zitrone, konfituere, schokolade };
}
/**
* initialises the cookies and the ingredients used for one cookie
*/
private void initialiseCookies() {
mailaenderli = new Cookie("Mailänderli", 7);
mailaenderli.addIngredient(mehl, 15);
mailaenderli.addIngredient(zucker, 11.25f);
mailaenderli.addIngredient(salz, 0.2f);
mailaenderli.addIngredient(eier, 5);
mailaenderli.addIngredient(butter, 12.5f);
mailaenderli.addIngredient(milch, 1);
mailaenderli.addIngredient(zitrone, 7.5f);
spitzbuben = new Cookie("Spitzbuben", 6);
spitzbuben.addIngredient(mehl, 25.5f);
spitzbuben.addIngredient(zucker, 6.25f);
spitzbuben.addIngredient(salz, 0.15f);
spitzbuben.addIngredient(eier, 4);
spitzbuben.addIngredient(butter, 12.5f);
spitzbuben.addIngredient(konfituere, 10.5f);
brownies = new Cookie("Schoggibuben", 6);
brownies.addIngredient(mehl, 15.5f);
brownies.addIngredient(zucker, 10);
brownies.addIngredient(salz, 0.10f);
brownies.addIngredient(eier, 3);
brownies.addIngredient(butter, 10.5f);
brownies.addIngredient(schokolade, 20.5f);
cookiesOfBakery = new Cookie[] {mailaenderli, spitzbuben, brownies};
}
/**
* uses simulated annealing to generate new possible solutions
* @return string contains the best found solution for all cookies
*/
private String simulatedAnnealing() {
String result = "";
// TODO
float startTemperature = temperature;
creationOfInitialConfiguration();
while (temperature >= 0) {
generateNextTestConfiguration();
if (checkIfValidSolution())
{
if (checkIfMoreCookiesAndBetterSolution() || (Math.random() * startTemperature) > temperature)
{
for (Cookie cookie : cookiesOfBakery) {
cookie.setBestNrOfCookies(cookie.getTestedNrOfCookies());
}
}
}
temperature -= heatGenerator.nextFloat();
}
for (Cookie cookie : cookiesOfBakery) {
result += cookie.getNameOfCookie() + ": " + cookie.getBestNrOfCookies() + ", ";
}
return result + "\n";
}
/**
* initialize very first run (temperature)
*/
private void creationOfInitialConfiguration() {
// TODO
temperature = 10_000_000;
}
/**
* Generate a randomized new test set of cookies
*/
private void generateNextTestConfiguration() {
// TODO
for (Cookie cookie : cookiesOfBakery)
{
if (heatGenerator.nextBoolean())
{
int incremental = cookie.getBestNrOfCookies() > 0 ? (heatGenerator.nextBoolean() ? 1 : -1) : 1;
cookie.setTestedNrOfCookies(cookie.getBestNrOfCookies() + incremental);
}
}
}
/**
* Check if this is a better solution (more cookies) then the solution already found
* @return true if the newly tested solution is better
*/
private boolean checkIfMoreCookiesAndBetterSolution() {
// TODO
return Stream.of(cookiesOfBakery).mapToInt((cookie) -> cookie.getTestedNrOfCookies()).sum()
>= Stream.of(cookiesOfBakery).mapToInt((cookie) -> cookie.getBestNrOfCookies()).sum();
}
/**
* Check if there are enough ingredients to bake this new solution
* @return true if enough ingredients
*/
private boolean checkIfValidSolution() {
// TODO
for (Ingredient ingredient : stockOfIngredients)
{
ingredient.initialiseStockBeforeCooking();
}
for (Cookie cookie : cookiesOfBakery)
{
for (int i = 0; i < cookie.getNrOfIngredients(); i++)
{
if (!cookie.getIngredientOfCookie(i).removeFromStock(cookie.getGramsPerIngredient(i) * cookie.getTestedNrOfCookies()))
{
return false;
}
}
}
return true;
}
}

View file

@ -0,0 +1,56 @@
package ch.nuth.zhaw.exbox;
public class Cookie {
private final String nameOfCookie;
private int bestNrOfCookies = 0;
private int testedNrOfCookies;
private final Ingredient[] ingredientsOfCookie;
private final float[] gramsPerIngredient;
private int nrOfIngredient = 0;
Cookie(String nameOfCookie, int nrOfIngridients) {
this.nameOfCookie = nameOfCookie;
ingredientsOfCookie = new Ingredient[nrOfIngridients];
gramsPerIngredient = new float[nrOfIngridients];
}
public String getNameOfCookie() {
return nameOfCookie;
}
public int getBestNrOfCookies() {
return bestNrOfCookies;
}
public void setBestNrOfCookies(int bestNrOfCookies) {
this.bestNrOfCookies = bestNrOfCookies;
}
public int getTestedNrOfCookies() {
return testedNrOfCookies;
}
public void setTestedNrOfCookies(int testedNrOfCookies) {
this.testedNrOfCookies = testedNrOfCookies;
}
void addIngredient(Ingredient ingredient, float gramsPerCookie) {
ingredientsOfCookie[nrOfIngredient] = ingredient;
this.gramsPerIngredient[nrOfIngredient] = gramsPerCookie;
nrOfIngredient++;
}
Ingredient getIngredientOfCookie(int nrOfIngredient)
{
return ingredientsOfCookie[nrOfIngredient];
}
float getGramsPerIngredient(int nrOfIngredient)
{
return gramsPerIngredient[nrOfIngredient];
}
int getNrOfIngredients() {
return nrOfIngredient;
}
}

View file

@ -0,0 +1,25 @@
package ch.nuth.zhaw.exbox;
public class Ingredient {
private final String name;
private final float gramInBakery;
private float gramUsedForBaking;
Ingredient (String name, int gramInBakery) {
this.name = name;
this.gramInBakery = gramInBakery;
}
void initialiseStockBeforeCooking() {
gramUsedForBaking = 0;
}
boolean removeFromStock(float gramToRemove) {
gramUsedForBaking += gramToRemove;
return gramUsedForBaking <= gramInBakery;
}
String getRemainingStock() {
return name + ": " + (gramInBakery - gramUsedForBaking) + ", ";
}
}