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

Pure strategy nash equilibrium #12

Merged
merged 7 commits into from
Nov 14, 2016
Merged

Pure strategy nash equilibrium #12

merged 7 commits into from
Nov 14, 2016

Conversation

cc7768
Copy link
Member

@cc7768 cc7768 commented Aug 4, 2016

This adds just a simple brute force algorithm for finding pure strategy Nash equilibrium -- Literally just iterates through all possible action profiles and stores them if they satisfy is_nash.

Has a very simple 2 player prisoner's dilemma test.

@oyamad
Copy link
Member

oyamad commented Aug 5, 2016

@cc7768 Thanks!

It seems the type of ne fails to be inferred. The following seems to work:

function pure_strategy_NE{N}(nfg::NormalFormGame{N})
    ...
    ne = Array(NTuple{N,Int}, 0)
    ...
end

Or we could add a type alias PureActionProfile{N}

typealias PureActionProfile{N} NTuple{N,PureAction}

@oyamad
Copy link
Member

oyamad commented Aug 5, 2016

Should

typealias PureAction Integer

in normal_form_game.jl be

typealias PureAction Int

?

@sglyon
Copy link
Member

sglyon commented Aug 5, 2016

@oyamad if we want to use PureAction like it is a concrete type then aliasing it to Integer will not work.

That being said, I looked through normal_form_game.jl and it seems to me that we only ever use PureAction as the type of a function argument, not as a type parameter or to construct arrays. There is no problem with this.

I like that right now it allows for any Integer type and think we should continue to support this. If we do, we just need to be careful that internal uses of PureAction won't result in abstract type parameters.

# For each action profile check whether it is NE
as = CartesianRange(na)
for a in as
_a = a.I::NTuple{np, Int}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having to insert type checks is never a great thing because (I believe) it incurs minor runtime cost.

It might be better to add a method is_nash{N}(::NormalFormGame{N}, ::CartesianIndex{N}) and then we can skip the _a bit all together

@oyamad
Copy link
Member

oyamad commented Aug 5, 2016

@spencerlyon2 I see, thanks.

@oyamad
Copy link
Member

oyamad commented Aug 5, 2016

Some thoughts on the function name.

  1. I would remove "strategy". This terminology is reserved for strategies in other classes of games, such as extensive form games. Just pure_NE or pure_nash should be fine.
  2. There are other methods that aim to find pure NEs, so I think it is better to include "brute force" in the function name, as pure_NE_brute or pure_nash_brute.

@oyamad
Copy link
Member

oyamad commented Aug 5, 2016

Maybe better to create a new file test_nash_equilibrium.jl?

@cc7768
Copy link
Member Author

cc7768 commented Aug 5, 2016

Excellent. Thanks for the feedback.

  1. I'll create a new test file and put the test in there -- Eventually we should probably test slightly more complicated games (like maybe N player Cournot).
  2. I will rename to remove the word "strategy" from the function name. Once we have better methods then we can change the name of this function to pure_NE_brute (or remove it completely), but for now since it is the only option we might as well keep it as pure_NE. Though I'm happy to rethink this if people disagree.
  3. I'll find a way to get rid of that type check.
  4. I didn't add the type alias, but it sounds like you two agree that it is ok now?

@oyamad
Copy link
Member

oyamad commented Sep 2, 2016

I think I would prefer pure_nash to pure_NE, consistent with the method is_nash. Or we could change is_nash to is_NE, keeping this pure_NE.

@cc7768
Copy link
Member Author

cc7768 commented Sep 6, 2016

With respect to what @spencerlyon2 said earlier about not using PureAction as a concrete type -- It seems like I am actually doing this in this piece of code. Note in pure_nash I use ne = Array(PureActionProfile, 0) where PureActionProfile is a type alias for NTuple{N, PureAction} and PureAction is a type alias for Integer. Thoughts on best way to address this? I like the aliases that @oyamad has created -- It makes writing the code very intuitive.

Also, removing the type check didn't change anything (as in we don't need it). The type of ::CartesianIndex.I is NTuple{...}, so the check could be removed without a problem.

Moved the test to test_pure_nash

Changed function name to pure_nash. I agree that the consistency is worthwhile.

@oyamad
Copy link
Member

oyamad commented Sep 7, 2016

The following seems to work:

typealias PureAction Integer
typealias PureActionProfile{N,T<:PureAction} NTuple{N,T}

function pure_nash{N}(nfg::NormalFormGame{N})
    ...
    ne = Array(PureActionProfile{N,Int}, 0)
    ...
end

If we follow this approach, should

typealias PureAction Integer

be rather

typealias AbstractPureAction Integer

?

In that case, how could we consistently define * and Abstract* type aliases?

@@ -0,0 +1,26 @@
"""
Finds all pure strategy Nash equilibrium for a normal form
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strategy -> action
equilibrium -> equilibria
(or just "pure Nash equilibria")

@cc7768
Copy link
Member Author

cc7768 commented Sep 7, 2016

Resolved documentation wording.

I like the solution you suggest for the type problem. I would be happy with not defining the Abstract* alias at all (and just using PureAction). It will mostly be used for function arguments (not array allocation). We could write a small note in dev docs that makes note of this -- "If you need to allocate array of PureActionProfile then make sure to specify its type arguments to avoid the issues discussed above." Thoughts?

@oyamad
Copy link
Member

oyamad commented Sep 8, 2016

Fine with me.

@cc7768 cc7768 mentioned this pull request Oct 26, 2016
@cc7768
Copy link
Member Author

cc7768 commented Oct 26, 2016

@oyamad Is this ready to merge -- The only thing undone from our discussion is a note in the dev docs (but there is a note under #17)

@oyamad
Copy link
Member

oyamad commented Oct 27, 2016

Maybe rename nash_equilibrium.jl to pure_nash.jl?

Otherwise I think this is ready to merge.

@cc7768
Copy link
Member Author

cc7768 commented Nov 14, 2016

I renamed the file. I am ready for this to be merged to master. I will wait for you to merge it in order to make sure that we agree.

Thanks for the feedback on this PR @oyamad and @spencerlyon2! I think it is much better than the original version.

@oyamad
Copy link
Member

oyamad commented Nov 14, 2016

@cc7768 Thanks, please do merge.

@cc7768 cc7768 merged commit 38d8127 into master Nov 14, 2016
@oyamad oyamad deleted the PSNE branch July 24, 2017 13:06
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