python 回溯法 子集树模板 系列 —— 13、最佳作业调度问题

简介: 问题给定 n 个作业,每一个作业都有两项子任务需要分别在两台机器上完成。每一个作业必须先由机器1 处理,然后由机器2处理。试设计一个算法找出完成这n个任务的最佳调度,使其机器2完成各作业时间之和达到最小。

问题

给定 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

img_46467092c87716f7d79be05249884db1.jpg

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

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

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

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

代码

'''
最佳作业调度问题 

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   # 一个解(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

效果图

img_1218c6f7269c8cb9a8b26f7ebbfabf51.jpg

目录
相关文章
|
Python 机器学习/深度学习 安全
python 回溯法 子集树模板 系列 —— 19、野人与传教士问题
问题 在河的左岸有N个传教士、N个野人和一条船,传教士们想用这条船把所有人都运过河去,但有以下条件限制: (1)修道士和野人都会划船,但船每次最多只能运M个人; (2)在任何岸边以及船上,野人数目都不能超过修道士,否则修道士会被野人吃掉。
1372 0
|
Python 数据可视化
python 回溯法 子集树模板 系列 —— 1、8 皇后问题
问题 8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 分析 为了简化问题,考虑到8个皇后不同行,则每一行放置一个皇后,每一行的皇后可以放置于第0、1、2、...、7列,我们认为每一行的皇后有8种状态。
966 0
|
10天前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###
|
1天前
|
Python
不容错过!Python中图的精妙表示与高效遍历策略,提升你的编程艺术感
本文介绍了Python中图的表示方法及遍历策略。图可通过邻接表或邻接矩阵表示,前者节省空间适合稀疏图,后者便于检查连接但占用更多空间。文章详细展示了邻接表和邻接矩阵的实现,并讲解了深度优先搜索(DFS)和广度优先搜索(BFS)的遍历方法,帮助读者掌握图的基本操作和应用技巧。
13 4
|
1天前
|
设计模式 程序员 数据处理
编程之旅:探索Python中的装饰器
【10月更文挑战第34天】在编程的海洋中,Python这艘航船以其简洁优雅著称。其中,装饰器作为一项高级特性,如同船上的风帆,让代码更加灵活和强大。本文将带你领略装饰器的奥秘,从基础概念到实际应用,一起感受编程之美。
|
3天前
|
存储 人工智能 数据挖掘
从零起步,揭秘Python编程如何带你从新手村迈向高手殿堂
【10月更文挑战第32天】Python,诞生于1991年的高级编程语言,以其简洁明了的语法成为众多程序员的入门首选。从基础的变量类型、控制流到列表、字典等数据结构,再到函数定义与调用及面向对象编程,Python提供了丰富的功能和强大的库支持,适用于Web开发、数据分析、人工智能等多个领域。学习Python不仅是掌握一门语言,更是加入一个充满活力的技术社区,开启探索未知世界的旅程。
13 5
|
1天前
|
机器学习/深度学习 JSON API
Python编程实战:构建一个简单的天气预报应用
Python编程实战:构建一个简单的天气预报应用
10 1
|
1天前
|
算法 Python
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果;贪心算法在每一步选择局部最优解,追求全局最优;动态规划通过保存子问题的解,避免重复计算,确保全局最优。这三种算法各具特色,适用于不同类型的问题,合理选择能显著提升编程效率。
14 2
|
3天前
|
人工智能 数据挖掘 开发者
探索Python编程:从基础到进阶
【10月更文挑战第32天】本文旨在通过浅显易懂的语言,带领读者从零开始学习Python编程。我们将一起探索Python的基础语法,了解如何编写简单的程序,并逐步深入到更复杂的编程概念。文章将通过实际的代码示例,帮助读者加深理解,并在结尾处提供练习题以巩固所学知识。无论你是编程新手还是希望提升编程技能的开发者,这篇文章都将为你的学习之旅提供宝贵的指导和启发。
|
8天前
|
数据处理 Python
从零到英雄:Python编程的奇幻旅程###
想象你正站在数字世界的门槛上,手中握着一把名为“Python”的魔法钥匙。别小看这把钥匙,它能开启无限可能的大门,引领你穿梭于现实与虚拟之间,创造属于自己的奇迹。本文将带你踏上一场从零基础到编程英雄的奇妙之旅,通过生动有趣的比喻和实际案例,让你领略Python编程的魅力,激发内心深处对技术的渴望与热爱。 ###

热门文章

最新文章