| BSc KI — Cursus Natuur & Berekening | 2025-26 |
In deze Java opdracht is het de bedoeling om een algoritme te schrijven dat zo goed mogelijk een variant van het zogenaamde Pole Balancing probleem oplost. Dit probleem kan als volgt worden omschreven:
De wereld bestaat uit een kar (in ons geval een golfkar) waarop een verticale paal staat (in ons geval een palmboom). De paal zit met een scharnier vast aan de kar, en kan naar links en rechts vrij bewegen. Als de kar dus stil blijft staan, zal de paal onder invloed van de zwaartekracht omvallen. Om dit echter tegen te gaan kan de kar naar links of naar rechts bewegen en zo de paal in evenwicht houden. De bedoeling is dat het algoritme, gegeven de hoek en snelheid van de paal, de kar beweegt en daarmee de paal in evenwicht houdt.
Voor het oplossen van deze opdracht krijg je van ons een simulator (zie technische details). Deze simulator simuleert de vallende paal en de kar, en toont een grafische representatie hiervan op het scherm. Het enige dat jouw code hoeft te doen is een interface implementeren, met een functie die gegeven de hoek en de hoeksnelheid van de paal bepaalt welke kracht er op de kar uitgeoefend moet worden. Lees eerst de hele opdracht en de technische details goed door voordat je begint.
Probeer eerst een simpel algoritme te bedenken (b.v. een aantal if-else statements) dat het al aardig doet. Kun je met een paar simpele regels een programma maken dat het beter doet dan je zelf kunt met de pijltjestoetsen? Lever deze klasse ook in.
Maak een klasse die je gaat gebruiken voor de nodes van je SOM, hierin worden de invoer waardes (2 double waardes) opgeslagen. Deze klasse moet de afstand tot een andere node kunnen berekenen (het is handig om hiervoor de euclidische afstand te gebruiken). Voeg ook vast functies toe voor het optellen en vermenigvuldigen van 2 nodes, en het vermenigvuldigen van de waardes in de node met een double.
Probeer nu in de provideForce functie een SOM te maken die de invoer netjes verdeelt over de nodes. Laat voorlopig nog even return 0; staan, zodat de paal gewoon omvalt en van de verschillende oriëntaties van de paal geleerd kan worden. Doe dit als volgt:
Vervolgens moet de uitvoer geleerd worden, zodanig dat er bij elke node in je SOM een uitvoer getal hoort. De waarde die de provideForce functie zal teruggeven is het gewogen over de outputs, aan de hand van de geselecteerde node en de neighbourhood-functie. De geselecteerde node zal dus de uitvoer voor het grootste deel bepalen, maar de omliggende nodes dragen hier ook aan bij.
Om de optimale uitvoer te benaderen, voegen we tijdens het leren elke keer aan de uitvoer wat ruis toe, en kijken we of dit de prestatie heeft verbeterd. Het is handig om hier de volgende stappen te nemen:
Download hier het jar-bestand met de simulator. Om deze te runnen gebruik je:
java -jar PoleBalancing.jar <ControllerNaam>
waar <ControllerNaam> de naam is van de controller die je wilt gebruiken. Gebruik bijvoorbeeld:
java -jar PoleBalancing.jar nl.uu.cs.ias.cartpolebalancing.controllers.KeyController
en je kunt met de pijltjestoetsen sturen. Ook zit er een simpele voorbeeld oplossing bij die het even volhoudt (nl.uu.cs.ias.cartpolebalancing.controllers.DummyController).
Om zelf een controller te bouwen moet je de interface nl.uu.cs.ias.cartpolebalancing.service.CartPoleController implementeren. De implementatie moet de volgende 4 functies implementeren:
Om je eigen implementatie te compileren gebruik je het volgende commando:
javac -cp PoleBalancing.jar <ControllerNaam>.java
waar <ControllerNaam> vervangen moet worden door de naam van jouw controller.
Om je op weg te helpen met het implementeren van interfaces in Java, de basis van je oplossing zal er zo uit moeten zien:
import nl.uu.cs.ias.cartpolebalancing.service.CartPoleController;
import nl.uu.cs.ias.cartpolebalancing.service.CartPoleStatus;
public class <ControllerNaam> implements CartPoleController {
public double provideForce(CartPoleStatus currentStatus) {
return 0;
}
public void startSimulation() {
}
public void startTraining(int step, int totalSteps) {
}
public void endTraining() {
}
}
| Laatst gewijzigd op woensdag 13 november 2024, om 15:02 uur | Auteur(s): Jeroen Bransen en Erik Mulder | Translate to en, ru, or tr |