《数据结构、算法与应用C++语言描述》-机器调度-最长处理时间(LPT)-堆应用

news2024/11/26 1:25:30

机器调度

完整可编译运行代码见:Github::Data-Structures-Algorithms-and-Applications/_28LongestProcessingTime

问题描述

一个工厂具有 m台一模一样的机器。我们有n 个任务需要处理。设作业i的处理时间为 t i t_i ti,这个时间包括把作业放入机器和从机器上取下的时间。所谓调度(schedule)是指按作业在机器上的运行时间分配作业,使得:

  • 一台机器在同一时间内只能处理一个作业。
  • 一个作业不能同时在两台机器上处理。
  • 一个作业i的处理时间是t,个时间单位。

假如每台机器在0时刻都是可用的,完成时间(finish time)或调度长度(length of a schedule)是指完成所有作业的时间。在一个非抢先调度中,一项作业i在一台机器上处理,从时刻 s i s_i si开始,到时刻 s i + t i s_i+t_i si+ti,结束。

我们的任务是写一个程序,实现在 m 台机器上执行 n 个作业的最小完成时间的调度。但是设计一个具有多项式时间复杂性的算法(即复杂度为 n k m l n^km^l nkml的算法,k和l是常数)来解决该问题非常难。调度问题是一个NP-复杂问题。

NP复杂问题和NP-完全问题

NP-复杂及NP-完全问题是指尚未找到具有多项式时间复杂性算法的问题。

NP-完全问题是一类判定问题,也就是说,对这类问题的每一个实例,答案为是或否。

NP-复杂问题可以是判定问题,也可以不是判定问题。

机器调度问题不是一个判定问题,因为对每一个问题实例,都是按照某种方案把作业分配给机器,以使完成时间最少。但是可以转换为判定问题。

对于机器调度问题,除了给定任务和机器外,还给定了时间TMin,要求确定是否存在一种调度,它的完成时间为 TMin 或更少。对于这类问题,答案为是或否。

NP-复杂问题的优化问题经常用**近似算法(approximation aigorithm)**解决,保证能找到近似最优解。

求解思路-最长处理时间(LPT)

在我们的调度问题中,采用了一个简单调度策略,称为最长处理时间(longest processing time,LPT),它的调度长度是最优调度长度的4/3-1/(3m)。在LPT算法中,作业按处理时间的递减顺序排列。当一个作业需要分配时,总是分配给最先变为空闲的机器。

**定理 12-2[Graham]*令 F(I)为在 m 台机器上执行作业集合 I 的最佳调度完成 时间,F(I)为采用 LPT 调度策略所得到的调度完成时间,则
F ( I ) F ∗ ( I ) ≤ 4 3 − 1 3 m \frac{F(I)}{F^*(I)}\leq\frac{4}{3}-\frac{1}{3m} F(I)F(I)343m1
可用堆来建立 LPT 调度方案,时间性能为 O(nlogn)。当n<m 时,只需要将作业 i 在0~t,时间内分配给机器i来处理。当 n>m 时,可以使用大根堆将作业按处理时间递增顺序排列。为了建立LPT调度方案,作业按相反次序进行分配。为了决定将一个作业分配给哪一台机器,必须知道哪台机器最先空闲。为此,维持一个m台机器的小根堆,元素类型为machineNode,它有数据成员avail(表示何时空闲)和id(机器编号)。machineNode类型实现()的重载。初始状态下所有machine的avail都为0。

用类jobNode表示作业,它有数据成员id(作业的唯一标识符)和time(作业需要的处理时间)。

举例

有3台机器,需要处理7个作业。7个作业的处理时间分别为(2,14,4,16,6,5,3)。3台机器的编号分别为M1、M2和M3。使用最长处理时间机器调度方法可以得到如下方案:

在这里插入图片描述

代码

main.cpp

#include <iostream>
#include <queue>
#include <vector>

// 表示机器,id表示机器的id,avail表示机器什么时候有空
struct machineNode {
    int avail;
    int id;

    machineNode() {
        avail = 0;
        id = 0;
    }

    machineNode(int pid, int pavail) {
        avail = pavail;
        id = pid;
    }

    explicit operator int() const { return avail; }

    bool operator>(const machineNode &a) const { return avail > a.avail; }
};

// 表示任务,id表示任务的id,time表示作业需要的处理时间
struct jobNode {
    int id;
    int time;

    jobNode() {
        id = 0;
        time = 0;
    }

    jobNode(int pid, int ptime) {
        id = pid;
        time = ptime;
    };

    explicit operator int() const { return time; }

    bool operator<(const jobNode &a) const { return time < a.time; }
};

int main() {
    // 整个算法的时间复杂度为O(logn)
    // 初始化任务大根堆,初始化时间为O(taskVec.size()==n)
    const std::vector<jobNode> taskVec = {jobNode(1, 2), jobNode(2, 14), jobNode(3, 4), jobNode(4, 16), jobNode(5, 6),
                                          jobNode(6, 5), jobNode(7, 3)};
    std::priority_queue<jobNode, std::vector<jobNode>> tasks(taskVec.begin(), taskVec.end());
    // 初始化机器小根堆,初始化时间为O(machineVec.size()==m)
    const std::vector<machineNode> machineVec = {machineNode{1, 0}, machineNode{2, 0}, machineNode{3, 0}};
    std::priority_queue<machineNode, std::vector<machineNode>, std::greater<>> machines(machineVec.begin(),
                                                                             machineVec.end());
    // 执行了2n次top、2n次 pop和2n次 push操作,每次top的时间是0(1),machines的pop和push的时间是O(logm),tasks的pop和push的时间是O(logn)。
    // 因此此for循环的时间复杂度为O(nlogn)
    for (int i = 0; i < taskVec.size(); i++) {
        machineNode temp = machines.top();
        machines.pop();
        jobNode taskNode = tasks.top();
        tasks.pop();
        std::cout << "Schedule job " << taskNode.id << " on machine " << temp.id << " from " << temp.avail << " to "
                  << (temp.avail + taskNode.time) << std::endl;
        temp.avail += taskNode.time;
        machines.push(temp);
    }
    std::cout << std::endl;
    return 0;
}

运行结果

"C:\Users\15495\Documents\Jasmine\prj\_Algorithm\Data Structures, Algorithms and Applications in C++\_28LongestProcessingTime\cmake-build-debug\_28LongestProcessingTime.exe"
Schedule job 4 on machine 3 from 0 to 16
Schedule job 2 on machine 2 from 0 to 14
Schedule job 5 on machine 1 from 0 to 6
Schedule job 6 on machine 1 from 6 to 11
Schedule job 3 on machine 1 from 11 to 15
Schedule job 7 on machine 2 from 14 to 17
Schedule job 1 on machine 1 from 15 to 17


Process finished with exit code 0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1319234.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【PostgreSQL】从零开始:(十二)PostgreSQL-数据库对象关系及定义

从图中我们可以看出服务器对象的关系 现在我们来了解它们的定义 数据库服务器(Server) 数据库服务器是一种用来存储、管理和查询大量数据的服务器。它是一个独立的计算机系统&#xff0c;运行数据库管理系统&#xff08;DBMS&#xff09;软件&#xff0c;并提供对数据库的访问…

【ECMAScript笔记二】运算符分类,流程控制(顺序结构、分支结构、循环结构)

文章目录 4 运算符4.1 算术运算符4.2 递增和递减运算符4.3 比较运算符4.4 逻辑运算符4.5 赋值运算符4.6 运算优先级 5 流程控制5.1 顺序结构5.2 分支结构5.2.1 if 语句5.2.2 switch 语句 5.3 循环结构5.3.1 for循环5.3.2 while循环5.3.3 do while循环5.3.4 continue和break 5.4…

数据科学知识库

​ 我的博客是一个技术分享平台&#xff0c;涵盖了机器学习、数据可视化、大数据分析、数学统计学、推荐算法、Linux命令及环境搭建&#xff0c;以及Kafka、Flask、FastAPI、Docker等组件的使用教程。 在这个信息时代&#xff0c;数据已经成为了一种新的资源&#xff0c;而机…

1.新入手的32位单片机资源和资料总览

前言&#xff1a; 学了将近1年的linux驱动和uboot&#xff0c;感觉反馈不足&#xff0c;主要是一直在学各种框架&#xff0c;而且也遇到了门槛&#xff0c;比如驱动部分&#xff0c;还不能随心所欲地编程&#xff0c;原因是有些外设的原理还不够深刻、有些复杂的底层驱动的代码…

java springboot 内存级数据库 H2 创建表并添加数据演示

好 上文 java简述springboot通过配合初始化H2数据库并完成登录 带着大家登进了 h2数据库 这里需要强调 你只需要第一次加上 datasource:url: jdbc:h2:~/testhikari:driver-class-name: org.h2.Driverusername: rootpassword: 123456这些 因为它要初始化 你后面再启动 去掉这些…

C语言预处理详解及其指令

预处理详解 1.预定义符号2.#define定义常量基本使用方法举例子如果在define定义的表示符后面加上分号会发生什么&#xff1f;用一下来解释 3. #define定义宏举例例1例2 4. 带有副作用的宏参数例如: 5. 宏替换的规则6. 宏函数的对比宏和函数的一个对比 7. #和##7.1 #运算符7.2 #…

shell子进程管理

简介 在我们平时写代码过程中&#xff0c;可能经常会遇到串行执行速度慢 &#xff0c;串行无法执行多个任务&#xff0c;这时便需要使用子进程同时执行。使用父进程创建子进程时&#xff0c;子进程会复制父进程的内存、文件描述符和其他相关信息。当然&#xff0c;子进程可以独…

2023年全球运维大会(GOPS深圳站)-核心PPT资料下载

一、峰会简介 1、大会背景与概述 全球运维大会&#xff08;GOPS&#xff09;是运维领域最具影响力的国际盛会&#xff0c;每年都会汇聚世界各地的运维专家、企业领袖、技术爱好者&#xff0c;共同探讨运维技术的最新发展、最佳实践以及面临的挑战。2023年GOPS深圳站作为该系列…

亚马逊云科技re:Invent推出生成式AI技术堆栈及关键服务和工具

亚马逊云科技于29日推出“生成式AI技术堆栈”后&#xff0c;又在30日的re:Invent 2023大会上宣布了一系列支持这一全新堆栈的关键服务和工具。 亚马逊云科技数据和人工智能副总裁Swami Sivasubramanian在主题演讲中&#xff0c;将生成式人工智能与“超新星爆炸”进行了比较&am…

HttpRunner接口自动化测试框架

简介 HttpRunner是一款面向 HTTP(S) 协议的通用测试框架&#xff0c;只需编写维护一份 YAML/JSON 脚本&#xff0c;即可实现自动化测试、性能测试、线上监控、持续集成等多种测试需求。 项目地址&#xff1a;GitHub - httprunner/httprunner: HttpRunner 是一个开源的 API/UI…

Apache SeaTunne简介

Apache SeaTunne简介 文章目录 1.Apache SeaTunne是什么&#xff1f;1.1[官网](https://seatunnel.apache.org/)1.2 项目地址 2.架构3.特性3.1 丰富且可扩展的连接器和插件机制3.2 支持分布式快照算法以确保数据一致性3.3 支持流、批数据处理&#xff0c;支持全量、增量和实时数…

Web前端-HTML(常用标签)

文章目录 1. HTML常用标签1.1 排版标签1&#xff09;标题标签h (熟记)2&#xff09;段落标签p ( 熟记)3&#xff09;水平线标签hr(认识)4&#xff09;换行标签br (熟记)5&#xff09;div 和 span标签(重点)6&#xff09;排版标签总结 1.2 标签属性1.3 图像标签img (重点)1.4 链…

新算法!!! TSOA-CNN-LSTM-Attention凌日优化卷积、长短期记忆网络融合注意力机制的多变量回归预测程序,数据由Excel导入,直接运行

适用平台&#xff1a;Matlab2023版及以上 凌日优化算法&#xff08;Transit Search Optimization Algorithm&#xff0c;TSOA&#xff09;是2022年8月提出的一种新颖的元启发式算法&#xff0c;当一颗行星经过其恒星前方时&#xff0c;会导致恒星的亮度微弱地下降&#xff0c;…

分布式事务 | 2PC与3PC 详解

分布式事务 2PC 2PC &#xff0c;两阶段提交&#xff0c;将事务的提交过程分成资源准备和资源提交两个阶段&#xff0c;并且由事务协调者来协调所有事务参与者&#xff0c;如果准备阶段所有事务参与者都预留资源成功&#xff0c;则进行第二阶段的资源提交&#xff0c;否则事务…

本章主要介绍Spring Framework中用来处理URI的多种方式

1.使用 UriComponentsBuilder 构建URi 话不多说 直接上代码 UriComponents uriComponents UriComponentsBuilder.fromUriString("https://example.com/hotels/{hotel}").queryParam("q", "{q}").encode().build();URI uri uriComponents.exp…

【Gradle】创建第一个项目

文章目录 1. 前提2. 创建项目并初始化1&#xff09;创建项目2&#xff09;初始化项目 3. 介绍生成的文件结构4. 执行5. 包的作成 &#xff08;非必须&#xff09;6. 推送&#xff08;非必须&#xff09; 本节将继 Gradle 之初体验 安装之后&#xff0c;创建第一个 Hello World…

Oracle(2-18)Export and Import Utilities

文章目录 一、基础知识1. Export &Import Utilities2、Exp/lmp Utility Overview Exp/mp实用程序概述3、Before Your Use Of Exp/lmp 在您使用Exp/lmp之前4、Methods to invoke Exp/lmp 调用Exp/lmp的方法5、Import Utility for Recovery 用于恢复的导入实用程序 二、基础操…

Mac如何安装stable diffusion

今天跟大家一起在Mac电脑上安装下stable diffusion&#xff0c;在midjourney等模型收费的情况下如何用自己的电脑算力用上免费的画图大模型呢&#xff1f;来吧一起实操起来 一、安装homebrew 官网地址&#xff1a;Homebrew — The Missing Package Manager for macOS (or Lin…

【科研论文】检索证明、科技查新、查收查引(附教育部、科技部查新工作站名单)

文章目录 1、什么是科技查新 & 查收查引2、科技查新 & 查收查引有什么用3、如何办理科技查新 & 查收查引4、教育部科技查新工作站5、科技部认定的查新机构名单 1、什么是科技查新 & 查收查引 科技查新是国家科技部为避免科研课题重复立项和客观正确地判别科研…