Voor een simulatie van genetic programming ben ik een programma aan het schrijven dat een wereld simuleert met daarin agenten. Deze agenten kunnen een aantal handelingen verrichten, waarvan sommigen invloed op de wereld hebben (zoals bewegen), andere zijn eigenlijk alleen interne logische operatoren (And, Not, IfThen etc).
Alle instucties/operatoren krijgen twee argumenten mee (twee bytes), en geven 1 byte terug.
Elke agent heeft zijn eigen DNA, dit dna beschrijft hoe het programma van de agent moet worden opgebouwd, dit opbouwen gebeurt dus eenmalig bij de "geboorte" van de agent. Daarna wordt telkens als de agent aan de beurt is (de agenten komen per ronde in een willekeurige volgorde aan de beurt) uitgevoerd.
Een voorbeeld:
Het dna van de agent beschrijft het volgende programma (hoe het dna dit beschrijft is nu even niet van belang):
IfThen (
DropFood ( 1010 0000, 0000 0101 ),
Attack ( 0000 0001, 0000 0000)
)
Attack ( 1111 0101, 0000 0000)
Hoe kan ik dit "programma" dan het beste opslaan zodat het ook uit te voeren is? Ik zat te denken aan een hoofdclasse voor alle instructies (genaamd "instructions"), elke mogelijke instructies heeft dan een klasse die hiervan erft, en er is een Number klasse, om ook nummers als argumenten (argumenten zijn namelijk dus ook altijd van het type instruction) mee te kunnen geven. Dit zorgt ervoor dat ik dus dit kan doen, in feite een soort boom dus:
Tevens heeft elke klasse ook een execute() functie, dus als ik bijvoorbeeld de bovenstaande dropfood.execute() uitvoer roept hij weer een .execute op zijn argumenten aan, in dit geval de twee Number instanties, die elk dan gewoon hun nummer returnen, waarna DropFood dus genoeg informatie heeft en daadwerkelijk aan de slag kan.
Op zich lijkt mij dit een best makkelijke manier van opslaan, maar het punt is dat als ik nu bijvoorbeeld bovenstaand programma uit wil voeren, en DropFood zijn argumenten heeft berekend hij niet alleen een waarde terug moet geven aan de IfThen, maar dat de agent ook daadwerkelijk eten moet "droppen", voordat verder wordt gegaan met het "executen" van de rest van het programma. Maar DropFood is dus een object binnen een object binnen een object etc van een instantie in de agent. Hoe kan kan ik dan zorgen dat het DropFood een functie kan aanroepen van zijn verre parent, de agent, zodat de agent de stap zet? Daarnaast moet DropFood voor zijn uitvoer ook informatie kunnen krijgen van de parent over de huidige situatie, om te bepalen wat hij teruggeeft aan de IfThen.
Ik hoop dat het een beetje duidelijk is zo, en als jullie de hele opslag/executie van het programma anders zouden doen dan hoor ik dat natuurlijk ook graag.
Alle instucties/operatoren krijgen twee argumenten mee (twee bytes), en geven 1 byte terug.
Elke agent heeft zijn eigen DNA, dit dna beschrijft hoe het programma van de agent moet worden opgebouwd, dit opbouwen gebeurt dus eenmalig bij de "geboorte" van de agent. Daarna wordt telkens als de agent aan de beurt is (de agenten komen per ronde in een willekeurige volgorde aan de beurt) uitgevoerd.
Een voorbeeld:
Het dna van de agent beschrijft het volgende programma (hoe het dna dit beschrijft is nu even niet van belang):
IfThen (
DropFood ( 1010 0000, 0000 0101 ),
Attack ( 0000 0001, 0000 0000)
)
Attack ( 1111 0101, 0000 0000)
Hoe kan ik dit "programma" dan het beste opslaan zodat het ook uit te voeren is? Ik zat te denken aan een hoofdclasse voor alle instructies (genaamd "instructions"), elke mogelijke instructies heeft dan een klasse die hiervan erft, en er is een Number klasse, om ook nummers als argumenten (argumenten zijn namelijk dus ook altijd van het type instruction) mee te kunnen geven. Dit zorgt ervoor dat ik dus dit kan doen, in feite een soort boom dus:
code:
1
2
3
4
| Code.add( new IfThen (
new DropFood(new Number (1010 0000), new Number (0000 0101)),
new Atack (new Number (0000 0001), new Number(0000 0000)) ) )
Code.add( new Attack ( new Number (1111 0101), new Number(0000 0000) ) |
Tevens heeft elke klasse ook een execute() functie, dus als ik bijvoorbeeld de bovenstaande dropfood.execute() uitvoer roept hij weer een .execute op zijn argumenten aan, in dit geval de twee Number instanties, die elk dan gewoon hun nummer returnen, waarna DropFood dus genoeg informatie heeft en daadwerkelijk aan de slag kan.
Op zich lijkt mij dit een best makkelijke manier van opslaan, maar het punt is dat als ik nu bijvoorbeeld bovenstaand programma uit wil voeren, en DropFood zijn argumenten heeft berekend hij niet alleen een waarde terug moet geven aan de IfThen, maar dat de agent ook daadwerkelijk eten moet "droppen", voordat verder wordt gegaan met het "executen" van de rest van het programma. Maar DropFood is dus een object binnen een object binnen een object etc van een instantie in de agent. Hoe kan kan ik dan zorgen dat het DropFood een functie kan aanroepen van zijn verre parent, de agent, zodat de agent de stap zet? Daarnaast moet DropFood voor zijn uitvoer ook informatie kunnen krijgen van de parent over de huidige situatie, om te bepalen wat hij teruggeeft aan de IfThen.
Ik hoop dat het een beetje duidelijk is zo, en als jullie de hele opslag/executie van het programma anders zouden doen dan hoor ik dat natuurlijk ook graag.