1987, Received 17 October 1985, in final form 13 May 1986


The single transferable vote (STV) method of conducting an election exists in a number of different formulations in different countries. Most of the methods are designed to be practicable when counting is by hand, and this necessarily enforces simplicity even at the expense of not always getting the best possible answer.

Meek[1,2] considered the question of the best possible method, within the STV framework, when a computer is available to do the counting, and it is his method that we present here. The method was rediscovered, in a different formulation, by Woodall[4]. However, neither Meek nor Woodall dealt with certain detailed points, such as how to resolve a `tie', so we have had to extend the system to be complete. The algorithm as given here has been adopted by the Royal Statistical Society for its Council elections.

The basis of any STV system consists of the following. (1) Voting by order of preference of candidates, the first choice being marked 1, the second 2, and so on, on the ballot papers. (Meek also considered an alternative formulation in which voters would be allowed to indicate equal preference for some candidates instead of a strict ordering; we have not implemented this alternative.) (2) A quota for election, calculated from the number of votes and the number of seats to be filled. (3) A first counting by first preferences only, and the election of any candidate who equals or exceeds the quota (except in the special case of a multi-way tie). (4) Redistribution of surplus votes (above the quota) for any candidate, in accordance with the voters' further preferences, and election of any who now reach the quota. (5) When no further redistribution of surpluses is possible, the exclusion of the candidate who then has the fewest votes, and redistribution of those papers. (6) Further counting, election, redistribution of surpluses and exclusion as necessary, until all seats are filled.

In the Meek formulation the rule for redistributing surpluses is that, at every stage, if a candidate has votes totalling k times the quota, then he (or she) keeps 1/k of each of those votes and passes (k-1)/k on to the next candidate on the voter's list. This same fraction applies also to portions of votes received as parts of other surpluses. This requires the iterative solution of non-linear equations. It is proved in Section 4 below that a solution always exists and is unique.

It should be emphasised that the results will not always be the same as by manual counting methods. The algorithm deliberately uses the power of the computer to get better results than are easily achievable by hand.



At each stage, each candidate is in one of three states, designated as `elected', `excluded' and `hopeful'. At the start every candidate is in the hopeful state.


At each stage the votes are scanned, and the one vote allowed to each voter may be split into parts that are assigned to the various candidates according to the voter's choices. At the first stage the whole of the vote goes to the first choice - this follows automatically from the operation of rules 2.1 and 2.3.


Each candidate, x, has an associated weight, wx, and keeps a proportion wx of each vote or part of a vote received, while passing on to another candidate (as specified by the voter's choices) a proportion 1-wx. Every hopeful candidate has weight 1, and therefore keeps everything received and passes nothing on. Every excluded candidate has weight 0, and therefore keeps nothing and passes everything on. Elected candidates have weights between 0 and 1, to be calculated by rule 2.5.


Thus if someone has voted for candidate a as first choice, b as second, c as third, and no more:

A fraction (1-wa)(1-wb)(1-wc) remains and this goes to `excess'. (Note that if a hopeful candidate appears in the list, all the fractions beyond that point automatically become 0).


The quota is defined as (total votes - total excess)/(number of seats + 1), and the weights for elected candidates are found such that the total vote remaining with each of them equals the quota. This is done by the convergent iterative scheme specified in rule 2.9.


The weights having been found, the resulting total votes for each hopeful candidate are examined, and any candidate whose total votes equal or exceed the quota changes state from hopeful to elected (except in the special case where all the hopeful candidates either have zero votes or exactly equal the quota. In this case all those with zero votes are excluded, one other is excluded by a pseudo-random choice and the others are elected).


If no candidate were elected under rule 2.6, then the hopeful candidate with the fewest votes changes state from hopeful to excluded. Any tie is resolved by a pseudo-random choice.


If the total number of elected candidates is equal to the number of seats, the election is complete. Otherwise the process is repeated from rule 2.2.


The convergent iterative scheme is as follows: set wj equal to 0 for excluded candidates, 1 for hopeful candidates, and their last calculated values wj0. for elected candidates. (Immediately after election of any candidate the last calculated value is 1 initially.) Applying rule 2.3, using these weights, let vj be the total value of votes received by candidate j and let e be the total excess. Using this value for e, calculate the new quota q using rule 2.5. Finally update the weights for elected candidates to values w1j = w0jq/vj. Repeat the process of successively updating vj, e, q and wj until every fraction q/vj, for elected candidates, lies within the limits 0.99999 and 1.00001 (inclusive).

(by I. D. HILL, and

We have allowed for up to 40 candidates, but the necessary change to allow a larger number is trivial.

3.1  The data

The data file should be held on disc, or other device that allows quick `rewinding', because it has to be read many times during program execution.

Its form should be as follows:

4 2
3 1 3 4 0
4 1 3 2 0
2 4 1 3 0
1 2 0
2 2 4 3 1 0
1 3 4 2 0

The first line means that there are 4 candidates for 2 seats. The second line means that candidate number 2 withdrew before the count. As many candidates as necessary may be included in this line, each preceded by a minus sign. If no candidate withdrew, the line should be omitted entirely. The third line means that 3 voters put candidate 1 first, candidate 3 second, candidate 4 third, and no more. Each such list must end with a zero. The final zero ends the votes. The subsequent lines name the candidates, in the order of candidate numbers as used in the votes, and finally give a title for the election. If any of these names, or the title, is longer than 20 characters, only the first 20 will be used.

For elections on any substantial scale, further programs are desirable to get the data into this required form. Machine-readable ballot papers would obviously be a great help if a suitable system can be devised.

3.2  Ties

The only ties that can occur in this system are as follows. (1) If n + 1 candidates all exactly equal the quota, where only n seats are available. One of these candidates must then be excluded (together with all other candidates, who necessarily have zero votes) and the other n elected. (2) If the candidate with fewest votes must be excluded and two or more have equal fewest. In both these cases a pseudo-random procedure is used, on the grounds that `if they are equal, they are equal' and any procedure to choose one must be arbitrary. Alternatives are sometimes recommended, such as excluding the one who had fewer votes the first time they were different, or the last time they were different, or whatever, but such rules add much complication for no real advantage, so simplicity is preferable.

The pseudo-random generator is derived, with permission, from Applied Statistics algorithm AS 183[3]. This needs three seeds to initialise it, and these are formed from data items for the particular election. This leaves it sufficiently nearly random that nobody can manipulate it to favour a particular candidate, yet has the advantage that, for a given election, there is always a unique result. Running it on a different day, or using a different computer, will make no change - in the unlikely event that a random choice is needed, the same thing will always happen for any given data set. If a tie does occur and a random choice has to be made, a warning message is printed.

It should be emphasised that a tie that actually influences the result is a very rare event.

3.3  Partial abstentions

There is no compulsion on voters to give a complete listing of candidates. They may stop short if desired. If they do so and the use of their vote `runs off the end' we allow it to do so, but adjust the quota to allow for the fact that there are now fewer remaining usable votes. This treats the partial abstention in such a way as to be fair to all remaining candidates.

This usage is different from that adopted in most manual counting systems where, under such circumstances, votes are divided into `transferable' and `non-transferable' and no quota adjustment is made. We are convinced that, within Meek's system, our approach is right, but it has to be made clear that we are in dispute over this with the council of the Electoral Reform Society. We have held up publication of the algorithm in the hope of resolving the difficulty, but now feel that we can wait no longer. Unfortunately, it is therefore necessary to warn potential users that they may be told by others that our method is undesirable in this particular.

3.4  Language

The algorithm is presented in standard Pascal. On some machines small, non-standard, changes may be required in the method of accessing the data file. We have used upper-case letters for Pascal word-symbols, lower-case or mixed-case for identifiers.

3.5  Listing

PROGRAM stvpas(datafile, output);

{This program counts the votes in a Single Transferable Vote election,
    using Meek's method, and reports the results}

{If there are more than 40 candidates an increase in the size of
   MaxCandidates is the only change needed}

CONST MaxCandidates = 40;
      NameLength = 20;

TYPE Candidates = 1 .. MaxCandidates;
     CandRange = 0 .. MaxCandidates;
     name = PACKED ARRAY [1 .. NameLength] OF char;

VAR  NumCandidates, NumSeats: Candidates;
     candidate, NumElected, NumExcluded,
          multiplier, ignored: CandRange;
     Droop, excess, quota, total: real;
     faulty, SomeoneElected, RandomUsed: Boolean;
     FracDigits: 1 .. 4;
     table, seed1, seed2, seed3: integer;
     datafile: text;
     title: name;
     votes, weight: ARRAY [Candidates] OF real;
     status: ARRAY [Candidates] OF (Hopeful, Elected, NewlyElected,
                   Almost, Excluded, ToBeExcluded, NotUsed, Used);
     names: ARRAY [Candidates] OF name;

FUNCTION InInteger: integer;

{Reads the next integer from datafile and returns its value}

   VAR i: integer;
   read(datafile, i);
   InInteger := i
   END; {InInteger}


{Updates the table number and prints out the current results}

   VAR arg: real;
      cand: Candidates; 
   table := table + 1;
   writeln(' ': 20, title);
   write('Table: ', table: 1);
   writeln(' Quota: ', quota: 1: FracDigits);

   {The numbers of blanks following Candidate, Retain and
       Transfer are 12, 3 and 3 respectively}

   writeln('Candidate            Retain   Transfer   Votes');
   FOR cand := 1 TO NumCandidates DO
      IF status[cand] = ToBeExcluded THEN
         arg := 100.0 ELSE arg := 100.0 * weight[cand];
      write(arg: 6: 1, '%');
      write(100.0 - arg: 8: 1, '%');

      {If it is valid to do so, print quota instead of votes[cand]
         because the latter might have a small rounding error that
         would confuse unsophisticated users}

      IF status[cand] = Elected THEN arg := votes[cand] / quota
         ELSE arg := 0.0;
      IF (arg >= 0.99999) AND (arg <= 1.00001) THEN arg := quota
         ELSE arg := votes[cand];
      write(arg: 10: FracDigits, '  ');
      IF status[cand] = Excluded THEN write('Excluded')
      ELSE IF status[cand] = Elected THEN write('Elected')
      ELSE IF status[cand] = NewlyElected THEN write('Newly Elected')
      ELSE IF status[cand] = ToBeExcluded THEN 
         write('To be Excluded');
         status[cand] := Excluded
      IF (NumCandidates > 9) AND (cand MOD 5 = 0) AND
         (cand <> NumCandidates) THEN writeln

   writeln('Excess', excess: 40: FracDigits);
   writeln('Total ', total: 40: FracDigits);
   END; {PrintOut}

PROCEDURE elect(cand: Candidates);
   status[cand] := NewlyElected;
   NumElected := NumElected + 1
   END; {elect}

PROCEDURE exclude(cand: Candidates);
   status[cand] := ToBeExcluded;
   weight[cand] := 0.0;
   NumExcluded := NumExcluded + 1;
   IF RandomUsed THEN 
      writeln('Random choice used to exclude ', names[cand])
   END; {exclude}

FUNCTION LowestCandidate: CandRange;

{Returns the candidate number of the candidate who currently has the
   lowest number of votes. If two or more are equal lowest, then a
   pseudo-random choice is made between them}

   VAR cand: Candidates;
       LowCand: CandRange;
FUNCTION random: real;

{Returns a pseudo-random number rectangularly distributed
   between 0 and 1. Based on Wichmann and Hill, Algorithm
   AS 183, Appl. Statist. (1982) 31, 188 - 190}

VAR rndm: real;

   { If seeds have not been set, then set them}

   IF seed1 = 0 THEN
      seed1 := NumCandidates; 
      seed2 := NumSeats + 10000;
      rndm := total + 20000.0;
      WHILE rndm > 30322.5 DO rndm := rndm - 30322.0;
      seed3 := round(rndm) 

   seed1 := 171 * (seed1 MOD 177) - 2 * (seed1 DIV 177);
   seed2 := 172 * (seed2 MOD 176) - 35 * (seed2 DIV 176);
   seed3 := 170 * (seed3 MOD 178) - 63 * (seed3 DIV 178);
   IF seed1 < 0 THEN seed1 := seed1 + 30269; 
   IF seed2 < 0 THEN seed2 := seed2 + 30307; 
   IF seed3 < 0 THEN seed3 := seed3 + 30323;
   rndm := seed1 / 30269.0 + seed2 / 30307.0 + seed3 / 30323.0;
   random := rndm - trunc(rndm) 
   END; {random}

FUNCTION lower(cand, lowest: CandRange): Boolean;

{Find whether cand has fewer votes than lowest, and also
   reports whether a random choice had to be made}

   VAR lowly: Boolean;
   IF lowest = 0 THEN
      RandomUsed := false;
      lower := true
   ELSE IF votes[cand] = votes[lowest] THEN
      RandomUsed := true;

      {Multiplier is used to make all equally-lowest candidates
          equally likely to be chosen, even though they are
          considered serially and not simultaneously}

      lower := (multiplier * random < 1.0)
      lowly := (votes[cand] < votes[lowest]);
      lower := lowly;
      IF lowly THEN RandomUsed := false
   IF RandomUsed THEN multiplier := multiplier + 1
      ELSE multiplier := 2
   END; {lower}

   LowCand := 0;
   FOR cand := 1 TO NumCandidates DO
      IF (status[cand] = Hopeful) OR (status[cand] = Almost) THEN
         IF lower(cand, LowCand) THEN LowCand := cand;
   LowestCandidate := LowCand
   END; {LowestCandidate}

PROCEDURE compute;

{This is the heart of the program, which counts the votes, taking
    the current weights into account, and adjusts the weights and
    the quota iteratively to attain the required solution}

   {MaxIterations is the maximum number of iterations allowed in
       calculating the weights. It is unlikely that so many will
       ever be used, but its value may be increased if desired}

   CONST MaxIterations = 500;
   VAR temp, value: real;
       count, iteration: integer;
       cand: CandRange;
       converged, ended: Boolean;
   PROCEDURE Rewind;

   {Returns to the beginning of datafile, and ignores the first two
       numbers on it. These are the number of candidates and the
       number of seats, whose values are not needed again. Numbers
       indicating withdrawn candidates are also ignored}
   VAR ig, ignore: integer;
   reset (datafile);
   FOR ig := -1 TO ignored DO ignore := InInteger
   END; {Rewind}

iteration := 1;

   excess := 0.0;
   FOR cand := 1 TO NumCandidates DO votes[cand] := 0.0;
   count := InInteger;

   WHILE count > 0 DO
      value := count;
      cand := InInteger;
      ended := false;

      WHILE cand>0 DO
         IF NOT ended AND (weight[cand] > 0.0) THEN
            ended := (status[cand] = Hopeful);
            IF ended THEN
               votes[cand] := votes[cand] + value;
               value := 0.0
               votes[cand] := votes[cand] + value * weight[cand];
               value := value * (1.0 - weight[cand])
         cand := InInteger

     excess := excess + value;
     count := InInteger
   quota := (total - excess) * Droop;
{The next statement is unlikely ever to be used, but is a
safeguard against certain pathological test data}

IF quota < 0.0001 THEN quota := 0.0001;
converged := true;
FOR cand := 1 TO NumCandidates DO
   IF status[cand] = Elected THEN
      temp := quota / votes[cand];
      IF (temp > 1.00001) OR (temp < 0.99999) THEN
         converged := false;
      temp := weight[cand] * temp;
      weight[cand] := temp;

      {The next statement is unlikely ever to be used, but is
        a safeguard agalast certaln pathological test data}

      IF temp > 1.0 THEN weight[cand] := 1.0

iteration := iteration + 1
UNTIL (iteration = MaxIterations) OR converged;

IF NOT converged THEN

   {The "Failure to converge" message is unlikely ever to appear.
     If it does, increasing MaxIterations will probably cure it}

   writeln('Failure to converge');
count := 0;

FOR cand := 1 TO NumCandidates DO
   IF (status[cand] = Hopeful) AND (votes[cand] >= quota) THEN
      status[cand] := Almost;
      count := count + 1

{Allow for the special case where there is a multi-way tie and
   too many candidates reach the quota simultaneously}

WHILE NumElected + count > NumSeats DO
   RandomUsed := false;
   FOR cand := 1 TO NumCandidates DO
      IF status[cand] = Hopeful THEN exclude(cand);
   count := count - 1

SomeoneElected := false;
FOR cand := 1 TO NumCandidates DO
   IF status[cand] = Almost THEN
      SomeoneElected := true

IF SomeoneElected THEN PrintOut;
FOR cand := 1 TO NumCandidates DO
   IF status[cand] = NewlyElected THEN
      IF NumElected < NumSeats THEN
         weight[cand] := quota / votes[cand];
      status[cand] := Elected
END; {compute}

PROCEDURE complete;

   {Used to elect all remaining candidates if the number
      remaining equals the number of seats remaining}

   VAR cand: Candidates;
   FOR cand := 1 TO NumCandidates DO
      IF status[cand] = Hopeful THEN elect(cand)
   END; {complete}

PROCEDURE Preliminaries;

   {Checks datafile for errors and sets initial values of variables}

   VAR cand, count, LineNo: integer;

   PROCEDURE error(cand: integer; TooBig: Boolean);
      write ('On line ' , LineNo: 1, ', Candidate ', cand: 1);
      IF TooBig THEN write (' exceeds maximum')
      ELSE write (' is repeated');
      faulty := true
      END; {error}

   PROCEDURE ReadName(VAR n: name);

      {Reads the name ot a candidate, or reads a title, and stores
          it for later use. If the name has more than NameLength
          characters the excess ones will be disregarded. If it
          has fewer than NameLength characters blanks will be used
          to extend it}

      VAR i: integer;
          ch: char;

         read(datafile, ch)
         UNTIL ch = '"';

      i := 0;
      read(datafile, ch);
      WHILE ch <> '"' DO
         IF i < NameLength THEN
            i := i + 1;
            n[i] := ch
         read(datafile, ch)

      WHILE i < NameLength DO
         i := i + 1;
         n[i] := ' '
      END; {ReadName}
   Droop := 1.0/(NumSeats + 1);
   LineNo := 1;
   seed1 := 0;
   total := 0.0;
   table := 0;
   NumElected := 0;
   NumExcluded := 0;
   ignored := 0;
   FOR cand := 1 TO NumCandidates DO weight[cand] := 1.0;
   count := InInteger;

   {Deal wlth withdrawals, if any}
   WHILE count < 0 DO
      weight[-count] := 0.0;
      count := InInteger
   WHILE count > 0 DO
      LineNo := LineNo + 1;
      total := total + count;
      FOR cand := 1 TO NumCandidates DO status[cand] := NotUsed;
      cand := InInteger;
      WHILE cand > 0 DO
         IF cand > NumCandidates THEN error(cand, true)
            ELSE IF status[cand] = Used THEN error(cand, false)
               ELSE status[cand] := Used;
         cand := InInteger

      count := InInteger

   FOR cand := 1 TO NumCandidates DO
      status[cand] := Hopeful;
      IF weight[cand] < 0.5 THEN
         status[cand] := Excluded;
         NumExcluded := NumExcluded + 1;
         ignored := ignored + 1
   IF NOT faulty THEN

      {FracDigits controls the number of digits beyond the decimal
          point that will be printed in the output tables}

      FracDigits := 4;
      IF total > 999.5 THEN FracDigits := FracDigits - 1;
      IF total > 99.5 THEN FracDigits := FracDigits - 1;
      IF total > 9.5 THEN FracDigits := FracDigits - 1
   END; {Preliminaries}

{Start of main program}

NumCandidates := InInteger;
NumSeats := InInteger;
writeln('Number of Candidates = ', NumCandidates: 1);
writeln ('Number of seats = ', NumSeats: 1);
IF NumCandidates < NumSeats THEN writeln('All candidates elected') ELSE
   faulty := false;
   IF NumCandidates <= NumSeats + NumExcluded THEN
       writeln('All non-withdrawn candidates elected') ELSE

       {The Preliminaries procedure will have reset faulty to true if
           the data contain errors}

       IF NOT faulty THEN

                {Count votes and elect candidates, transferrlng
                    surpluses until no more can be done or all
                    seats are filled}

                UNTIL NOT SomeoneElected OR (NumElected >= NumSeats);

                {Unless the election is finished, someone must
                    now be excluded}

                IF NumElected < Numseats THEN
                   IF NumCandidates - NumExcluded = NumSeats
                      THEN complete ELSE PrintOut
                UNTIL NumElected = NumSeats;

             {Now that all seats are filled, exclude any candidates not
                 already elected, and print out the final table}

             RandomUsed := false;
             FOR candidate := 1 TO NumCandidates DO
                IF status[candidate] = Hopeful THEN exclude(candidate);


We prove in this section that the equations that need to be solved at each stage of Meek's method have a unique solution.

At each stage, each candidate is in one of three states, called ` elected', `excluded' and `hopeful'. It is explained in Section 2 how a candidate arrives in one of these states; but for the purposes of the formal proof it is irrelevant: we may suppose that each candidate is assigned to one of these states at random, subject to the condition that the number m of `elected' candidates is non-zero and does not exceed the number s of seats to be filled: 1 m s. We also require the following non-triviality condition: there is at least one ballot paper that contains the name of a `hopeful' candidate in its list of preferences. These conditions would certainly be fulfilled in a real election (in which no equation needs to be solved until some candidate is declared `elected').

Let the `elected' candidates be C1, ..., Cm. Let the weight assigned to candidate X (as in Section 2.3) be wx (0 wx 1). Since each `excluded' candidate always receives weight 0 and each `hopeful' candidate receives weight 1, the assigned weights are specified uniquely by the m-vector w = (w1, . . ., wm), in which wj is the weight assigned to Cj for each j (j = 1, . . ., m).

In the situation described by the m-vector w, let Vx(w) denote the vote for candidate X (that is, the sum of the part-votes that X receives from all the electors); for convenience, write VCj(w) as Vj(w). Let E(w) denote the total excess vote, and define the quota Q(w) to be (V-E(w))/(s+1), where V is the total number of votes (ballot papers). The effect of the non-triviality condition mentioned above is to ensure that Q(w) 1/(s+ 1) > 0 for all w, since if a ballot paper contains the name of a `hopeful' candidate among its preferences then no part of that vote can be lost to the excess vote, and so V-E(w) 1.

We shall make extensive use of the following facts, which are obvious from the above definitions and from Section 2.4, and in which we use the terms `increases' and `decreases' in the weak sense (that is, both terms correctly describe a number that does not change): if one component wj of w is decreased whilst all the other components are unchanged, then:

Vj(w) decreases, in exact proportion to the decrease in wj;

each Vk(w) (k j) increases;

the sum of the votes for all the `elected' candidates decreases by an amount v 0 (since the contribution from each ballot paper decreases);

the excess vote increases, by at most v;

the quota decreases, by at most v/(s+ 1).

Let an m-vector w be called feasible if 0 wj 1 and Vj(w) Q(w) for each j, and be called a solution vector if 0 wj 1 and Vj(w) = Q(w) for each j (j = 1, ..., m). The purpose of this section is to prove that if there is a feasible vector, then there is a unique solution vector. We note in passing that, in a real election, the existence of a feasible vector is assured, since the solution vector at each stage of the counting yields a feasible vector for the next stage.

We shall use the following algorithm which, starting with a feasible vector, will construct a solution vector. (This is the algorithm described in Section 2.9.)

Algorithm: Let w0 = (w01, ..., w0m ) be a feasible vector. Given wi, define wi+1 by the rule

wi+1j : = wijQ(wi)/Vj(wi)              (6)

for each j (j = 1, ..., m).

Theorem 1. This Algorithm constructs a sequence of feasible vectors that converges to a solution vector.

Proof. Suppose that wi is a feasible vector, so that Vj(wi) Q(wi) > 0 and so wij > 0 for each j. Then to convert wi into wi+1 we must (weakly) decrease each of its components. Fix j, and let w be the vector obtained from wi by replacing the one component wij by wi+1j. By (2), (1), (6) and (5),

Vj(wi+1) Vj(w) = Vj(wi)wi+1j/wij

= Q(wi) Q(wi+1).              (7)

This holds for each j, and so wi+1 is a feasible vector. Since w0 is feasible by hypothesis, it follows by induction that wi is feasible for all i.

It follows from this that, for each fixed j, the sequence

w0j, w1j, w2j ...

is a monotonic decreasing sequence that is bounded below (by 0), and so converges. Thus there is a limit vector w = (w1,. ...., wm). We must prove that w is a solution vector. By the feasibility of wi and (7),

0 Vj(wi)-Q(wi) = Vj(wi)-Vj(w),


since decreasing wj by d cannot decrease Vj(w) by more than Vd (V being the total number of ballot papers). But, as i , wij-wi+1j 0, and since Vj(w) and Q(w) are continuous functions of w it follows that Vj(w) = Q(w). This holds for each j, and so w is a solution vector, as required. [¯]

Theorem 2. The solution vector, whose existence was proved in Theorem 1, is unique.

Proof. Let w = (w1, , wm) and w* = (w*1, ..., w*m) be two solution vectors and define w0 = (w01, ..., w0m) by

w0j : = min
(wj, w*j)

for each j. For a fixed j suppose without loss of generality that w0j = wj, and note that, by (2) and (5)

Vj(w0) Vj(w) = Q(w) Q(w0).

This holds for each j, and so w0 is a feasible vector. By Theorem 1 we can apply the Algorithm to w0 to construct a solution vector w = (w0 ..., wm) such that

0 < wj w0j wj

for each j. We shall prove that w = w, from which it will immediately follow that w = w0 = w*, as required.

We prove first that Q(w) = Q(w). By (5), Q(w) Q(w). By the same argument that is used to derive (5) from (3),

(s+1) (Q(w)-Q(w)) = E(w)-E(w)


j = 1 

= m(Q(w)-Q(w))

since w and w are both solution vectors. Since m s, Q(w)-Q(w) 0. Thus Q(w) = Q(w), and

Vj(w) = Vj(w)                 (8)

for each j.

Finally, let S denote the set of candidates Cj (if any) for whom wj < wj, and suppose that S is non-empty. Since wj < 1 for each such j and Vj(w) = Q(w) > 0, it is not difficult to see (by considering each ballot paper) that the sum of the votes for all the candidates in S is a strictly increasing function of the weight assigned to each such candidate, and so must strictly increase when the vector w is replaced by w. But this violates (8). So S must be empty and w = w. This completes the proof that there can be at most one solution vector w. [¯]


B. L. Meek. Une nouvelle approche du scrutin transférable. Mathématiques et sciences humaines 25, 13-23 (1969).

B. L. Meek. Une nouvelle approche du scrutin transférable (fin). Mathématiques et sciences humaines 29, 33-39 (1970).

B. A. Wichmann and I. D. Hill. Algorithm AS 183 - an efficient and portable pseudo-random number generator. Applied Statistics 31, 188-190 (1983).

D. R. Woodall. Computer counting in STV elections. Representation 90, 4-6 (1982).

A  Document details, Not published

Scanned and converted to LATEX, November 1999.

The second paragraph of section 4 states: there is at least one ballot paper that contains the name of a `hopeful' candidate in its list of preferences. The program does not check this! This error was corrected in the versions of Meek in actual use in 1999.

The program as published above produces quite voluminous output in relation to the standard `result sheet' that the Electoral Reform Society uses for STV elections. Versions of Meek used in real elections therefore summarise the output in some way - which can even be to produce a conventional result sheet.


1 Clinical Research Centre, Harrow, Middlesex, HA1 3UJ

2 5 Ellis Farm Close, Woking, GU22 9QN

3 Department of Mathematics, University of Nottingham, Nottingham NG7 2RD

File translated from TEX by TTH, version 2.25.
On 17 May 2000, 20:33.

Back to Meek Algorithm Index
List of Candidates for Election to Council