package core; IMPORT grafic.LiveObject; IMPORT measurements.GeneratorFloat; IMPORT measurements.HasNext; IMPORT processing.core.PApplet; IMPORT static core.AgentiEpistemici.*; 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; protected INT chats; protected final static GeneratorFloat success = LiveObject.readRegulator("Psuccess") ,experiment = LiveObject.readRegulator("Pexperiment") ,communication = LiveObject.readRegulator("Pcommunication") //,speechSteps = LiveObject.readRegulator("speech steps") ,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() { init(); } Agent(Agent parent) { this(); linkFrom(parent, randomIniT.getValue()); getNewTeacher(); } PRIVATE void init() { deathAge = PApplet.round(randomDeath.getValue()); belief = randomBelief.getValue(); pragmatism = randomPragmatism.getValue(); charisma = randomCharisma.getValue(); exaggerate = exaggeration.getValue(); } public void socialize() { FOR (INT k=0; k<5; k++) { Agent candidate; do {candidate = mediu.randomAgentOtherThan(this);} WHILE (candidate.isTeacherOf(this)); linkFrom(candidate, randomTrust.getValue()); } } public void live() { chats = 0; // experimentează IF (experiment.happens()) { IF (success.happens()) { belief += pragmatism*(1.0f-belief); } ELSE { belief -= pragmatism*belief; } } // parcurge lista de profi și învață de la ei FOR (Teacher him=teachers; him!=null; him=him.next) { 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(); IF (him.lastSpeech>=0.0f && agreementInfluence.getValue()>0.001f) him.trust += map(age, 0, 100, 0.001f, agreementInfluence.getValue()) * (agreeWith(him.lastSpeech) - him.trust); him.lastSpeech = teacher.speak(); 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)) { getNewTeacher(); } // îmbătrânește age++; pragmatism -= pragmatismDecay.getValue()*pragmatism; } boolean isTeacherOf(Agent other) { IF (students==null) RETURN false; FOR (Student him=students; him!=null; him=him.next) IF (other==him.theAgent()) RETURN true; RETURN false; } boolean isStudentOf(Agent other) { IF (teachers==null) RETURN false; FOR (Teacher him=teachers; him!=null; him=him.next) IF (other==him.theAgent()) RETURN true; RETURN false; } 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; Agent teacher; do { answer = askRandomFriend(this); teacher = answer.agent; } WHILE(teacher==this || teacher.isTeacherOf(this) || teacher.isStudentOf(this)); linkFrom(answer.agent, answer.trust); } public Answer askRandomFriend(Agent whoAsks) { 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() { /* if (speechSteps.getValue()==1) return belief; else if (belief==1.0f) return 1.0f; else return 1.0f/(speechSteps.getValue()-1) * PApplet.floor(speechSteps.getValue() * belief); */ 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); } public boolean isRipe() { RETURN age>=deathAge; } public void die() { IF (teachers !=null) { teachers.die(); teachers = null; // doar pentru ușurarea de Garbage Collection } IF (students !=null) { students.die(); students = null; // doar pentru ușurarea de Garbage Collection } } public void linkFrom(Agent teacherAgent, float trust) { Teacher teacher = teacherAgent.new Teacher(trust); Student student = new Student(); this.addTeacher(teacher); teacherAgent.addStudent(student); teacher.student = student; student.teacher = teacher; } /* public void linkTo(Agent studentAgent, float i, float p) { Teacher teacher = new Teacher(i, p); Student student = studentAgent.new Student(); studentAgent.addTeacher(teacher); this.addStudent(student); teacher.student = student; student.teacher = teacher; } */ PRIVATE void addStudent(Student student) { IF (students !=null) students.prev = student; student.next = students; students = student; nStudents++; } PRIVATE void addTeacher(Teacher teacher) { IF (teachers !=null) teachers.prev = teacher; teacher.next = teachers; teachers = teacher; nTeachers++; } protected final class Teacher extends HasNext<Teacher> { // vârf de săgeată protected Teacher prev; protected Student student; // celălalt capăt (fundul) protected float trust; protected float lastSpeech; PRIVATE Teacher(float trust) { this.trust = trust; lastSpeech = -1.0f; } PRIVATE void detach() { // se auto-scoate din lista teachers a nodului-părinte IF (next!=null) next.prev = prev; IF (prev!=null) prev.next = next; ELSE student.theAgent().teachers = next; student.theAgent().nTeachers--; student = null; // doar pentru ușurarea de Garbage Collection } PRIVATE void die() { // auto-distrugere recursivă a listei teachers IF (next!=null) next.die(); // recursie student.detach(); this.detach(); // doar pentru ușurarea de Garbage Collection } public Agent theAgent() { RETURN Agent.this; } } protected final class Student extends HasNext<Student> { // fund de săgeată PRIVATE Student prev; PRIVATE Teacher teacher; // celălalt capăt (vârful) PRIVATE void detach() { // se auto-scoate din lista students a nodului-părinte IF (next!=null) next.prev = prev; IF (prev!=null) prev.next = next; ELSE teacher.theAgent().students = next; teacher.theAgent().nStudents--; teacher = null; // doar pentru ușurarea de Garbage Collection } PRIVATE void die() { // auto-distrugere recursivă a listei students IF (next!=null) next.die(); // recursie teacher.detach(); this.detach(); // doar pentru ușurarea de Garbage Collection } public Agent theAgent() { RETURN Agent.this; } } } final class Answer { Agent agent; float trust; Answer(Agent agent, float trust) { this.agent = agent; this.trust = trust; } Answer with(float trust) { this.trust *= trust; RETURN this; } public Answer withNoTrust() { this.trust = 0.0f; RETURN this; } }