-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
update hawk/dove with options for different risk attitude distributions #55
Conversation
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## hawkdove-adjust-recent-payoff #55 +/- ##
=================================================================
+ Coverage 61.01% 62.76% +1.74%
=================================================================
Files 16 16
Lines 767 803 +36
=================================================================
+ Hits 468 504 +36
Misses 299 299 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great! LOVE the distribution work!
elif self.risk_distribution == "bimodal": | ||
# to generate a bimodal distribution, alternately generate | ||
# values from two different normal distributions centered | ||
# around the beginning and end of our risk attitude range | ||
while True: | ||
yield int(self.random.gauss(1, 0.75)) | ||
yield int(self.random.gauss(7, 0.75)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what a cool idea for a bimodal distribution using generators. "bimodal" can then mean programmatically just alternating between the two modes ! very cool.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a cool idea! Nice work.
Because r now ranges between 0 and 9, either the distributions should be centered around 1 and 8 or around 2 and 7 (I think the former is better because it leads to more extreme values--as long as it's still possible to get all the values).
elif self.risk_distribution == "skewed left": | ||
# return values from a triangler distribution centered around 0 | ||
while True: | ||
yield round( | ||
self.random.triangular(self.min_risk_level, self.max_risk_level, 0) | ||
) | ||
elif self.risk_distribution == "skewed right": | ||
# return values from a triangler distribution centered around 8 | ||
while True: | ||
yield round( | ||
self.random.triangular(self.min_risk_level, self.max_risk_level, 8) | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice. I did not know about random.triangular
. Looks like just what you need here, no more nor less.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, I think these should be centered around 0 and 9, or around 1 and 8.
if self.risk_distribution == "uniform": | ||
# uniform/random: generate random integer within risk level range | ||
while True: | ||
yield self.random.randint(self.min_risk_level, self.max_risk_level) | ||
if self.risk_distribution == "normal": | ||
# return values from a normal distribution centered around 4 | ||
while True: | ||
yield int(self.random.gauss(4, 1.5)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. Cool to have two kinds of "normal" here compared (normal random
behavior, normal/Gaussian distribution).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be centered around 4.5.
def get_risk_attitude(self): | ||
"""return the next value from risk attitude generator, based on | ||
configured distribution.""" | ||
val = next(self.risk_attitude_generator) | ||
# occasionally generators will return values that are out of range. | ||
# rather than capping to the min/max and messing up the distribution, | ||
# just get the next value | ||
while not self._risk_level_in_bounds(val): | ||
val = next(self.risk_attitude_generator) | ||
return val |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so this is what keeps those while True
's above from infinite-looping? nice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, was looking for a good solution for alternating values for the bimodal and figured out I could return a generator for all of them that generates however many values you need. I was initially looking at the distribution options in numpy, but couldn't figure out a way to do anything like this - you have to generate all the values at once based on the needed size.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the bimodal distribution centered around 7, I almost never got a value of 9 on the initial distribution ("step 1"), though I did get a value of 5 quite frequently. The probability of these should be symmetric, right (aside from the miniscule probability of the distribution centered around 1 yielding 5)? Might want to check to make sure that the range ends at 9, rather than 8, everywhere? (Though I did occassionally get a value of 9, so I'm not totally sure what's happening.)
update hawk/dove with options for different risk attitude distributions
ref #18
The easiest way to see how it's working is to run the model with solara and try switching between the different distributions, then run for one step to see the bar chart of the number of agents for each risk attitude. Works better on larger grids.
(temporarily comparing against adjust payoff branch to isolate diffs, since this code is forked from that branch)