实例详解Python基于回溯法子集树模板解决最佳作业调度


本文摘自php中文网,作者巴扎黑,侵删。

这篇文章主要介绍了Python基于回溯法子集树模板解决最佳作业调度问题,简单说明了作业调度问题并结合实例形式给出了Python使用回溯法子集树模板实现最佳作业调度问题的具体步骤与相关操作技巧,需要的朋友可以参考下

本文实例讲述了Python基于回溯法子集树模板解决最佳作业调度问题。分享给大家供大家参考,具体如下:

问题

给定 n 个作业,每一个作业都有两项子任务需要分别在两台机器上完成。每一个作业必须先由机器1 处理,然后由机器2处理。

试设计一个算法找出完成这n个任务的最佳调度,使其机器2完成各作业时间之和达到最小。

分析:

看一个具体的例子:

tji 机器1 机器2
作业1 2 1
作业2 3 1
作业3 2 3

最优调度顺序:1 3 2

处理时间:18

这3个作业的6种可能的调度方案是1,2,3;1,3,2;2,1,3;2,3,1;3,1,2;3,2,1;

它们所相应的完成时间和分别是19,18,20,21,19,19。易见,最佳调度方案是1,3,2,其完成时间和为18。

以1,2,3为例:

作业1在机器1上完成的时间为2,在机器2上完成的时间为3
作业2在机器1上完成的时间为5,在机器2上完成的时间为6
作业3在机器1上完成的时间为7,在机器2上完成的时间为10
3+6+10 = 19

1,3,2

作业1在机器1上完成的时间为2, 在机器2上完成的时间为3
作业3在机器1上完成的时间为4,在机器2上完成的时间为7
作业2在机器1上完成的时间为7,在机器2上完成的时间为8

3+7+8 = 18

解编码:(X1,X2,...,Xn),Xi表示顺序i执行的任务编号。所以,一个解就是任务编号的一个排列。

解空间:{(X1,X2,...,Xn)| Xi属于S,i=1,2,...,n},S={1,2,...,n}。所以,解空间就是任务编号的全排列。

讲道理,要套用回溯法的全排列模板。

不过,有了前面两个例子做铺垫,这里套用回溯法的子集树模板。

代码


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

'''

最佳作业调度问题

tji     机器1   机器2

作业1     2     1

作业2     3     1

作业3     2     3

'''

n = 3 # 作业数

# n个作业分别在两台机器需要的时间

t = [[2,1],

   [3,1],

   [2,3]]

x = [0]*# 一个解(n元数组,xi∈J)

X = []   # 一组解

best_x = [] # 最佳解(一个调度)

best_t = 0 # 机器2最小时间和

# 冲突检测

def conflict(k):

  global n, x, X, t, best_t

  # 部分解内的作业编号x[k]不能超过1

  if x[:k+1].count(x[k]) > 1:

    return True

  # 部分解的机器2执行各作业完成时间之和未有超过 best_t

  #total_t = sum([sum([y[0] for y in t][:i+1]) + t[i][1] for i in range(k+1)])

  j2_t = []

  s = 0

  for i in range(k+1):

    s += t[x[i]][0]

    j2_t.append(s + t[x[i]][1])

  total_t = sum(j2_t)

  if total_t > best_t > 0:

    return True

  return False # 无冲突

# 最佳作业调度问题

def dispatch(k): # 到达第k个元素

  global n, x, X, t, best_t, best_x

  if k == n: # 超出最尾的元素

    #print(x)

    #X.append(x[:]) # 保存(一个解)

    # 根据解x计算机器2执行各作业完成时间之和

    j2_t = []

    s = 0

    for i in range(n):

      s += t[x[i]][0]

      j2_t.append(s + t[x[i]][1])

    total_t = sum(j2_t)

    if best_t == 0 or total_t < best_t:

      best_t = total_t

      best_x = x[:]

  else:

    for i in range(n): # 遍历第k个元素的状态空间,机器编号0~n-1,其它的事情交给剪枝函数

      x[k] = i

      if not conflict(k): # 剪枝

        dispatch(k+1)

# 测试

dispatch(0)

print(best_x) # [0, 2, 1]

print(best_t) # 18

效果图

以上就是实例详解Python基于回溯法子集树模板解决最佳作业调度的详细内容,更多文章请关注木庄网络博客!!

相关阅读 >>

Python会取代php吗?

Python注释快捷键是什么

怎么在Python安装pil

Python怎么删除

Python实现des加密解密的方法介绍(代码)

Python有序列表以及方法的介绍(代码)

Python中关于django对数据库mysql的增删改查操作详解

Python利用smtplib实现qq邮箱发送邮件

Python如何遍历list

Python脚本在linux下如何自启动与定时任务的实例详解

更多相关阅读请进入《Python》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...