| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
共有 3110 人关注过本帖
标题:再次请教学生如何分派
取消只看楼主 加入收藏
chychychy
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:376
专家分:133
注 册:2015-4-18
收藏
得分:0 
回复 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 &&查看测试用
2024-12-05 20:58
chychychy
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:376
专家分:133
注 册:2015-4-18
收藏
得分:0 
回复 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编辑过]

2024-12-07 21:35
chychychy
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:376
专家分:133
注 册:2015-4-18
收藏
得分:0 
回复 25楼 wengjl
感谢,几天在在外有考试任务,回去后发您,我qq313693957,您的?方便我加您
2024-12-08 12:50
chychychy
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:376
专家分:133
注 册:2015-4-18
收藏
得分:0 
回复 24楼 schtg
您这这种规则不仅是单纯的12344321,中间还有变化,请教比如9、10、11、12和13、14、15、16变化的逻辑是什么?用vfp如何实现?
2024-12-09 10:40
chychychy
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:376
专家分:133
注 册:2015-4-18
收藏
得分:0 
回复 29楼 my2318
新建文件夹 (2).rar (1.95 MB)

谢谢,数据都差不多,wengjl的数据也比较有代表性,难在用什么方式解决人数不均等、不成倍数关系下的“均衡”
2024-12-09 16:50
chychychy
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:376
专家分:133
注 册:2015-4-18
收藏
得分:0 
回复 33楼 schtg
cjk.rar (175.39 KB)
您的这个数和我们这边要求的有出入,我将您的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编辑过]

2024-12-10 09:48
chychychy
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:376
专家分:133
注 册:2015-4-18
收藏
得分:0 
回复 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编辑过]

2024-12-10 14:20
chychychy
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:376
专家分:133
注 册:2015-4-18
收藏
得分:0 
回复 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
2024-12-11 08:13
chychychy
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:376
专家分:133
注 册:2015-4-18
收藏
得分:0 
回复 41楼 my2318
看来最准确就是这样,sdta版当年也这样表达过,现在是想请教能否更简单的交给程序去判断
2024-12-11 08:44
chychychy
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:376
专家分:133
注 册:2015-4-18
收藏
得分:0 
回复 56楼 wengjl
如果考虑校际均衡的话这是一个很好的思路,不过目前大多数地方学校都不行学校之间招生计划数不均衡是其一,学校分重点和非重点是更重要的原因
2024-12-13 08:22
快速回复:再次请教学生如何分派
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.029738 second(s), 12 queries.
Copyright©2004-2025, BC-CN.NET, All Rights Reserved