-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathvotefair_ranking.cpp
9274 lines (7778 loc) · 418 KB
/
votefair_ranking.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// VoteFairRanking.cpp or votefair_ranking.cpp
//
// This application calculates VoteFair Ranking
// results. Specifically it calculates:
//
// * VoteFair popularity ranking
//
// * VoteFair representation ranking
//
// * VoteFair party ranking
//
// It does not calculate VoteFair
// partial-proportional ranking because that
// requires additional information, and the
// method is simple enough to do using a
// spreadsheet.
//
// It does not calculate VoteFair Negotiation
// Ranking (for use among legislators in a
// legislature or parliament) because that method
// must be done interactively.
//
// For use when voters want a simple
// single-winner method that is better than RCIPE
// but not as good as VoteFair popularity
// ranking, this application also calculates:
//
// * Instant Pairwise Elimination (IPE)
//
//
// -----------------------------------------------
//
// COPYRIGHT & LICENSE
//
// (c) Copyright 1991 through 2022 by Richard
// Fobes at www.VoteFair.org. You can
// redistribute and/or modify this
// VoteFairRanking software under the MIT
// software license terms that appear below.
// (Also a copy of the license is included in the
// "license" file.)
//
// Conversion of this code into another
// programming language is also covered by the
// above license terms.
//
//
// -----------------------------------------------
//
// VERSION
//
// Version 6.00 - In 2019 Richard Fobes ported
// portions of the Perl library version (5.00)
// into this standalone C++ version.
// See the Perl-version history for earlier
// developments.
//
// Version 6.10 - In 2020 Richard Fobes added
// functions to calculate methods that eliminate
// one choice (candidate) at a time.
//
// Version 6.20 - In early 2021 Richard Fobes
// refactored the subroutines that calculate
// one-by-one elimination methods.
//
// Version 6.30 - In late May 2022 Richard Fobes
// removed the code that calculated IRV and
// RCIPE because those methods are now
// calcluated in program: rcipe_stv.cpp
// Also removed were calculations for methods
// that had been added for comparison purposes.
//
// Version 6.31 - In June 2022 removed a
// potential bug.
//
// -----------------------------------------------
//
// USAGE
//
// This file (currently named
// votefair_ranking.cpp or VoteFairRanking.cpp)
// does the calculations for VoteFair Ranking.
// VoteFair Ranking is described at
// www.VoteFair.org and in the book "Ending The
// Hidden Unfairness In U.S. Elections" by
// Richard Fobes. The components of VoteFair
// Ranking that are implemented here are briefly
// described below in the ABOUT section.
//
// The following sample code compiles and
// executes this software under a typical Windows
// environment with the g++ compiler and the
// mingw32 library already installed.
//
// path=C:\Program Files (x86)\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\bin\
//
// g++ votefair_ranking.cpp -o votefair_ranking
//
// .\votefair_ranking < input_votefair_ranking_case_123.txt > output_votefair_ranking_case_123.txt
//
// This usage assumes that file
// input_votefair_ranking_case_123.txt contains
// appropriately formatted election/survey/poll
// data for case numbered 123, and it writes the
// coded results to file
// output_votefair_ranking_case_123.txt.
//
// Typically the input file is generated by other
// software, and typically the output file is
// used as input to other software. An example
// of such software is the "VoteFair-polls" code
// on GitHub (in the CPSolver repository).
//
// The mathematical algorithms of VoteFair
// Ranking are in the public domain.
//
//
// -----------------------------------------------
//
// ABOUT
//
// This software calculates VoteFair Ranking results. The portions
// of VoteFair Ranking implemented here are:
//
// * VoteFair popularity ranking. This voting method calculates the
// full popularity ranking of all candidates (or choices in the case
// of a survey) from most popular and second-most popular down to
// least popular. It uses the preference information collected on
// 1-2-3 ballots or ranked ballots (or any equivalent way of
// expressing "ranked" preferences). When a single position
// is being filled, the most popular candidate is declared the winner.
// This calculation method is mathematically equivalent to the
// Condorcet-Kemeny election method. See below about very rare cases
// when this software can yield results that do not match VoteFair
// popularity ranking.
//
// * VoteFair representation ranking. This voting method is used to
// elect a second candidate who represents the voters who are not
// well-represented by the most-popular candidate, or to fill
// multiple board-of-director positions, or to choose a second
// simultaneous activity in addition to the most popular activity.
// This method reduces the influence of the voters who are already
// well-represented by the most popular candidate (or choice), and
// it does so in a way that protects against strategic voting. If
// instead the second-most popular candidate as identified by
// VoteFair popularity ranking were chosen, the same voters who
// prefer the first winner also can determine the second winner, and
// this can leave large numbers of other voters unrepresented.
// Additional levels of representation ranking can be used to fill
// additional seats, although VoteFair partial-proportional ranking
// should be used instead if "proportional representation" of
// political parties is needed, especially for the purpose of
// defeating attempts to gerrymander district boundaries.
// This ranking provides "proportional representation." It ignores
// political-party associations, yet when used in a governmental
// election the winners are typically from different political
// parties (unless just one party offers great candidates and the
// other parties offer bad candidates).
//
// * VoteFair party ranking. This voting method ranks political
// parties according to a different kind of "popularity". The
// results can be used in high-stakes elections to limit the number
// of candidates allowed by each party. In such cases the two or
// three political parties that are ranked highest can be limited to
// offering just two candidates from each party, and lower-ranked
// parties can be allowed to offer one candidate each, and any
// additional parties can be prohibited from offering any candidate
// (because those parties are too unpopular and too
// unrepresentative). Such limits have not been needed in the past
// because the fear of vote splitting has limited each political
// party to offering just one candidate in each contest.
//
// Note that VoteFair partial-proportional ranking is not calculated
// by this software because it requires knowing the results of many
// elections, and because those results can be calculated using a
// simple spreadsheet.
//
// For detailed descriptions of VoteFair Ranking, see
// www.VoteFair.org or the book "Ending The Hidden Unfairness In
// U.S. Elections" by Richard Fobes.
//
// In addition to being useful for elections, VoteFair Ranking also
// is useful for calculating results for surveys and polls, ranking
// the popularity of songs and movies, and much more.
//
// In mathematical terms, VoteFair Ranking is useful for doing
// "combinatorial optimization" and may be useful for solving the
// "linear ordering problem". See Wikipedia for details about these
// terms.
//
// VoteFair popularity ranking calculations are mathematically
// equivalent to the Condorcet-Kemeny vote-counting method.
//
// Clarification: For reasons of computation time, there are some
// very rare cases for which this software can produce results that
// differ from full VoteFair popularity ranking results.
// These exceptions involve more choices (candidates) than the
// value of the constant named "global_check_all_scores_choice_limit",
// which currently has a default value of 6.
// In those rare cases, the software estimates which top (6) choices
// are the most popular, and then does the full VoteFair popularity
// ranking to determine which of those top choices is most popular.
// The rare cases in which the estimation method produces different
// results involve one or more rock-paper-scissors-like cycles
// that include the top choices, which is a rare combination.
// As an analogy, those cases are like finding the highest
// sand dune in a desert, whereas most cases are like finding
// the highest mountain peak in a mountain range.
// As the number of ballots increases (such as beyond 50 ballots),
// the likelihood of such cycles greatly decreases.
// If this difference is important, the value of the constant
// "global_check_all_scores_choice_limit" can be increased, but
// that change will dramatically increase calculation time,
// to the point of requiring years of computation time for values
// even as small as 20. Therefore, values larger than 12 are not
// recommended.
//
// Additional details about the calculations appear within comments
// within some of the function code below.
//
//
// -----------------------------------------------
//
// LICENSE
//
// This VoteFairRanking software is licensed
// under the following MIT License terms.
//
// MIT License for VoteFairRanking.cpp (or votefair_ranking.cpp)
//
// Copyright (c) 2019 through 2022 by Richard Fobes at VoteFair.org
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
//
// -----------------------------------------------
//
// IMPORTANT NOTE TO CODERS!
//
// If you offer improvements to this code,
// please use conventions that are easy to
// convert into other programming languages.
//
// Also, resist the temptation to add the
// handling of choice names and any other
// text that appears on ballots. The
// absense of that text makes it obvious
// that this code is completely unbiased --
// because the questions and choices are
// identified by simple numbers, which
// cannot be associated with specific
// political positions.
//
//
// -----------------------------------------------
// -----------------------------------------------
// Begin code.
// -----------------------------------------------
// -----------------------------------------------
// Specify libraries needed.
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <map>
#include <algorithm>
#include <cstdio>
#include <vector>
// -----------------------------------------------
// Declare constants, specifically the true and
// false values. These are used instead of
// language-specific codes because different
// programming languages use different
// conventions for their true/false logic, and
// this approach allows for easier conversion
// between programming languages).
const int global_true = 1 ;
const int global_false = 0 ;
// -----------------------------------------------
// Declare global variables.
const int global_maximum_vote_info_list_length = 200000 ;
const int global_maximum_question_number = 20 ;
const int global_maximum_choice_number = 100 ;
const int global_maximum_twice_highest_possible_score = 999999 ;
const int global_maximum_output_results_length = 2000 ;
const int global_default_representation_levels_requested = 6 ;
const int global_limit_on_representation_rank_levels = 6 ;
// Declare a list that stores the number of
// choices for each question.
int global_choice_count_for_question[ 21 ] ;
// Declare a variable for how many choices
// can be handled for each question,
// and declare lists that have that length.
int global_plurality_count_for_actual_choice[ 101 ] ;
int global_popularity_ranking_for_actual_choice[ 101 ] ;
int global_full_popularity_ranking_for_actual_choice[ 101 ] ;
int global_representation_ranking_for_actual_choice[ 101 ] ;
int global_full_representation_ranking_for_actual_choice[ 101 ] ;
int global_party_ranking_for_actual_choice[ 101 ] ;
int global_adjusted_choice_for_actual_choice[ 101 ] ;
int global_actual_choice_for_adjusted_choice[ 101 ] ;
int global_using_choice[ 101 ] ;
int global_ballot_preference_for_choice[ 101 ] ;
int global_adjusted_ranking_for_adjusted_choice_bottom_up_version[ 101 ] ;
int global_adjusted_ranking_for_adjusted_choice_top_down_version[ 101 ] ;
int global_pair_counter_offset_for_first_adjusted_choice[ 101 ] ;
int global_log_info_choice_at_position[ 101 ] ;
int global_rank_to_normalize_for_adjusted_choice[ 101 ] ;
int global_normalized_ranking_level_for_adjusted_choice[ 101 ] ;
int global_choice_score_popularity_rank_for_actual_choice[ 101 ] ;
int global_insertion_sort_popularity_rank_for_actual_choice[ 101 ] ;
int global_sortable_sequence_used_during_normalization [ 101 ] ;
int global_tally_uses_of_choice_number[ 101 ] ;
int global_actual_choice_at_popularity_list_sequence_position[ 101 ] ;
// Declare input-related and output-related lists.
// Allow extra space for codes at end.
int global_vote_info_list[ 200005 ] ;
int global_output_results[ 2005 ] ;
// Declare pairwise lists.
int global_adjusted_first_choice_number_in_pair[ 2001 ] ;
int global_adjusted_second_choice_number_in_pair[ 2001 ] ;
int global_tally_first_over_second_in_pair[ 2001 ] ;
int global_tally_second_over_first_in_pair[ 2001 ] ;
int global_tally_first_equal_second_in_pair[ 2001 ] ;
// Input and output codes that identify
// the meaning of the next number in the (coded) list.
// These are NOT in the same order as the negative-number codes.
// Also specify text words that can be used in the input
// file, or can be requested to be used in the output file.
const int global_voteinfo_code_for_start_of_all_cases = -1 ;
const int global_voteinfo_code_for_end_of_all_cases = -2 ;
const int global_voteinfo_code_for_case_number = -3 ;
const int global_voteinfo_code_for_question_number = -4 ;
const int global_voteinfo_code_for_total_ballot_count = -5 ;
const int global_voteinfo_code_for_number_of_choices = -6 ;
const int global_voteinfo_code_for_start_of_all_vote_info = -7 ;
const int global_voteinfo_code_for_end_of_all_vote_info = -8 ;
const int global_voteinfo_code_for_start_of_ballot = -9 ;
const int global_voteinfo_code_for_end_of_ballot = -10 ;
// The following ballot count indicates how many ballots have the same ranking.
const int global_voteinfo_code_for_ballot_count = -11 ;
const int global_voteinfo_code_for_preference_level = -12 ;
const int global_voteinfo_code_for_choice = -13 ;
const int global_voteinfo_code_for_tie = -14 ;
const int global_voteinfo_code_for_start_of_votefair_popularity_ranking_sequence_results = -15 ;
const int global_voteinfo_code_for_end_of_votefair_popularity_ranking_sequence_results = -16 ;
const int global_voteinfo_code_for_start_of_votefair_popularity_ranking_levels_results = -17 ;
const int global_voteinfo_code_for_end_of_votefair_popularity_ranking_levels_results = -18 ;
const int global_voteinfo_code_for_start_of_votefair_representation_ranking_sequence_results = -19 ;
const int global_voteinfo_code_for_end_of_votefair_representation_ranking_sequence_results = -20 ;
const int global_voteinfo_code_for_start_of_votefair_representation_ranking_levels_results = -21 ;
const int global_voteinfo_code_for_end_of_votefair_representation_ranking_levels_results = -22 ;
const int global_voteinfo_code_for_start_of_votefair_party_ranking_sequence_results = -23 ;
const int global_voteinfo_code_for_end_of_votefair_party_ranking_sequence_results = -24 ;
const int global_voteinfo_code_for_start_of_votefair_party_ranking_levels_results = -25 ;
const int global_voteinfo_code_for_end_of_votefair_party_ranking_levels_results = -26 ;
const int global_voteinfo_code_for_ranking_level = -27 ;
const int global_voteinfo_code_for_next_ranking_level = -28 ;
const int global_voteinfo_code_for_early_end_of_ranking = -29 ;
const int global_voteinfo_code_for_start_of_tally_table_results = -30 ;
const int global_voteinfo_code_for_end_of_tally_table_results = -31 ;
const int global_voteinfo_code_for_first_choice = -32 ;
const int global_voteinfo_code_for_second_choice = -33 ;
const int global_voteinfo_code_for_tally_first_over_second = -34 ;
const int global_voteinfo_code_for_tally_second_over_first = -35 ;
const int global_voteinfo_code_for_start_of_plurality_results = -36 ;
const int global_voteinfo_code_for_end_of_plurality_results = -37 ;
const int global_voteinfo_code_for_plurality_count = -38 ;
const int global_voteinfo_code_for_skip_case = -39 ;
const int global_voteinfo_code_for_skip_question = -40 ;
const int global_voteinfo_code_for_request_votefair_representation_rank = -41 ;
const int global_voteinfo_code_for_request_no_votefair_representation_rank = -42 ;
const int global_voteinfo_code_for_request_votefair_party_rank = -43 ;
const int global_voteinfo_code_for_request_no_votefair_party_rank = -44 ;
const int global_voteinfo_code_for_request_only_plurality_results = -45 ;
const int global_voteinfo_code_for_request_pairwise_counts = -46 ;
const int global_voteinfo_code_for_request_no_pairwise_counts = -47 ;
const int global_voteinfo_code_for_number_of_representation_levels_to_compute = -48 ;
const int global_voteinfo_code_for_request_text_output = -49 ;
const int global_voteinfo_code_for_request_instant_runoff_voting = -50 ;
const int global_voteinfo_code_for_request_instant_pairwise_elimination = -51 ;
const int global_voteinfo_code_for_request_rcipe_voting = -52 ;
const int global_voteinfo_code_for_winner_instant_runoff_voting = -53 ;
const int global_voteinfo_code_for_winner_instant_pairwise_elimination = -54 ;
const int global_voteinfo_code_for_winner_rcipe_voting = -55 ;
const int global_voteinfo_code_for_request_star_voting = -56 ;
const int global_voteinfo_code_for_winner_star_voting = -57 ;
const int global_voteinfo_code_for_request_pairwise_loser_elimination = -58 ;
const int global_voteinfo_code_for_winner_pairwise_loser_elimination = -59 ;
const int global_voteinfo_code_for_winner_irv_bottom_two_runoff = -60 ;
const int global_voteinfo_code_for_winner_borda_count = -61 ;
const int global_voteinfo_code_for_flag_as_interesting = -62 ;
const int global_voteinfo_code_for_winner_approval_voting = -63 ;
const int global_voteinfo_code_for_winner_condorcet = -64 ;
const int global_voteinfo_code_for_request_logging_off = -65 ;
const int global_voteinfo_code_for_winner_pairwise_support_count = -66 ;
const int global_voteinfo_code_for_number_of_equivalent_seats = -67 ;
const int global_voteinfo_code_for_request_quota_droop_not_hare = -68 ;
const int global_voteinfo_code_for_winner_next_seat = -69 ;
const int global_voteinfo_code_for_begin_tied_for_next_seat = -70 ;
const int global_voteinfo_code_for_end_tied_for_next_seat = -71 ;
const int global_voteinfo_code_for_counting_cycle_number = -72 ;
const int global_voteinfo_code_for_pairwise_losing_candidate = -73 ;
const int global_voteinfo_code_for_eliminated_candidate = -74 ;
const int global_voteinfo_code_for_quota_count_this_cycle = -75 ;
const int global_voteinfo_code_for_candidate_and_transfer_count = -76 ;
const int global_voteinfo_code_for_candidate_to_ignore = -77 ;
const int global_voteinfo_code_for_request_ignore_shared_rankings = -78 ;
const int global_voteinfo_code_for_invalid_input_word = -200 ;
std::map< std::string , int > global_voteinfo_code_for_alias_word ;
std::string global_text_for_voteinfo_code[ 400 ] ;
// Declare the case number (variable).
// It is received from the input file and copied
// to the output file to allow verifying a match
// between the ballots and the results.
int global_case_number ;
// Declare the variables used to specify the
// current relevant question number and choice
// number.
int global_question_number ;
int global_choice_number ;
// Specify an extra output file that contains a log
// of actions for the purpose of monitoring or
// debugging intermediate calculations.
std::ofstream log_out ;
// Declare message strings.
std::string global_possible_error_message ;
std::string global_pairwise_matrix_text ;
std::string global_supplied_vote_info_text ;
std::string global_warning_end ;
// Input/output-related pointers and variables.
int global_input_pointer_start_next_case ;
int global_pointer_to_current_ballot ;
int global_length_of_vote_info_list ;
int global_pointer_to_output_results ;
int global_length_of_result_info_list ;
// Declare flags that indicate which results are to be calculated,
// and what other choices to make.
int global_true_or_false_request_votefair_popularity_rank ;
int global_true_or_false_always_request_votefair_popularity_rank ;
int global_true_or_false_request_only_plurality_results ;
int global_true_or_false_always_request_only_plurality_results ;
int global_true_or_false_request_no_pairwise_counts ;
int global_true_or_false_always_request_no_pairwise_counts ;
int global_true_or_false_request_votefair_representation_rank ;
int global_true_or_false_always_request_votefair_representation_rank ;
int global_true_or_false_request_votefair_party_rank ;
int global_true_or_false_always_request_votefair_party_rank ;
int global_number_of_representation_levels_to_compute ;
int global_true_or_false_request_text_output ;
// Declare miscellaneous variables.
int global_logging_info ;
int global_number_of_questions ;
int global_adjusted_choice_number ;
int global_adjusted_choice_count ;
int global_full_choice_count ;
int global_choice_count_at_top_popularity_ranking_level ;
int global_choice_count_at_full_top_popularity_ranking_level ;
int global_choice_count_at_full_second_representation_level ;
int global_ballot_info_repeat_count ;
int global_current_total_vote_count ;
int global_ballot_influence_amount ;
int global_pair_counter_maximum ;
int global_true_or_false_tally_table_created ;
int global_check_all_scores_choice_limit ;
int global_representation_levels_requested ;
int global_second_most_representative_actual_choice ;
int global_actual_choice_at_top_of_full_popularity_ranking ;
int global_actual_choice_at_second_representation_ranking ;
int global_count_of_popularity_rankings ;
int global_actual_choice_at_top_popularity_ranking_level ;
int global_true_or_false_always_request_dashrep_phrases_in_output ;
int global_code_associations_filename ;
int global_comparison_count ;
int global_sequence_score ;
int global_not_same_count ;
int global_sequence_score_using_choice_score_method ;
int global_sequence_score_using_insertion_sort_method ;
int global_sequence_score_using_all_scores_method ;
int global_top_choice_according_to_choice_specific_scores ;
int global_count_of_continuing_choices ;
int global_count_of_choices_at_pairwise_max_opposition_or_min_support ;
int global_count_of_choices_with_smallest_first_choice_count ;
float global_scale_for_logged_pairwise_counts ;
std::string global_ranking_type_being_calculated ;
// -----------------------------------------------
// Declare variables, constants, and arrays for
// counting methods that eliminate one choice
// during each elimination round. Currently only
// Instant Pairwise Elimination (IPE) is calculated
// this way.
//
// For speed reasons, arrays are declared here,
// even if a single function uses them.
// These variables and lists use actual choice
// numbers, not adjusted choice numbers.
int global_elimination_result_type ;
int global_choice_to_eliminate ;
int global_true_or_false_request_instant_pairwise_elimination ;
int global_true_or_false_find_largest_not_smallest ;
int global_true_or_false_find_pairwise_opposition_not_support ;
int global_integer_count_for_choice[ 101 ] ;
int global_list_of_choices_with_largest_or_smallest_count[ 101 ] ;
int global_list_of_choices_with_smallest_pairwise_support_count[ 101 ] ;
int global_list_of_choices_with_largest_pairwise_opposition_count[ 101 ] ;
int global_list_of_choices_with_smallest_single_pairwise_count[ 101 ] ;
int global_true_or_false_continuing_for_choice[ 101 ] ;
int global_true_or_false_continuing_subset_includes_choice[ 101 ] ;
int global_pairwise_opposition_or_support_count_for_choice[ 101 ] ;
int global_list_of_choices_having_pairwise_opposition_or_support[ 101 ] ;
int global_loss_count_for_choice[ 101 ] ;
int global_win_count_for_choice[ 101 ] ;
// -----------------------------------------------
// convert_integer_to_text
//
// This function is used instead of "std::to_string"
// for compatibility with older C++ "string" libraries
// that have a bug. The bug is that the "to_string"
// function is not recognized as being within the
// "std" library, even though it is defined there.
std::string convert_integer_to_text( int supplied_integer )
{
int unused_string_length ;
char c_format_string[ 50 ] ;
try
{
unused_string_length = sprintf( c_format_string , "%1d" , supplied_integer ) ;
return ( std::string ) c_format_string ;
}
catch( ... )
{
return "NAN" ;
}
}
// -----------------------------------------------
// convert_float_to_text
//
// To read why this function is here, see the comment
// above for function: convert_integer_to_text
std::string convert_float_to_text( float supplied_float )
{
std::string returned_string ;
char c_format_string[ 50 ] ;
int unused_string_length ;
try
{
unused_string_length = sprintf( c_format_string , "%1f" , supplied_float ) ;
returned_string = ( std::string ) c_format_string ;
// next line assumes the sprintf result always includes a decimal point
returned_string.erase( returned_string.find_last_not_of( "0" ) + 1 , std::string::npos ) ;
returned_string.erase( returned_string.find_last_not_of( "." ) + 1 , std::string::npos ) ;
return returned_string ;
}
catch( ... )
{
return "NAN" ;
}
}
// -----------------------------------------------
// convert_text_to_integer
//
// To read why this function is here, see the comment
// above for function: convert_integer_to_text
int convert_text_to_integer( char * supplied_text )
{
int equivalent_integer ;
try
{
equivalent_integer = atoi( supplied_text ) ;
}
catch( ... )
{
equivalent_integer = -999 ;
}
return equivalent_integer ;
}
// -----------------------------------------------
// do_initialization
void do_initialization( )
{
int pointer ;
int question_number ;
int choice_number ;
// -----------------------------------------------
// Initialize lists to zeros.
for ( pointer = 0 ; pointer <= 2001 ; pointer ++ )
{
global_vote_info_list[ pointer ] = 0 ;
global_output_results[ pointer ] = 0 ;
}
global_log_info_choice_at_position[ 0 ] = 0 ;
for ( question_number = 0 ; question_number <= global_maximum_question_number ; question_number ++ )
{
global_choice_count_for_question[ question_number ] = 0 ;
}
for ( choice_number = 0 ; choice_number <= global_maximum_choice_number ; choice_number ++ )
{
global_plurality_count_for_actual_choice[ choice_number ] = 0 ;
global_popularity_ranking_for_actual_choice[ choice_number ] = 0 ;
global_full_popularity_ranking_for_actual_choice[ choice_number ] = 0 ;
global_representation_ranking_for_actual_choice[ choice_number ] = 0 ;
global_full_representation_ranking_for_actual_choice[ choice_number ] = 0 ;
global_party_ranking_for_actual_choice[ choice_number ] = 0 ;
global_adjusted_choice_for_actual_choice[ choice_number ] = 0 ;
global_actual_choice_for_adjusted_choice[ choice_number ] = 0 ;
global_using_choice[ choice_number ] = 0 ;
global_ballot_preference_for_choice[ choice_number ] = 0 ;
global_adjusted_ranking_for_adjusted_choice_bottom_up_version[ choice_number ] = 0 ;
global_adjusted_ranking_for_adjusted_choice_top_down_version[ choice_number ] = 0 ;
global_pair_counter_offset_for_first_adjusted_choice[ choice_number ] = 0 ;
global_log_info_choice_at_position[ choice_number ] = 0 ;
global_rank_to_normalize_for_adjusted_choice[ choice_number ] = 0 ;
global_choice_score_popularity_rank_for_actual_choice[ choice_number ] = 0 ;
global_insertion_sort_popularity_rank_for_actual_choice[ choice_number ] = 0 ;
}
for ( pointer = 0 ; pointer <= 200 ; pointer ++ )
{
global_output_results[ pointer ] = 0 ;
global_tally_first_over_second_in_pair[ pointer ] = 0 ;
global_tally_second_over_first_in_pair[ pointer ] = 0 ;
global_tally_first_equal_second_in_pair[ pointer ] = 0 ;
global_adjusted_first_choice_number_in_pair[ pointer ] = 0 ;
global_adjusted_second_choice_number_in_pair[ pointer ] = 0 ;
}
// -----------------------------------------------
// Reset logging flag.
global_logging_info = global_true ;
// -----------------------------------------------
// Associate text "words" with the code numbers,
// which are negative numbers.
global_voteinfo_code_for_alias_word[ "startallcases" ] = -1 ;
global_voteinfo_code_for_alias_word[ "endallcases" ] = -2 ;
global_voteinfo_code_for_alias_word[ "case" ] = -3 ;
global_voteinfo_code_for_alias_word[ "q" ] = -4 ;
global_voteinfo_code_for_alias_word[ "votes" ] = -5 ;
global_voteinfo_code_for_alias_word[ "choices" ] = -6 ;
global_voteinfo_code_for_alias_word[ "startcase" ] = -7 ;
global_voteinfo_code_for_alias_word[ "endcase" ] = -8 ;
global_voteinfo_code_for_alias_word[ "bal" ] = -9 ;
global_voteinfo_code_for_alias_word[ "b" ] = -10 ;
global_voteinfo_code_for_alias_word[ "x" ] = -11 ;
global_voteinfo_code_for_alias_word[ "pref" ] = -12 ;
global_voteinfo_code_for_alias_word[ "ch" ] = -13 ;
global_voteinfo_code_for_alias_word[ "tie" ] = -14 ;
global_voteinfo_code_for_alias_word[ "popularity-sequence" ] = -15 ;
global_voteinfo_code_for_alias_word[ "end-pop-seq" ] = -16 ;
global_voteinfo_code_for_alias_word[ "popularity-levels" ] = -17 ;
global_voteinfo_code_for_alias_word[ "end-pop-levels" ] = -18 ;
global_voteinfo_code_for_alias_word[ "rep-seq" ] = -19 ;
global_voteinfo_code_for_alias_word[ "end-rep-seq" ] = -20 ;
global_voteinfo_code_for_alias_word[ "rep-levels" ] = -21 ;
global_voteinfo_code_for_alias_word[ "end-rep-levels" ] = -22 ;
global_voteinfo_code_for_alias_word[ "party-seq" ] = -23 ;
global_voteinfo_code_for_alias_word[ "end-party-seq" ] = -24 ;
global_voteinfo_code_for_alias_word[ "party-levels" ] = -25 ;
global_voteinfo_code_for_alias_word[ "end-party-levels" ] = -26 ;
global_voteinfo_code_for_alias_word[ "level" ] = -27 ;
global_voteinfo_code_for_alias_word[ "next-level" ] = -28 ;
global_voteinfo_code_for_alias_word[ "end-seq-early" ] = -29 ;
global_voteinfo_code_for_alias_word[ "tallies" ] = -30 ;
global_voteinfo_code_for_alias_word[ "end-tallies" ] = -31 ;
global_voteinfo_code_for_alias_word[ "ch1" ] = -32 ;
global_voteinfo_code_for_alias_word[ "ch2" ] = -33 ;
global_voteinfo_code_for_alias_word[ "1over2" ] = -34 ;
global_voteinfo_code_for_alias_word[ "2over1" ] = -35 ;
global_voteinfo_code_for_alias_word[ "plurality" ] = -36 ;
global_voteinfo_code_for_alias_word[ "end-plurality" ] = -37 ;
global_voteinfo_code_for_alias_word[ "plur" ] = -38 ;
global_voteinfo_code_for_alias_word[ "case-skipped" ] = -39 ;
global_voteinfo_code_for_alias_word[ "question-skipped" ] = -40 ;
global_voteinfo_code_for_alias_word[ "request-rep" ] = -41 ;
global_voteinfo_code_for_alias_word[ "request-no-rep" ] = -42 ;
global_voteinfo_code_for_alias_word[ "request-party" ] = -43 ;
global_voteinfo_code_for_alias_word[ "request-no-party" ] = -44 ;
global_voteinfo_code_for_alias_word[ "request-plurality-only" ] = -45 ;
global_voteinfo_code_for_alias_word[ "request-pairwise-counts" ] = -46 ;
global_voteinfo_code_for_alias_word[ "request-no-pairwise-counts" ] = -47 ;
global_voteinfo_code_for_alias_word[ "number-rep-levels-to-compute" ] = -48 ;
global_voteinfo_code_for_alias_word[ "request-text-output" ] = -49 ;
global_voteinfo_code_for_alias_word[ "request-instant-runoff-voting" ] = -50 ;
global_voteinfo_code_for_alias_word[ "request-instant-pairwise-elimination" ] = -51 ;
global_voteinfo_code_for_alias_word[ "request-rcipe-voting" ] = -52 ;
global_voteinfo_code_for_alias_word[ "winner-instant-runoff-voting" ] = -53 ;
global_voteinfo_code_for_alias_word[ "winner-instant-pairwise-elimination" ] = -54 ;
global_voteinfo_code_for_alias_word[ "winner-rcipe-voting" ] = -55 ;
global_voteinfo_code_for_alias_word[ "request-star-voting" ] = -56 ;
global_voteinfo_code_for_alias_word[ "winner-star-voting" ] = -57 ;
global_voteinfo_code_for_alias_word[ "request-pairwise-loser-elimination" ] = -58 ;
global_voteinfo_code_for_alias_word[ "winner-pairwise-loser-elimination" ] = -59 ;
global_voteinfo_code_for_alias_word[ "winner-irv-bottom-two-runoff" ] = -60 ;
global_voteinfo_code_for_alias_word[ "winner-borda-count" ] = -61 ;
global_voteinfo_code_for_alias_word[ "flag-as-interesting" ] = -62 ;
global_voteinfo_code_for_alias_word[ "winner-approval-voting" ] = -63 ;
global_voteinfo_code_for_alias_word[ "winner-condorcet" ] = -64 ;
global_voteinfo_code_for_alias_word[ "request-logging-off" ] = -65 ;
global_voteinfo_code_for_alias_word[ "winner-pairwise-support-count" ] = -66 ;
global_voteinfo_code_for_alias_word[ "number-of-equivalent-seats" ] = -67 ;
global_voteinfo_code_for_alias_word[ "request-quota-droop-not-hare" ] = -68 ;
global_voteinfo_code_for_alias_word[ "winner-next-seat" ] = -69 ;
global_voteinfo_code_for_alias_word[ "begin-tied-for-next-seat" ] = -70 ;
global_voteinfo_code_for_alias_word[ "end-tied-for-next-seat" ] = -71 ;
global_voteinfo_code_for_alias_word[ "counting-cycle-number" ] = -72 ;
global_voteinfo_code_for_alias_word[ "pairwise-losing-candidate" ] = -73 ;
global_voteinfo_code_for_alias_word[ "eliminated-candidate" ] = -74 ;
global_voteinfo_code_for_alias_word[ "quota-count-this-cycle" ] = -75 ;
global_voteinfo_code_for_alias_word[ "candidate-and-transfer-count" ] = -76 ;
global_voteinfo_code_for_alias_word[ "candidate-to-ignore" ] = -77 ;
global_voteinfo_code_for_alias_word[ "invalid-input-word" ] = -200 ;
// -----------------------------------------------
// Open the extra output files.
log_out.open ( "output_votefair_ranking_log.txt" , std::ios::out ) ;
// -----------------------------------------------
// Define constants.
std::string global_warning_end = "\n-----\n\n" ;
// -----------------------------------------------
// Request that the output file use negative
// code numbers in the output.
// If text codes are preferred, either insert
// the code "request_text_output" in the input file,
// or maybe set this value to global_true.
global_true_or_false_request_text_output = global_false ;
// -----------------------------------------------
// Initialize the "always" versions of the
// requests for specified results.
global_true_or_false_always_request_votefair_popularity_rank = global_true ;
global_true_or_false_always_request_only_plurality_results = global_false ;
global_true_or_false_always_request_no_pairwise_counts = global_false ;
global_true_or_false_always_request_votefair_representation_rank = global_false ;
global_true_or_false_always_request_votefair_party_rank = global_false ;
global_true_or_false_always_request_dashrep_phrases_in_output = global_false ;
global_true_or_false_request_votefair_popularity_rank = global_true_or_false_always_request_votefair_popularity_rank ;
global_true_or_false_request_only_plurality_results = global_true_or_false_always_request_only_plurality_results ;
global_true_or_false_request_no_pairwise_counts = global_true_or_false_always_request_no_pairwise_counts ;
global_true_or_false_request_votefair_representation_rank = global_true_or_false_always_request_votefair_representation_rank ;
global_true_or_false_request_votefair_party_rank = global_true_or_false_always_request_votefair_party_rank ;
// -----------------------------------------------
// Initialize zero and empty values.
global_length_of_vote_info_list = 0 ;
global_input_pointer_start_next_case = 0 ;
global_pointer_to_output_results = 0 ;
global_case_number = 0 ;
global_question_number = 0 ;
global_number_of_questions = 0 ;
global_choice_number = 0 ;
global_ballot_info_repeat_count = 0 ;
global_current_total_vote_count = 0 ;
global_pointer_to_current_ballot = 0 ;
global_length_of_result_info_list = 0 ;
global_ballot_influence_amount = 0 ;
global_adjusted_choice_number = 0 ;
global_adjusted_choice_count = 0 ;
global_full_choice_count = 0 ;
global_pair_counter_maximum = 0 ;
global_choice_count_at_top_popularity_ranking_level = 0 ;
global_choice_count_at_full_top_popularity_ranking_level = 0 ;
global_choice_count_at_full_second_representation_level = 0 ;
global_representation_levels_requested = 0 ;
global_second_most_representative_actual_choice = 0 ;
global_actual_choice_at_top_of_full_popularity_ranking = 0 ;
global_actual_choice_at_second_representation_ranking = 0 ;
global_elimination_result_type = 0 ;
global_possible_error_message = "" ;
global_ranking_type_being_calculated = "" ;
global_pairwise_matrix_text = "" ;
// -----------------------------------------------
// Initialize false values for requesting the
// IPE method.
global_true_or_false_request_instant_pairwise_elimination = global_false ;
// -----------------------------------------------
// Poplulate the list global_text_for_voteinfo_code
// using the information in the list
// global_voteinfo_code_for_alias_word.
for ( std::map< std::string , int >::iterator iteration_pointer = global_voteinfo_code_for_alias_word.begin( ) ; iteration_pointer != global_voteinfo_code_for_alias_word.end( ) ; ++ iteration_pointer )
{
// log_out << " " << iteration_pointer->first << " " << iteration_pointer->second << std::endl ;
global_text_for_voteinfo_code[ -1 * iteration_pointer->second ] = iteration_pointer->first ;
}
// -----------------------------------------------
// If needed, un-comment this code to view
// bucket usage for associative list named
// global_voteinfo_code_for_alias_word.
/*
for ( unsigned pointer = 0; pointer < global_voteinfo_code_for_alias_word.bucket_count() ; ++pointer) {
std::cout << "bucket #" << pointer << " contains:" ;
for ( auto iteration_pointer = global_voteinfo_code_for_alias_word.begin(pointer) ; iteration_pointer != global_voteinfo_code_for_alias_word.end(pointer) ; ++iteration_pointer )
{
std::cout << " " << iteration_pointer->first ;
}
std::cout << std::endl ;
}
*/
// -----------------------------------------------
// Get ready to start calculations.
global_case_number = 0 ;
// -----------------------------------------------
// End of function do_initialization.
return ;
}
// -----------------------------------------------
// -----------------------------------------------
// always_do_rep_and_party_ranking
//
// Requests that VoteFair representation ranking and
// VoteFair party ranking always be done -- except
// when only plurality votes are requested (because
// in those cases 1-2-3 ballots have not been used).
//
// -----------------------------------------------
// -----------------------------------------------
void always_do_rep_and_party_ranking( )
{
// -----------------------------------------------
// Request that VoteFair representation ranking
// and VoteFair party ranking always be done.
global_true_or_false_always_request_only_plurality_results = global_false ;
global_true_or_false_always_request_votefair_popularity_rank = global_true ;
global_true_or_false_always_request_votefair_representation_rank = global_true ;
global_true_or_false_always_request_votefair_party_rank = global_true ;
global_true_or_false_request_only_plurality_results = global_true_or_false_always_request_only_plurality_results ;
global_true_or_false_request_votefair_popularity_rank = global_true_or_false_always_request_votefair_popularity_rank ;
global_true_or_false_request_votefair_representation_rank = global_true_or_false_always_request_votefair_representation_rank ;
global_true_or_false_request_votefair_party_rank = global_true_or_false_always_request_votefair_party_rank ;
// -----------------------------------------------
// Function always_do_rep_and_party_ranking done.
return ;
}
// -----------------------------------------------
// -----------------------------------------------
// pad_integer
//
// Pads integer with spaces, to left side.
// Also ensures value of zero shows as "0",
// not blank.
//
// -----------------------------------------------
// -----------------------------------------------
std::string pad_integer( int input_integer , int pad_width )
{
std::string output_text ;
output_text = "" ;
int text_length ;
if ( input_integer == 0 )
{
output_text = "0" ;
} else
{
output_text = convert_integer_to_text( input_integer ) ;
}
text_length = output_text.length( ) ;
while ( text_length < pad_width )
{
output_text = " " + output_text ;