final class Agent { protected Student students; protected Teacher teachers; protected int nStudents, nTeachers; protected int age; // zile traite protected int deathAge; // durata de viata (numarul de zile pana la moarte) protected float belief; // increderea in ipoteza protected float pragmatism; // pragmatism, coeficientul de invatare din experienta protected float charisma; protected float exaggerate; // coeficientul de exagerare protected int chats; // câte „discuții” are într-o zi cu profesorii săi protected final static GeneratorFloat // ăștia sunt parametrii: slidere sau PDF-uri // fiecare din ei are metoda esențială getValue(), prin care întoarce o valoare atunci când i se cere // sliderele întorc valoarea setată, PDF-urile întorc o valoare conform distribuției de probabilitate setate // mai au și metodele utilitare happens(), vezi mai jos success = LiveObject.readRegulator("Psuccess") ,experiment = LiveObject.readRegulator("Pexperiment") ,communication = LiveObject.readRegulator("Pcommunication") //,speechSteps = LiveObject.readRegulator("speech steps") // l-am desființat de când am introdus exaggeration ,maturity = LiveObject.readRegulator("sexual maturity") ,randomDeath = LiveObject.readRegulator("death age") ,randomBelief = LiveObject.readRegulator("belief at birth") ,randomPragmatism = LiveObject.readRegulator("pragmatism at birth") ,randomTrust = LiveObject.readRegulator("trust at birth") ,randomCharisma = LiveObject.readRegulator("charisma at birth") ,randomIniT = LiveObject.readRegulator("trust in parent") ,randomD = LiveObject.readRegulator("trust diffusion") ,agreementInfluence = LiveObject.readRegulator("agreement influence on trust") ,trustDecay = LiveObject.readRegulator("trust decay") ,needForTeachers = LiveObject.readRegulator("need for teachers") ,pragmatismDecay = LiveObject.readRegulator("pragmatism decay") ,trustInfluence = LiveObject.readRegulator("trust influence on belief") ,trustDump = LiveObject.readRegulator("trust thresh. to dump teacher") ,tolerance = LiveObject.readRegulator("listen to untrusted") ,successFrequency = LiveObject.readRegulator("success frequency") ,beliefFrequency = LiveObject.readRegulator("belief frequency") ,exaggeration = LiveObject.readRegulator("exaggeration") ,globalExaggeration = LiveObject.readRegulator("global exaggeration") ; Agent(Agent parent) { // ia ca profesor inițial părintele, plus încă un profesor cerut ca recomandare de la părinte this(); linkFrom(parent, randomIniT.getValue()); getNewTeacher(); } private void init() { // inițializarea cu parametrii setați deathAge = PApplet.round(randomDeath.getValue()); belief = randomBelief.getValue(); pragmatism = randomPragmatism.getValue(); charisma = randomCharisma.getValue(); exaggerate = exaggeration.getValue(); } public void socialize() { // la început de tot, când se inițializează populația, fiecare agent mai primește 5 profesori la întâmplare for (int k=0; k<5; k++) { Agent candidate; do {candidate = mediu.randomAgentOtherThan(this);} while (candidate.isTeacherOf(this)); linkFrom(candidate, randomTrust.getValue()); // trustul inițial în acești 5 profesori e setat din randomTrust } } public void live() { // asta-i „o zi” din viața agentului chats = 0; // experimentează în mediu if (experiment.happens()) { // cu probabilitatea dată de sliderul Pexperiment if (success.happens()) { // aici probabilitatea e dată de sliderul Psuccess belief += pragmatism*(1.0f-belief); // belieful se apropie de 1 } else { belief -= pragmatism*belief; // belieful se apropie de 0 } } // parcurge lista de profi și învață de la ei for (Teacher him=teachers; him!=null; him=him.next) { // lista tachers conține _linkuri_ către profesori; e nevoie de theAgent() pentru a obține efectiv profesorul him.trust -= trustDecay.getValue()*him.trust; // viteza de scădere a încrederii odată cu înaintarea în vârstă if (communication.happens(map(him.trust, 0.0f, 1.0f, tolerance.getValue(), 1.0f))) { chats++; Agent teacher = him.theAgent(); // aici obțin efectiv agentul profesor if (him.lastSpeech>=0.0f && agreementInfluence.getValue()>0.001f) // updatez trustul în profesor him.trust += map(age, 0, 100, 0.001f, agreementInfluence.getValue()) * (agreeWith(him.lastSpeech) - him.trust); him.lastSpeech = teacher.speak(); // rețin ultima lui spusă, ca să am cu ce compara în viitor // aici e inima programului: updatarea beliefului în funcție de ce zice profesorul belief += teacher.charisma * him.trust * trustInfluence.getValue() * (him.lastSpeech - belief); } } // dacă nu prea are încredere într-un profesor, îl abandonează for (Teacher him=teachers; him!=null;) { // atenție că trecerea la next o fac manual în corpul ciclului !!! Teacher nextTeacher = him.next; if (trustDump.happens(him.trust)) { him.student.detach(); him.detach(); } him = nextTeacher; } // eventual își alege un profesor nou if (needForTeachers.happens(1.0f/nTeachers)) { // deci needForTeachers este raportat le numărul efectiv de profesori getNewTeacher(); } // îmbătrânește age++; pragmatism -= pragmatismDecay.getValue()*pragmatism; } protected float agreeWith(float speech) { // în ce măsură speechul lui este apropiat de părerea mea // apropiere mare: agree -> 100%; apropiere mică: agree -> 0% return 1 - Math.abs(speech - belief); } void getNewTeacher() { Answer answer; // Answer conține un agent recomandat și trustul în el Agent teacher; do { answer = askRandomFriend(this); // cere o recomandare de la cineva din cercul de prieteni (informând „eu întreb, să nu mă dați pe mine ca răspuns”) teacher = answer.agent; } while(teacher==this // deci, răspunsul să nu fiu eu însumi, || teacher.isTeacherOf(this) // să nu fie un profesor de-al meu, || teacher.isStudentOf(this)); // și să nu fie un student de-al meu linkFrom(answer.agent, answer.trust); } public Answer askRandomFriend(Agent whoAsks) { // ok, asta e mai complicat, puteți sări peste float diffusion = randomD.getValue(); float nGenericStudents = (nStudents + 1)*diffusion; float nFriends = nGenericStudents+nTeachers; float n; int nmax; float trust; Agent candidate; do { n = nFriends * random.nextFloat(); if (n<diffusion) { // omul de pe stradă trust = 0.0f; candidate = mediu.randomAgentOtherThan(this, whoAsks); } else if (n<nGenericStudents) { // un student n -= diffusion; nmax = Math.min(nStudents, (int) Math.floor(n/diffusion)); assert nmax<=nStudents : "nStudents = "+nStudents+", n = "+nmax; Student student = students; for (int i=0; i<nmax; i++) student = student.next; trust = 0.0f; if (student==null) student = students; assert student!=null : "Student is null! WHY THE FUCK??? nStudents = "+nStudents+", nmax = "+nmax; candidate = student.theAgent(); } else { // un profesor n -= nGenericStudents; nmax = Math.min(nTeachers, (int) Math.floor(n)); assert nmax<=nTeachers : "nTeachers = "+nTeachers+", n = "+nmax; Teacher teacher = teachers; for (int i=0; i<nmax; i++) teacher = teacher.next; if (teacher==null) teacher = teachers; assert teacher!=null : "Teacher is null! WHY THE FUCK??? nTeachers = "+nTeachers+", nmax = "+nmax; trust = teacher.trust; candidate = teacher.theAgent(); } } while (candidate==whoAsks); if (trust==0.0f) return candidate.askRandomFriend(this).withNoTrust(); // recursie prin elev/omul de pe stradă else if (happens(trust)) return new Answer(candidate, trust); // e profesor de încredere, îl întorc chiar pe el else return candidate.askRandomFriend(this).with(trust); // recursie prin profesor de neîncredere } protected float speak() { float e = exaggerate * globalExaggeration.getValue(); e = (1+e)/(1-e); if (e==0.0f) return belief; else if (belief==0.5f) return 0.5f; else if (belief<0.5f) return 0.5f*(float) Math.pow(2*belief,e); else return 1-0.5f*(float) Math.pow(2*(1-belief),e); } }