Collaborative Coding for Simulation
-
@rob In regard to "factions":
First off, I should clarify that the person I mean by "user" is the one who is describing the candidate list, the electorate, etc. for a simulation. In short, defining the problem the simulator is tasked to solve. No programming skill is required of the user. I'm thinking that a guest programmer would give me their code and I would integrate it in the framework.
If the user wants to describe an electorate with a thousand voters, or ten thousand, or a hundred thousand, or a million, said user (U) is not going to want to sit there and list for each of the million voters, that voter's evaluations of the maybe 18 candidates. Instead, the user should be able to describe chunks of voters who share the same evaluations. I have been calling such chunks of like-minded voters "factions". Do you propose a different name and/or a different scheme for what options are open to the user in laying out the problem?
In regard to the Codepen tool:
What constraints does it impose that wouldn't apply to a website that I might implement?
In regard to the programming language and to an example:
You have chosen Javascript. So what I would be interested in seeing from you is an example strategy function in Javascript. Again, it doesn't have to be tested. It can be a first draft.
-
@jack-waugh
I'm not sure what you are looking for regarding a "strategy function" but you can look at how I implemented strategy for a few methods in my simulator.This video does show code, and if you want you can look at the code in the actual app (which has been improved / expanded since I made the video), here it is:
https://pianop.ly/voteSim/voteSim.html(also, I'm not sure how this is particularly relevant to the JavaScript question. I mean, any language should be able to do whatever algorithm you come up with, right? )
The way I implemented strategy is pretty simple. Basically, I assume that voters would attempt to guess who would be the front runners, and vote accordingly. So if it is approval and you know that the winner will be one of four candidates out of ten, you approve all candidates that you like equal to or better than the average score you give each of those four candidates. (a bit simplistic, but reasonable)
The trick is how to know who will be the front runners. And to do this, I just iterated, having everyone voting with the above algorithm, then narrow down the candidates. And it iterates until it stabilizes. Some voters were "more strategic" than others, which simply meant that they were able to narrow it down further. So the least strategic would vote as if all candidates were front runners, while the most strategic would narrow it down to two. My simulator showed the progress by animating the sorting of candidates, slowly enough that your eyes can sort of follow it. (it shows how strategic each voter is by the "warmth" of their color: oranger is more strategic, bluer is less strategic)
Not sure if that makes sense, but feel free to watch the video and play with the app and look at the code if you want.
I did sort of the opposite extreme of putting each voter into a faction. I just spread them over a 2d ideological spectrum with a random distribution. I don't think that is perfectly realistic, and think a little "clumping" would improve it. But I never got around to that.
One of these days I'll put some more work into the app. I'd like to do IRV but that one is tricky strategywise. I am not convinced that a good Condorcet method would have any reasonable strategy beyond ranking them in your order of preference. So I only did approval, FPTP, score and for and against, all of which have a fairly straight forward strategy if you know which of the candidates is in the running.
-
@rob, thanks for that link to the code.
I wasn't looking just for algorithms, but more particularly, to know the techniques whereby they are carried out and whereby the inputs and results are coupled from and to the rest of the program.
I see that you use imperative style and native looping constructs + setTimeout.
-
@jack-waugh Yes I find imperative styles easy to follow especially by the less experienced. setTimeout() is to allow for the animations.
I'm curious what approach you are using to simulate strategy. Is it purely based on being able to guess the front runners, "hall of mirrors" style (as mine is), or something else?
-
@rob said in Collaborative Coding for Simulation:
what approach you are using to simulate strategy
I haven't implemented anything yet, but was thinking along the lines of heuristics. I would make available to the strategic code, the preferences of all the factions (a more sophisticated simulation for some purposes could blur these, but to start with, I would provide them verbatim). If the favorite candidate of the faction the code is working for at the moment is unpopular, the code would look for a lesser evil. For Score, the less popular the preferred candidate is, the greater the degree to which the support for the lesser evil would be exaggerated.
-
@jack-waugh Sounds really difficult to do in a way where it is actually good strategy. For instance, how do you determine if a candidate is popular? Does it mean "likely to be elected under the current method?" Because that by its nature needs to be iteratively solved. (well, that's the only way I can think of to solve that). And then, how do you determine how good voters are at guessing how others will vote? Do they all have equal ability?
I also have trouble imagining how you decide what voters go in what faction, in anything approaching realism, unless you do something along the lines of what I did which is give each voter (and each candidate) a position in "ideological space", which I simplified into a 2-dimensional space. Note that in the latest version I also gave candidates a "universal appeal" property, so it wasn't only about proximity to the candidate in ideological space.
Finally, I don't know how to algorithmically do strategic voting under IRV or Condorcet. It seems like a voter needs to be able to guess with a great deal of precision how others will vote in order to effectively rank the candidates in anything other than your sincere preferences.
-
@rob I feel there is a certain amount of demerit in my spending more time jawboning about the simulation I have in mind than coding it. Nevertheless.
I am choosing to exclude from the scope of the simulation, any modeling of how or why the voters come to the evaluations they have of the candidates. I want to simply allow the researcher (the user) to specify those. The purpose of running the simulations is to see which combinations of strategies and voting systems do better in the sense of tipping the result the way the researcher is interested in (presumably, toward defeating the duopoly) with the least support in terms of count of voters on one side or the other with respect to whatever polarization interests the researcher. My idea is to allow the researcher to find this tipping point by titration, by adjusting a slider control back and forth and observing when the combinations of voting systems with strategies for them tip between electing the sort of candidate the researcher supports to the sort the researcher opposes. The slider position will affect the numbers of voters holding certain valuations of the candidates and nothing else. The valuations will drive the votes via the strategies. Every seriously proposed voting system has an obvious naïve strategy, and I will offer that in all cases.
For Condorcet and IRV, I don't know offhand any strategies to offer other than the naïve strategy, which is just to order the candidates according to preference. This is the strategy recommended by IRV advocates.
For Score (and STAR), the popularity of the preferred candidate is directly available in the simulation (as it would not be in real life) from the evaluations of the voters toward the candidates. A threshold could be chosen based on what the candidate scores would be in a forced "honest" Score election, based on reading the voters' minds rather than giving them freedom of choice. Maybe instead of a hard threshold, this should be a parameter to choose a logistic function through which to map the scores given to the middle candidates. I'm not sure whether that makes sense; it's just an idea. But generally, the idea is that if honest scoring would elect Nader, there is no need to settle for Gore or Bush, whichever we judge to be the lesser evil. But if Nader is polling at 1%, we might care about the Gore-Bush part of the election and would want to exaggerate support for the lesser evil.
So, my assumption is that all voters are perfectly good at guessing what the other voters want (not how they will vote), and as good as the author of the strategy routine at choosing an advantageous strategy. The reason for these assumptions is I am trying to pit the voting systems against each other, above all else. I want to find out, and show others, circumstances where one voting system "works" better than the other at overcoming the kinds of antidemocratic behaviors that FPtP exhibits. I believe that when a system has been in place for several elections, all factions will figure out how best to game it for their purposes, to the extent that is possible. My grounds for expecting this are general Darwinism plus the experience that every American knows that a naïve choice under FPtP is not always the most advantageous choice.
I haven't thought about any simulation that would address the choice that a potential candidate would make to run or not run, as a variable to be computed. But the choice not to run in FPtP is an example of how the public has come to understand strategy.
-
@rob said in Collaborative Coding for Simulation:
Finally, I don't know how to algorithmically do strategic voting under IRV or Condorcet. It seems like a voter needs to be able to guess with a great deal of precision how others will vote in order to effectively rank the candidates in anything other than your sincere preferences.
Usually in Condorcet, strategy involves trying to force a cycle. But you will then have the task of determining whether doing this is beneficial for you.
A general case for voting strategy might be to define some sort of distance between two elections based on the number of ballots changed (but perhaps assigning different weights to each ballot-vote combination, since some voters wouldn't want to participate in a strategy as it undermines what they want, also, if your supporters aren't easily persuaded to vote strategically, they might require higher weights; the weights would represent the difficulty of convincing a voter to cast a specific vote), and then a naive approach might be to find the election with a different outcome of nearest distance to the election that is expected, then for each voter to choose from the votes that they are willing to cast whichever vote either maximizes or minimizes the distance from the expected election given their chosen vote and the nearest different outcome, depending on whether they prefer it or not.
One challenge with this idea is that strategy is local, so the distance won't be valid everywhere. Another is that it doesn't take into account uncertainty in our estimates.
I think that this is a bit of a ways off from being something you could usefully code, but I think it could develop into a useful model.
-
@marylander said in Collaborative Coding for Simulation:
find the election with a different outcome of nearest distance to the election that is expected
Your choice of concepts invites me to reexamine which ones I'm emphasizing when thinking about strategy. A way to look at is to start by asking whether the freedom of movement available to our faction allows us cast better than a naïve vote in terms of the quality of the electoral outcome as measured by our values. The expected election might be the one that would result if we voted naïvely and our opponents bullet voted. If there's an algorithm that explores all around the envelope of what we can do in search of a better outcome, assuming the opponents continue to bullet vote, that could be interesting. If no better alternative election is found within that freedom of movement, we should vote naïvely in order to avoid perturbing the secondary indications of the election. If more than one better election is found, we should try to force the best one.
-
@marylander said in Collaborative Coding for Simulation:
Usually in Condorcet, strategy involves trying to force a cycle. But you will then have the task of determining whether doing this is beneficial for you.
Yeah my feeling -- and it is more of a feeling than anything I've been able to mathematically reason -- is that for a normal voter to try to do this is going to be beyond their capabilities. They might try, but they are probably equally likely to do something has a negative effect as to have a positive effect. And if it does have a positive effect, it will be an extremely subtle one.
This is nothing like how under other systems -- such as FPTP, Approval, and Score -- simply knowing who the two front runners are dramatically helps you to vote effectively. Even being able to narrow it down, say from a field of 8 to a field of 4, makes a big difference.
-
@rob said in Collaborative Coding for Simulation:
Yeah my feeling -- and it is more of a feeling than anything I've been able to mathematically reason -- is that for a normal voter to try to do this is going to be beyond their capabilities. They might try, but they are probably equally likely to do something has a negative effect as to have a positive effect. And if it does have a positive effect, it will be an extremely subtle one.
I think there are simple cases where it might be possible for voters to use Condorcet strategy, if only because a campaign might be able to figure out some burial scenario and try to communicate to their voters "do this, just trust me." I have center-squeeze cases in mind in particular: often when the plurality winner has 1 pairwise win and 1 pairwise defeat to the (sincere) Condorcet winner, they'll win if their voters bury the sincere Condorcet winner. If the plurality winner's pairwise victory is large enough, the risk of this strategy is low. But the campaign itself would have to push this, since voters are not very good at figuring out strategy when left to their own devices.
-
@jack-waugh on the original question regarding languages, I don't really know FORTH (or its variations) and I have a strong attraction to LISP. But for the simple and practical reasons that simulations have to be run on some system, having JavaScript client code is really the only way to go if you want more than a handful of users running simultaneous simulations.
-
If you are looking for voting strategies and you aren't already familiar with it, you might want to look at Warren D. Smith's 2000 Range Voting paper. In it he proposes Range Voting (now more commonly referred to as Score) and compares it to about 30 other voting methods (really 14 other methods with naïve and strategic variations), The last I checked the paper can be found at Range Voting. The (c) code is also available at votetest2.c.
According to the (many) voting papers I've read over the past several years, there is a major decision that needs to be made when representing the electorate. In my opinion, the worst option is to use tournaments, which essentially ignore voters and even elections, and are about choosing a winner among a fixed set of alternatives based on a graph in which an arrow points from node A to node B if A would defeat B in a one-on-one simple majority election. The graph is just a given, and the challenge is to figure out a way to pick the winner. These papers have tended to focus on the computational difficulty of making this choice when the graph is large. The second way of representing the electorate is preference profiles, which is just a ranking of the fixed set of alternatives combined with a mulitplicity for each raking indicating how many voters would order the alternative that way. My problem with this method is that it doesn't provide any data for approval voting or score voting, or indeed any cardinal voting method.
My preferred method (which generally requires computer simulation for any realistically sized electorate) is to represent voters as points in an issue space (usually 2D or higher), and use a distance function between the voters and the alternatives (also points in the issue space) to generate ordinal or cardinal ballots.
One of the projects I'm considering is to start with something like Nicky Case's To Build A Better Ballot, and use interactive JavaScript to illustrate many of the problems with various voting systems. This is also similar to what @rob did in the underlying electorate model in his voting strategy simulation. (I do have an ulterior motive here. If the simulations start with the voters and distance functions to the alternatives, it becomes a lot easier to show exactly how an iterative voting system like SAVE would work, and how it would be significantly better than any non-iterative system. That argument is a lot easier with pictures.)
-
@tec said in Collaborative Coding for Simulation:
My preferred method (which generally requires computer simulation for any realistically sized electorate) is to represent voters as points in an issue space (usually 2D or higher), and use a distance function between the voters and the alternatives (also points in the issue space) to generate ordinal or cardinal ballots.
......
This is also similar to what @rob did in the underlying electorate model in his voting strategy simulationYes that is exactly what I do. The thing I do that isn't realistic at all, though, is that I simply spread the voters around with a random distribution, rather than having any clustering at all. That said, most of the clustering in US politics today is, in my opinion, caused by the voting system itself. Duverger's law and such. So I erred in the opposite direction, and assumed that it was spread evenly among the electorate. The orange/gray/blue dots below represent voters in "issue space" (or "ideological space"). The crosshair simply indicates the median value of X and Y.
I use 2 dimensions rather than more because it is easier to show on screen, as well as just being the right level of complexity to illustrate concepts to people (which I prioritized a bit higher than making it fully realistic). Both candidates and voters have an X and a Y value. When talking about it, I usually consider X to mean "left vs. right", both in a geometrical sense but also political. (so I can talk about "voters on the left" indicating liberals/democrats, at least in the US politics sense)
In addition to X and Y values, voters have another property which is "how strategic they are." This is shown in the color: orange is fully strategic, blue is fully sincere. I use this in a simplified, but not totally unrealistic way: those that are the most strategic vote as if they know for sure who the two front runners are, those who are most sincere vote as if they consider every single candidate equally likely to be elected. Those in the middle will vote as if some in-between number of candidates (say, 4) will be front-runners.
Meanwhile, candidates (large colored dots with a letter on them) have a property beyond their X Y position in issue space, and that is what I call "universal appeal." This can include things like their appearance, their speaking skills and debating skills, their intelligence, and so on. Basically, those things that are deemed good regardless of what a voter's position on issues are. So candidate B above has higher universal appeal than others, while candidate E has lower universal appeal. This is shown by size. (note that the video I shared earlier did not have this as I hadn't implemented it yet)
Notice that I have also added one more thing to the simulation, which is the "Raw" scoring in the output. (at right)
This is not calculated based on any vote, but just by determining the average "voter satisfaction" at their being elected. I consider this to be an indication of what is the best winner actually is. This only works because the app has the ability to essentially read the voter's minds --- for the actual voting methods, the app can only look at their ballots.It is expected that the raw scoring "method" will tend to give the candidate nearest the median (i.e. the crosshair) the highest score. More or less. And this assumes that all have the same universal appeal.
I haven't yet tried to do Condorcet methods, STAR or IRV, since strategy is so much more complicated for them.
(the app in its current form -- i.e. unfinished -- is at https://pianop.ly/voteSim/voteSim.html . To use it, first click "make voters", then click around to place candidates, then click "vote". You can delete candidates by clicking on them, you can adjust their universal appeal by mousing over them and using up and down arrow keys, or by using the "default UA" slider prior to placing them)
-
Codesandbox
If you have a github repo, you can automatically deploy to CodeSandbox.io to give a sandbox for your creations.
Here's an example I'm working on: https://codesandbox.io/s/github/paretoman/votekit
Embeds
Also, we might be able to embed examples here: https://codesandbox.io/docs/embedding
But that is something that would have to be specifically set up somehow on NodeBB, and I don't really know about that. For now, a link is good.
-
@rob, does this code represent voter affinities toward candidates?
-
@jack-waugh said in Collaborative Coding for Simulation:
@rob, does this code represent voter affinities toward candidates?
Are you speaking of Paretoman's code? I don't know what it represents, I ran it quickly but in the absence of a good explanation I don't know what it is supposed to be showing.
Personally I'd recommend a video demo if he cares to do one. OBS and YouTube are your friends.
-
@paretoman said in Collaborative Coding for Simulation:
Maybe _codesandbox_ is part of a good solution, but, to date, I haven't taken time to look into it, because I am already using [0] a hosting solution that provides full flexibility.
-
If anybody would feel inclined to make their tabulation API 'black boxed' so you can just hand me a .csv file and I will hand you a list of winners, I would be happy to implement a great number of voting methods, including some of the most complicated like Stable Voting or Meek-STV.
I do want to contribute, but I'm just much more comfortable iterating on local scripts in Julia or Python than I am with JS. Does JS have the ability to invoke command line scripts?
-
@andy-dienes JS can be run on the command line via node.js, which is quick to download and install and generally "just works". Of course it also allows you to run web servers and the like, but you can also just say "node myprogram.js" to run things from the command line on mac, windows and any flavor of linux.
I prefer things like Codepen, though, because it is so easily sharable. You can just point people to the Codepen url, and they can paste whatever data in they want. They can also fork it if they want to edit the code. I did a bunch of work to parse ballot formats that are easy to use in forums. (comma separated aren't terrible, but that seems a bit more optimized for the machine rather than for human eyes, and I prefer optimizing for humans)
See https://codepen.io/karmatics/pen/ExKZVjM for example. You can paste in data or use the default. (just click "tabulate" in the bottom right)
But yeah if you prefer work at the command line, but do it in javascript, I'd be glad to convert them to Codepens (or set up a simple template so you can do it yourself), so you can just refer people to a url rather than having them send you csv files, which doesn't lend itself to experimentation and such.