In our paper on defining IRV and STV for weak orders, we needed to sample random weak-order profiles. We did this using a "coin flip model" and a "radius model", see page 16.
The "coin-flip" method with parameter $p\in [0,1]$ works as follows: in an order $\succ$, for each pair of consecutively ranked candidates $a$ and $b$, we add a tie between them (and thus put them in the same indifference class) with probability $p$. For example, for the linear order $a \succ b \succ c \succ d$ we throw 3 independent coins, one for each occurrence of the $\succ$ symbol, and replace a strict preference by an indifference when the coin comes up heads (which happens with probability $p$). If the coins come up tails, heads, tails, the resulting weak order is ${a} \succ {b, c} \succ {d}$.
The "radius" method is specific to Euclidean models, in which voters $v$ and candidates $c$ are placed in random locations $p(v), p(c) \in \mathbb{R}^d$ in Euclidean space. The method is parameterized by a radius $r \ge 0$, which from the perspective of voter $v$ divides the candidates into sets $C_k = {(k-1)r \le |p(c)-p(v)| < kr}$. This produces the weak order $C_1 \succ C_2 \succ \dots$ for voter $v$.
This could be a useful addition to the prefsampling package.
Our code for the coin-flip strategy:
n_voters, n_candidates = len(orders), len(orders[0])
## Merge the candidates in orders:
weak_orders = []
for order in orders:
weak_order = [[order[0]]]
for i in range(1, n_candidates):
if np.random.rand() > p:
weak_order.append([order[i]])
else:
weak_order[-1].append(order[i])
weak_orders.append(weak_order)
return weak_orders
In our paper on defining IRV and STV for weak orders, we needed to sample random weak-order profiles. We did this using a "coin flip model" and a "radius model", see page 16.
This could be a useful addition to the
prefsamplingpackage.Our code for the coin-flip strategy: