設備排班

python進行設備排班

關鍵字:

  • 組合:排列中的唯一順序(從小到大)選擇結果,通常比排列的結果集少得多。

摘要:

  • python代碼實現設備排班;
  • 本文使用的常用函數:(1) 列表追加:list.append() ;(2)列表排序:list.sorted() ,默認升序;
  • 本文使用的庫:(1) 排列組合:import itertools

###題目:

某研究室有四臺高級設備需要以天爲單位(週一至週日)安排輪換啓用,輪換規則爲:
每臺設備功能相同;
每臺設備每週需要啓用四天;
每臺設備之間啓用時間不能完全相同;
週一至週五每天需要兩臺設備工作;
週六週日每天需要三臺設備工作;
每種設備需要在週六週日中至少一天工作;
試利用編程方式計算:
1)共有多少種設備排班方案(若日期相同而分配設備不同視作同一方案,例如:
[1356, 1467, 2357, 2467][1467, 2357, 1356, 2467]視作同一方案);
2)限定每臺設備均不能連續工作超過兩天(例如123567671均不可),重新計算排班方案數量。

###思路:

(1) 根據題意,總的工作時work_list = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7];
(2) 可以用4個列表分別代表4臺設備,每個列表中需要有7或6;
(3) 手動枚舉找規律,避免重複,按從大到小逐步夾逼,比如:

[4, 5, 6, 7], [3, 5, 6, 7], [1, 2, 4, 7], [1, 2, 3, 6];

[4, 5, 6, 7], [2, 5, 6, 7], [1, 3, 4, 7], [1, 2, 3, 6];

[4, 5, 6, 7], [1, 5, 6, 7], [2, 3, 4, 7], [1, 2, 3, 6];

(4) 寫一些之後,發現仍不能寫出相應的代碼,也沒有顯著的規律,僅發現每個列表都是從[1, 2, 3, 4, 5, 6, 7]中挑出來4個元素,裏面需要有7或6,同時每組4個列表拼接起來(再排序一下)的元素及其個數與總的工作時一致;
(5) 等到不想再手動枚舉,讓電腦來自動枚舉時,自然想到排列組合,排列去重比較麻煩,組合天然就有去重屬性,且運算快;
(6) 兩次組合:第一次,從7箇中挑出4個的組合,用“裏面有7或6”篩選出初步符合的;第二次,從所有初步符合的結果集中挑出4個的組合,分配給4臺設備,用“每組4個列表拼接起來與總工作時一致”再篩選一次;
(7)第二題,將第一次7選4且有7或6的初步符合結果,再用沒有子集{1, 2, 3}或{2, 3, 4}或{3, 4, 5}或{4, 5, 6}或{5, 6, 7}或{6, 7, 1}或{7, 1, 2}篩選一次,接下來與第(6)步第二次一致。

  • 程序段展示:

import itertools

work_list = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7]  # 總的排班

schedule_init = []  # 初步排班
combination_init = itertools.combinations([1, 2, 3, 4, 5, 6, 7], 4)  # 抽4天工作的所有組合

for i in combination_init:
    if 6 in i or 7 in i:  # 有6或7的擴充到列表
        schedule_init.append(list(i))

schedule_second = []  # 二版排班,對四臺設備進行組合
combination_second = itertools.combinations(schedule_init, 4)  # 對列表中的初步合格組合分配給4臺設備,也用組合
for i in combination_second:
    if sorted(i[0] + i[1] + i[2] + i[3]) == work_list:  # 每一種組合中的列表拼接,然後排序,需要等於總排班,纔是正確分配
        schedule_second.append(list(i))
        print(i)
num_exercise_1 = len(schedule_second)  # 第一題排班總數
print('第一題總數', num_exercise_1)

# 第二題:
schedule_third = []  # 三版排班,剔除對連續工作3天的情況
for i in schedule_init:
    if not (set(i).issuperset({1, 2, 3}) or set(i).issuperset({7, 1, 2}) or set(i).issuperset({6, 7, 1}) or set(
            i).issuperset({2, 3, 4}) or set(i).issuperset({3, 4, 5}) or set(i).issuperset({4, 5, 6}) or set(
        i).issuperset(
        {5, 6, 7})):  # 選擇初版排班中,不包含連續工作3天的情況
        schedule_third.append(i)

schedule_final = []  # 終版,對四臺設備進行組合
combination_third = itertools.combinations(schedule_third, 4)
for i in combination_third:
    if sorted(i[0] + i[1] + i[2] + i[3]) == work_list:  # 每一種組合中的列表拼接,然後排序,需要等於總排班,纔是正確分配
        schedule_final.append(list(i))
        print(i)
num_exercise_2 = len(schedule_final)  # 第二題排班總數
print('第二題總數', num_exercise_2)

總結:

發佈了18 篇原創文章 · 獲贊 2 · 訪問量 637
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章