分單是很多企業日常工作中非常典型的一項內容,它非常複雜,但同時又極為重要,如何合理的分單是企業管理中一個很重要的課題。
之所以說分單很複雜,是因為影響單據該分給誰,分多少量這個事兒本身就有太多的影響因子;一旦管理者在分單的公平性上出現大的問題,厚此薄彼了,往大了講,員工的做事積極性有可能都會被挫傷。
簡單列舉幾類:
1、員工的技能矩陣;
2、員工的出勤資料;
3、各種型別單據的SPT(標準作業時間);
4、員工手中已有的單據量;
5、不同型別單據量的分佈情況;
6、某種型別的單據不夠分時,該優先分給誰;
7、每次單據的來件數量、來件的型別高度不確定;
8、當某種型別給某些員工少分了一些數量,如何在另外一些型別上儘量多分他一些,使得每個人分到的總量儘可能均衡;
9、單據的黑白名單策略(某些型別,某些申請人提的優先不分給哪些人,優先分給哪些人);
10、某個單據被被駁回過,如何在第二次分單時優先分給當初的處理人;
11、某些人可以同時處理兩個環節,如何保證他不處理同一個單據的前後兩個環節,避免內控管理失效;
12、多個領單小組共用某些流程埠,如何區分單據優先分給哪個組;
13、如何保證每個人能處理能力範圍內的儘可能多的型別的單據,以確保員工的能力得到充分鍛鍊;
……
您瞅瞅,我覺沒撒謊,這可一點都不簡單。偏偏在小爬我的實際業務中,就被要求解決這麼頭疼的問題。但是你以為小爬我這就怕了?NO NO NO,需求越有挑戰,小爬越高興。
先說說如何解決每個人分配的單據量不均衡的問題,其中一種思路:我們把總單據量基於業務型別分成N組,然後基於每個員工能處理的業務型別和當天的出勤情況,找到能處理每種業務型別的人員列表,假設是M個人。我們可以利用演演算法,每次分單前將人員列表的順序隨機打亂,那麼每次分單時,每個人都有一定概率出現在佇列末尾,也就是單據不夠分給他的情況,最終只要我們把N組型別的單據都分完時,大家的概率總體上是均衡的,不過概率的事兒沒人能說它絕對公平。
下面這段程式碼,就可以完美地打亂某個列表的順序,讓它徹底重排:
import random def shuffle_list(lst): '''將列表的順序隨機打亂,得到一個新的列表''' new_lst = lst[:] # 複製原列表,否則會影響原列表 random.shuffle(new_lst) # 打亂順序 return new_lst
可是它依然不是絕對公平的,沒法保證每個人分到的單據量儘可能一樣多,因為它只是在模擬扔色子,寄希望於概率均勻分佈。如何保證大家的數量相對公平呢?
我們不妨利用python的字典,儲存每個人(key)已經分到的單據號的列表合集,把列表作為字典的Value。當我們在對某種型別的N個單據分給M個人時,就好比是發撲克牌,但是又不能簡單去按順序發牌,而是看誰手上的牌少,就優先把剩餘的牌發給它,這樣手上牌少的人,總是能被照顧,直到最後大家手上發到的牌數接近。如何知道這個特殊的字典中,到底哪個Key的牌最少(列表的長度最短)呢?您不妨參考下下面的演演算法。
def get_Dic_shortest_key(keyList,my_dict): '''根據輸入的字典,字典的鍵對應的值都是一個列表,如果哪個鍵對應的列表的長度最短,則返回該鍵''' shortest_key = None shortest_length = float('inf') for key, value in my_dict.items(): if key in keyList and len(value) < shortest_length: shortest_key = key shortest_length = len(value) # Return the key with the shortest list value return shortest_key
有了上面的演演算法,我們也就解決了每次的發牌優先分給誰的問題,怎麼把牌發完到對的人手上,就不是個問題了,程式碼範例如下:
def seperate_list(lst,personList, personFormNumber_dic): """ 將一個列表拆分成n個子列表組成的二維列表,要求每個子列表元素的長度儘可能接近 :param lst: 待分配的單據號列表 :param personList: 可以參與此次分單的人員列表 :param personFormNumber_dic:字典結構,每個人key手上已有的單據列表value :return: personFormNumber_dic 返回這個字典(每個人手上的單據清單) """ m = len(lst) for i in range(m): # 從後往前遍歷列表 targetPerson="" targetPerson=get_Dic_shortest_key(personList,personFormNumber_dic) for random_element in lst: personFormNumber_dic[targetPerson].append(random_element) lst.remove(random_element) break return personFormNumber_dic
希望這些對現實業務的思考和程式碼實現,能對您的工作有所啟發。不管咋說,活到老,學到老。拒絕躺平,一起捲起來!
快來關注本公眾號 獲取更多爬蟲、資料分析的知識!