注册 登录
编程论坛 VFP论坛

再次请教学生如何分派

chychychy 发布于 2024-12-03 16:06, 1156 次点击
只有本站会员才能查看附件,请 登录

工作需要均衡分配学生,近日浏览查询发现论坛前期wengjl曾发过同样的帖子,一是我个人水平有限没完全读懂高手的语句,二是没完全解决问题
这里我借鉴wengjl数据表,修改了一下人数(致谢)
报名库(bmk)中共3200人,按计划库(zkjhk)中字段zsrs人数要求分别录取到一中(招690人)、二中(招850人)、三中(招1000人)、四中(招660人),分派时,只考虑中考成绩的均衡即可(性别及毕业学校等不用考虑)
请教
1.Tiger5392版的程序结果有时人数不完全相同,如何解决,能否注解一下
2.wengjl版用平均分(pjf)来衡量均衡性,请教还有更好的方式吗
Tiger5392版语句如下
程序代码:
CLOSE ALL
USE zkjhk
COPY TO ARRAY laArr FIELDS zsrs
USE bmk.DBF
RAND(SECONDS())
STORE 0 TO lnCnt1,lnCnt2,lnCnt3,lnCnt4
SCAN
    lnRound=RAND()
    DO CASE
    CASE lnRound<=laArr(1)/(laArr(1)+laArr(2)+laArr(3)+laArr(4)) AND lnCnt1<laArr(1)
        lcSchool='0100'
        lnCnt1=lnCnt1+1
    CASE lnRound<=(laArr(1)+laArr(2))/(laArr(1)+laArr(2)+laArr(3)+laArr(4)) AND lnCnt2<laArr(2)
        lcSchool='0200'
        lnCnt2=lnCnt2+1
    CASE lnRound<=(laArr(1)+laArr(2)+laArr(3))/(laArr(1)+laArr(2)+laArr(3)+laArr(4)) AND lnCnt3<laArr(3)
        lcSchool='0300'
        lnCnt3=lnCnt3+1
    OTHERWISE
        lcSchool='0400'
        lnCnt4=lnCnt4+1
    ENDCASE
    REPLACE lqxxdm WITH lcSchool
ENDSCAN
SELECT lqxxdm,COUNT(*) lqrs,AVG(tot) pjf FROM bmk GROUP BY lqxxdm
56 回复
#2
sdta2024-12-03 19:50
均衡分配学生,其均衡的标准是什么?
#3
chychychy2024-12-03 20:30
回复 2楼 sdta
确实难,大T 版的是看平均分,里面的逻辑我也没看懂。如果平均分班的话,能s 型排列,这个人数又不均等,求指教

[此贴子已经被作者于2024-12-5 21:36编辑过]

#4
chychychy2024-12-03 21:02
回复 2楼 sdta
原来是分到3个校区,比如A校区500,B和C各1000,因为整好是倍数关系,我们是像分班一样按分数高低(1234554321)蛇形分成5个,类似抓阄,A抓一个,B和C各抓两个。以此实现分数高低的均衡。可是现在分成4个校区,而且人数不均等,还要【均衡】,我也没能想明白,请指教

[此贴子已经被作者于2024-12-3 21:48编辑过]

#5
schtg2024-12-04 07:19
回复 楼主 chychychy
测试了一下,自动 + 手动,确有难度。
只有本站会员才能查看附件,请 登录

只有本站会员才能查看附件,请 登录
#6
chychychy2024-12-04 07:59
回复 5楼 schtg
您用的还是之前wengjl(https://bbs.bccn.net/viewthread.php?tid=355567&highlight=%D1%A7%C9%FA)上传数据(他的人数更细致具体到了个位数),看来也还在留意这个数据的处理,平时也关注您的帖子及回复,想看看您对程序注解和对均衡的建议,谢谢

[此贴子已经被作者于2024-12-4 08:13编辑过]

#7
sxcl78992024-12-04 08:16
回复 4楼 chychychy
原来分数从高到低分成5类,现在是否也可以按照5类分,假设A类的人员在3200个人中间占比30%吧,那么分到一中的A类人员为:690*0.3/3200,以此类推,确定好各类分配人员,再随机抽取,或者再结合一下平均成绩,是否更好一点呢?
#8
chychychy2024-12-04 08:30
回复 7楼 sxcl7899
这样有一定道理,先把学生分成5类或者3类,能够更相对公平,分完再合并。这样学生录取人数下来达到【均衡】忒不好实现了,有了思路,再考虑程序语句才更有意义,谢谢
[附件]
只有本站会员才能查看附件,请 登录
[/附件]
这样想,将学生按总分从高到底分成4类,再按Tiger5392版的方式分派

以下是Tiger5392当年表达的
RAND()产生均匀分布的随机数,根据待分配的4个学校的名额,设计4个随机数该落入的区间,假如名额分别占10%、20%、30%、40%,则区间分别为(0,0.1]、(0.1,0.3]、(0.3,0.6]、(0.6,1]。由于所产生的随机数并不一定均匀,故落入4个区间的实际随机数并不一定占10%、20%、30%、40%,结果人数就不一定是正确的。需要做点微调:一种情况就是分配好了以后人为调整学校;二种情况就是修改程序(稍微麻烦一点)

[此贴子已经被作者于2024-12-4 09:39编辑过]

#9
wengjl2024-12-04 08:50
非常感谢Tiger5392版,当年给了我代码!最终领导没有出台派位招生的政策,但学到了思路。经T版的帮助,我就有了应对领导出台派位法招生的思路和方法,心中也就不用焦虑了!
我通过学习所理解的原理是,随机散落的机会是均等的,就像农民在田间撒种子,把一块田看作 1 ,四校的招生占比总和  =1 ,虽然各校招生数多少不一,用了T版的思路就很好地解决了问题
对每位学生写上一个随机数后,按随机数所在区间划给相应的学校,以此实现随机分配学生。
#10
chychychy2024-12-04 09:30
回复 9楼 wengjl
我看您当年帖子【经过反反复复的计算,结果基本符合心理预期,最作一些修改,就可用于解决实际问题了】求教您如何进一步修改的,我们这里现在面临分到4个校区且人数不等的情况,学校和领导想要分数的均衡,尤其是相对高分段人数的均衡

[此贴子已经被作者于2024-12-4 09:34编辑过]

#11
wengjl2024-12-04 10:52
以下是引用chychychy在2024-12-4 09:30:53的发言:

我看您当年帖子【经过反反复复的计算,结果基本符合心理预期,最作一些修改,就可用于解决实际问题了】求教您如何进一步修改的,我们这里现在面临分到4个校区且人数不等的情况,学校和领导想要分数的均衡,尤其是相对高分段人数的均衡


回家去U盘里找找看,退休5年了,找到的话我发上来,找不到的话已是想不出来了。
#12
chychychy2024-12-04 13:58
回复 11楼 wengjl
感谢,退休五年乐悠悠,岁月静好福满园,安康喜乐每一天!
#13
schtg2024-12-04 20:33
回复 6楼 chychychy
使用你的数据,仍采取 自动 + 手动,确有难度,一起研究哈。
只有本站会员才能查看附件,请 登录

只有本站会员才能查看附件,请 登录
#14
wengjl7 天前 08:06
只有本站会员才能查看附件,请 登录

数据找到,楼主你慢慢研究。可在界面上多点几下录取按钮进行体验
当时只模拟到总分相对均等,男女基本平衡。事实上还有毕业初中的均衡等问题...
再次感谢T版当年的帮助!后来把这个思路用于分班操作也很好。
#15
easyppt7 天前 08:15
向老师们致敬!
#16
chychychy7 天前 08:40
回复 13楼 schtg
只有本站会员才能查看附件,请 登录
只有本站会员才能查看附件,请 登录

谢谢,从上面截图看每个校区前5名和前10名分布,不很理想,比如前5,0300校区的前5都是总分的前10,0100校区和他比就相对都靠后;各校区尤其关心高分段学生的分布,如何更好解决?求教

[此贴子已经被作者于2024-12-5 08:48编辑过]

#17
chychychy7 天前 08:48
回复 14楼 wengjl
感谢🙏
#18
wengjl7 天前 08:53
高分段人数,肯定是谁总数大,谁多!中国是人口大国,聪明人肯定比人口小国多。
应该是做到高分段人数的占比相对均等就可以了

#19
chychychy7 天前 09:10
回复 18楼 wengjl
🙏
#20
chychychy7 天前 20:58
回复 18楼 wengjl
感谢wengjl版提供的帮助,解决了我的大难题。为了满足学校对高分段学生均衡的要求,考虑前200名12344321蛇形排列,领导初步同意
剩下的按wengjl版的方式随机来处理。因水平有限,程序写起来很不简洁,请指教。同时请论坛内高手看看还有更好的方法解决吗
程序代码:
***第一步蛇形处理前200名
CLEAR
CLOSE DATABASES
MESSAGEBOX("准备打开需分派的数据表",0+48)
fn1=GETFILE('dbf','打开分派数据库')
USE (fn1) ALIAS bmk IN 0
BLANK FIELDS lqxxdm ALL &&清空录取学校代码字段,测试用

***先取出前200名,12344321蛇形分派
SELECT * FROM bmk ORDER BY zf DESC INTO CURSOR tmp READWRITE &&按总分降序排列


IF TYPE([zfwc])=[U] &&增加总分位次字段
    ALTER TABLE tmp ADD zfwc N(8)
ENDIF
UPDATE tmp SET zfwc=(SELECT COUNT(*)+1 FROM tmp AS b WHERE b.zf>tmp.zf) &&排列总分位次字段

IF TYPE([分派号])=[U]  &&增加分派号字段
    ALTER TABLE tmp ADD 分派号 N(2)
ENDIF
SELECT TOP 200 * FROM tmp ORDER BY zf DESC INTO CURSOR tmp200 READWRITE &&导出前200名临时表
SELECT tmp200

NN=4 &&重要:设定需分派数,此处为4个校区,如需增加减少,替换NN即可,顺序写入分班
REPLACE ALL 分派号 WITH IIF(MOD(RECNO()-1,2*NN)<NN,MOD(RECNO()-1,NN)+1,NN-MOD(RECNO()-1,NN))

SCAN FOR !EMPTY(分派号) &&&&按分派号替换写入录取学校代码lqxxdm
    DO CASE
    CASE 分派号=1
        REPLACE lqxxdm WITH '0100'
    CASE 分派号=2
        REPLACE lqxxdm WITH '0200'
    CASE 分派号=3
        REPLACE lqxxdm WITH '0300'
    CASE 分派号=4
        REPLACE lqxxdm WITH '0400'
    ENDCASE
ENDSCAN
*SELECT zkzh,zf,zfwc,分派号,lqxxdm FROM tmp200 ORDER BY zf DESC
*GO TOP
*BROWSE
*SELECT tmp
SELECT lqxxdm,COUNT(*) rs,AVG(zf) pjf GROUP BY 1 FROM tmp200 &&测试查看用
UPDATE tmp FROM tmp200 SET lqxxdm=tmp200.lqxxdm WHERE tmp.zkzh=tmp200.zkzh
UPDATE bmk from tmp200 SET lqxxdm=tmp200.lqxxdm WHERE bmk.zkzh=tmp200.zkzh &&&将前200名录取结果写回原始报名库

SELECT bmk

SELECT * FROM tmp where EMPTY(lqxxdm) INTO cursor tmp2 READWRITE

***第二步,按wengjl版的方式处理剩余数据
LOCAL zss1,zss2,zss3,zss4,lnCnt1,lnCnt2,lnCnt3,lnCnt4,xhkz

MESSAGEBOX("准备打开招生计划库数据表",0+48)
fn2=GETFILE('dbf','打开计划数据库')
USE (fn2) ALIAS zkjhk IN 0
SELECT *,zsrs-50 as zsrs1 FROM zkjhk INTO CURSOR zkjhk1 READWRITE &&减去上面的200人,4给校区各减去50人


COPY TO ARRAY laArr FIELDS zsrs1
*zss1=thisform.cont1.text1.value
*zss2=thisform.cont1.text2.value
*zss3=thisform.cont1.text3.value
*zss4=thisform.cont1.text4.value
zss1=laArr(1)
zss2=laArr(2)
zss3=laArr(3)
zss4=laArr(4)
?zss1 &&测试查看用
?zss2 &&测试查看用
?zss3 &&测试查看用
?zss4 &&测试查看用

xhkz=.T.    &&&&循(XUN)环(HUAN)控制变量

SELECT tmp2
*IF RECCOUNT()>zss1+zss2+zss3+zss4
*  MESSAGEBOX([color=#FF0000]'待录取的人数大于总招生数,会使程序进入死循环的!!! 请修改招生计划或修改录取程序!',48,'警告:')[/color]
*  [color=#0000FF]RETURN[/color]
*ENDIF

GO TOP
RAND(SECONDS())     &&&& 根据时间秒数的不一,来产生随机数,保证每次启动都不一样
STORE 0 TO lnCnt1,lnCnt2,lnCnt3,lnCnt4   &&& 给四个变量赋初值为0
DO WHIL xhkz        &&&& 当循环控制变量为真时循环进行下去
    GO TOP
    SCAN FOR EMPTY(lqxxdm)
        lnRound=RAND()
        DO CASE
        CASE lnRound<=zss1/(zss1+zss2+zss3+zss4) AND lnCnt1<zss1
            lcSchool='0100'
            lnCnt1=lnCnt1+1
            REPLACE lqxxdm WITH lcSchool
        CASE lnRound<=(zss1+zss2)/(zss1+zss2+zss3+zss4) AND lnCnt2<zss2
            lcSchool='0200'
            lnCnt2=lnCnt2+1
            REPLACE lqxxdm WITH lcSchool
        CASE lnRound<=(zss1+zss2+zss3)/(zss1+zss2+zss3+zss4) AND lnCnt3<zss3
            lcSchool='0300'
            lnCnt3=lnCnt3+1
            REPLACE lqxxdm WITH lcSchool
        CASE lnRound<=(zss1+zss2+zss3+zss4)/(zss1+zss2+zss3+zss4) AND lnCnt4<zss4
            lcSchool='0400'
            lnCnt4=lnCnt4+1
            REPLACE lqxxdm WITH lcSchool
*!*        OTHERWISE
*!*          lcSchool='0400'
*!*          lnCnt4=lnCnt4+1
        ENDCASE
    ENDSCAN
    *--------------
*每完成一次扫描后,检测是否有学生未被录取,有学生未被录取,必有学校未招满学生
    nn=0
    GO TOP
    SCAN
        IF EMPTY(lqxxdm)
            nn=nn+1
        ENDIF
    ENDSCAN
    IF nn=0     &&&& 如果全部学生都有录取学校了,则改变循环控制变量为假,使循环结束。
        xhkz=.F.
    ENDIF
ENDDO
*SELECT lqxxdm,COUNT(*) FROM tmp2 GROUP BY 1 &&测试查看用
UPDATE bmk from tmp2 SET lqxxdm=tmp2.lqxxdm WHERE bmk.zkzh=tmp2.zkzh &&&将前200名录取结果写回原始报名库


* 对各校的录取情况进行统计
SELECT bmk
*SELECT lqxxdm,COUNT(*) FROM bmk GROUP BY 1 &&测试查看用

SELECT zkjhk
GO TOP
SCAN
    SELECT bmk
    sn=0
    GO TOP
    SCAN
        IF bmk.lqxxdm=zkjhk.xxdm
            sn=sn+bmk.zf
        ENDIF
    ENDSCAN
    GO TOP
    COUNT TO nn FOR bmk.lqxxdm=zkjhk.xxdm
    COUNT TO mm FOR bmk.xbm='2' AND bmk.lqxxdm=zkjhk.xxdm
    SELECT zkjhk
    REPLACE zkjhk.lqrs WITH nn,zkjhk.pjf WITH sn/nn
    REPLACE zkjhk.nsrs WITH mm,zkjhk.nsbl WITH mm/nn*100 &&计算女生比例
ENDSCAN

*SELECT bmk
*GO top
*BROWSE &&查看测试用
SELECT zkjhk
GO TOP
BROWSE &&查看测试用
#21
wengjl6 天前 16:48
以下是引用chychychy在2024-12-5 20:58:25的发言:

感谢wengjl版提供的帮助,解决了我的大难题。为了满足学校对高分段学生均衡的要求,考虑前200名12344321蛇形排列,领导初步同意
剩下的按wengjl版的方式随机来处理。因水平有限,程序写起来很不简洁,请指教。同时请论坛内高手看看还有更好的方法解决吗
***第一步蛇形处理前200名
CLEAR
CLOSE DATABASES
MESSAGEBOX("准备打开需分派的数据表",0+48)
fn1=GETFILE('dbf','打开分派数据库')
USE (fn1) ALIAS bmk IN 0
BLANK FIELDS lqxxdm ALL &&清空录取学校代码字段,测试用

***先取出前200名,12344321蛇形分派
SELECT * FROM bmk ORDER BY zf DESC INTO CURSOR tmp READWRITE &&按总分降序排列


IF TYPE([zfwc])=[U] &&增加总分位次字段
    ALTER TABLE tmp ADD zfwc N(8)
ENDIF
UPDATE tmp SET zfwc=(SELECT COUNT(*)+1 FROM tmp AS b WHERE b.zf>tmp.zf) &&排列总分位次字段

IF TYPE([分派号])=[U]  &&增加分派号字段
    ALTER TABLE tmp ADD 分派号 N(2)
ENDIF
SELECT TOP 200 * FROM tmp ORDER BY zf DESC INTO CURSOR tmp200 READWRITE &&导出前200名临时表
SELECT tmp200

NN=4 &&重要:设定需分派数,此处为4个校区,如需增加减少,替换NN即可,顺序写入分班
REPLACE ALL 分派号 WITH IIF(MOD(RECNO()-1,2*NN)<NN,MOD(RECNO()-1,NN)+1,NN-MOD(RECNO()-1,NN))

SCAN FOR !EMPTY(分派号) &&&&按分派号替换写入录取学校代码lqxxdm
    DO CASE
    CASE 分派号=1
        REPLACE lqxxdm WITH '0100'
    CASE 分派号=2
        REPLACE lqxxdm WITH '0200'
    CASE 分派号=3
        REPLACE lqxxdm WITH '0300'
    CASE 分派号=4
        REPLACE lqxxdm WITH '0400'
    ENDCASE
ENDSCAN
*SELECT zkzh,zf,zfwc,分派号,lqxxdm FROM tmp200 ORDER BY zf DESC
*GO TOP
*BROWSE
*SELECT tmp
SELECT lqxxdm,COUNT(*) rs,AVG(zf) pjf GROUP BY 1 FROM tmp200 &&测试查看用
UPDATE tmp FROM tmp200 SET lqxxdm=tmp200.lqxxdm WHERE tmp.zkzh=tmp200.zkzh
UPDATE bmk from tmp200 SET lqxxdm=tmp200.lqxxdm WHERE bmk.zkzh=tmp200.zkzh &&&将前200名录取结果写回原始报名库

SELECT bmk

SELECT * FROM tmp where EMPTY(lqxxdm) INTO cursor tmp2 READWRITE

***第二步,按wengjl版的方式处理剩余数据
LOCAL zss1,zss2,zss3,zss4,lnCnt1,lnCnt2,lnCnt3,lnCnt4,xhkz

MESSAGEBOX("准备打开招生计划库数据表",0+48)
fn2=GETFILE('dbf','打开计划数据库')
USE (fn2) ALIAS zkjhk IN 0
SELECT *,zsrs-50 as zsrs1 FROM zkjhk INTO CURSOR zkjhk1 READWRITE &&减去上面的200人,4给校区各减去50人


COPY TO ARRAY laArr FIELDS zsrs1
*zss1=thisform.cont1.text1.value
*zss2=thisform.cont1.text2.value
*zss3=thisform.cont1.text3.value
*zss4=thisform.cont1.text4.value
zss1=laArr(1)
zss2=laArr(2)
zss3=laArr(3)
zss4=laArr(4)
?zss1 &&测试查看用
?zss2 &&测试查看用
?zss3 &&测试查看用
?zss4 &&测试查看用

xhkz=.T.    &&&&循(XUN)环(HUAN)控制变量

SELECT tmp2
*IF RECCOUNT()>zss1+zss2+zss3+zss4
*  MESSAGEBOX('待录取的人数大于总招生数,会使程序进入死循环的!!! 请修改招生计划或修改录取程序!',48,'警告:')
*  RETURN
*ENDIF

GO TOP
RAND(SECONDS())     &&&& 根据时间秒数的不一,来产生随机数,保证每次启动都不一样
STORE 0 TO lnCnt1,lnCnt2,lnCnt3,lnCnt4   &&& 给四个变量赋初值为0
DO WHIL xhkz        &&&& 当循环控制变量为真时循环进行下去
    GO TOP
    SCAN FOR EMPTY(lqxxdm)
        lnRound=RAND()
        DO CASE
        CASE lnRound<=zss1/(zss1+zss2+zss3+zss4) AND lnCnt1<zss1
            lcSchool='0100'
            lnCnt1=lnCnt1+1
            REPLACE lqxxdm WITH lcSchool
        CASE lnRound<=(zss1+zss2)/(zss1+zss2+zss3+zss4) AND lnCnt2<zss2
            lcSchool='0200'
            lnCnt2=lnCnt2+1
            REPLACE lqxxdm WITH lcSchool
        CASE lnRound<=(zss1+zss2+zss3)/(zss1+zss2+zss3+zss4) AND lnCnt3<zss3
            lcSchool='0300'
            lnCnt3=lnCnt3+1
            REPLACE lqxxdm WITH lcSchool
        CASE lnRound<=(zss1+zss2+zss3+zss4)/(zss1+zss2+zss3+zss4) AND lnCnt4<zss4
            lcSchool='0400'
            lnCnt4=lnCnt4+1
            REPLACE lqxxdm WITH lcSchool
*!*        OTHERWISE
*!*          lcSchool='0400'
*!*          lnCnt4=lnCnt4+1
        ENDCASE
    ENDSCAN
    *--------------
*每完成一次扫描后,检测是否有学生未被录取,有学生未被录取,必有学校未招满学生
    nn=0
    GO TOP
    SCAN
        IF EMPTY(lqxxdm)
            nn=nn+1
        ENDIF
    ENDSCAN
    IF nn=0     &&&& 如果全部学生都有录取学校了,则改变循环控制变量为假,使循环结束。
        xhkz=.F.
    ENDIF
ENDDO
*SELECT lqxxdm,COUNT(*) FROM tmp2 GROUP BY 1 &&测试查看用
UPDATE bmk from tmp2 SET lqxxdm=tmp2.lqxxdm WHERE bmk.zkzh=tmp2.zkzh &&&将前200名录取结果写回原始报名库


* 对各校的录取情况进行统计
SELECT bmk
*SELECT lqxxdm,COUNT(*) FROM bmk GROUP BY 1 &&测试查看用

SELECT zkjhk
GO TOP
SCAN
    SELECT bmk
    sn=0
    GO TOP
    SCAN
        IF bmk.lqxxdm=zkjhk.xxdm
            sn=sn+bmk.zf
        ENDIF
    ENDSCAN
    GO TOP
    COUNT TO nn FOR bmk.lqxxdm=zkjhk.xxdm
    COUNT TO mm FOR bmk.xbm='2' AND bmk.lqxxdm=zkjhk.xxdm
    SELECT zkjhk
    REPLACE zkjhk.lqrs WITH nn,zkjhk.pjf WITH sn/nn
    REPLACE zkjhk.nsrs WITH mm,zkjhk.nsbl WITH mm/nn*100 &&计算女生比例
ENDSCAN

*SELECT bmk
*GO top
*BROWSE &&查看测试用
SELECT zkjhk
GO TOP
BROWSE &&查看测试用

#22
schtg6 天前 18:54
回复 20楼 chychychy
谢谢分享!
经过 自动 + 手动,目前可以达到的效果:
只有本站会员才能查看附件,请 登录

只有本站会员才能查看附件,请 登录


可以使用下面的数据表检验一下
只有本站会员才能查看附件,请 登录

确属较高难度的动作哦!

[此贴子已经被作者于2024-12-7 13:34编辑过]

#23
chychychy5 天前 21:35
回复 22楼 schtg
谢谢,我再试试,相信拿出有你这个数据分析当支撑,校长和领导们会更满意。请指教分享您的这段程序。
程序代码:

SELECT lqxxdm,COUNT(*) zrs ,;
SUM(IIF(sxh<=4,1,0)) AS 前4名, ;
SUM(IIF(sxh<=8,1,0)) AS 前8名, ;
SUM(IIF(sxh<=12,1,0)) AS 前12名, ;
SUM(IIF(sxh<=20,1,0)) AS 前20名, ;
SUM(IIF(sxh<=50,1,0)) AS 前50名, ;
SUM(IIF(sxh<=100,1,0)) AS 前100名, ;
SUM(IIF(sxh<=200,1,0)) AS 前200名 ;
FROM 学生分配表 GROUP BY 1 WHERE !EMPTY(sxh)


[此贴子已经被作者于2024-12-8 06:15编辑过]

#24
schtg4 天前 09:33
回复 23楼 chychychy
前面位次录取,在Excel中做的(这次取了前384名作为位次录取),剩余考生按照你提供的代码做的哈,所以才有 自动 + 手动,才有难度
提供 位次考生 录取 规则:
只有本站会员才能查看附件,请 登录

按照这个规则,比较好地体现位次均衡,同时方便平衡总分。
结果:
只有本站会员才能查看附件,请 登录


检验文件
只有本站会员才能查看附件,请 登录


[此贴子已经被作者于2024-12-8 09:41编辑过]

#25
wengjl4 天前 11:35
我下周有时间,可以研究一下你的需求。@chychychy,能否把你的真实数据发给我,可以的话加QQ。
#26
chychychy4 天前 12:50
回复 25楼 wengjl
感谢,几天在在外有考试任务,回去后发您,我qq313693957,您的?方便我加您
#27
chychychy3 天前 10:40
回复 24楼 schtg
您这这种规则不仅是单纯的12344321,中间还有变化,请教比如9、10、11、12和13、14、15、16变化的逻辑是什么?用vfp如何实现?
#28
my23183 天前 10:51
以下是引用schtg在2024-12-8 09:33:50的发言:

前面位次录取,在Excel中做的(这次取了前384名作为位次录取),剩余考生按照你提供的代码做的哈,所以才有 自动 + 手动,才有难度
提供 位次考生 录取 规则:

按照这个规则,比较好地体现位次均衡,同时方便平衡总分。
结果:


检验文件

每轮8个人,按蛇形排列组成4对,
如果每轮分派随机把一对学生分到一个学校,不知均衡性如何?
#29
my23183 天前 10:55
以下是引用wengjl在2024-12-8 11:35:46的发言:

我下周有时间,可以研究一下你的需求。@chychychy,能否把你的真实数据发给我,可以的话加QQ。

如果把姓名家庭住址身份证号码脱敏,真实数据发上来应该没问题
#30
chychychy3 天前 16:50
回复 29楼 my2318
只有本站会员才能查看附件,请 登录

谢谢,数据都差不多,wengjl的数据也比较有代表性,难在用什么方式解决人数不均等、不成倍数关系下的“均衡”
#31
schtg前天 06:56
回复 27楼 chychychy
这是一个老教务告诉我的方法,如何用VFP来实现?确实没有想到好的办法,所以才放到Excel中去粘贴的。
VFP可否可以使用数组来填充录取信息?有空时试一下。
#32
schtg前天 06:58
回复 28楼 my2318
随机的话,应该也是可以的哈。但我觉得这样硬性分配更直观、具体一点,不知理解对否?
#33
schtg前天 08:39
回复 30楼 chychychy
请问:如何理解 2B2C2D 以上考生?
我的理解对吗?注意删除部分(即不能参与录取的)是否合理?
只有本站会员才能查看附件,请 登录


经过自动 + 手动,结果如下:
只有本站会员才能查看附件,请 登录

录取数据表
只有本站会员才能查看附件,请 登录


[此贴子已经被作者于2024-12-10 09:26编辑过]

#34
chychychy前天 09:48
回复 33楼 schtg
只有本站会员才能查看附件,请 登录
您的这个数和我们这边要求的有出入,我将您的xkzh字段按下面语句重新排序,将lqxxdm字段标记31对比了一下,我计算符合条件的有5974条,您的是6621条,
关于BBCCDD(2B2C2D)这个我多年前在https://bbs.bccn.net/thread-495360-1-1.html讨论求助过,在这个要求里(2B2C2D)是最低标准,而且目前是不能折合替代,比如有的地方有一个A可以多一个D
2009370982001810262这个BBBCCD,3B2C1D,是符合要求的,高于2B2C2D最低要求;
2009370982100510041这个BCCCCC,1B5C是不符合要求的了,少一个B;
我借助论坛程序,将等级排列组合重新排序,然后逐个对位比较的,方法比较笨但是安全可靠,论坛大佬的其他方式当时有的我没能理解透
程序代码:

BLANK FIELDS xkzh ALL
BROWSE
**提取并排序
SCAN
    SCATTER FIELDS wldj,hxdj,zzdj,lsdj,dldj,swdj TO px6
    = ASORT(px6)
    REPLACE xkzh WITH ALLTRIM(px6[1] - px6[2] - px6[3] - px6[4] - px6[5] - px6[6] )
ENDSCAN
**对位比较,因为最低组合是BBCCDD;排序后利用A<B<C<D逻辑逐个对位比较
REPLACE ALL lqxxdm  WITH '31' FOR SUBSTR(xkzh,1,1)<='B' AND SUBSTR(xkzh,2,1)<='B' AND SUBSTR(xkzh,3,1)<='C' AND SUBSTR(xkzh,4,1)<='C'AND SUBSTR(xkzh,5,1)<='D'AND SUBSTR(xkzh,6,1)<='D'




[此贴子已经被作者于2024-12-10 11:00编辑过]

#35
schtg前天 12:43
回复 34楼 chychychy
好的,我就是不太理解 2B2C2D 的含义,我还在那里参与讨论,好像还是没有搞懂,谢谢纠正!

[此贴子已经被作者于2024-12-10 13:01编辑过]

#36
sdta前天 13:06
2B2C2D 的含义,应该是:
最多2个B
最多2个C
最多2个D

#37
chychychy前天 14:20
回复 36楼 sdta
这个地方确实有点绕,当年您指导过,您的排序等语句给很大的帮助
CREATE CURSOR TT (X1 C(1));FOR I = 65 TO 68
    INSERT INTO TT VALUES(CHR(I))
ENDFOR
……
这样我测试过,具体结果忘了
当年我参与时,在执行中,BBCCDD(2B2C2D)是底线要求,而且A不能向下抵
BBBCCD,3B2C1D高于(BBCCDD)要求,符合
BCCCCC,1B5C,低于(BBCCDD)要求,不符合,少一个B;
ACCCCD,1A3C1D,低于(BBCCDD)要求,不符合,少一个B;
ACDDDD,1A1C4D,低于(BBCCDD)要求,不符合,D多了两个,B少一个;
如果简单整体判断,因为A<B<C<D<E,所以导致ACCCCD\ACDDDD等不符合2B2C2D(BBCCDD)的情况也被计算为合格了。
后来没再参与这个工作,而且后续文件也有了改变,指导意见表述内容如下:
统招生。生物、道德与法治、历史、地理等级成绩的基本要求为 2C1D。在进行等级科目成绩比较时,4 门等级科目之间可进行等级置换,
即一科目降低一个等级,另一科目可提高一个等级。如:某考生生物等级成绩为 A,道德与法治等级成绩为 D,当生物降低一个等级变为 B 后,道德与法治可提高一个等级变为 C,即 1A1D=1B1C

4个科目是2C1D以上是基本要求,重点高中的是2B1C1D,一般高中直接表述的 2C1D,这样判断又变的更复杂了,
我没测试,但我觉得您当年判断(下面蓝色语句)应该适合上面的这种要求(即一科目降低一个等级,另一科目可提高一个等级)
过去判断BCCC(1B3C)条件
OCCURS("D", 字符串) = 0 AND OCCURS("C", 字符串) <= 3 AND 字符串 <= "BCCC"

现在一个同事商讨集团内部已录取考生均衡分派,因人数不均衡也不成倍数比例,所以又来爬论坛求教了。



[此贴子已经被作者于2024-12-11 08:18编辑过]

#38
凝聚双眼前天 16:42
以下是引用schtg在2024-12-8 09:33:50的发言:

前面位次录取,在Excel中做的(这次取了前384名作为位次录取),剩余考生按照你提供的代码做的哈,所以才有 自动 + 手动,才有难度
提供 位次考生 录取 规则:

按照这个规则,比较好地体现位次均衡,同时方便平衡总分。
结果:


检验文件


这个位次怎么个规律?有实现的代码吗?
#39
schtg昨天 06:14
回复 38楼 凝聚双眼
这个办法是一个老教务老师告诉我的,这是他从事这项工作的经验吧,类似于S型,但又不完全相同。
我将总分从高到低排序,在Excel的一列中粘贴这个顺序(手动),暂时没有VFP代码哈。
#40
chychychy昨天 08:13
回复 36楼 sdta
再次请教探讨关于满足2B1C1D(BBCD)条件组合,如何更好的交给程序去判断
程序代码:

**判断是否满足BBCD,2B1C1D条件
***建立4科等级排列
CREATE CURSOR tt (x1 c(1))
FOR i = 65 TO 69
    INSERT INTO tt VALUES (CHR(i))
ENDFOR
SELECT aa.x1 + bb.x1 + cc.x1 + dd.x1  ZH FROM tt aa ;
    INNER JOIN tt bb ON bb.x1 >= aa.x1 ;
    INNER JOIN tt cc ON cc.x1 >= bb.x1 ;
    INNER JOIN tt dd ON dd.x1 >= cc.x1 ;
    ORDER BY 1 INTO CURSOR  tmp1 READWRITE
*BROWSE  &&查看测试用
SELECT *,RECNO() xh ,00 SFHG FROM tmp1 INTO DBF zh4 &&SFHG为是否合格

BROWSE

***所以包含E的均为不合格,将SFHG字段标记为2
REPLACE SFHG WITH 2 FOR "E" $ ZH &&去掉35条

***手动判断去掉11条不合格的,将SFHG字段标记为3
**----------------------------
*ACDD,ADDD,
*BBDD,BCCD,BCDD,BDDD
*CCCC,CCCD,CCDD,CDDD,
*DDDD
** 70-35-11=24条 所有符合条件的组合
REPLACE sfhg WITH 3 FOR zh='ACDD' OR zh='ADDD' OR zh='BBDD'OR zh='BCCD' OR zh='BCDD' OR zh='BDDD' OR zh='CCCC' OR zh='CCCD' OR zh='CCDD' OR zh='CDDD' OR zh='DDDD'
**---------------------------
SELECT * FROM zh4 WHERE sfhg=0 &&所有符合条件的组合,是否合格sfhg字段为0,有24条
SELECT * FROM zh4 WHERE OCCURS("E", zh) = 0 AND OCCURS("D", zh) <= 3 AND zh <= "BBCD"  &&&这个判断会显示有25条
**多了ACDD\ADDD
**少了BCCC
#41
my2318昨天 08:25
个人观点,等级录取最好的办法是建一个由所有科目和所有学校及录取类别的字段组成的自由表,然后穷尽所有科目等级组合及对应的可录取学校及类别的记录(所有的录取规则),然后再用单个学生成绩在这个表里查找,看可以录取到那个学校及那类学生,最后再统计,这样做虽然不是效率最高的办法,但是是最可靠的办法,现在的计算机性能强劲,用时不会长
#42
chychychy昨天 08:44
回复 41楼 my2318
看来最准确就是这样,sdta版当年也这样表达过,现在是想请教能否更简单的交给程序去判断
#43
wengjl昨天 08:54
以下是引用my2318在2024-12-11 08:25:59的发言:

个人观点,等级录取最好的办法是建一个由所有科目和所有学校及录取类别的字段组成的自由表,然后穷尽所有科目等级组合及对应的可录取学校及类别的记录(所有的录取规则),然后再用单个学生成绩在这个表里查找,看可以录取到那个学校及那类学生,最后再统计,这样做虽然不是效率最高的办法,但是是最可靠的办法,现在的计算机性能强劲,用时不会长


这个最好。原则是有变化的时候,少改代码,只改某表的内容
#44
wengjl昨天 08:59
趁与下属部门校对数据的间隙,做了前200的分配,仅供参考
只有本站会员才能查看附件,请 登录


       *******************
       * 名称:最优200名分配录取
       *
       * 时间:2024-12-11
       *******************
       CLEAR ALL
       SET ENGINEBEHAVIOR 70
       SET SAFETY OFF
       SET DELETED on        
       PUBLIC mypath
       cCurrentProcedure = SYS(16,1)
       nPathStart = AT(":",cCurrentProcedure)- 1
       nLenOfPath = RAT("\", cCurrentProcedure) - (nPathStart)
       mypath=SUBSTR(cCurrentProcedure, nPathStart, nLenofPath)
       SET DEFAULT TO (mypath)
       *---
       SELECT SPACE(10) as sjs,* from bmk1 orde by zf desc,sx desc,yw desc,wy desc top 200 into table bmkls   && 提取前200名学生。此句的orde by 子句中,可加入等级内容 加上WHERE 过滤评价不符
       RAND(SECONDS())     &&&& 根据时间秒数的不一,来产生随机数,保证每次启动都不一样
       SELECT bmkls
       REPLACE sjs with ALLTRIM(STR((RAND()*987651327))) all
       SELECT * from bmkls orde by sjs into cursor temp readw   && 按随机数排序
       SELECT temp
       REPLACE lqxxdm with [A501] for RECNO()<=50
       REPLACE lqxxdm with [A502] for RECNO()>50 and RECNO()<=100
       REPLACE lqxxdm with [A503] for RECNO()>100 and RECNO()<=150
       REPLACE lqxxdm with [A504] for RECNO()>150   
       *---分配结束
       GO top
       SCAN
         SELECT bmkls
         LOCATE for bmkls.xsdm=temp.xsdm
         IF FOUND()
           REPLACE bmkls.lqxxdm with temp.lqxxdm
         ENDIF
         SELECT temp
       ENDSCAN
       *---分配结果写入
       CLOSE DATABASES
       SELECT [    ] as 抽签学校,lqxxdm,sum(zf) as zf,coun(*) as rs ,sum(zf)/coun(*) as pjf,sum(IIF([女]$xb,1,0)) as nsrs,;
              sum(IIF(zf>=670,1,0)) as fsd670,sum(IIF(zf>=660 and zf<670,1,0)) as fsd660,;
              sum(IIF(zf>=650 and zf<660,1,0)) as fsd650,sum(IIF(zf>=640 and zf<650,1,0)) as fsd640 ;
              from bmkls grou by lqxxdm into table q200fptj
       SELECT q200fptj
       BROWSE    && 观察结果,浏览尚未满意,就重新运算,      
       *---分配统计,观察满意后结束。并组织校长进行抽签

[此贴子已经被作者于2024-12-11 09:24编辑过]

#45
my2318昨天 09:58
以下是引用chychychy在2024-12-11 08:44:12的发言:

看来最准确就是这样,sdta版当年也这样表达过,现在是想请教能否更简单的交给程序去判断

程序解决效率可能更高,但规则变了就要改程序,比较麻烦。如果建表,规则变了,只要修改表就行了,后期维护简单到用户直接改一下表就行了。
#46
schtg昨晚 19:25
回复 44楼 wengjl
谢谢!学习啦!
#47
my231818 小时前
只有本站会员才能查看附件,请 登录


用大家的方法试了试,大概这个结果

[此贴子已经被作者于2024-12-12 03:28编辑过]

#48
wengjl13 小时前
以下是我昨晚创建的一个2B2C2D综合评价项对照标准库,仅供参考!

程序代码:
     ************************
     * 名称:生成一个2B2C2D及以上的评价对照标准库
     * 用途:
     * 时间:20241211
     ************************
     SET engi 70
     SET SAFETY off
     CLOSE DATABASES
     CREATE TABLE ls(djpj c(6),abcde c(10))
     SELECT ls
     zfc=[ABCDE]
     FOR i=1 to 5          &&&1 个学科的五种可能
       zh1=SUBSTR(zfc,i,1)
       FOR k= 1 to 5          &&&2 个学科的五种可能
         zh2=SUBSTR(zfc,k,1)
         FOR j=1 to 5          &&&3 个学科的五种可能
           zh3=SUBSTR(zfc,j,1)
           FOR x=1 to 5          &&&4 个学科的五种可能
             zh4=SUBSTR(zfc,x,1)
             FOR y=1 to 5          &&&5 个学科的五种可能
               zh5=SUBSTR(zfc,y,1)
               FOR z=1 to 5          &&&6 个学科的五种可能
                 zh6=SUBSTR(zfc,z,1)
                 SELECT ls
                 APPEND BLANK
                 REPLACE djpj with zh1+zh2+zh3+zh4+zh5+zh6   &&& 全部排列共有 56 次方个=15625
               NEXT
             NEXT
           NEXT
         NEXT
       NEXT
     NEXT
     *---
     GO top
     SCAN
       sa=0
       sb=0
       sc=0
       sd=0
       se=0
       FOR i=1 to 6
         IF SUBSTR(djpj,i,1)=[A]
           sa=sa+1          &&& 计算 A 的个数
         ENDIF
         IF SUBSTR(djpj,i,1)=[B]
           sb=sb+1          &&& 计算 B 的个数
         ENDIF
         IF SUBSTR(djpj,i,1)=[C]
           sc=sc+1          &&& 计算 C 的个数
         ENDIF
         IF SUBSTR(djpj,i,1)=[D]
           sd=sd+1          &&& 计算 D 的个数
         ENDIF
         IF SUBSTR(djpj,i,1)=[E]
           se=se+1          &&& 计算 E 的个数
         ENDIF         
       NEXT
       REPLACE abcde with allt(STR(sa))+[A]+allt(STR(sb))+[B]+allt(STR(sc))+[C]+allt(STR(sd))+[D]+allt(STR(se))+[E]
       *--转换成 nAnBnCnDnE 的形式,便于取得唯一
     ENDSCAN
     *---
     SELECT djpj,[  ] as px,abcde,[符合 2B2C2D 要求    ] as sm from ls grou by abcde orde by abcde desc into table djpjbzk
     SELECT djpjbzk
     REPLACE sm with [] for [E]$djpj     && 带 E 等的,肯定是不符的
     REPLACE sm with [] for SUBSTR(abcde,7,1)>[2]                           && D 等超过2个的,肯定是不符
     REPLACE sm with [] for SUBSTR(abcde,7,2)=[2] and SUBSTR(abcde,5,1)>[2] && 当D为2个时,C超2个,说明B不足2个,是为不符
     REPLACE sm with [] for SUBSTR(abcde,7,2)=[1] and SUBSTR(abcde,5,1)>[3] && 当D为1个时,C超3个,肯定是不符
     REPLACE sm with [] for SUBSTR(abcde,7,2)=[0] and SUBSTR(abcde,5,1)>[4] && 当D为0时,C超4个,肯定是不符
     *---使用时,在学生成绩库上,也建一个abcde字段,录取时,只要到这个表上对照一下就行
     MESSAGEBOX('综合素质评价等级对照标准库,已生成!!!',64,'提示:')
     QUIT


#49
wengjl12 小时前
程序代码:
       *******************
       * 名称:最优200名分配的S形录取
       *
       * 时间:2024-12-12
       *******************
       CLEAR ALL
       SET ENGINEBEHAVIOR 70
       SET SAFETY OFF
       SET DELETED on        
       PUBLIC mypath
       cCurrentProcedure = SYS(16,1)
       nPathStart = AT(":",cCurrentProcedure)- 1
       nLenOfPath = RAT("\", cCurrentProcedure) - (nPathStart)
       mypath=SUBSTR(cCurrentProcedure, nPathStart, nLenofPath)
       SET DEFAULT TO (mypath)
       *---
       SELECT SPACE(10) as sjs,* from bmk1 orde by zf desc,sx desc,yw desc,wy desc top 200 into table ls   && 提取前200名学生。此句的orde by 子句中,可加入等级内容 加上WHERE 过滤评价不符
       SELECT * from ls orde by xb,zf desc into table bmkls
       SELECT bmkls
       GO top
       lqm=[A501|A502|A503|A504|A504|A503|A502|A501]
       FOR i=1 to 25
         FOR k=1 to 8
           REPLACE lqxxdm with SUBSTR(lqm,5*k-4,4)
           SKIP +1
         ENDFOR
       ENDFOR  
       *---分配结束
       CLOSE DATABASES
       SELECT [    ] as 抽签学校,lqxxdm,sum(zf) as zf,coun(*) as rs ,sum(zf)/coun(*) as pjf,sum(IIF([]$xb,1,0)) as nsrs,;
              sum(IIF(zf>=670,1,0)) as fsd670,sum(IIF(zf>=660 and zf<670,1,0)) as fsd660,;
              sum(IIF(zf>=650 and zf<660,1,0)) as fsd650,sum(IIF(zf>=640 and zf<650,1,0)) as fsd640 ;
              from bmkls grou by lqxxdm into table q200fptj
       SELECT q200fptj
       BROWSE    && 观察结果

#50
schtg12 小时前
回复 48楼 wengjl
谢谢!
#51
schtg12 小时前
回复 49楼 wengjl
非常感谢!我知道我的该如何修改啦
12