编排试场的算法,如何保证前后座考生不是来自同一个学校?

请教:有一个dbf表,有准考号、考点代码、毕业学校代码 3个关键字段,原先已经通过随机编排产生了准考号,编排的条件是(例如先指定毕业学校代码为01、02、03的考生,各200人(或者220、150、200,即人数可以不一样多),将他们的考点代码设成A1考点,将毕业学校代码为04、05、06、07的考生,各180人,将他们的考点代码设成A2考点,依次类推,然后通过产生随机数,将他们按先考点,后随机数大小排序,根据这个顺序,产生连续的准考号),现在多了一个要求,需要让连续的准考号其前后考生的毕业学校代码不同,即前后排不能来自同一个学校。
请教有什么好的算法,要么在生成准考号时直接加入这个控制要求,或者是生成后通过比较前后考生的毕业学校码,来调换准考号,使满足要求。
目前已通过第2种方法将顺序调整,但由于是随机调动,可能造成某个考点由于最后剩下的几个考生都来自同一个学校而出错,请大家指教,非常感谢。
我的代码如下,用的方法很土:
USE bmk ORDER zkzh
DO WHILE !EOF()
bmd=byxxdm  &&毕业学校代码
kh1=zkzh  &&准考号
kd=kddm  &&考点代码
IF !EOF()
SKIP
num=RECNO()  &&记录指针位置
kh2=zkzh
IF byxxdm=bmd AND !EOF() AND kddm=kd
SCAN REST FOR byxxdm <>bmd AND kddm=kd
kh3=zkzh
REPLACE bmk.zkzh WITH kh2
newnum=RECNO()  &&记录新指针位置
GO num
REPLACE bmk.zkzh WITH kh3
GO newnum
EXIT
ENDSCAN
ENDIF
ENDIF
ENDDO

 

 

解决方法:

我曾经设计过类似的程序,现将主要思路说明如下,希望能对你有帮助

增加一个字段为过度码(gdm)

1、按照毕业学校进行排序,
2、将nCnt赋值为考试总人数;
3、分别将nCnt_1,nCnt_2……赋值为各学校人数;
4、应用下面的命令设置过度码
for i=1 to nCnt_1 step nCnt_1/nCnt  **将毕业学校人数与考试总人数的商作为跳步设置过度码
replace all gdm with str(i)for alltrim(毕业学校)="01"
skip
endfor

for i=1 to nCnt_2 step nCnt_2/nCnt  **将毕业学校人数与考试总人数的商作为跳步设置过度码
replace all gdm with str(i)for alltrim(毕业学校)="02"
skip
endfor

……

5、按照过度码排序
6、编一个程序查找相邻的考生是否同校即可。
思路:将表中第一个考生的学校名称存入一个变量如byxx1,将第二个考生的学校名称存入变量如byxx2,比较byxx1和byxx2是否相同,如相同则显示或存入一个表,注意循环。

接着

如果找到学校相同的考生相邻,只需将过度码微调即可,因为这样的几率已经很小,即使有,也不会很多,我在操作15所学校近5000考生时,只出现了3对。另外如果出现很多,您可以通过调整各学校的i的初值来逐步调整,知道人数较少时就可以了。
说明:1、为了使排出的结果更符合需求,对过度码(数值型)的位数设置的多一些,尤其是小数部分,前面的代码可能有错误,抱歉。
2、排出的结果能保证每个学校在每一个考场都有考生,对于学校来讲或许更能体现公平。
3、这种方法得到的结果中,出现同校相邻的考生大多来自于考生数最多的学校。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值