{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# ProfileNoisyDiscrete: More Options" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:15.997752Z", "start_time": "2021-02-15T09:50:10.615026Z" } }, "outputs": [], "source": [ "from fractions import Fraction\n", "import poisson_approval as pa" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Weak orders" ] }, { "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2020-02-20T05:41:15.651548Z", "start_time": "2020-02-20T05:41:15.646521Z" } }, "source": [ "The profile can contains weak orders. Voters of the form ``'a>b~c'`` (*lovers*) always vote for their top candidate, and voters of the form ``'a~b>c'`` (*haters*) always vote for their two top candidates." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:16.016349Z", "start_time": "2021-02-15T09:50:16.001904Z" } }, "outputs": [ { "data": { "text/plain": [ "a~b: 2/5> (Condorcet winner: a, b)" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "profile = pa.ProfileNoisyDiscrete({\n", " ('abc', 0.9, 0.01): Fraction(3, 10), \n", " ('bac', 0.9, 0.01): Fraction(3, 10), \n", " 'c>a~b': Fraction(4, 10)\n", "})\n", "profile" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Which rankings are in the profile?" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:16.047778Z", "start_time": "2021-02-15T09:50:16.020715Z" } }, "outputs": [ { "data": { "text/plain": [ "{abc, bac}" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "profile.support_in_rankings" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Which weak orders are in the profile?" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:16.067784Z", "start_time": "2021-02-15T09:50:16.049771Z" } }, "outputs": [ { "data": { "text/plain": [ "{c>a~b}" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "profile.support_in_weak_orders" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Does the profile contain rankings?" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:16.083870Z", "start_time": "2021-02-15T09:50:16.069786Z" } }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "profile.contains_rankings" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Does the profile contain weak orders?" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:16.108681Z", "start_time": "2021-02-15T09:50:16.086733Z" } }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "profile.contains_weak_orders" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Expressive voters" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Two kinds of expressive voters are defined:\n", "\n", "* *Sincere* voters vote for their top candidate anyway, and vote for their second candidate if and only if their utility for her is strictly greater than 0.5.\n", "* *Fanatic* voters always vote for their top candidate only." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Define a profile with some sincere and some fanatic voters:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:16.131466Z", "start_time": "2021-02-15T09:50:16.111968Z" } }, "outputs": [ { "data": { "text/plain": [ " (Condorcet winner: b) (ratio_sincere: 1/100) (ratio_fanatic: 1/50)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "profile = pa.ProfileNoisyDiscrete({\n", " ('abc', 0.4, 0.01): Fraction(1, 10),\n", " ('bac', 0.2, 0.01): Fraction(6, 10),\n", " ('cab', 0.7, 0.01): Fraction(3, 10)\n", "}, ratio_sincere=Fraction(1, 100), ratio_fanatic=Fraction(2, 100))\n", "profile" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the example above, in all groups, a fraction 1/100 of the voters vote sincerely, and a fraction 2/100 vote fanatically. For example, let us define a strategy:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:16.150562Z", "start_time": "2021-02-15T09:50:16.134604Z" } }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "strategy = pa.StrategyOrdinal({'abc': 'a', 'bac': 'ab', 'cab': 'c'})\n", "strategy" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we apply this strategy to the profile, what happens?" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:16.174498Z", "start_time": "2021-02-15T09:50:16.153218Z" } }, "outputs": [ { "data": { "text/plain": [ " ==> a" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "profile.tau(strategy)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Out of the 3/10 of voters of the group $(cab, 0.7, 0.01)$:\n", "\n", "* 1/100 of them, i.e. 3/1000, are sincere and vote for $ac$,\n", "* 2/100 of them, i.e. 6/1000, are fanatic and vote for $c$,\n", "* The rest of them, i.e. 291/1000, apply the given strategy and vote for $c$.\n", "\n", "In total, 3/1000 vote for $ac$ and 297/1000 vote for $c$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The analyzed strategies take this behavior into account:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:16.272726Z", "start_time": "2021-02-15T09:50:16.178487Z" } }, "outputs": [ { "data": { "text/plain": [ "Equilibrium:\n", " ==> b (FF)\n", "\n", "Non-equilibria:\n", " ==> b (FF)\n", " ==> a (D)\n", " ==> a (D)\n", " ==> b (FF)\n", " ==> b (FF)\n", " ==> b (D)\n", " ==> a (D)" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "profile.analyzed_strategies_ordinal" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that without expressive voters, the equilibria are different:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:16.353510Z", "start_time": "2021-02-15T09:50:16.276715Z" } }, "outputs": [ { "data": { "text/plain": [ "Equilibria:\n", " ==> b (FF)\n", " ==> a (D)\n", "\n", "Non-equilibria:\n", " ==> b (FF)\n", " ==> a (D)\n", " ==> b (FF)\n", " ==> b (FF)\n", " ==> a, b (FF)\n", " ==> a (D)" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "profile = pa.ProfileNoisyDiscrete({\n", " ('abc', 0.4, 0.01): Fraction(1, 10),\n", " ('bac', 0.2, 0.01): Fraction(6, 10),\n", " ('cab', 0.7, 0.01): Fraction(3, 10)\n", "})\n", "profile.analyzed_strategies_ordinal" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Other Voting Rules: Plurality and Anti-Plurality" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In addition to Approval, the package also implements Plurality and Anti-plurality." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For Plurality, you just need to specify ``voting_rule=pa.PLURALITY`` when you define a Profile or a Strategy:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:16.369467Z", "start_time": "2021-02-15T09:50:16.356502Z" } }, "outputs": [ { "data": { "text/plain": [ " (Condorcet winner: b) (Plurality)" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "profile = pa.ProfileNoisyDiscrete({\n", " ('abc', 0.4, 0.01): Fraction(1, 10),\n", " ('bac', 0.2, 0.01): Fraction(6, 10),\n", " ('cab', 0.7, 0.01): Fraction(3, 10)\n", "}, voting_rule=pa.PLURALITY)\n", "profile" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:16.400893Z", "start_time": "2021-02-15T09:50:16.373456Z" } }, "outputs": [ { "data": { "text/plain": [ " (Plurality)" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "strategy = pa.StrategyOrdinal({'abc': 'a', 'bac': 'b', 'cab': 'a'}, voting_rule=pa.PLURALITY)\n", "strategy" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that if you define a strategy with an attached profile, you do not need to specify the voting rule again because it is deduced from the one of the profile:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:16.423832Z", "start_time": "2021-02-15T09:50:16.402898Z" } }, "outputs": [ { "data": { "text/plain": [ " ==> b (Plurality)" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "strategy = pa.StrategyOrdinal({'abc': 'a', 'bac': 'b', 'cab': 'a'}, profile=profile)\n", "strategy" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "All the other features work as usual. For example:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:16.475700Z", "start_time": "2021-02-15T09:50:16.427820Z" } }, "outputs": [ { "data": { "text/plain": [ "Equilibria:\n", " ==> b (Plurality) (FF)\n", " ==> a (Plurality) (FF)\n", " ==> b (Plurality) (FF)\n", "\n", "Non-equilibria:\n", " ==> b (Plurality) (FF)\n", " ==> a (Plurality) (UF)\n", " ==> b (Plurality) (FF)\n", " ==> a (Plurality) (FF)\n", " ==> a (Plurality) (FF)" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "profile.analyzed_strategies_ordinal" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Similarly, there exists an option ``voting_rule=pa.ANTI_PLURALITY``. Since this package is focused on Approval, the anti-plurality ballots are represented by their approval counterpart: for example, a ballot against candidate $c$ is represented by $ab$." ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:16.498151Z", "start_time": "2021-02-15T09:50:16.480680Z" } }, "outputs": [ { "data": { "text/plain": [ " (Condorcet winner: b) (Anti-plurality)" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "profile = pa.ProfileNoisyDiscrete({\n", " ('abc', 0.4, 0.01): Fraction(1, 10),\n", " ('bac', 0.2, 0.01): Fraction(6, 10),\n", " ('cab', 0.7, 0.01): Fraction(3, 10)\n", "}, voting_rule=pa.ANTI_PLURALITY)\n", "profile" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:16.523085Z", "start_time": "2021-02-15T09:50:16.500146Z" } }, "outputs": [ { "data": { "text/plain": [ " ==> a (Anti-plurality)" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "strategy = pa.StrategyOrdinal({'abc': 'ab', 'bac': 'ab', 'cab': 'ac'}, profile=profile)\n", "strategy" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:16.550014Z", "start_time": "2021-02-15T09:50:16.528087Z" } }, "outputs": [ { "data": { "text/plain": [ "EquilibriumStatus.NOT_EQUILIBRIUM" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "strategy.is_equilibrium" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.3" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": false, "sideBar": true, "skip_h1_title": true, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": true, "toc_window_display": false } }, "nbformat": 4, "nbformat_minor": 2 }