Exploring Indian Democracy: Alternative Voting Systems and Their Math
Hi. Today is Makara Sankranti, its the first anniversary of my blog. Thanks a lot to all my readers for giving your time to read my articles.
Today’s blog explores India’s democracy and voting systems. It draws from notes I’ve written over time to deepen my understanding, insights from books I’ve read, and my observations of Bharat and her socioeconomic conditions. Additionally, it includes a mathematical model I wrote in python to simulate alternative voting systems.
The makers of constitution decided to do an ambitious experiment: “Democracy before development”. In 1947 when India got independence from Colonial oppression, her people had literacy rate of just 12%, another data from 1951 says it was 18% along with a very low per capita GDP[1]. Yet the constitution granted equal voting rights to all citizens, regardless of their education, socioeconomic condition, caste, religion or other factors.
In contrast, the United States initially restricted voting rights to white male landowners. Women in the U.S. gained the right to vote only in 1920, and the Voting Rights Act of 1965 finally outlawed racial discrimination in voting by which time the U.S. was already a developed nation.
Many skeptics predicted that India’s unique experiment on democracy might fail, but here we are, India has never experienced a military coup, and over the past 25 years, every elected government has successfully completed its five-year term - a rarity among South Asian democracies. This equal voting right is something we should be proud of, as it is empowering marginalized groups in society.
The current voting system
The current voting system First-Past-the-Post(FPP) favours the person who got most number of votes, without any minimum requirements. England and most of its ex-colonies have this electoral system. This “majority rules” style is essentially flawed considering democratic context. Democracy is for everyone, not just the majority or minority. In FPP the Government or the ruling party often represents the majority may be sometimes only a few particular groups and not all the people, while democracy should be fundamentally for all the people.
Flaws of current voting system
The first generation of politicians in India had a nation-building mission as most of them were freedom fighters. Even the current Prime Minister Shri Narendra Modi mentioned in his podcast with Nikhil Kamath that those politicians were more creative and were dedicated for India’s development [2]. However after 1970s, the new generation of politicians had a more election -winning mindset. This mindset shift has led to exploit India and her democracy, especially the voting system.
The current voting system can be exploited and has been getting exploited a lot. Rather than investing in broad-based development, politicians are trying to do just enough to please few particular groups often categorized by caste, region and religion [3]. They can win election by gaining their support as current system favours the person with more number of votes This ‘Vote bank politics’(clientelism) is by a large extent an effect of current FPP system. Caste and religion based appeasement politics is really common in India, literally many party-coalition reflect more towards groups they are targeting and less towards development and policies [4].
Mulayam Singh Yadav and Lalu Yadav’s MY+(Muslims, Yadavs, plus small groups) vote bank in the 1990s in Uttar Pradesh and Bihar respectively, Charan Singh’s AJGAR (Ahir, Jaat, Gurjar, Rajput) in the 1970s. Even today mainly in UP and Bihar these groups are called vote banks and political parties often try to please them while neglecting others. It is a pain for the broad-based development and a form of discrimination achieved by exploiting democratic system.
One more irony is sometimes FPP does not reflect Majority’s or a large group’s opinion. For example in 2020 Delhi Assembly elections BJP got 38.5% of the votes but won only 8 out of 70 seats. In fact in my home state, Odisha Assembly elections 2024 BJD got 40.22% vote share but ended up winning 51 seats out of total 147, while BJP with 40.07% vote share managed to win 78 seats[5].
But how can we solve it? Are there any other electoral systems? Well! yes there are.
Alternative electoral systems
Any electoral system is not 100% perfect. Veritasium has a really cool video on this[6]. But a very sophisticated electoral system is highly necessary for the democracy as it will be harder to manipulate. There are different types of alternate systems like, Borda Count(BC)/Modified Borda Count(MBC), Quota Borda System(QBS), Matrix vote etc. In this blog as of today I am discussing about Modified Borda count and its implementation in python. The material I used for reference is primarily “Designing an All-Inclusive Democracy, Peter Emerson” book[7].
Modified Borda Count (MBC)
Modified Borda Count is a variation of Borda Count(BC) electoral system is a point based voting system[8]. In MBC, the voters rank the candidates as their preference number. The candidate with the highest score is the winner. While there is a limit on how many preferences one can have, which is usually 6 and one can not assign same preference number to two different candidates.
Advantages of MBC over FPP
MBC allows voters to rank candidates, encouraging the election of candidates who have broader support across the electorate, minimizing polarization. MBC ensures that voters preferences are counted even if their top choice does not win, giving weight to second, third, or lower preferences and reduces vote wastage which is more democratic. It represents both Majority and minority’s opinion pressuring political entities to focus on overall development. Also it is suitable for India as it is a very diverse country.
Lets get into the simulation of MBC.
Scoring:
If there are n candidates and maximum number of preference is m then,
1st candidate will get m points,
2nd candidate will get m-1 points,
.
.
mth candidate will get m-(m-1) points,
others will get 0.
Normalization
Let’s say one can rank only 6 candidates but he/she decides to rank only 3 of them. Normally only 3 will get points and others will get 0, which is not so fair. To encounter this normalization is done.
If one has ranked 6 candidates the total points will be: 6+5+4+3+2+1 = 21 points But in case one ranks only 3 of them it needs to be normalized.
Normalization factor = (no of preferences a voter ranked / Maximum allowed preferences). Here Normalization factor will be 3/6 = 0.5
Without normalization the 3 candidates would have gotten 6, 5, 4 points respectively. But after normalization they’ll get (Normalization factor * Points without normalization).
Now normalized points for,
Rank 1 candidate: 0.5 * 6 = 3.0
Rank 2 candidate: 0.5 * 5 = 2.5
Rank 3 candidate: 0.5 * 4 = 2.0
Python implementation for simulation
You can skip the code part if you are not familiar with programming.
import matplotlib.pyplot as plt
# In modified borda count(MBC), the voters rank the candidates as their preference number
# The candidate with the highest score is the winner
# While there is a limit on how many preferences one can have, which is usually 6.
# One can not assign same preference number to two different candidates.
# Scoring
"""
If there are n candidates and maximum number of preference is m then
1st candidate will get m points
2nd candidate will get m-1 points
.
.
mth candidate will get m-(m-1) points
others will get 0
"""
## Normalization
"""
Let's say one can rank only 6 candidates but he/she decides to rank only 3 of them
Normally only 3 will get points and others will get 0, which is not so fair.
To encounter this normalization is done.
If one has ranked 6 candidates the total points will be: 6+5+4+3+2+1 = 21 points
But in case one ranks only 3 of them it needs to be normalized.
Normalization factor = no of pref one ranked / Max preferences
Here Normalization factor will be 3/6 = 0.5
Without normalization the 3 candidates would have gotten 6, 5, 4 points respectively.
But after normalization they'll get (Normalization factor * Points without normalization)
Now normalized points for,
Rank 1 candidate: 0.5 * 6 = 3
Rank 2 candidate: 0.5 * 5 = 2.5
Rank 3 candidate: 0.5 * 4 = 2.0
"""
# Let A, B, C, D, E, F, G, H, I, J are 10 candidates.
CANDIDATES = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']
MAX_PREFERENCES = 6
# initialize candidate scores
candidates = {candidate: 0 for candidate in CANDIDATES}
votes = [
{1: 'A', 2: 'B', 3: 'C', 4: 'D', 5: 'E', 6: 'F'},
{1: 'A', 2: 'D', 3: 'B', 4: 'I', 5: 'E', 6: 'G'},
{1: 'J', 2: 'A', 3: 'J', 4: 'G', 5: 'B', 6: 'I'},
{1: 'D', 2: 'C', 3: 'I'},
{1: 'B', 2: 'C', 3: 'I', 4: 'A', 5: 'B', 6: 'G'},
{1: 'B', 2: 'A', 3: 'F', 4: 'E', 5: 'D', 6: 'H'},
{1: 'J', 2: 'G', 3: 'I', 4: 'A'},
]
def validate_vote(vote):
"""
Validate that no candidate appears more than once in the same voter's ranking.
If there are duplicates, return False (invalid vote).
Otherwise, return True (valid vote).
"""
# if there are duplicates in the values(rankings), the vote is invalid.
seen = set()
for candidate in vote.values():
if candidate in seen:
return False # Duplicate candidate found
seen.add(candidate)
return True
def poll(votes, candidates):
for i in range(len(votes)):
vote = votes[i]
if any(candidate not in CANDIDATES for candidate in vote.values()):
print(f"Voter {i+1} voted for invalid candidates: {vote.values()}. Skipping...")
continue
if not validate_vote(vote):
print(f"Invalid vote detected from voter {i+1}: {vote}. Skipping...")
continue
pref_count = len(votes[i])
nf = pref_count / MAX_PREFERENCES # Normalization factor
if pref_count == 0:
print(f"Voter {i+1} submitted an empty vote. Skipping...")
continue
for j, candidate in sorted(vote.items()): # Access the dictionary values
if candidate in candidates:
candidates[candidate] += nf * (MAX_PREFERENCES - j + 1)
def score_count(candidates):
"""
Display the final scores
"""
sorted_candidates = sorted(candidates.items(), key=lambda x: x[1], reverse= True)
print("\nfinal scores: ")
for candidate, score in sorted_candidates:
print(f"{candidate}: {score: .2f}")
def plot(candidates):
x = list(candidates.keys())
y = list(candidates.values())
plt.bar(x, y)
plt.title('Poll statistics')
plt.xlabel('Candidate Name')
plt.ylabel('Score')
plt.show()
def main():
poll(votes, candidates)
score_count(candidates)
plot(candidates)
if __name__ == "__main__":
main()
Output:
Invalid vote detected from voter 3: {1: 'J', 2: 'A', 3: 'J', 4: 'G', 5: 'B', 6: 'I'}. Skipping...
final scores:
A: 22.00
B: 17.00
D: 13.00
I: 11.67
C: 11.50
F: 11.00
E: 7.00
G: 5.33
J: 4.00
H: 1.00
Disadvantages of Modified Borda Count
MBC is more complex to understand and implement compared to simpler voting methods. While modern computing makes implementation easier, explaining it to the general public can be quite challenging. Another issue is the influence of irrelevant alternatives, which can distort the outcome. The system can also fail to elect the Condorcet winner - a candidate who would win against every other candidate in head-to-head comparisons. Additionally, MBC is prone to the no-show paradox, where voters might achieve a better outcome by abstaining from voting altogether [9].
I have plans about writing about other electoral systems and I am still learning about them. I am open to any critique on this post, let me know your thoughts and arguments. By initiating open discussions, rational debates, leveraging Mathematics and computational methods, taking data-driven decisions democracy is only going to get stronger. The founders of our constitution will be proud of us if we will be able to achieve a feat on electoral reforms which will have direct impact on state-effectiveness.
I want to conclude this post with a quote from former Prime Minister Shri Atal Bihari Bajpayee’s legendary speech in Loksabha: “Satta ka toh khel chalega, sarkarein aayengi-jayengi, partiyaan banengi-bigdengi magar yeh desh rehna chahiye, is desh ka lok tantra amar rehna chahiye”. It translates to governments will come and go, parties will be created and destroyed but this Nation must endure, its democracy should remain eternally.
References:
[1]: PIB Archive: LITERACY IN INDIA: STEADY MARCH OVER THE YEARS
[2]: People with The Prime Minister Shri Narendra Modi x Nikhil Kamath | Episode 6 | By WTF
[3]: Accelerating India’s Development, Karthik Muralidharan
[4]: Caste in Indian Politics (1973), Rajni Kothari
[5]: First to the finish line: Electoral outcomes, Vipul Anekant, Decan Herald
[6]: Why Democracy Is Mathematically Impossible
I hope you liked this post. If you wanna say Hi or anything, here’s my Telegram @ashirbadtele or you can mail me at ashirbadreal@proton.me.