Skip to content
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

Merged
merged 1 commit into from
Dec 15, 2023

Conversation

rlskoeser
Copy link
Contributor

ref #18

  • new model parameter with list of supported distributions
  • new method to generate agent risk level based on configured distribution
  • configure the new option to be available in the solara interface

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)

Copy link

codecov bot commented Dec 15, 2023

Codecov Report

Merging #55 (61406fc) into hawkdove-adjust-recent-payoff (add8299) will increase coverage by 1.74%.
The diff coverage is 100.00%.

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              

Copy link

@quadrismegistus quadrismegistus left a 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!

Comment on lines +242 to +248
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))

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.

Copy link
Collaborator

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).

Comment on lines +230 to +241
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)
)

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.

Copy link
Collaborator

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.

Comment on lines +222 to +229
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))

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).

Copy link
Collaborator

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.

Comment on lines +250 to +259
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

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

Copy link
Contributor Author

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.

Copy link
Collaborator

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.)

Base automatically changed from hawkdove-adjust-recent-payoff to main December 15, 2023 17:51
@rlskoeser rlskoeser merged commit 6bd6021 into main Dec 15, 2023
6 checks passed
@rlskoeser rlskoeser deleted the risk-distribution branch December 15, 2023 17:52
rlskoeser added a commit that referenced this pull request Feb 12, 2024
update hawk/dove with options for different risk attitude distributions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants