当前位置:编程学习 > VB >>

将订单分配给不同的员工,保持各个员工工作量平衡



有表一和表二两个表,需要把表二中的订单按照工作组分给表一的每个工作组下面的成员。不能平均把订单分给每个人。而是根据成员现有的订单量去分配,现在订单量多的,就少分配,尽量平衡每个成员的订单量。例如A组,表二中有5个A组的订单,A组有A1和A2两个成员,他们现有的工作量分别是3,2,所以5个订单的分法应该是2个给A1,3个给A2。

请大家帮忙看看如何用VBA实现?

表一

工作组 成员 订单量
A A1 3
A A2 2
B B1 3
B B2 1
B B3 6
C C1 5
C C2 10
C C3 0
C C4 0
C C5 4

表二
订单 工作组
订单1 A
订单2 C
订单3 B
订单4 A
订单5 A
订单6 B
订单7 B
订单8 C
订单9 C
订单10 A
订单11 B
订单12 C
订单13 C
订单14 C
订单15 B
订单16 B
订单17 C
订单18 C
订单19 C
订单20 C
订单21 C
订单22 A
订单23 B
订单24 C
订单25 C
订单26 C
订单27 C
订单28 C
订单29 C
--------------------编程问答-------------------- 如果想请人写代码,请到 www.csto.com 去发布任务。
否则请自己写代码,针对具体问题进行提问。
提问的智慧 --------------------编程问答-------------------- 请问针对我的问题,你觉得我应该如何提问才能让问题尽快等到解决呢? --------------------编程问答-------------------- 那么你的问题是什么?
方案有了,就剩写代码了。
写代码可不属于问题! --------------------编程问答-------------------- 1)现在表二中算出工作量,比如A共5个。
2)在表一中找出A1和A2的当前工作量,3个和2个。
3)先使A2的工作量和A1相等,就是给A2一个工作量,这样总共剩下4个。
4)平均分配4个,如果不能平均,就每人一个一个给。 --------------------编程问答-------------------- 本人只是懂得一些简单的VBA编程,对于这个的方案,肯能会涉及一些比较复杂的算法,不知如何下手,只是希望有人提示应该怎么做。如果你帮不到忙,请别出声。也许写代码对你来说不是问题,但对于我,它是个问题。 --------------------编程问答--------------------
引用 4 楼 dsd999 的回复:
1)现在表二中算出工作量,比如A共5个。
2)在表一中找出A1和A2的当前工作量,3个和2个。
3)先使A2的工作量和A1相等,就是给A2一个工作量,这样总共剩下4个。
4)平均分配4个,如果不能平均,就每人一个一个给。


谢谢dsd999,如果每组有3个人,4个人或跟多人呢?是否需要把他们的工作量排序,然后把所有人的工作量跟最大的工作量拉平,然后在平均。是这样子吗? --------------------编程问答-------------------- 前面看你自己把答案解出来了,而且问的是“如何用VBA实现”,怎么知道你求的是算法?
无论需要求解的是什么问题,都需要明说。
所以才给你发《提问的智慧》。
--------------------编程问答--------------------
引用 6 楼 excelforfun 的回复:
Quote: 引用 4 楼 dsd999 的回复:

1)现在表二中算出工作量,比如A共5个。
2)在表一中找出A1和A2的当前工作量,3个和2个。
3)先使A2的工作量和A1相等,就是给A2一个工作量,这样总共剩下4个。
4)平均分配4个,如果不能平均,就每人一个一个给。


谢谢dsd999,如果每组有3个人,4个人或跟多人呢?是否需要把他们的工作量排序,然后把所有人的工作量跟最大的工作量拉平,然后在平均。是这样子吗?

有个最直接最烂的算法  订单一个接着一个往里加 每次都加到最少的上面 --------------------编程问答--------------------
引用 7 楼 Tiger_Zhao 的回复:
前面看你自己把答案解出来了,而且问的是“如何用VBA实现”,怎么知道你求的是算法?
无论需要求解的是什么问题,都需要明说。
所以才给你发《提问的智慧》。


大哥,你就别回复啦!我明白你的伟大的想法了。当别人问你问题是,你也许都会说去看某本书,而不是帮人家直接指出问题所在。

如果你不想帮别人解决问题,就别胡乱回复。浪费大家的时间。别高高在上的样子,挥着大棒去教育别人。 --------------------编程问答--------------------
引用 7 楼 Tiger_Zhao 的回复:
前面看你自己把答案解出来了,而且问的是“如何用VBA实现”,怎么知道你求的是算法?
无论需要求解的是什么问题,都需要明说。
所以才给你发《提问的智慧》。

大牛  你发的提问与智慧小菜我刚刚看了 很受用  

新人不会问问题也很正常  不必过于纠结
--------------------编程问答-------------------- 算法从适用不同输入上考虑,应该从低到高的次序进行工作量的拉平。
比如B组 {B1:3,B2:1,B3:6}
最小为 B2:1
第二小为 B1:3,花2个工作量拉平成 {B1:3,B2:3,B3:6}
第三小为 B3:6,花6个工作量拉平成 {B1:6,B2:6,B3:6}

基本算法的伪码如下
Sub AssignWork()

    'n为待分配的工作量
    While n > 0
        Call f(B, n)
    Wend

End Sub

Sub f(B, n)
    m1 = 求最小值(B)
    c1 = 求最小值个数(B)
    m2 = 求次小值(B)

    If 不存在m2 Then '已经全部拉平
        Call f1(B, m1, n \ c1)
        Call f2(B, m1, n Mod c1)
        n = 0
    ElseIf n >= ((m2 - m1) * c1) Then '可以拉平到 m2
        Call f1(B, m1, m2 - m1)
        n = n - (m2 - m1) * c1
    Else '不够拉平到 m2
        Call f1(B, m1, n \ c1)
        Call f2(B, m1, n Mod c1)
        n = 0
    End If
End Sub

Sub f(B, m1, d)
    '所有等于 m1 的工作量都加上 d
End Sub

Sub f(B, m1, c)
    '前 c 个等于 m1 的工作量都加上 1
End Sub

可以优化成一次性拉平到某个量,然后分配余量。 --------------------编程问答-------------------- 楼主也少说点儿吧  不要激动
回归主题
还有何问题 --------------------编程问答--------------------
引用 9 楼 excelforfun 的回复:
大哥,你就别回复啦!我明白你的伟大的想法了。当别人问你问题是,你也许都会说去看某本书,而不是帮人家直接指出问题所在。

如果你不想帮别人解决问题,就别胡乱回复。浪费大家的时间。别高高在上的样子,挥着大棒去教育别人。

不是不愿回答你的问题,而是“不知道你提的是什么问题”。
只有 dsd999 猜出你在问算法。 --------------------编程问答-------------------- 由于对编程只是有非常简单的认识,所以提问题没说到点上,希望理解。谢谢大家。 --------------------编程问答-------------------- 请问如何求次小值?用VBA中的small函数,如果有两个或以上的最小值,就不对了。次小值就会与最小值一样。 --------------------编程问答-------------------- 用最小值做过滤,次小值必须是不等于(大于)最小值。 --------------------编程问答-------------------- 由于编程知识有限,搞不定。找人写代码去。 --------------------编程问答--------------------
引用 11 楼 Tiger_Zhao 的回复:
算法从适用不同输入上考虑,应该从低到高的次序进行工作量的拉平。
比如B组 {B1:3,B2:1,B3:6}
最小为 B2:1
第二小为 B1:3,花2个工作量拉平成 {B1:3,B2:3,B3:6}
第三小为 B3:6,花6个工作量拉平成 {B1:6,B2:6,B3:6}

基本算法的伪码如下
Sub AssignWork()

    'n为待分配的工作量
    While n > 0
        Call f(B, n)
    Wend

End Sub

Sub f(B, n)
    m1 = 求最小值(B)
    c1 = 求最小值个数(B)
    m2 = 求次小值(B)

    If 不存在m2 Then '已经全部拉平
        Call f1(B, m1, n \ c1)
        Call f2(B, m1, n Mod c1)
        n = 0
    ElseIf n >= ((m2 - m1) * c1) Then '可以拉平到 m2
        Call f1(B, m1, m2 - m1)
        n = n - (m2 - m1) * c1
    Else '不够拉平到 m2
        Call f1(B, m1, n \ c1)
        Call f2(B, m1, n Mod c1)
        n = 0
    End If
End Sub

Sub f(B, m1, d)
    '所有等于 m1 的工作量都加上 d
End Sub

Sub f(B, m1, c)
    '前 c 个等于 m1 的工作量都加上 1
End Sub

可以优化成一次性拉平到某个量,然后分配余量。


有一些疑问想搞清楚
1. 有两个sub f(),那个是sub f1(),那个是sub f2().

2. 在全部拉平的情况下在call f1,f2. 这能保证工作量出来是整数吗? call f1的时候所有等于 m1 的工作量都加上 d,B里的值已经发生变化.就是说没有m1存在了,只有m1+d存在,然后再call f2还有用吗?
3. 最终返回的只是什么,数组B吗?
--------------------编程问答-------------------- >1. 有两个sub f(),那个是sub f1(),那个是sub f2().
Sub f1(B, m1, d)
Sub f2(B, m1, c)


>2. 在全部拉平的情况下在call f1,f2. 这能保证工作量出来是整数吗? call f1的时候所有等于 m1 的工作量都加上 d,B里的值已经发生变化.就是说没有m1存在了,只有m1+d存在,然后再call f2还有用吗?
Call f1(B, m1, n \ c1)
Call f2(B, m1 + (n \ c1), n Mod c1)'加上变化的考虑


>3. 最终返回的只是什么,数组B吗?
这只是伪码,B 可以表示数据库表一中 B 组记录,也可以是你自定义结构的数组。
自己考虑选用何种结构。 --------------------编程问答-------------------- 1. n\c1不一定是整数啊?工作量应该是整数的哦。

2. 还有f2是怎么实现的,能给定提示吗?
Sub f2(B, m1, c)
    '前 c 个等于 m1 的工作量都加上 1
End Sub

3. 我是这样子实现sub f1()的,正确吗?
Sub f1(arr, m, d)
'所有等于 m1 的工作量都加上 d
    Dim i As Integer
    For i = 1 To UBound(arr)
        If arr(i, 2) = m Then
            arr(i, 2) = arr(i, 2) + d
        End If
    Next  
End Sub --------------------编程问答-------------------- >1. n\c1不一定是整数啊?工作量应该是整数的哦。
\ 是整除

2. 还有f2是怎么实现的,能给定提示吗?
在 f1 的基础上,d 固定为 1,并且每加一次就计一次,达到 c 次后直接 Exit For

3. 我是这样子实现sub f1()的,正确吗?
可以

补充:VB ,  VBA
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,