liquid_feedback_core

diff core.sql @ 411:44a07d8f1bb4

"schulze_rank" includes tie-breaking by "id"
author jbe
date Mon Dec 23 20:22:32 2013 +0100 (2013-12-23)
parents d301dc24b25c
children 399dc1a86398
line diff
     1.1 --- a/core.sql	Mon Oct 14 19:36:33 2013 +0200
     1.2 +++ b/core.sql	Mon Dec 23 20:22:32 2013 +0100
     1.3 @@ -707,13 +707,13 @@
     1.4  COMMENT ON COLUMN "initiative"."negative_votes"         IS 'Calculated from table "direct_voter"';
     1.5  COMMENT ON COLUMN "initiative"."direct_majority"        IS 'TRUE, if "positive_votes"/("positive_votes"+"negative_votes") is strictly greater or greater-equal than "direct_majority_num"/"direct_majority_den", and "positive_votes" is greater-equal than "direct_majority_positive", and ("positive_votes"+abstentions) is greater-equal than "direct_majority_non_negative"';
     1.6  COMMENT ON COLUMN "initiative"."indirect_majority"      IS 'Same as "direct_majority", but also considering indirect beat paths';
     1.7 -COMMENT ON COLUMN "initiative"."schulze_rank"           IS 'Schulze-Ranking without tie-breaking';
     1.8 -COMMENT ON COLUMN "initiative"."better_than_status_quo" IS 'TRUE, if initiative has a schulze-ranking better than the status quo (without tie-breaking)';
     1.9 -COMMENT ON COLUMN "initiative"."worse_than_status_quo"  IS 'TRUE, if initiative has a schulze-ranking worse than the status quo (without tie-breaking)';
    1.10 +COMMENT ON COLUMN "initiative"."schulze_rank"           IS 'Schulze-Ranking';
    1.11 +COMMENT ON COLUMN "initiative"."better_than_status_quo" IS 'TRUE, if initiative has a schulze-ranking better than the status quo';
    1.12 +COMMENT ON COLUMN "initiative"."worse_than_status_quo"  IS 'TRUE, if initiative has a schulze-ranking worse than the status quo (DEPRECATED, since schulze-ranking is unique per issue; use "better_than_status_quo"=FALSE)';
    1.13  COMMENT ON COLUMN "initiative"."reverse_beat_path"      IS 'TRUE, if there is a beat path (may include ties) from this initiative to the status quo';
    1.14  COMMENT ON COLUMN "initiative"."multistage_majority"    IS 'TRUE, if either (a) this initiative has no better rank than the status quo, or (b) there exists a better ranked initiative X, which directly beats this initiative, and either more voters prefer X to this initiative than voters preferring X to the status quo or less voters prefer this initiative to X than voters preferring the status quo to X';
    1.15  COMMENT ON COLUMN "initiative"."eligible"               IS 'Initiative has a "direct_majority" and an "indirect_majority", is "better_than_status_quo" and depending on selected policy the initiative has no "reverse_beat_path" or "multistage_majority"';
    1.16 -COMMENT ON COLUMN "initiative"."winner"                 IS 'Winner is the "eligible" initiative with best "schulze_rank" and in case of ties with lowest "id"';
    1.17 +COMMENT ON COLUMN "initiative"."winner"                 IS 'Winner is the "eligible" initiative with best "schulze_rank"';
    1.18  COMMENT ON COLUMN "initiative"."rank"                   IS 'Unique ranking for all "admitted" initiatives per issue; lower rank is better; a winner always has rank 1, but rank 1 does not imply that an initiative is winner; initiatives with "direct_majority" AND "indirect_majority" always have a better (lower) rank than other initiatives';
    1.19  
    1.20  
    1.21 @@ -3811,8 +3811,6 @@
    1.22        "battle_row"        "battle"%ROWTYPE;
    1.23        "rank_ary"          INT4[];
    1.24        "rank_v"            INT4;
    1.25 -      "done_v"            INTEGER;
    1.26 -      "winners_ary"       INTEGER[];
    1.27        "initiative_id_v"   "initiative"."id"%TYPE;
    1.28      BEGIN
    1.29        PERFORM "require_transaction_isolation"();
    1.30 @@ -3830,8 +3828,8 @@
    1.31        FOR "battle_row" IN
    1.32          SELECT * FROM "battle" WHERE "issue_id" = "issue_id_p"
    1.33          ORDER BY
    1.34 -        "winning_initiative_id" NULLS LAST,
    1.35 -        "losing_initiative_id" NULLS LAST
    1.36 +        "winning_initiative_id" NULLS FIRST,
    1.37 +        "losing_initiative_id" NULLS FIRST
    1.38        LOOP
    1.39          "vote_matrix"["i"]["j"] := "battle_row"."count";
    1.40          IF "j" = "dimension_v" THEN
    1.41 @@ -3898,9 +3896,7 @@
    1.42        -- Determine order of winners:
    1.43        "rank_ary" := array_fill(NULL::INT4, ARRAY["dimension_v"]);
    1.44        "rank_v" := 1;
    1.45 -      "done_v" := 0;
    1.46        LOOP
    1.47 -        "winners_ary" := '{}';
    1.48          "i" := 1;
    1.49          LOOP
    1.50            IF "rank_ary"["i"] ISNULL THEN
    1.51 @@ -3909,34 +3905,33 @@
    1.52                IF
    1.53                  "i" != "j" AND
    1.54                  "rank_ary"["j"] ISNULL AND
    1.55 -                "matrix"["j"]["i"] > "matrix"["i"]["j"]
    1.56 +                ( "matrix"["j"]["i"] > "matrix"["i"]["j"] OR
    1.57 +                  -- tie-breaking by "id"
    1.58 +                  ( "matrix"["j"]["i"] = "matrix"["i"]["j"] AND
    1.59 +                    "j" < "i" ) )
    1.60                THEN
    1.61                  -- someone else is better
    1.62                  EXIT;
    1.63                END IF;
    1.64 -              IF "j" = "dimension_v" THEN
    1.65 +              "j" := "j" + 1;
    1.66 +              IF "j" = "dimension_v" + 1 THEN
    1.67                  -- noone is better
    1.68 -                "winners_ary" := "winners_ary" || "i";
    1.69 +                "rank_ary"["i"] := "rank_v";
    1.70                  EXIT;
    1.71                END IF;
    1.72 -              "j" := "j" + 1;
    1.73              END LOOP;
    1.74 +            EXIT WHEN "j" = "dimension_v" + 1;
    1.75            END IF;
    1.76 -          EXIT WHEN "i" = "dimension_v";
    1.77            "i" := "i" + 1;
    1.78 +          IF "i" > "dimension_v" THEN
    1.79 +            RAISE EXCEPTION 'Schulze ranking does not compute (should not happen)';
    1.80 +          END IF;
    1.81          END LOOP;
    1.82 -        "i" := 1;
    1.83 -        LOOP
    1.84 -          "rank_ary"["winners_ary"["i"]] := "rank_v";
    1.85 -          "done_v" := "done_v" + 1;
    1.86 -          EXIT WHEN "i" = array_upper("winners_ary", 1);
    1.87 -          "i" := "i" + 1;
    1.88 -        END LOOP;
    1.89 -        EXIT WHEN "done_v" = "dimension_v";
    1.90 +        EXIT WHEN "rank_v" = "dimension_v";
    1.91          "rank_v" := "rank_v" + 1;
    1.92        END LOOP;
    1.93        -- write preliminary results:
    1.94 -      "i" := 1;
    1.95 +      "i" := 2;  -- omit status quo with "i" = 1
    1.96        FOR "initiative_id_v" IN
    1.97          SELECT "id" FROM "initiative"
    1.98          WHERE "issue_id" = "issue_id_p" AND "admitted"
    1.99 @@ -3966,17 +3961,17 @@
   1.100              AND "issue_row"."voter_count"-"negative_votes" >=
   1.101                  "policy_row"."indirect_majority_non_negative",
   1.102            "schulze_rank"           = "rank_ary"["i"],
   1.103 -          "better_than_status_quo" = "rank_ary"["i"] < "rank_ary"["dimension_v"],
   1.104 -          "worse_than_status_quo"  = "rank_ary"["i"] > "rank_ary"["dimension_v"],
   1.105 -          "multistage_majority"    = "rank_ary"["i"] >= "rank_ary"["dimension_v"],
   1.106 -          "reverse_beat_path"      = "matrix"["dimension_v"]["i"] >= 0,
   1.107 +          "better_than_status_quo" = "rank_ary"["i"] < "rank_ary"[1],
   1.108 +          "worse_than_status_quo"  = "rank_ary"["i"] > "rank_ary"[1],
   1.109 +          "multistage_majority"    = "rank_ary"["i"] >= "rank_ary"[1],
   1.110 +          "reverse_beat_path"      = "matrix"[1]["i"] >= 0,
   1.111            "eligible"               = FALSE,
   1.112            "winner"                 = FALSE,
   1.113            "rank"                   = NULL  -- NOTE: in cases of manual reset of issue state
   1.114            WHERE "id" = "initiative_id_v";
   1.115          "i" := "i" + 1;
   1.116        END LOOP;
   1.117 -      IF "i" != "dimension_v" THEN
   1.118 +      IF "i" != "dimension_v" + 1 THEN
   1.119          RAISE EXCEPTION 'Wrong winner count (should not happen)';
   1.120        END IF;
   1.121        -- take indirect majorities into account:
   1.122 @@ -4082,7 +4077,7 @@
   1.123        END LOOP;
   1.124        -- set schulze rank of status quo and mark issue as finished:
   1.125        UPDATE "issue" SET
   1.126 -        "status_quo_schulze_rank" = "rank_ary"["dimension_v"],
   1.127 +        "status_quo_schulze_rank" = "rank_ary"[1],
   1.128          "state" =
   1.129            CASE WHEN EXISTS (
   1.130              SELECT NULL FROM "initiative"

Impressum / About Us