CustomNode.java.wp: Difference between revisions
From Santa Fe Institute Events Wiki
No edit summary |
No edit summary |
||
(3 intermediate revisions by 2 users not shown) | |||
Line 5: | Line 5: | ||
* | * | ||
* Created on January 22, 2005, 2:41 PM | * Created on January 22, 2005, 2:41 PM | ||
* Modified on June | * Modified on June 18, 2006, 13:55 by Jack | ||
* Modified June 22, 2006 00:16 by Andrew | |||
* Modified June 22, 2006 16:40 by Jack | |||
* | * | ||
* This class contains the parameters and methods | * This class contains the parameters and methods | ||
Line 41: | Line 43: | ||
public static GUIModel guiModel = null; | public static GUIModel guiModel = null; | ||
public static RepMod model; | public static RepMod model; | ||
// voteType, whether to use democratic or meritocratic votes | |||
// 0 = democratic | |||
// 1 = meritocratic | |||
// public static int voteType; | |||
// intVoteValue, the intrinsic value of an agent's vote | |||
// vote weight = intVoteValue + (1-intVoteValue)*reputation | |||
// now have continuous scale between democratic and meritocratic, | |||
// and also avoid divide by zero for zero rep agents voting. | |||
// 1 = democratic | |||
// 0 = complete meritocratic | |||
public static double intVoteValue; | |||
// the degree by which the historical opinion is weighted | |||
public static double histWeight; | |||
// weight of current reputation of focus when assigning new opinion | |||
public static double repWeight; | |||
// the (negative of) slope of skill vs variance of noise | |||
public static double noiseSlope; | |||
//********************************8** | //********************************8** | ||
Line 59: | Line 83: | ||
public double reputation; // current wealth or stored reputation | public double reputation; // current wealth or stored reputation | ||
public double skill; // skill parameter | public double skill; // skill parameter | ||
public int numVotes; // the number of vote rounds | //public int numVotes; // the number of vote rounds | ||
public double success; // most recent success | //public double success; // most recent success | ||
Line 72: | Line 99: | ||
id = nextID++; // set id and iterate to next | id = nextID++; // set id and iterate to next | ||
this.skill = skill; | this.skill = skill; | ||
reputation = | reputation = 0.5; // Generalize. Currently hard-coded | ||
if (guiModel != null) | if (guiModel != null) | ||
setNodeEdgeColorFromSkill(); | setNodeEdgeColorFromSkill(); | ||
numVotes = 0; | //numVotes = 0; | ||
success = 0; | //success = 0; | ||
} | } | ||
Line 85: | Line 112: | ||
// Outputs: array of strings holding parameter names | // Outputs: array of strings holding parameter names | ||
public String[] getProbedProperties(){ | public String[] getProbedProperties(){ | ||
return new String[] {"id", "reputation", "skill | return new String[] {"id", "reputation", "skill"}; | ||
} | } | ||
Line 127: | Line 154: | ||
} | } | ||
/////////////////////////////////////////////////////// | |||
// | |||
// Input: double success, the focus' real | /////////////////////////////////////////////////////// | ||
// Output: double vote, the voter's estimate of focus' | // formOpinion | ||
public double | // Input: double success, the focus' real skill | ||
// Output: double vote, the voter's estimate of focus' skill | |||
public double formOpinion(double fSkill, double prevOp, double fRep){ | |||
double op = fSkill + model.getNormalDouble(0, getNoiseFromSkill(this.skill)); | |||
op = histWeight*prevOp + repWeight*fRep + (1 - histWeight- repWeight)*op; | |||
return op; | |||
} | } | ||
// it should /really/ be (arguably, of course): | |||
// opinion = (1 - weight) * (focus' real skill + noise) | |||
// + weight * [opinion-weighted average of common nbrs opinions of focus] | |||
/* | |||
// | /////////////////////////////////////////////////////// | ||
// Input: double, | // formOpinion | ||
// Output: | // Input: double success, the focus' real skill | ||
public | // Output: double vote, the voter's estimate of focus' skill | ||
double | public double formOpinion(double fSkill, double prevOp){ | ||
double op = fSkill + model.getNormalDouble(0, getNoiseFromSkill(this.skill)); | |||
op = histWeight*prevOp + (1-histWeight)*op; | |||
return op; | |||
} | } | ||
// new formOpinion | |||
public double formOpinion2(double fSkill, double fRep){ | |||
// opinion = (1- repweight) * (focus' real skill + noise) | |||
// | // + repweight * focus' reputation | ||
public void | double op = fSkill+model.getNormalDouble(0,getNoiseFromSkill(this.skill)); | ||
op = repWeight*fRep + (1-repWeight)*op; | |||
// here I truncate to [0,1] -- this is open to further discussion | |||
if (op > 1) op = 1; // must...not...write...Python... | |||
if (op < 0) op = 0; // too many languages in one head! | |||
return op; | |||
} | |||
*/ | |||
//////////////////////////////////////////////////////// | |||
// voteAll | |||
public void voteAll(){ | |||
ArrayList edgeList = this.getOutEdges(); | |||
double opinion = 0; | |||
int vote = 0; | |||
for (int i = 0; i < edgeList.size(); i++){ | |||
CustomEdge edge = (CustomEdge) edgeList.get(i); | |||
CustomNode node = (CustomNode) edge.getTo(); | |||
opinion = formOpinion(node.getSkill(), edge.getOpinion(), node.getReputation()); | |||
edge.setOpinion(opinion); | |||
if (opinion > 0.5) | |||
vote = 1; | |||
else | |||
vote = 0; | |||
edge.setVote(vote); | |||
} | |||
} | } | ||
// new voteAll | |||
/* | |||
public void voteAll2(){ | |||
ArrayList edgeList = this.getOutEdges(); | |||
double opinion = 0; | |||
int vote = 0; | |||
for (int i = 0; i < edgeList.size(); i++){ | |||
// for each neighbor | |||
CustomEdge edge = (CustomEdge) edgeList.get(i); | |||
CustomNode node = (CustomNode) edge.getTo(); | |||
// get opinion (truncated 0 to 1) | |||
opinion = formOpinion2(node.getSkill(), node.getReputation()); | |||
// (optionally) locally normalize - omitted for now | |||
// set those opinions | |||
edge.setOpinion(opinion); | |||
// votes are opinions | |||
edge.setVote(opinion); // Java lines get semicolons, dipshit. | |||
} | |||
}*/ | |||
//////////////////////////////////////////////////////// | |||
// calcReputation | |||
// Input: none | |||
// Ouput: none | |||
public void calcReputation(){ | |||
ArrayList edgeList = this.getInEdges(); | |||
double repSum = 0; | |||
double normSum = 0; | |||
for (int i = 0; i < edgeList.size(); i++){ | |||
CustomEdge edge = (CustomEdge) edgeList.get(i); | |||
CustomNode node = (CustomNode) edge.getFrom(); | |||
repSum += edge.getVote() *(intVoteValue + (1-intVoteValue)*node.getReputation()); | |||
normSum += (intVoteValue + (1-intVoteValue)*node.getReputation()); | |||
/* | |||
if (voteType ==0){ | |||
repSum += edge.getVote(); | |||
normSum ++; | |||
} | |||
else if (voteType ==1){ | |||
repSum += edge.getVote() * node.getReputation(); | |||
normSum += node.getReputation(); | |||
}*/ | |||
} | |||
reputation = repSum/normSum; | |||
} | |||
Line 174: | Line 273: | ||
public void setSkill(double i) {skill = i;} | public void setSkill(double i) {skill = i;} | ||
public double getSuccess() {return success;} | //public double getSuccess() {return success;} | ||
public void setSuccess(double i) {success = i;} | //public void setSuccess(double i) {success = i;} | ||
//*************************************************************** | //*************************************************************** | ||
Line 209: | Line 308: | ||
nextID = 0; | nextID = 0; | ||
} | } | ||
/////////////////////////////////////////////////////////// | |||
// getNoiseFromSkill | |||
// Inputs: double skill | |||
// Outputs: double, the noise variance | |||
public static double getNoiseFromSkill(double skill){ | |||
return (1-skill)*noiseSlope; | |||
} | |||
//public static int getVoteType() {return voteType;} | |||
//public static void setVoteType(int i) {voteType = i;} | |||
public static double getIntVoteValue() {return intVoteValue;} | |||
public static void setIntVoteValue(double i) {intVoteValue = i;} | |||
public static double getHistWeight() {return histWeight;} | |||
public static void setHistWeight(double i) {histWeight = i;} | |||
public static double getRepWeight() {return repWeight;} | |||
public static void setRepWeight(double w) {repWeight = w;} | |||
public static double getNoiseSlope() {return noiseSlope;} | |||
public static void setNoiseSlope(double i) {noiseSlope = i;} | |||
} | } | ||
</pre> | </pre> |
Latest revision as of 22:41, 22 June 2006
/* * CustomNode.java * * Created on January 22, 2005, 2:41 PM * Modified on June 18, 2006, 13:55 by Jack * Modified June 22, 2006 00:16 by Andrew * Modified June 22, 2006 16:40 by Jack * * This class contains the parameters and methods * for an agent acting on the network */ package RepMod; import uchicago.src.sim.gui.NetworkDrawable; import uchicago.src.sim.network.DefaultDrawableNode; import uchicago.src.sim.gui.DrawableNonGridNode; import uchicago.src.sim.util.Random; import uchicago.src.sim.gui.OvalNetworkItem; import java.awt.Color; import uchicago.src.sim.gui.ColorMap; import uchicago.src.sim.engine.CustomProbeable; import java.util.ArrayList; /** * * @author Jack Waddell * */ // DefaultDrawableNode lets us draw it in the GUI // CustomProbeable lets us define which attributes appear when // probed in the GUI public class CustomNode extends DefaultDrawableNode implements CustomProbeable { //*********************************** // Static Parameters // tracks next unique id public static int nextID = 0; public static GUIModel guiModel = null; public static RepMod model; // voteType, whether to use democratic or meritocratic votes // 0 = democratic // 1 = meritocratic // public static int voteType; // intVoteValue, the intrinsic value of an agent's vote // vote weight = intVoteValue + (1-intVoteValue)*reputation // now have continuous scale between democratic and meritocratic, // and also avoid divide by zero for zero rep agents voting. // 1 = democratic // 0 = complete meritocratic public static double intVoteValue; // the degree by which the historical opinion is weighted public static double histWeight; // weight of current reputation of focus when assigning new opinion public static double repWeight; // the (negative of) slope of skill vs variance of noise public static double noiseSlope; //********************************8** // Instance parameters // Two colormaps are generated for color-coding the nodes in GUI public static ColorMap centerColorMap; public static ColorMap edgeColorMap; public static final int colorMapSize = 16; public static final int colorMapMax = colorMapSize - 1; private int id; // uniquely ids node public Color myColor; // used to draw color in GUI public String myPajekColor = "Red"; // color to appear in Pajek output public double reputation; // current wealth or stored reputation public double skill; // skill parameter //public int numVotes; // the number of vote rounds //public double success; // most recent success /////////////////////////////////////////////////////////////// // constructor // Inputs: NetworkDrawable drawable, to draw in GUI // double skill, the skill parameter public CustomNode (NetworkDrawable drawable, double skill) { super(drawable); id = nextID++; // set id and iterate to next this.skill = skill; reputation = 0.5; // Generalize. Currently hard-coded if (guiModel != null) setNodeEdgeColorFromSkill(); //numVotes = 0; //success = 0; } /////////////////////////////////////////////////////////// // getProbedProperties // Required to implement CustomProbeable // Inputs: none // Outputs: array of strings holding parameter names public String[] getProbedProperties(){ return new String[] {"id", "reputation", "skill"}; } ////////////////////////////////////////////////////////// // step // Input: none // Output: none // (Can be) Called by main model to have nodes execute a single step public void step(){ } ////////////////////////////////////////////////////////// // setNodeColorFromReputation // Input: maxReputation, the highest reputation from all agents // Output: none // Sets the node color to the colormap leval depending on reputation public void setNodeColorFromReputation(double maxReputation){ int i = (int) Math.round(colorMapMax*(reputation)/ (maxReputation)); this.setColor(centerColorMap.getColor(i)); } ////////////////////////////////////////////////////////// // setNodeEdgeColorFromSkill // Input: none // Output: none // Sets the node edge color to the colormap level depending on skill public void setNodeEdgeColorFromSkill(){ int i = (int) Math.round(colorMapMax*skill); this.setBorderColor(edgeColorMap.getColor(i)); this.setBorderWidth(3); } /////////////////////////////////////////////////////// // getDegree // Input: none // Output: int degree // Calculates the degree of the node (assuming symmetric) public int getDegree(){ return (this.getOutNodes()).size(); } /////////////////////////////////////////////////////// // formOpinion // Input: double success, the focus' real skill // Output: double vote, the voter's estimate of focus' skill public double formOpinion(double fSkill, double prevOp, double fRep){ double op = fSkill + model.getNormalDouble(0, getNoiseFromSkill(this.skill)); op = histWeight*prevOp + repWeight*fRep + (1 - histWeight- repWeight)*op; return op; } // it should /really/ be (arguably, of course): // opinion = (1 - weight) * (focus' real skill + noise) // + weight * [opinion-weighted average of common nbrs opinions of focus] /* /////////////////////////////////////////////////////// // formOpinion // Input: double success, the focus' real skill // Output: double vote, the voter's estimate of focus' skill public double formOpinion(double fSkill, double prevOp){ double op = fSkill + model.getNormalDouble(0, getNoiseFromSkill(this.skill)); op = histWeight*prevOp + (1-histWeight)*op; return op; } // new formOpinion public double formOpinion2(double fSkill, double fRep){ // opinion = (1- repweight) * (focus' real skill + noise) // + repweight * focus' reputation double op = fSkill+model.getNormalDouble(0,getNoiseFromSkill(this.skill)); op = repWeight*fRep + (1-repWeight)*op; // here I truncate to [0,1] -- this is open to further discussion if (op > 1) op = 1; // must...not...write...Python... if (op < 0) op = 0; // too many languages in one head! return op; } */ //////////////////////////////////////////////////////// // voteAll public void voteAll(){ ArrayList edgeList = this.getOutEdges(); double opinion = 0; int vote = 0; for (int i = 0; i < edgeList.size(); i++){ CustomEdge edge = (CustomEdge) edgeList.get(i); CustomNode node = (CustomNode) edge.getTo(); opinion = formOpinion(node.getSkill(), edge.getOpinion(), node.getReputation()); edge.setOpinion(opinion); if (opinion > 0.5) vote = 1; else vote = 0; edge.setVote(vote); } } // new voteAll /* public void voteAll2(){ ArrayList edgeList = this.getOutEdges(); double opinion = 0; int vote = 0; for (int i = 0; i < edgeList.size(); i++){ // for each neighbor CustomEdge edge = (CustomEdge) edgeList.get(i); CustomNode node = (CustomNode) edge.getTo(); // get opinion (truncated 0 to 1) opinion = formOpinion2(node.getSkill(), node.getReputation()); // (optionally) locally normalize - omitted for now // set those opinions edge.setOpinion(opinion); // votes are opinions edge.setVote(opinion); // Java lines get semicolons, dipshit. } }*/ //////////////////////////////////////////////////////// // calcReputation // Input: none // Ouput: none public void calcReputation(){ ArrayList edgeList = this.getInEdges(); double repSum = 0; double normSum = 0; for (int i = 0; i < edgeList.size(); i++){ CustomEdge edge = (CustomEdge) edgeList.get(i); CustomNode node = (CustomNode) edge.getFrom(); repSum += edge.getVote() *(intVoteValue + (1-intVoteValue)*node.getReputation()); normSum += (intVoteValue + (1-intVoteValue)*node.getReputation()); /* if (voteType ==0){ repSum += edge.getVote(); normSum ++; } else if (voteType ==1){ repSum += edge.getVote() * node.getReputation(); normSum += node.getReputation(); }*/ } reputation = repSum/normSum; } //*************************************************************** // Getters and Setters public int getID() {return id;} public void setMyPajekColor(String i) {myPajekColor = i;} public String getMyPajekColor() {return myPajekColor;} public double getReputation() {return reputation;} public void setReputation(double i) {reputation = i;} public double getSkill() {return skill;} public void setSkill(double i) {skill = i;} //public double getSuccess() {return success;} //public void setSuccess(double i) {success = i;} //*************************************************************** // Static Methods public static void setModel(RepMod m) {model = m;} ////////////////////////////////////////////////////////// // setUpNodeDrawing // Input: GUIModel m, a pointer to the GUIModel // Output: none public static void setUpNodeDrawing (GUIModel m) { guiModel = m; centerColorMap = new ColorMap(); edgeColorMap = new ColorMap(); double minColor = 0.1; for (int i = 0; i < colorMapSize; i++){ double fracColor = minColor + ( (1.0-minColor)*i/colorMapMax ); centerColorMap.mapColor(i, 0, 0, fracColor); edgeColorMap.mapColor(i, 0, fracColor, 0); } } /////////////////////////////////////////////////////////// // resetNextID // Inputs: none // Outputs: none // Resets nextID. Called when the model is reset, and a // new set of nodes is generated public static void resetNextID(){ nextID = 0; } /////////////////////////////////////////////////////////// // getNoiseFromSkill // Inputs: double skill // Outputs: double, the noise variance public static double getNoiseFromSkill(double skill){ return (1-skill)*noiseSlope; } //public static int getVoteType() {return voteType;} //public static void setVoteType(int i) {voteType = i;} public static double getIntVoteValue() {return intVoteValue;} public static void setIntVoteValue(double i) {intVoteValue = i;} public static double getHistWeight() {return histWeight;} public static void setHistWeight(double i) {histWeight = i;} public static double getRepWeight() {return repWeight;} public static void setRepWeight(double w) {repWeight = w;} public static double getNoiseSlope() {return noiseSlope;} public static void setNoiseSlope(double i) {noiseSlope = i;} }