# HG changeset patch # User jbe # Date 1363546981 -3600 # Node ID 5f3cd73f328d9e650a5a4bd4c0ab273f9053ff82 # Parent 8344753f2ac147cc207efcc54afbaa7243c89ae2 Added comments to lf_update_suggestion_order.c diff -r 8344753f2ac1 -r 5f3cd73f328d lf_update_suggestion_order.c --- a/lf_update_suggestion_order.c Sun Mar 17 17:13:45 2013 +0100 +++ b/lf_update_suggestion_order.c Sun Mar 17 20:03:01 2013 +0100 @@ -25,18 +25,21 @@ free(ptr); } +// column numbers when querying "individual_suggestion_ranking" view in function main(): #define COL_MEMBER_ID 0 #define COL_WEIGHT 1 #define COL_PREFERENCE 2 #define COL_SUGGESTION_ID 3 +// data structure for a candidate (in this case a suggestion) to the proportional runoff system: struct candidate { - char *key; - double score_per_step; - double score; - int seat; + char *key; // identifier of the candidate, which is the "suggestion_id" string + double score_per_step; // added score per step + double score; // current score of candidate; a score of 1.0 is needed to survive a round + int seat; // equals 0 for unseated candidates, or contains rank number }; +// compare two integers stored as strings (invocation like strcmp): static int compare_id(char *id1, char *id2) { int ldiff; ldiff = strlen(id1) - strlen(id2); @@ -44,13 +47,16 @@ else return strcmp(id1, id2); } +// compare two candidates by their key (invocation like strcmp): static int compare_candidate(struct candidate *c1, struct candidate *c2) { return compare_id(c1->key, c2->key); } +// candidates are stored as global variables due to the constrained twalk() interface: static int candidate_count; static struct candidate *candidates; +// function to be passed to twalk() to store candidates ordered in candidates[] array: static void register_candidate(char **candidate_key, VISIT visit, int level) { if (visit == postorder || visit == leaf) { struct candidate *candidate; @@ -60,6 +66,7 @@ } } +// performs a binary search in candidates[] array to lookup a candidate by its key (which is the suggestion_id): static struct candidate *candidate_by_key(char *candidate_key) { struct candidate *candidate; struct candidate compare; @@ -72,29 +79,36 @@ return candidate; } +// section of a ballot with equally ranked candidates: struct ballot_section { int count; struct candidate **candidates; }; +// ballot of the proportional runoff system: struct ballot { - int weight; - struct ballot_section sections[4]; + int weight; // if weight is greater than 1, then the ballot is counted multiple times + struct ballot_section sections[4]; // 4 sections, most preferred candidates first }; +// determine candidate, which is assigned the next seat (starting with the worst rank): static struct candidate *loser(int round_number, struct ballot *ballots, int ballot_count) { - int i, j, k; - int remaining; + int i, j, k; // index variables for loops + int remaining; // remaining candidates to be seated + // reset scores of all candidates: for (i=0; i 1) while (1) { + double scale; // factor to be later multiplied with score_per_step: + // reset score_per_step for all candidates: for (i=0; i 0.0) { @@ -127,28 +142,34 @@ } } } + // add scale*score_per_step to each candidates score: for (i=0; i 0.0) { double max_scale; max_scale = (1.0-candidates[i].score) / candidates[i].score_per_step; if (max_scale == scale) { + // score of 1.0 should be reached, so we set score directly to avoid floating point errors: candidates[i].score = 1.0; remaining--; } else { candidates[i].score += scale * candidates[i].score_per_step; if (candidates[i].score >= 1.0) remaining--; } + // when there is only one candidate remaining, then break loop: if (remaining <= 1) break; } } } - for (i=candidate_count-1; i>=0; i--) { + // return remaining candidate: + for (i=0; isections[preference].count++; old_member_id = member_id; } + // allocate memory for ballot sections: for (i=0; iseat = candidate_count - i; printf("Assigning rank #%i to suggestion #%s.\n", candidate_count - i, candidate->key); } + // free ballots[] array: for (i=0; i