Board logo

主題: [DB] [問題] 請問得獎名單地理區域平均篩選怎麼做 ? [打印本頁]

發表人: jocosn    時間: 2012-9-26 05:04 AM     主題: [問題] 請問得獎名單地理區域平均篩選怎麼做 ?

朋友有個問題,網路投票資料庫有一個投票者資料表格,假設有 3000 人,我要篩出 200 個寄發贈品,請問要怎麼平均的每個地理區域都有人篩選出,湊足 200 位得獎人?


網路票選有一個投票者資料表格,
欄位: 「編號(auto increament)、投票者姓名、地址、電話」這 4 個欄位。


篩選問題:
如何平均分配地區?
      例如台北市、新北市、澎湖、台東每個縣市都要有得獎者。
      使用亂數篩選,如果某些地區,例如澎湖,只有零星幾個投票者,容易篩選不到。但是只要那個縣市有人投票,篩選時,就要有那個投票地區人數出來。

---------------------------
目前只想到用 趴數 % 去限定最低篩選人數。但是這樣有辦法讓 total 得獎人數=200 嗎?不限使用資料庫 SQL 或哪家資料庫,從資料庫篩出後再用 javascript 篩出也可以。或是給個方向, goole 查循條件是甚麼。


-----------------------------------------------------
09/26 改一下問題描述:
要怎麼各縣市都有得獎者抽出,然後湊足 200 位得獎人?

[jocosn 在  2012-9-26 04:47 PM 作了最後編輯]
發表人: watchme    時間: 2012-9-26 06:56 AM

你要的是演算規則嗎?不難,200/3000=1/15,要每個區域平均又要每個區都有,那就各區先抽一個,然後各區減去14人,不足14人的區合併成一區才減,然後再每區抽一個... ...抽跟減去都用亂數作,這樣就會湊出200人了。
發表人: 陽だまり    時間: 2012-9-26 08:28 AM

先析出各縣市人數之後
用降冪排序
然後再從上往下持續亂數抽1
抽到滿200人這樣?

不過抽獎用平均不會很奇怪嗎
假設連江縣只有2人抽的話
用平均來看的話,每縣市最少會有9人中獎
這樣連江縣的2人不就穩中了

[陽だまり 在  2012-9-26 08:30 AM 作了最後編輯]
發表人: jocosn    時間: 2012-9-26 04:45 PM

抱歉,我的題意沒說清楚。
今天要從 3000 人中抽出 200 人,但是「每個縣市都要有人被選出」,我說的平均是指這個。因為如果只是用亂數選出,有些縣市投票者只有5個,一般都不容易選到。

像這樣:
MySQL
SELECT col1 FROM votetable ORDER BY RAND() LIMIT 200;

不管 votetable 是否有按地區排序,有些弱勢地區,投票人數太少,都不容易篩到。但是朋友說,每個地區都要篩到至少 1 人。但是我又想到一個問題,該縣有 800 個投票,可能這 200 個得獎名額都給他佔光了。


至於該縣市要選出幾個人,這個可以自由設定。
例如如果該縣只有 2 個投票,就選出 1 個就好,不能 2 個都選到。重點是只要該縣有人投票,就一定要有至少 1 位得獎者。該縣只有 1 個投票,就一定是他得獎。該縣有 20 個投票,就選出 2~8 個 (自由設定,很自由)。該縣有 500 個投票,選出幾個都好,但是不要得獎比率太多,不然會壓到別縣的得獎人數比率 。這人數比率多寡,可由自己設定,但也是設計重點。可能某一縣像新北市有 2000 人投票,如果新北市得獎者就抽出 190 名那就慘了。如果另一縣像是台南縣有 800 人投票,但是抽出的人數比新北市還多,投票人數少的抽出的比投票人數多的縣數人數還多,那也慘了。
主要就是這其中的演算邏輯不知道怎麼設計。如何得獎名單出來,可以讓人知道這是各區亂數抽出,可能某縣投票者比較多所以得獎者比較多一點沒關係,但又不能太偏重某一區,多很多就不行。至於怎樣叫多很多,怎樣叫沒有多很多只是多的剛剛好,只要你可以說的天花亂墜,讓人心服就行。

所以讓看題的人誤會,真是抱歉,我應該改成,各縣市都有抽出得獎者。但各縣得獎人數比率不一定。

我的 SQL 超弱,假設先不管執行效率。
--------------------------------------------------------------------------

[jocosn 在  2012-9-26 05:20 PM 作了最後編輯]
發表人: 陽だまり    時間: 2012-9-26 07:21 PM

那watchme兄的方法可行嗎?
發表人: jocosn    時間: 2012-9-26 10:16 PM

watchme 兄的解法可能比較沒辦法,因為我的題意讓大家都看不懂。非常抱歉。

我剛剛在洗澡時想到一個,就是把問題丟給對方,
我先用 group、count 統計出來各縣市投票人口數,然後讓對方自己選各縣市得票人數,像這樣:

STEP 1 -- 列出各縣+直轄市投票數與比率。由低往高排。

CODE:
[Copy to clipboard]
澎湖       投票人數 2 人            佔總投票數比率 0.07%         估計抽出的得票人數___人     剩餘名額___人
台東縣   投票人數 30 人         佔總投票數比率  2.9%         估計抽出的得票人數___人     剩餘名額___人
嘉義縣   投票人數 88 人         佔總投票數比率 17%         估計抽出的得票人數___人     剩餘名額___人
............ 略
台北市   投票人數 500 人       佔總投票數比率 17%         估計抽出的得票人數___人     剩餘名額___人
新北市   投票人數 1000 人    佔總投票數比率 34%         估計抽出的得票人數___人     剩餘名額___人
Step 2

CODE:
[Copy to clipboard]
估計抽出的得票人數___人    →這部份由對方自己輸入
剩餘名額___人                        →這部份由電腦幫你算出
STEP 3
輸入完畢後,按下 submit 就開始依據自行輸入的得獎人數作篩選。

這樣簡單多了。
但是這樣分 3 步驟解,我覺得不專業很遜。因為有幾個縣市要抽獎,第 3 步驟就要下幾個相同的 SQL 指令。

感覺這根本是作假的網路抽獎,我真是服了我那朋友的抽獎條件,他給我看上一次的網路抽獎得獎名單(公家機關的網站,每年都會招標找人維護網站),我看了第 5 次左右突然發現怎麼剛好每個縣市都有得獎者,感覺好神,一問之下才發現他的得獎條件好詭異。不知這是不是公家機構的巧思還是大家都是這樣搞網路投票。
這樣的話,大樂透各縣市都會有得獎者,以 17 期或其倍數做個輪迴,因為全台灣目前縣+直轄市有 17 個。

[jocosn 在  2012-9-26 10:23 PM 作了最後編輯]
發表人: 陽だまり    時間: 2012-9-27 06:43 PM

我以為是21個縣、市?

那,每個縣市最少要有一人的話
那就200除21等於9-10人為可中獎人數
再來統計每個縣市的總抽獎人數再取30%為該縣市最大能中獎人數
最大能中獎人數大於可中獎人數則取可中獎人數
最大能中獎人數小於可中獎人數則取最大能中獎人數
然後當縣市抽獎人口愈大,最大能中獎人數再乘於20%
然後開始亂數抽,當抽的結果大於該縣市的最大能中獎人數
則再重抽,至到抽滿200人這樣

補充一下:一開始還是得先抽一輪,把最少票的縣市先保障一人再開始抽

[陽だまり 在  2012-9-28 06:09 AM 作了最後編輯]
發表人: ma1111    時間: 2012-9-28 08:17 AM

個人直覺:可能要用程式處理,SQL指令不是萬能的,

我的解決方法:
1.資料抓回local,
2.每個地區有flag,當所有flag沒on,每個地區只能一人,否則跳過
3.(2)條件OK,就繼續跑跑完吧
發表人: Yves    時間: 2012-9-30 04:35 AM

我怎麼記得現在是22縣市
用資料庫來做的話,可以用cursor或tempdb來做
前提是要確定縣市大家填的字眼都是一樣(不然會有 台北市 臺北市 北市 這樣會變成3個不同的區域)

假設前三碼是縣市
1. Select count(1), 地址前三碼 from ... group by 地址前三碼 order by count(1)
insert到tempdb (次數最少的排在上面)
並Select出所有的筆數丟到變數裡
***第一步驟要確認的是 挑出來行數的是否少於22(縣市), 避免有人亂填(我就常亂填...)

2. 從最少的開始(所以剛剛有排序)
Select max(次數/總次數*200,1)   得到該地區得獎人數
**用max是因為 最少要抽1位. 至於要不要4捨5入就隨意啦
***注意: 因為有進位的問題. 所以要設變數去統計得獎人數 避免超過200人

3. Select 該地區 去rand出那些人得獎

4.迴圈到2 換下一個縣市

PS. 第2點比例要更精準的話 就是 (地區次數)/(總人次-已rand過的區域次數)*(200-已用掉的人數)
不然所有被進位的人數都會扣在最後(最多人)的區域

[Yves 在  2012-9-30 04:46 AM 作了最後編輯]




歡迎光臨 TWed2k (http://twed2k.org/) Powered by Discuz! 4.1.0