Solve Exercise 13
This commit is contained in:
parent
c99b0817c0
commit
39a1585a4b
3 changed files with 243 additions and 0 deletions
162
app/src/main/java/ch/nuth/zhaw/exbox/BakeryCookieServer.java
Normal file
162
app/src/main/java/ch/nuth/zhaw/exbox/BakeryCookieServer.java
Normal 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;
|
||||
}
|
||||
}
|
56
app/src/main/java/ch/nuth/zhaw/exbox/Cookie.java
Normal file
56
app/src/main/java/ch/nuth/zhaw/exbox/Cookie.java
Normal 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;
|
||||
}
|
||||
}
|
25
app/src/main/java/ch/nuth/zhaw/exbox/Ingredient.java
Normal file
25
app/src/main/java/ch/nuth/zhaw/exbox/Ingredient.java
Normal 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) + ", ";
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue