|
楼主 |
发表于 2013-5-21 10:34
|
显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用 · 内置多项VBA编程加强工具 ★ 免费下载 ★ ★ 使用手册★
本帖最后由 小花鹿 于 2013-6-4 01:25 编辑
香川群子 发表于 2013-5-20 14:21
你的代码看上去是没有用到【死循环参数】,但实际上还是用了,你的【死循环参数】是=0
解释:
也就是说p这个参数决定了能否比较均匀的把某一学校的学生分布在各个考场中,p越小分布的越不均匀,但死循环次数越少,相反,p越大分布的越均匀,但同时死循环次数越多。是这个意思吗?
在这里补充不随机的解法:
1、当某校人数大于总人数的一半时:
Sub test()
Dim ar, drs, dxh, M, i&, drsk, s1, s2, n1&, n2&, zwb, Hs&, Ls&, H&, L&, n&
Set drs = CreateObject("scripting.dictionary")
Set dxh = CreateObject("scripting.dictionary")
ar = Sheet3.[a1].CurrentRegion
For i = 2 To UBound(ar)
drs(ar(i, 1)) = drs(ar(i, 1)) + 1
dxh(ar(i, 1) & ar(i, 4)) = ""
Next i
M = Application.Max(drs.items)
M = Application.Match(M, drs.items, 0)
drsk = drs.keys
M = drsk(M - 1)
s1 = Filter(dxh.keys, M, True)
s2 = Filter(dxh.keys, M, False)
Hs = 7: Ls = 6
For i = 0 To Int((UBound(s1) - 1) / 20)
ReDim zwb(1 To Hs, 1 To Ls)
For H = 1 To Hs
For L = ((H - 1) Mod 2) + 1 To Ls Step 2
If H = Hs And L = 1 Then
Else
If n1 <= UBound(s1) Then zwb(H, L) = s1(n1): n1 = n1 + 1
End If
Next L
Next H
For H = 1 To Hs
For L = (H Mod 2) + 1 To Ls Step 2
If H = Hs And L = Ls Then
Else
If n2 <= UBound(s2) Then zwb(H, L) = s2(n2): n2 = n2 + 1
End If
Next L
Next H
Sheet3.[h2].Offset(i * 8).Resize(Hs, Ls) = zwb
Next i
End Sub
2、当某校人数小于等于总人数的一半时:
Sub test()
Dim ar, i&, j&, r&, zwb(), Hs&, Ls&, H&, L&, n1&, n2&, t&
ar = Sheet3.[a1].CurrentRegion
r = UBound(ar)
Hs = 7: Ls = 6: n1 = 1: n2 = 1: t = Int((r / 2))
For i = 0 To Int((r - 2) / 40)
ReDim zwb(1 To Hs, 1 To Ls)
For H = 1 To Hs
For L = ((H - 1) Mod 2) + 1 To Ls Step 2
If H = Hs And L = 1 Then
Else
n1 = n1 + 1
If n1 - 1 <= t Then zwb(H, L) = ar(n1, 1) & ar(n1, 4)
End If
Next L
Next H
For H = 1 To Hs
For L = (H Mod 2) + 1 To Ls Step 2
If H = Hs And L = Ls Then
Else
n2 = n2 + 1
If n2 + t <= r Then zwb(H, L) = ar(n2 + t, 1) & ar(n2 + t, 4)
End If
Next L
Next H
Sheet3.[h2].Offset(i * 8).Resize(Hs, Ls) = zwb
Next i
End Sub
如果要适合两者,可以把上面两段代码合起来。
考场安排代码改进:
优点:
1、尽量做到随机抽取
2、不用以学校进行排序
3、考虑到了某校人数小于等于总人数的一半(这时没有空位)和某校人数大于总人数的一半(这时有空位)两种情况
小学升学考试座位表.rar
(33.23 KB, 下载次数: 39)
Sub testx()
Randomize
Dim ar, drs, dxh, i&, Hs&, Ls&, H&, L&, M&, kc&, drsi, drsk, xmb, zwb, s, tm, r, xh, xm, Mxm
Set drs = CreateObject("scripting.dictionary")
Set dxh = CreateObject("scripting.dictionary")
ar = Sheet3.[a1].CurrentRegion
redo:
For i = 2 To UBound(ar)
drs(ar(i, 1)) = drs(ar(i, 1)) + 1
dxh(CStr(i)) = i & "," & ar(i, 1)
Next i
i = Application.Max(drs.items)
M = Int((i - 1) / 20)
kc = Int((UBound(ar) - 2) / 40)
If M > kc Then kc = M
i = Application.Match(i, drs.items, 0)
drsk = drs.keys
Mxm = drsk(i - 1)
Hs = 7: Ls = 6
For i = 0 To kc
ReDim xmb(Hs, Ls)
ReDim zwb(1 To Hs, 1 To Ls)
For H = 1 To Hs
For L = 1 To Ls
If H = Hs And (L = 1 Or L = Ls) Then
Else
If drs.Count = 1 And (xmb(H - 1, L) = Mxm Or xmb(H, L - 1) = Mxm) Then L = L + 1
If L > Ls Then Exit For
s = dxh.items
M = Application.Max(drs.items)
M = Application.Match(M, drs.items, 0)
drsk = drs.keys
tm = drsk(M - 1)
If tm <> xmb(H - 1, L) And tm <> xmb(H, L - 1) Then
s = Filter(s, tm, True)
Else
tm = xmb(H - 1, L): If tm <> "" Then s = Filter(s, tm, False)
tm = xmb(H, L - 1): If tm <> "" Then s = Filter(s, tm, False)
End If
If UBound(s) = -1 Then drs.RemoveAll: dxh.RemoveAll: GoTo redo
r = Int(Rnd() * (UBound(s) + 1))
xh = Split(s(r), ",")(0)
dxh.Remove (xh)
zwb(H, L) = ar(xh, 1) & ar(xh, 4)
xm = Split(s(r), ",")(1)
xmb(H, L) = xm
If drs(xm) = 1 Then drs.Remove (xm) Else drs(xm) = drs(xm) - 1
End If
If dxh.Count = 0 Then GoTo ext
Next L
Next H
ext:
Sheet3.[h4].Offset(i * 8).Resize(Hs, Ls) = zwb
Next i
End Sub
- Sub testx()
- Randomize
- Dim ar, drs, dxh, i&, Hs&, Ls&, H&, L&, M&, kc&, drsi, drsk, xmb, zwb, s, tm, r, xh, xm, Mxm
- Set drs = CreateObject("scripting.dictionary")
- Set dxh = CreateObject("scripting.dictionary")
- ar = Sheet3.[a1].CurrentRegion
- redo:
- For i = 2 To UBound(ar)
- drs(ar(i, 1)) = drs(ar(i, 1)) + 1
- dxh(CStr(i)) = i & "," & ar(i, 1)
- Next i
- i = Application.Max(drs.items)
- M = Int((i - 1) / 20)
- kc = Int((UBound(ar) - 2) / 40)
- If M > kc Then kc = M
- i = Application.Match(i, drs.items, 0)
- drsk = drs.keys
- Mxm = drsk(i - 1)
- Hs = 7: Ls = 6
- For i = 0 To kc
- ReDim xmb(Hs, Ls)
- ReDim zwb(1 To Hs, 1 To Ls)
- For H = 1 To Hs
- For L = 1 To Ls
- If H = Hs And (L = 1 Or L = Ls) Then
- Else
- If drs.Count = 1 And (xmb(H - 1, L) = Mxm Or xmb(H, L - 1) = Mxm) Then L = L + 1
- If L > Ls Then Exit For
- s = dxh.items
- M = Application.Max(drs.items)
- M = Application.Match(M, drs.items, 0)
- drsk = drs.keys
- tm = drsk(M - 1)
- If tm <> xmb(H - 1, L) And tm <> xmb(H, L - 1) Then
- s = Filter(s, tm, True)
- Else
- tm = xmb(H - 1, L): If tm <> "" Then s = Filter(s, tm, False)
- tm = xmb(H, L - 1): If tm <> "" Then s = Filter(s, tm, False)
- End If
- If UBound(s) = -1 Then drs.RemoveAll: dxh.RemoveAll: GoTo redo
- r = Int(Rnd() * (UBound(s) + 1))
- xh = Split(s(r), ",")(0)
- dxh.Remove (xh)
- zwb(H, L) = ar(xh, 1) & ar(xh, 4)
- xm = Split(s(r), ",")(1)
- xmb(H, L) = xm
- If drs(xm) = 1 Then drs.Remove (xm) Else drs(xm) = drs(xm) - 1
- End If
- If dxh.Count = 0 Then GoTo ext
- Next L
- Next H
- ext:
- Sheet3.[h4].Offset(i * 8).Resize(Hs, Ls) = zwb
- Next i
- End Sub
复制代码
|
|