pbvoting / pabutools

A complete set of tools to work with participatory budgeting elections.
https://pbvoting.github.io/pabutools/
GNU General Public License v3.0
7 stars 12 forks source link

Weighted voters #28

Open oriyalperin opened 3 months ago

oriyalperin commented 3 months ago

Does the library support assigning weights to voters?

erelsgl commented 3 months ago

This could be useful, for example, for checking settings such as: a city has 100 voters; 60 support projects A1,...,A10 and 40 support projects B1,...,B10. We expect 60% of the budget to go to projects A1,...,A10.

In abcvoting, many algorithms allow a weight parameter. It is possible in pabutools?

Simon-Rey commented 3 months ago

Well for your example there is no need for weights Erel, you can just multiply the ballots.

For the general answer: every rule support both Profile and MultiProfile (see the docs) where the latter is a mapping from ballots to multiplicity of the ballots. I believe that putting non-integer values would not break anything but one would need to be check that.

Simon-Rey commented 3 months ago

https://pbvoting.github.io/pabutools/usage/profiles.html#multiprofile

oriyalperin commented 3 months ago

Thanks @Simon-Rey, I tried using float values similarly to the example here, but they aren't supported. According to the docs, the MultiProfile class inherits from the Python class Counter, so this makes sense to me. Is there another way to define MultiProfile that allows using non-integer values?

Simon-Rey commented 3 months ago

I am not sure what you tried, this works for me:

from pabutools.election import Project, ApprovalBallot, ApprovalProfile

projects = [Project("p" + str(i), cost=2) for i in range(10)]
b1 = ApprovalBallot(projects[:2])
b2 = ApprovalBallot(projects[:5])

f1 = b1.frozen()
f2 = b2.frozen()

profile = ApprovalProfile([b1] * 4 + [b2] * 10)

m = profile.as_multiprofile()

m[f1] = 0.75
m[f2] = 0.84

m.total()  # => 1.5899999999999999

The counter class does not force int.

Simon-Rey commented 3 months ago

In general though, it is pretty ugly and could be implemented in a better fashion. But at least since the support for multiprofile is there for almost everything, it should not be difficult to have weights as well. If someone wants to implement that, I'm happy to help :)