-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAgent.java
More file actions
149 lines (123 loc) · 4.46 KB
/
Agent.java
File metadata and controls
149 lines (123 loc) · 4.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/* Implementation of an Agent.
*
* Wanders around the simulation grid, rebels if sufficiently aggrieved
* with the "central authority".
*
*/
import java.lang.Math;
public class Agent implements Person {
// set of possible agent states
public enum State {
INACTIVE,
ACTIVE,
JAILED
}
// default initial values for private attributes
private static final State INITIAL_STATE = Agent.State.INACTIVE;
private static final int INITIAL_TERM = 0;
// used to stabilise numeric calculations
private static final double EPSILON = 0.1;
private State state;
private Cell location;
// agent's personal degree of risk aversion, and perceived hardship
private double aversion;
private double hardship;
// time remaining to spend in jail, after being arrested
private int remainingTerm;
public Agent(double aversion, double hardship, Cell location) {
this.aversion = aversion;
this.hardship = hardship;
this.location = location;
this.location.enter(this);
this.state = INITIAL_STATE;
this.remainingTerm = INITIAL_TERM;
}
public void move() {
// check: not jailed
if (this.state == Agent.State.JAILED) {
return;
}
// get random cell in vicinity
Cell target = this.location.getRandomUnoccupiedNeighbor();
// change location if there exists an unoccupied neighbor
if (target != null) {
this.moveTo(target);
}
}
private void moveTo(Cell target) {
this.location.leave(this);
target.enter(this);
this.location = target;
}
// Checks whether the agent is sufficiently aggreived with the
// government that they wish to actively rebel. If this is the case
// puts them in ACTIVE state, otherwise puts them in INACTIVE state.
// Takes current level of government legitimacy as input.
public void rebel(double legitimacy) {
// if currently in jail ...
if (this.state == Agent.State.JAILED) {
// ... then reduce jail term by 1
this.remainingTerm--;
// if agent still has time to serve ...
if (this.remainingTerm > 0) {
// ... then can't do anything else
return;
}
}
// otherwise, if agent's grievance outweighs risk of rebelling ...
if (this.computeGrievance(legitimacy) >= this.computeRisk()
+ Agent.EPSILON) {
// ... then rebel
this.state = Agent.State.ACTIVE;
} else {
// ... otherwise don't rebel
this.state = Agent.State.INACTIVE;
}
}
// compute an agent's grievance against the government, given their
// current level of legitimacy
private double computeGrievance(double legitimacy) {
return this.hardship * (1 - legitimacy);
}
// compute an agent's perceived risk of actively rebelling
private double computeRisk() {
return this.aversion * this.computePerceivedDanger();
}
// computes an agent's perceived danger of actively rebelling, based
// on their own risk aversion, and the ratio of cops to active
// agents in the neighborhood
private double computePerceivedDanger() {
// count the number of cops and active agents in neighborhood
int cops = this.location.countCopsInNeighborhood();
int agents = this.location.countActiveAgentsInNeighborhood();
// denominator is at least 1, for numerical stability
if (agents <= 0) {
agents = 1;
}
// compute perceived danger
return (1 - Math.exp(-2.3 * Math.floor(
(double) cops / (double) agents)));
}
// arrest the agent - puts the agent in JAILED state for the given
// number of time-steps
public void arrest(int term) {
this.remainingTerm = term;
this.state = Agent.State.JAILED;
}
// check whether the agent is actively rebelling
public boolean isActive() {
return this.state == Agent.State.ACTIVE;
}
// check whether the agent is in jail
public boolean isJailed() {
return this.state == Agent.State.JAILED;
}
// get the agent's current state
public State getState(Agent agent){
return this.state;
}
// get the agent's current location
public Cell getLocation() {
return this.location;
}
}