WikiPeerCode
/*
* RepMod.java
*
* Created on January 22, 2005, 6:11 PM
* Modified June 19, 2006 18:20 by Jack
* Modified June 22, 2006 00:16 by Andrew
*/
package RepMod;
import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import uchicago.src.sim.engine.BasicAction;
import uchicago.src.sim.engine.Schedule;
//import uchicago.src.sim.engine.SimModelImpl;
//import uchicago.src.sim.gui.DisplaySurface;
//import uchicago.src.sim.gui.Network2DDisplay;
import uchicago.src.sim.gui.OvalNetworkItem;
//import uchicago.src.sim.network.NetworkFactory;
//import uchicago.src.sim.network.NetworkRecorder;
//import uchicago.src.sim.network.Node;
//import uchicago.src.sim.util.Random;
import uchicago.src.sim.util.SimUtilities;
//import uchicago.src.sim.network.DefaultDrawableNode;
//import uchicago.src.sim.network.DefaultDrawableEdge;
//import uchicago.src.sim.gui.CircularGraphLayout;
//import uchicago.src.sim.gui.KamadaGraphLayout;
//import uchicago.src.sim.gui.AbstractGraphLayout;
//import uchicago.src.sim.space.Object2DGrid;
//import uchicago.src.sim.gui.Object2DDisplay;
import uchicago.src.sim.util.*;
import java.util.Collections;
import java.util.Comparator;
import uchicago.src.sim.network.NetUtilities;
/**
*
* @author Jack Waddell
*/
public class RepMod extends ModelParameters{
// model variables
public int numAgents = 16;
public ArrayList<CustomNode> agentList = new ArrayList<CustomNode> (numAgents);
public int worldXSize = 400;
public int worldYSize = 400;
public Schedule schedule; // Schedules Events
public CompNodeRep compNodes; // compares node reputations
// The P parameter for regular lattice -> small world rewiring
// Also used as the probability in the random network
public double reconnectProb;
// the connection radius of the regular lattice
public int connectRadius;
// selects which network type to use in Network.java
public int netType;
// Stores how frequently, in units of time steps, to update...
public int updateInterval; // The report file
public int pajekUpdateInterval; // The pajek files
Network net; // The network class
// The following class performs calculations on the network
NetUtilities netCalculator = new NetUtilities();
// the degree to weight the voter's historical opinion vs. new opinion
public double histWeight;
// weight of current reputation in new opinion
public double repWeight;
// voteType, whether to use democratic or meritocratic votes
// 0 = democratic
// 1 = meritocratic
public int voteType;
public int opScheme; // opinion scheme: 1 = old, 2 = new (AS rep feedback)
// the (negative of) slope of skill vs variance of noise
public double noiseSlope;
public int numTopAgents = 5; // Andrew hacking TopRep calculation
/** Creates a new instance of RepMod */
public RepMod() {
}
/////////////////////////////////////////////////
// begin
// builds model-required elements
public void begin () {
buildModel ();
buildSchedule ();
}
///////////////////////////////////////////////////////
// addModelSpecificParameters
// Maps the input parameters.
public void addModelSpecificParameters () {
parametersMap.put( "size", "numAgents");
parametersMap.put( "ui", "updateInterval");
parametersMap.put( "rP", "reconnectProb");
parametersMap.put( "cR", "connectRadius");
parametersMap.put( "nT", "netType");
parametersMap.put( "pUI", "pajekUpdateInterval");
parametersMap.put( "vT", "voteType");
parametersMap.put( "oS", "opScheme");
parametersMap.put( "hW", "histWeight");
parametersMap.put( "rW", "repWeight"); // still not sure what this does...
parametersMap.put( "nS", "noiseSlope");
parametersMap.put( "nTA", "numTopAgents");
}
//////////////////////////////////////////////////////
// getInitParam
// Controls what appears the the GUI parameter panel
public String[] getInitParam () {
String[] params = { "numAgents", "connectRadius",
"reconnectProb", "netType", "voteType",
"histWeight", "noiseSlope",
"numTopAgents", // AS added for top agents param
"opScheme", // AS for new opinion scheme
"repWeight", // AS for new opinion scheme
// these are from the super class:
"rDebug", "seed"};
return params;
}
//////////////////////////////////////////////////////////
// getters and setters
// ******************** Note *************************
// Specific format required if using inputted parameters
// (either through batch or gui)
public int getWorldXSize () {return worldXSize;}
public void setWorldXSize (int size) {worldXSize = size;}
public int getWorldYSize () {return worldYSize;}
public void setWorldYSize (int size) {worldYSize = size;}
public int getNumAgents() {return numAgents;}
public void setNumAgents(int i) {numAgents = i;}
public double getReconnectProb() {return reconnectProb;}
public void setReconnectProb(double i) {reconnectProb = i;}
public int getConnectRadius() {return connectRadius;}
public void setConnectRadius(int i) {connectRadius = i;}
public void setNetType(int i) {netType = i;}
public int getNetType() {return netType;}
public void setVoteType(int i) {
voteType = i;
CustomNode.setVoteType(i);
}
public int getVoteType() {return voteType;}
public void setOpScheme(int i) {opScheme = i;}
public int getOpScheme() { return opScheme;}
public void setHistWeight(double i) {
histWeight = i;
CustomNode.setHistWeight(i);
}
public double getHistWeight() {return histWeight;}
public void setRepWeight(double w) {
repWeight = w;
CustomNode.setRepWeight(w);
}
public double getRepWeight() {return repWeight;}
public void setNoiseSlope(double i) {
noiseSlope = i;
CustomNode.setNoiseSlope(i);
}
public double getNoiseSlope() {return noiseSlope;}
public int getUpdateInterval() {return updateInterval;}
public void setUpdateInterval(int i) {updateInterval = i;}
public int getPajekUpdateInterval() {return pajekUpdateInterval;}
public void setPajekUpdateInterval(int i) {pajekUpdateInterval = i;}
// AS added for top agents param
public int getNumTopAgents() {return numTopAgents;}
public void setNumTopAgents(int n) {numTopAgents = n;}
//////////////////////////////////////////////////////////
// buildModel
// Does what it says
public void buildModel(){
if(rDebug > 0)
System.out.printf("Build Model Begin\n");
// CALL FIRST -- defined in super class -- it starts RNG, etc
buildModelStart();
// set static parameters in node class
CustomNode.setHistWeight(histWeight);
CustomNode.setRepWeight(repWeight); // AS for new op scheme
CustomNode.setVoteType(voteType);
CustomNode.setNoiseSlope(noiseSlope);
// setup the network class
net = new Network(numAgents, connectRadius, reconnectProb);
net.setModel(this);
CustomNode.setModel(this);
// have the network class build the network
net.buildAdjacencyMatrix(netType); // first build the adjacency matrix
net.buildAgentList(); // then the agent list
agentList = net.getAgentList();
// setup the gamemaster
compNodes = new CompNodeRep();
// prepare pajek file
net.startPajekFile(0);
System.out.printf("Build Model End\n");
// some post-load finishing touches
startReportFile();
// you probably don't want to remove any of the following
// calls to process parameter changes and write the
// initial state to the report file.
// NB -> you might remove/add more agentChange processing
applyAnyStoredChanges();
//stepReport();
//getPlaintextReportFile().flush();
}
//////////////////////////////////////////////////////////
// buildSchedule
// Sets what is to happen, when.
public void buildSchedule () {
// schedule the current BatchModel's step() function
// to execute every time step starting with time step 0
schedule.scheduleActionBeginning( 0, this, "step" );
// Schedule to stop at a particular time, StopT. Rem out
// to run indefinitely
schedule.scheduleActionAt(getStopT(), this, "processEndOfRun");
// Only run every updateInterval steps
schedule.scheduleActionAtInterval(updateInterval, new BasicAction() {
public void execute() {
System.gc(); // garbage collect
stepReport(); // write step report
}
}, Schedule.LAST);
// Only run every pajekUpdateInterval steps
schedule.scheduleActionAtInterval(pajekUpdateInterval, new BasicAction() {
public void execute() {
nextPajekNetwork(); // write pajek file and open new one
}
}, Schedule.LAST);
// Execute at step 1 only
schedule.scheduleActionAt(1, new BasicAction() {
public void execute() {
stepReport();
nextPajekNetwork();
}
}, Schedule.LAST);
}
/////////////////////////////////////////////////////////////////////////
// printProjectHelp
// this could be filled in with some help to get from running with
// -help parameter
public void printProjectHelp() {
// print project help
System.out.printf( "\n%s -- \n", getName() );
System.out.printf( "\n **** Add more info here!! **** \n" );
System.out.printf( "\n" );
printParametersMap();
System.exit( 0 );
}
//////////////////////////////////////////////////////////////
// Setup
// Prepares the model, or resets it after the reset button is pressed
// in GUI model
public void setup () {
if ( rDebug > 0 )
System.out.printf( "<== Model setup() done.\n" );
// Clean up previous instances
schedule = null;
System.gc ();
// Set default values
// These are overwritten by inputted values, if any
numAgents = 64;
updateInterval = 1;
pajekUpdateInterval = 1000000;
worldXSize = 400;
worldYSize = 400;
netType = 0;
connectRadius = 2;
reconnectProb = 0.1;
voteType = 0;
histWeight = 0;
noiseSlope = 1;
// AS added for top agents param
numTopAgents = 5;
CustomNode.resetNextID();
agentList = new ArrayList (numAgents);
super.setup(); // Reads in input values
schedule = new Schedule (1);
}
/////////////////////////////////////////////////////////////
// step
// governs what happens at each step
public void step(){
stepNodes();
}
////////////////////////////////////////////////////////////////
// stepNodes
// Steps each node.
// Has each vote for neighbors, then has each calculation
// own reputation.
public void stepNodes(){
if (opScheme == 2) { // new opinion scheme
for(CustomNode node : agentList) { // that's syntax I don't know...
node.voteAll2();
}
for(CustomNode node : agentList) {
node.calcReputation();
}
} else {
for(CustomNode node : agentList){
node.voteAll();
}
for(CustomNode node : agentList){
node.calcReputation();
}
}
}
/////////////////////////////////////////////////////////////
// addAgent
// Input: CustomNode agent
// Output: none
// Adds a new agent to the agent list
public void addAgent(CustomNode agent){
agentList.add(agent);
}
/////////////////////////////////////////////////////////////
// delAgent
// Input: CustomNode agent
// Output: none
// Deletes an agent from the agent list
public void delAgent(CustomNode agent){
agentList.remove(agentList.indexOf(agent));
System.gc();
}
//////////////////////////////////////////////////////////////////////
// calcAvgReputation()
public double calcAvgReputation(){
double sum = 0;
for(int i = 0; i < numAgents; i++){
CustomNode node = (CustomNode) agentList.get(i);
sum += (double) node.getReputation();
}
return sum/(double) numAgents;
}
/////////////////////////////////////////////////////////////
// calcTopRepSkills
// inputs: int x, the number of top agents include
// outputs: double, the reputation of the top x agents
// This calculates the sum of the skils of the top x agents
// AS: could be changed to just use numTopAgents directly,
// but I'm gonna change it at call time only--
// lower impact if I fuck something up.
public double calcTopRepSkills(int x){
ArrayList<CustomNode> tempList = new ArrayList<CustomNode>();
tempList.addAll(agentList);
Collections.sort(tempList, compNodes);
double skillSum = 0;
CustomNode node;
for (int i = numAgents -x; i < numAgents; i++){
node = tempList.get(i);
skillSum += node.getSkill();
}
return skillSum;
}
//////////////////////////////////////////////////////////////
// calcRepSkillMatch
// inputs: none
// outputs: double, the fraction of cases that a Rep and Skill match
// (High/Low)
public double calcRepSkillMatch(){
double count = 0;
for(CustomNode node : agentList){
if (node.getReputation() <= 0.5 & node.getSkill() <= 0.5){
count ++;
}
else if (node.getReputation() > 0.5 & node.getSkill() > 0.5){
count ++;
}
}
return count / ((double) numAgents);
}
///////////////////////////////////////////////////////////////////////
// stepReport
// each step write out:
// time expectivity
//
// Note: update the writeHeaderCommentsToReportFile() to print
// lines of text describing the data written to the report file.
public void stepReport () {
String s;
s = String.format("%f %f %f",
schedule.getCurrentTimeDouble(), calcTopRepSkills(numTopAgents),
calcRepSkillMatch());
//writeLineToReportFile ( "<stepreport>" + s + "</stepreport>" );
writeLineToPlaintextReportFile( s );
// flush the buffers so the data is not lost in a "crash"
//getReportFile().flush();
getPlaintextReportFile().flush();
}
/////////////////////////////////////////////////////////////////////////
// writeHeaderCommentsToReportFile
// customize to match what you are writing to the report files in
// stepReport.
public void writeHeaderCommentsToReportFile () {
writeLineToReportFile( "<comment>" );
writeLineToReportFile( " " );
writeLineToReportFile( " time expectivity " );
writeLineToReportFile( "</comment>" );
writeLineToPlaintextReportFile( " #time topSkill RepSkillMatch" );
}
public Schedule getSchedule () {
return schedule;
}
public String getName () {
return "Network";
}
public ArrayList<CustomNode> getAgentList() {return agentList;}
public static void main (String[] args) {
uchicago.src.sim.engine.SimInit init = new uchicago.src.sim.engine.SimInit ();
RepMod model = new RepMod ();
init.loadModel (model, null, false);
}
// The following are some debugging methods
public static void printVector(double[] vector){
System.out.printf("\n");
for(int i = 0; i < vector.length; i++){
System.out.printf("%f ", vector[i]);
}
System.out.printf("\n");
}
public static void printVector(int[] vector){
System.out.printf("\n");
for(int i = 0; i < vector.length; i++){
System.out.printf("%d ", vector[i]);
}
System.out.printf("\n");
}
public void printAgentList(){
System.out.printf("Printing agentList, size = %d\n", agentList.size());
CustomNode node;
CustomNode inode;
for(int i = 0; i < (agentList.size()); i++){
node = (CustomNode) agentList.get(i);
ArrayList <CustomNode> outNodes = node.getToNodes();
System.out.printf("Node %d points to (%d objects): ", node.getID(),
outNodes.size());
for(int j = 0; j < (outNodes.size()); j++){
inode = (CustomNode) outNodes.get(j);
System.out.printf(" %d ", inode.getID());
}
System.out.printf("\n");
}
System.out.printf("\n");
}
/////////////////////////////////////////////////////////
// nextPajekNetwork
// closes the current pajek file and opens the new one.
public void nextPajekNetwork(){
net.writePajekNetwork(agentList);
net.endPajekFile();
net.startPajekFile((int) schedule.getCurrentTime()/pajekUpdateInterval + 1);
}
/////////////////////////////////////////////////////////////////////
// processEndOfRun
// ends process
public void processEndOfRun ( ) {
long finalStep = (long) schedule.getCurrentTime();
if ( rDebug > 0 )
System.out.printf("\n\n===== Model processEndOfRun =====\n\n" );
applyAnyStoredChanges();
stepReport();
endReportFile(finalStep);
net.writePajekNetwork(agentList);
net.endPajekFile();
this.fireStopSim();
}
//*******************************************************************
// Inner classes
private class CompNodeRep implements Comparator{
public CompNodeRep(){
}
public int compare(Object o1, Object o2){
CustomNode nodei = (CustomNode) o1;
CustomNode nodej = (CustomNode) o2;
if (nodei.getReputation() < nodej.getReputation())
return -1;
else if (nodei.getReputation() > nodej.getReputation())
return 1;
else
return 0;
}
}
}