Sunteți pe pagina 1din 9

1.

Ideea problemei

Această lucrare explorează ideea utilizării agenților adaptivi artificiali în teoria economică. În
special, folosim algoritmi genetici (GA) pentru a modela comportamentul de învățare al unei populații de
agenti adaptativi si rationali ce interactioneaza intr-un sistem economic.

Modelul COBWEB este modelul unei piete pentru un bun singular. Teorema COBWEB,
formulata pentru prima oara de catre Mordecai Ezekiel in 1938, spune ca (pornind de la ipoteza ca o
firma isi bazeaza planul de productie pe presupunerea ca pretul din prezent va fi si in viitor si cantitea
produsa de catre firma respectiva nu va afecta pretul de pe piata), pretul pietei va converge catre un
echilibru daca ratia dintre cerere si oferta este mai mica decat 1 (cazul convergent). Daca raportul celor
2 este mai mare decat 1 (cazul divergent), atunci pretul pietei se indeparteaza de echilibru.

2. Descrierea modelului COBWEB

Intr-o piata competitiva exista n firme care stabilesc pretul si produc acelasi bun. Intrucat
ciclul de productie necesita timp, cantitatatile produse trebuie sa fie stabilite inainte de aparitia unui
pret de vanzare pentru ele.
Costul de productie al unei firme i este dat de formula:

, unde

1
este costul de productie al unei firme i la momentul t, si este cantitatea optima
produsa de firma si destinata vanzarii la un moment t.

Profitul previzionat de catre o firma este de

, unde este pretul previzionat pentru


bunul in cauza la momentul t.

La momentul t-1, fiecare companie alege cantitatea ce se presupune ca ii va maximiza

profitul pe baza asteptarilor sale legate de pretul ce va fi valabil la momentul t.


Astfel, cantitatea pentru maximizarea profitului va fi:

Pretul din momentul t determinat de catre curba cererii va fi:

In modelul ideal in care (asteptarile companiei privind pretul la momentul t sunt


egale cu pretul de echilibru), avem astfel:

In care pentru toate companiile i, sau .

Obiectivele aplicatiei GA sunt sa observe daca acele cantitati produse si oferite spre vanzare
de catre companiile care folosesc GA se vor apropia de aceasta cantitate q constanta.

3. Algoritm genetic (GA)

O populatie de cromozomi At reprezinta o colectie a deciziilor companiei din momentul t. O


firma i, i=1,…,n, ia o decizie privind productia sa la momentul t folosing cromozomul A i,t (membra a
populatiei in momentul t), un sir binar de lungimea l, scris cu alphabet {0,1}. O valoare decodata a sirului
binar i da valoarea cantitatii produse de firma i in perioada t.
De exemplu: urmatorul este un sir binar : 001001110001000 si este tradus de la dreapta la
stanga dupa cum urmeaza: 0*20 + 0* 21 + 0*22 + 1*23 + 0*24+ 0*25 + 0*26 + 1*27 + 1*28 + 1*29 + 0*210 +
0*211 + 1*212 + 0*213 + 0*214 + 0*215 +0*216 = 4096+512+256+128+8=5000.

Decodarea se face cu urmatoarea formula:

2
, unde este valoarea (0,1) din pozitia k a sirului.
k
Fiecare sir de lungimea k are 2 posibile valori. Folosirea unui sir binar face procesul genetic
mai usor si mai rapid. Normalizarea se realizeaza prin impartirea la valoarea maxima a sirului. Sirul
poate avea orice lungime, si pentru orice sir binar de lungimea k, numarul maxim de combinatii este 2k.
Totusi, dat fiind ca una din aceste valori este 0, numarul maxim de valori reprezinta de fapt 2k-1.
Functia de evaluare(functia ce masoara un criteriu de fitness) care determina modul in care
Solutia se apropia de Solutia cea mai buna in cazul modelului COBWEB este valoarea profitului castigat
de o companie intr-o perioada de timp t:

Procedura selecteaza cromozomi mai buni (cu o valoare mai mare a fitness-ului), si ii elimina
pe cei rai. De aceea, performanta unui algoritm depinde foarte mult de criteriul de evaluare al fitness-
ului. Pe acesti cromozomi parinti selectati sunt aplicati operatori genetici si astfel se creeaza cromozomi
noi (urmasi).
Algoritmii genetici conventionali iau in considerare doar valoarea fitness-ului cromozomului in
cauza pentru a-i masura aptitudinea pentru selectia in generatia urmatoare, adica fitness-ul unui
cromozom este o functie de o valoare a functiei de evaluare (profitul in cazul nostrum). Fitness-ul unui
cromozom x este g[f(x)], unde f(x) este functia de evaluare, iar g este o alta functie care da valoarea
fitness-ului primind o valoare f(x). De aceea, un algoritm genetic conventional nu face discriminare intre
doi urmasi identici, unul produs din parinti mai buni (cu o valoare mai mare a fitness-ului) si altul din
parinti comparabil mai slabi (cu o valoare mai mica a fitness-ului). In natura, in mod normal un urmas
poseda o capacitate mai mare de a se descurca mai bine in mediul sau daca apartine unei familii mai
bune (stramosi mai bine adaptati). Deci, valoarea fitness-ului unui individ depinde si de valoarea fitness-
ului stramosilor sai, in plus fata de propria-I valoare. Aceasta este probabil motivul de baza pentru a da
mai multa greutate cromozomilor mai bine adaptati (cu o valoare mai mare a fitness-ului) sa produca
mai multi urmasi pentru generatiile urmatoare.

Deciziile firmei sunt updatate folosind 3 operatori genetici (reproducere, incrucisare si


mutatie) in modelul de baza GA sau folosindu-se 4 operatori genetici (reproducere, incrucisare, mutatie
si alegere) in versiunea augmentata a GA.
a) Procedura de selectie/reproducere- face copii ai cromozomilor individuali. Se aleg
cromozomi cu un indice al fitness-ului mai mare dupa formula:

Procesul copiaza siruri individuale (numite cromozomi parinti) intr-o tentative de noua
populatie (numita bazinul de imperechere-matting pool) pentru operatii genetice. Cele mai frecvente
procedure de selectie sunt selectia prin roata ruletei (roulette wheel) si selectia liniara. Cand sunt
realizate n copii procesul se incheie.
b) Incrucisarea – scopul sau principal este schimbul de informatie intre cromozomi parinti
alesi aleatoriu pentru a nu pierde nicio informatie importanta. In prima faza sunt alese 2 siruri din
bazinul de imperechere la intamplare. In a doua faza se alege un numar k, unde k este in intervalul (1,
…, l-1) si se formeaza 2 noi siruri prin schimbarea valorilor binare de la dreapta pozitiei k. Un exemplu
pentru incrucisarea intre 2 siruri in care l=8 si k=4 este:

3
Faza initiala:

Faza finala

c) Mutatia- este procesul prin care in mod aleatoriu se schimba valoarea unei pozitii dintr-
un sir.
d) Alegerea-testeaza noii cromozomi generati inainte de a li se permite sa devina membrii
ai noii populatii.

4. Implementare in JAVA

Clasa Individuals.java
package cobweb;

import cobweb.FitnessCalc;

public class Individual {

static int defaultGeneLength = 16;


private byte[] genes = new byte[defaultGeneLength];
// Cache
private int fitness = 0;

// crearea in mod aleatoriu a unui individ


public void generateIndividual() {
for (int i = 0; i < size(); i++) {
byte gene = (byte) Math.round(Math.random());
genes[i] = gene;
}
}

// este folosita daca doriti sa creati indivizi cu lungimi diferite


public static void setDefaultGeneLength(int length) {
defaultGeneLength = length;
}

public byte getGene(int index) {


return genes[index];
}

public void setGene(int index, byte value) {


genes[index] = value;
fitness = 0;
}

4
/* */
public int size() {
return genes.length;
}

public int getFitness() {


if (fitness == 0) {
fitness = FitnessCalc.getFitness(this);
}
return fitness;
}

@Override
public String toString() {
String geneString = "";
for (int i = 0; i < size(); i++) {
geneString += getGene(i);
}
return geneString;
}
}

Clasa Population.java
package cobweb;

import cobweb.Individual;

public class Population {

Individual[] individuals;

/*
* Constructors
*/
// Create a population
public Population(int populationSize, boolean initialise) {
individuals = new Individual[populationSize];
// Initialize population
if (initialise) {
// Loop and create individuals
for (int i = 0; i < size(); i++) {
Individual newIndividual = new Individual();
newIndividual.generateIndividual();
saveIndividual(i, newIndividual);
}
}
}

/* Getters */
public Individual getIndividual(int index) {
return individuals[index];
}

public Individual getFittest() {

5
Individual fittest = individuals[0];
// Loop through individuals to find fittest
for (int i = 0; i < size(); i++) {
if (fittest.getFitness() <= getIndividual(i).getFitness()) {
fittest = getIndividual(i);
}
}
return fittest;
}

/* Public methods */
// Get population size
public int size() {
return individuals.length;
}

// Save individual
public void saveIndividual(int index, Individual indiv) {
individuals[index] = indiv;
}
}
Clasa FitnessCalc.java
package cobweb;

import cobweb.Individual;

public class FitnessCalc {

static byte[] solution = new byte[16];

// setarea unei solutii ca un sir byte


public static void setSolution(byte[] newSolution) {
solution = newSolution;
}

// pentru a deveni mai rapid algoritmul il setam ca fiind un sir


// format din cifrele 0 si 1
static void setSolution(String newSolution) {
solution = new byte[newSolution.length()];
// se parcuge fiecare caracter al sirului si se salveaza intr-un byte
for (int i = 0; i < newSolution.length(); i++) {
String character = newSolution.substring(i, i + 1);
if (character.contains("0") || character.contains("1")) {
solution[i] = Byte.parseByte(character);
} else {
solution[i] = 0;
}
}
}

// se calculeaza fitness-ul individual si se compara cu solutia candidata


static int getFitness(Individual individual) {
int fitness = 0;
// se parcurg genele copii si se compara cu parintii
for (int i = 0; i < individual.size() && i < solution.length; i++) {

6
if (individual.getGene(i) == solution[i]) {
fitness++;
}
}
return fitness;
}

// obtinere fitness optim


static int getMaxFitness() {
int maxFitness = solution.length;
return maxFitness;
}
}

Clasa Algorithm.java
package cobweb;

import cobweb.Individual;
import cobweb.Population;

public class Algorithm {

/* parametrii GA */
private static final double uniformRate = 0.5;
private static final double mutationRate = 0.015;
private static final int tournamentSize = 5;
private static final boolean elitism = true;

/* Public methods */

// selectarea unei populatii


public static Population evolvePopulation(Population pop) {
Population newPopulation = new Population(pop.size(), false);

// se pastreaza cei mai buni indivizi


if (elitism) {
newPopulation.saveIndividual(0, pop.getFittest());
}

// se face incrucisarea
int elitismOffset;
if (elitism) {
elitismOffset = 1;
} else {
elitismOffset = 0;
}
// se parcuge populatia si se creeaza noi indivizi cu
// incrucisare
for (int i = elitismOffset; i < pop.size(); i++) {
Individual indiv1 = tournamentSelection(pop);
Individual indiv2 = tournamentSelection(pop);
Individual newIndiv = crossover(indiv1, indiv2);
newPopulation.saveIndividual(i, newIndiv);

7
}

// se realizeaza mutatia
for (int i = elitismOffset; i < newPopulation.size(); i++) {
mutate(newPopulation.getIndividual(i));
}

return newPopulation;
}

// mutatia
private static Individual crossover(Individual indiv1, Individual
indiv2) {
Individual newSol = new Individual();
// parcurgerea genelor
for (int i = 0; i < indiv1.size(); i++) {
// mutatia
if (Math.random() <= uniformRate) {
newSol.setGene(i, indiv1.getGene(i));
} else {
newSol.setGene(i, indiv2.getGene(i));
}
}
return newSol;
}

// mutatia unui individ


private static void mutate(Individual indiv) {
// parcurgerea genelor
for (int i = 0; i < indiv.size(); i++) {
if (Math.random() <= mutationRate) {
// crearea unei gene in mod aleator
byte gene = (byte) Math.round(Math.random());
indiv.setGene(i, gene);
}
}
}

// selectarea indivizilor pentru incrucisare


private static Individual tournamentSelection(Population pop) {
// crearea unei populatii pentru incrucisare
Population tournament = new Population(tournamentSize, false);
// pentru fiecare pozitie din selectie se alege in mod aleatoriu un
individ
for (int i = 0; i < tournamentSize; i++) {
int randomId = (int) (Math.random() * pop.size());
tournament.saveIndividual(i, pop.getIndividual(randomId));
}
// alegerea celui mai potrivit
Individual fittest = tournament.getFittest();
return fittest;
}
}
Clasa GA.java
package cobweb;

8
import cobweb.Algorithm;
import cobweb.FitnessCalc;
import cobweb.Population;

public class GA {

public static void main(String[] args) {

// se alege o pozitie candidat


FitnessCalc.setSolution("0001001110001000");

// crearea unei populatii initiale


Population myPop = new Population(50, true);

// se creste populatia pana ajungem la o solutie optima


int generationCount = 0;
while (myPop.getFittest().getFitness() <
FitnessCalc.getMaxFitness()) {
generationCount++;
System.out.println("Generation: " + generationCount + " Fittest:
" + myPop.getFittest().getFitness());
myPop = Algorithm.evolvePopulation(myPop);
}
System.out.println("Solutie gasita!");
System.out.println("Generation: " + generationCount);
System.out.println("Genes:");
System.out.println(myPop.getFittest());

}
}

SOLUTIA:

Generation: 1 Fittest: 12
Generation: 2 Fittest: 15
Generation: 3 Fittest: 15
Solutie gasita!
Generation: 3
Genes:
0001001110001000

5. Bibliografie:
 J. Arifovic-Genetic algorithm learning and the cobweb model
 H. Dawid, M. Kopel-On economic applications of the genetic algorithm: a model of the
Cobweb Type
 S. Ostafiev-Algoritmi genetici pentru rezolvarea problemelor prin evolutie si co-
evolutie

S-ar putea să vă placă și