Comment detail
議席数をドント方式で (Nested Flatten)This comment is reply for 1258 JDO: Prolog です。とーても、長いコード...(議席数をドント方式で). Go to thread root.
まぁ。なんと短い。predsort なんていう便利な述語があるんですねぇ。これに、述語 count でハッシュテーブルですね。なにより、d'Hondt方式のアルゴリズムとして、無駄のない計算になってますよね。私のように、無駄なリストだらだら生成したりしない。。。私のような Prolog ズブの初心者からすると、とても、勉強になるコードでした。ありがとうございました。
Java です。katsu さんの Prolog プログラムを Java で焼き直ししてみました。(なんだか見た目、長いですね。。。)
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 | import java.lang.Comparable ;
import java.util.Arrays ;
class dHondtMethod
{
static class Vote implements Comparable
{
String 政党名 ; int 得票数 ; int 既得の議席数 ;
Vote (String 名, int 票, int 席)
{政党名 = 名 ; 得票数 = 票 ; 既得の議席数 = 席 ;}
public int compareTo (Object another_)
{
Vote another = (Vote) another_ ;
Double thisValue
= new Double (this.得票数 / (this.既得の議席数 + 1.)) ;
Double anotherValue
= new Double (another.得票数 / (another.既得の議席数 + 1.)) ;
int cmp = thisValue .compareTo (anotherValue) ;
return cmp!=0 ? cmp : this.得票数 - another.得票数 ;
}
public String toString ()
{return "(政党名="+政党名+", 得票数="+得票数
+", 既得の議席数="+既得の議席数+")" ;}
}
public static void main (String [] _)
{
int 定数 = 100 ;
Vote [] votes =
{new Vote ("A党", 123, 0), new Vote ("B党", 4, 0),
new Vote ("C党", 56, 0), new Vote ("D党", 78, 0)} ;
while (0< 定数)
{
Arrays.sort (votes) ;
Vote last = votes [votes.length - 1] ; // 最大のもの
++last.既得の議席数 ;
--定数 ;
}
for (int i=0; i<votes.length; ++i)
{System.out .println (votes [i]) ;}
}
}
|
Scheme です。 Java で書いてみて分かったのですが、議席数の計算のつど、[A,B,C,D] 全体で sort する必要はないですよね。全体で sort が必要なのは最初の1回だけで、次回以降は、その時 議席を獲得した党の順位が入れ替わるだけ。たとえば、議席計算の最初の第1回目では全体で sort すると A党(=123), D党(=78), C党(=56), B党(=4) の順になり A党 が議席獲得ですが、次回は、A党の数値のみが変わる(123→66.5)だけなので、A党の順位のみを気にすればいいだけ。こう考えると、マージソートにすれば、最適化を図れるわけですよね。つまり、残りの [D, C, B] に対して、大きい順で マージ (追加) する処理をすれば、最小限の sort 処理になります。実際、今の例ですと、D党(=78) と入れ替わるだけで、すみます。。。。ということで、長くなりましたが、マージ方式のアルゴリズムで書いてみました。時々は、気分を変えて、Scheme で書いてみました。(Scheme らしからぬ書き方ですが。。。)
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 | ; Vote オブジェクトの定義
(define (new_Vote party-name vote-count seat-count)
(list party-name vote-count seat-count))
(define (Vote_getPartyName this) (car this))
(define (Vote_getVoteCount this) (cadr this))
(define (Vote_getSeatCount this) (caddr this))
(define (Vote_increaseSeatCount this)
(new_Vote
(Vote_getPartyName this)
(Vote_getVoteCount this)
(+ (Vote_getSeatCount this) 1)
)
)
(define (Vote_isLessThan this another)
(let
(
(thisValue (/ (Vote_getVoteCount this) (+ (Vote_getSeatCount this) 1)))
(anotherValue (/ (Vote_getVoteCount another) (+ (Vote_getSeatCount another)1)))
)
(if (= thisValue anotherValue)
(< (Vote_getVoteCount this) (Vote_getVoteCount another))
(< thisValue anotherValue)
)
)
)
(define (Vote_display this)
(display "party-name: ") (display (Vote_getPartyName this)) (display ", ")
(display "vote-count: ") (display (Vote_getVoteCount this)) (display ", ")
(display "seat-count: ") (display (Vote_getSeatCount this)) (newline)
)
; d'Hondt 方式の要
; 新しい Vote オブジェクトを大きい順で追加する
(define (dHondt_add this vote)
(if (null? this)
(list vote)
(if (Vote_isLessThan (car this) vote)
(cons vote this)
(cons (car this) (VoteList_add (cdr this) vote)) ; .... ?
))
)
; ここが d'Hondt の処理
(define (dHondt total-seat-count sorted-vote-list)
(do () ((= 0 total-seat-count))
; 次回の 今回議席を獲得した党 (car) の議席数を
; 1増やして (increaseSeatCount)、
; 残りの党たちのリスト (cdr) に add する
; (このアルゴリズムのポイント)
(set! sorted-vote-list
(dHondt_add
(cdr sorted-vote-list)
(Vote_increaseSeatCount (car sorted-vote-list))
)
)
(set! total-seat-count (- total-seat-count 1))
)
sorted-vote-list
)
; お試しコード ------------------------------------------------------------
(define otameshi-list ())
(set! otameshi-list (dHondt_add otameshi-list (new_Vote "A" 123 0)))
(set! otameshi-list (dHondt_add otameshi-list (new_Vote "B" 4 0)))
(set! otameshi-list (dHondt_add otameshi-list (new_Vote "C" 56 0)))
(set! otameshi-list (dHondt_add otameshi-list (new_Vote "D" 78 0)))
(set! otameshi-list (dHondt 100 otameshi-list))
(Vote_display (car otameshi-list))
(Vote_display (cadr otameshi-list))
(Vote_display (caddr otameshi-list))
(Vote_display (cadddr otameshi-list))
|
おっとっと。46行目、書き間違いです。(Upの直前に名前変更したもので、、、)すみません。
1 2 3 | 誤: (cons (car this) (VoteList_add (cdr this) vote))
正: (cons (car this) (dHondt_add (cdr this) vote))
|




katsu
#1275()
[
Prolog
]
Rating1/1=1.00
Rating1/1=1.00-0+