近日,需要進行一次大型考試的考場安排工作,遂做了一番深究,並成功實現了一種考場排定的演算法。
安排考生的基本思想是:對於報名人數較多的報名點的考生,應盡量分布在所有考場中去,這樣可以使得同一考場,同一報名點人數較少。
演算法的基本思想是:依照每場人數將報名庫中的學生依照一定的次序排定在從首場至尾場的考室中去。另外,還需要打亂其報名號。舉例來說的話,如果有100個考場,每考場30人,就是依次把按一定順序的考生放入第1場、第2場……,直至100場,放30輪即可完成。那麼,考生的順序怎麼來確定呢?
考生安排順序的確定取決於兩個方面:1.考生所在報名點;2.為該考生隨機生成的隨機數。具體來說,就是從報名庫中取考生的順序,查詢獲取考生依據的排序關鍵字為兩個:「隨機數」、報名點。
報名點順序的產生辦法:從報名庫中查詢到所有報名點的考生數,根據各報名點的考生數從多到少,給報名點賦予順序號0、1、2、……
考慮到需要排定的考生較多,如果一次從資料庫中查詢所有的考生,放到記憶體中排定,則記憶體的容量可能吃緊。所以每次都直接從資料庫中查詢,排定時將考場號和座位號存入資料庫中。其基本程式的實現如下(此程式使用pony的orm,考生報名庫為postgresql。github庫:
import random,math
from pony.orm import *
__author__ = "cloveses"
db_params =
db = database()
class studarrg(db.entity):
signid = required(str)
name = required(str)
schcode = required(str)
sch = required(str)
sch_seq = optional(int)
room_code = optional(int)
number = optional(int)
sturand = optional(float)
db.bind(**db_params)
room_unit = 30
# 為所有考生設定隨機數,以打亂報名號
@db_session
def set_rand():
for s in studarrg.select():
s.sturand = random.random() * 10000
# 查詢獲取考生數、計算考場數、尾場人數、各報名學校人數
@db_session
def get_sch_data(room_unit=room_unit):
totals = count(studarrg.select())
rooms = math.ceil(totals / room_unit)
tails = totals % room_unit
sch_data = select((s.schcode,count(s.name)) for s in studarrg)[:]
sch_data.sort(key=lambda s:s[1],reverse=true)
return (rooms,tails),sch_data
# 為報名學生設定序號(報名人數較多優先排定,讓學生均勻分布各考場)
@db_session
def set_sch_seq(sch_seq):
for index,sch in enumerate(sch_seq):
for s in select(s for s in studarrg if s.schcode == sch[0]):
s.sch_seq = index
# 安排考生的考場和座位號
@db_session
def arrange_room():
rooms,sch_data = get_sch_data()
set_rand()
set_sch_seq(sch_data)
# print(rooms)
totals,tails = rooms
# 安排定考室
for i in range(tails):
rc = 0
while true:
stud = studarrg.select(lambda s:s.room_code <= 0 or s.room_code is none).order_by(studarrg.sturand).order_by(studarrg.sch_seq).first()
if stud:
stud.room_code = rc + 1
rc += 1
if rc >= totals:
break
totals -= 1 ## 去除尾場考生安排
for i in range(room_unit - tails):
rc = 0
while true:
stud = studarrg.select(lambda s:s.room_code <= 0 or s.room_code is none).order_by(studarrg.sturand).order_by(studarrg.sch_seq).first()
if stud:
stud.room_code = rc + 1
rc += 1
if rc >= totals:
break
# 排定座位號
for i in range(totals):
arrange_seat(i+1)
# 排定一場座位號(考點學生從多到少排列後確定)
@db_session
def arrange_seat(roomth):
studs = studarrg.select(lambda s:s.room_code == roomth)[:]
schs = [s.schcode for s in studs]
sch_num_dict =
studs.sort(key=lambda s:sch_num_dict[s.schcode],reverse=true)
half = math.ceil(len(studs) / 2)
res =
for x,y in zip(studs[:half],studs[half:]):
res.extend([x,y])
for i,s in enumerate(res):
s.number = i + 1
if __name__ == '__main__':
arrange_room()
邏輯回歸演算法的一種實現
邏輯回歸演算法的一種實現 1 import numpy as np import matplotlib.pyplot as plt 載入資料集,將資料集中兩列資料分別儲存到datamat和labelmat def loaddataset datamat labelmat fr open home j...
快速排序演算法的一種實現
參考部落格 白話經典演算法系列之六 快速排序 快速搞定 功能 實現快速排序演算法 include 方法宣告 intadjustsort int a,int m,int n void quicksort int a,int m,int n int main void printf 排序前的陣列順序.n...
一種濾波演算法
剛看到要寫濾波演算法的時候懵了,想著是不是要去掉最大值 最小值什麼的,感覺很高大上 於是開始查資料了解,發現濾波演算法其實有很多種方法,如下列舉了一些,當然能起到的濾波作用也是不同的 於是我看了下,選擇了一種最簡單實用的濾波演算法學習了一下,即下面的中位值濾波演算法 簡單來說就是多次取樣,排序,取中...