【关键字】:
- 组合:排列中的唯一顺序(从小到大)选择结果,通常比排列的结果集少得多。
摘要:
- python代码实现设备排班;
- 本文使用的常用函数:(1) 列表追加:
list.append()
;(2)列表排序:list.sorted()
,默认升序; - 本文使用的库:(1) 排列组合:import itertools
题目:
某研究室有四台高级设备需要以天为单位(周一至周日)安排轮换启用,轮换规则为:
每台设备功能相同;
每台设备每周需要启用四天;
每台设备之间启用时间不能完全相同;
周一至周五每天需要两台设备工作;
周六周日每天需要三台设备工作;
每种设备需要在周六周日中至少一天工作;
试利用编程方式计算:
1)共有多少种设备排班方案(若日期相同而分配设备不同视作同一方案,例如:
[1356, 1467, 2357, 2467]与[1467, 2357, 1356, 2467]视作同一方案);
2)限定每台设备均不能连续工作超过两天(例如123、567、671均不可),重新计算排班方案数量。
思路:
(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}筛