|
本帖最后由 yangyangzhifeng 于 2014-7-30 07:02 编辑
张雄友 发表于 2014-7-29 20:55
不对,有一个人无法安排。透视表验证是:9,1,应该是10 才对。
女舍006 9
试试看- Sub yangyangzhifeng() 'http://club.excelhome.net/thread-895293-12-1.html
- '只要理论上可以分配,就一定可以分好,要更好的随机性,可以将初始名单乱序后再运行!
- Dim xb$, each_room_p&
- Range("E2:E65536").ClearContents
- each_room_p = Val(InputBox("定义多少人一间宿舍", "你想", 14))
- xb = "男"
- test xb, each_room_p
- xb = "女"
- test xb, each_room_p
- ActiveSheet.PivotTables("数据透视表1").PivotCache.Refresh '刷新数据透视表
- End Sub
- Sub test(ByVal xb$, ByVal each_room_p&)
- '将学校按可安排的宿舍的盈余量升序排序,每次依此排序安排好一个宿舍
- '当盈余量为0时,代表每次必须分配该校的学生
- '当出现当盈余量<0的情况时,说明无法满足同宿舍没有来自同校的学生
- Dim ar, n&, i&, j&, k&, d, e, br(), cr(), dr&(), x&, y&
- Set d = CreateObject("scripting.dictionary")
- Set e = CreateObject("scripting.dictionary")
- n = Range("A65536").End(3).Row
- ar = Range("A2:E" & n) '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- For i = 1 To UBound(ar)
- If ar(i, 4) = xb Then '第四列为性别!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- If d(ar(i, 3)) = "" Then d(ar(i, 3)) = d.Count '对第三列进行不重复值设置!!!!!!!!!!!!!!!!!!!!!!!!!!
- e(ar(i, 3)) = e(ar(i, 3)) + 1 '累加变量!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- End If
- Next
- n = Application.Max(e.items)
- ReDim br(0 To n, 1 To d.Count), cr(1 To d.Count, 1 To 2)
- n = Application.RoundUp(Application.Sum(e.items) / each_room_p, 0)
- ReDim dr(1 To n) '记录宿舍空位
- For i = 1 To UBound(ar)
- If ar(i, 4) = xb Then '第四列为性别!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- x = d(ar(i, 3)) '学校序号!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- br(0, x) = br(0, x) + 1 '学校总人数
- br(br(0, x), x) = i '记录学生的位置号
- End If
- Next
- For i = 1 To UBound(br, 2)
- cr(i, 1) = i: cr(i, 2) = n - br(0, i)
- 'If cr(i, 2) < 0 Then MsgBox xb & "生无法满足同宿舍人员来自不同学校": Exit Sub
- '如执行宏,输入14,就是每个宿舍住14人时,女生宿舍无法满足来自不同的学校。
- '这个不能满足,是指个别宿舍无法满足的,但是个别宿舍还是可以满足的,
- '能不能把可以满足的宿舍分出来,不能满足的就最后安排在一间宿舍?
- 'If cr(i, 2) < 0 Then MsgBox xb & "生无法满足同宿舍人员来自不同学校": Exit Sub
- '改成
- If cr(i, 2) < 0 Then MsgBox xb & "生无法满足同宿舍人员来自不同学校"
- Next
- For i = 1 To n
- paixu cr
- For j = 1 To each_room_p
- x = br(0, cr(j, 1))
- y = br(x, cr(j, 1))
- If x = 0 Then dr(i) = each_room_p - j + 1: Exit For
- ar(y, 5) = xb & "舍" & Format(i, "000") '在第五列生成宿舍号!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- x = x - 1
- If x = 0 Then
- cr(j, 2) = n
- End If
- br(0, cr(j, 1)) = x
- Next
- For k = j To UBound(cr) '本轮未分配的学校,宿舍盈余-1
- cr(k, 2) = cr(k, 2) - 1
- Next
- Next
- If Application.Sum(Application.Index(br, 1, 0)) > 0 Then
- i = 0: j = 0
- Do
- Do
- i = i + 1
- If br(0, i) > 0 Then x = br(0, i): Exit Do
- If i = d.Count Then i = 0
- Loop
- Do
- j = j + 1
- If dr(j) > 0 Then Exit Do
- Loop
- ar(br(x, i), 5) = xb & "舍" & Format(j, "000")
- x = x - 1: br(0, i) = x
- If Application.Sum(Application.Index(br, 1, 0)) = 0 Then Exit Do
- j = j Mod n
- i = i Mod d.Count
- Loop
- End If
- Range("A2").Resize(UBound(ar), UBound(ar, 2)) = ar
- End Sub
- Sub paixu(t())
- Dim i&, j&, x
- For i = UBound(t) - 1 To 1 Step -1
- For j = 1 To i
- If t(j, 2) >= t(j + 1, 2) Then '不稳定排序以实现随机性
- x = t(j, 2): t(j, 2) = t(j + 1, 2): t(j + 1, 2) = x
- x = t(j, 1): t(j, 1) = t(j + 1, 1): t(j + 1, 1) = x
- End If
- Next
- Next
- End Sub
复制代码
|
评分
-
1
查看全部评分
-
|