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

news2024/9/25 1:15:25

机器调度

完整可编译运行代码见: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/1310739.html

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

相关文章

Amazon Aurora Limitless Database:数据库管理的全新境界

授权说明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 亚马逊云科技开发者社区, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道 在当今数亿用户、PB级数据和数百万交易的业务环境中&#xff0c;数…

12.14_黑马数据结构与算法笔记Java

目录 120 二叉搜索树 min max 121 二叉搜索树 put 122 二叉搜索树 前任后任1 123 二叉搜索树 前任后任2 124 二叉搜索树 删除1 125 二叉搜索树 删除2 126 二叉搜索树 删除3 127 二叉搜索树 删除 递归1 128 二叉搜索树 删除 递归2 129 二叉搜索树 范围查询 130 二叉搜…

KUKA机器人如何隐藏程序或程序段?

KUKA机器人如何隐藏程序或程序段? 如下图所示,新建一个示例程序进行说明, 如下图所示,如果红框中的动作指令不想让别人看到,想隐藏起来,如何做到? 如下图所示,在想要隐藏的程序或程序段的前后,分别添加 ;fold 和 endfold指令(这里要注意是英文状态下的输入法), 如…

国标GB28181安防监控系统/磁盘阵列EasyCVR(V.3.4)新亮点:免保活功能

TSINGSEE青犀近日发布了EasyCVR安防管理平台的V.3.4版本&#xff0c;其中一大亮点就是很多朋友都在咨询的“免保活”功能&#xff0c;那么&#xff0c;什么是“免保活”功能&#xff1f;又该如何配置呢&#xff1f; 在EasyCVR平台有个【按需直播】按钮&#xff0c;顾名思义&…

如何部署Portainer容器管理工具+cpolar内网穿透实现公网访问管理界面

文章目录 前言1. 部署Portainer2. 本地访问Portainer3. Linux 安装cpolar4. 配置Portainer 公网访问地址5. 公网远程访问Portainer6. 固定Portainer公网地址 前言 本文主要介绍如何本地安装Portainer并结合内网穿透工具实现任意浏览器远程访问管理界面。Portainer 是一个轻量级…

大象elephant目标检测数据集VOC+YOLO格式2300张

大象是长鼻目象科的哺乳动物&#xff0c;有两个属&#xff0c;是世界上最大的陆生动物。其像柱子一样的四肢和宽厚的脚掌可以稳稳支撑住庞大的身体。巨大的头上长有蒲扇状的大耳朵和长且有弹性的鼻子。象耳上有丰富的血管&#xff0c;可以有效散热。鼻子和上唇合而为一的象鼻由…

YB9225是一种固定工作频率的高效率电流模式升压转换器。

YB9225B 1.2 MHz。峰值5A 电流&#xff0c;升压转换器 概述 &#xff1a; YB9225是一种固定工作频率的高效率电流模式升压转换器。YB9225集成了一个非常低的 Rds-on NMOSFTET&#xff0c;以减少功率损耗和实现高效率。最高效率可达93% 。功率 MOSFET 的峰值电流限制在5 A。1.…

网站使用CDN后无法获取用户真实IP的解决方法

宝塔或Nginx环境 如果你使用的宝塔或Nginx&#xff0c;可以在宝塔面板或Nginx中&#xff0c;找到配置文件增加如下代码后&#xff0c;重载配置或者重启 Nginx 即可&#xff1a; #CDN获取真实ip set_real_ip_from 0.0.0.0/0; real_ip_header X-Forwarded-For; PHP语言函数方法…

36、什么是池化算法

池化算法也是 CNN 网络中非常常见的算法。 池化这一算法理解起来比较简单,从名字中或许可以看到一些东西:从一个像素池子中选取一些有代表性的像素出来。 常见的池化有最大池化和平均池化。最大池化就是从像素池子中选取最大值出来,而平均池化就是从像素池子中选取平均值出…

HTML---初识CSS

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 一.CSS概念 CSS是层叠样式表&#xff08;Cascading Style Sheets&#xff09;的缩写。它是一种用于描述HTML文档外观样式的标记语言。通过CSS&#xff0c;开发者可以在不改变HTML标记结构的情况…

机器学习 | 机器学习基础知识

一、机器学习是什么 计算机从数据中学习规律并改善自身进行预测的过程。 二、数据集 1、最常用的公开数据集 2、结构化数据与非结构化数据 三、任务地图 1、分类任务 Classification 已知样本特征判断样本类别二分类、多分类、多标签分类 二分类&#xff1a;垃圾邮件分类、图像…

【数据结构入门精讲 | 第一篇】打开数据结构之门

数据结构与算法是计算机科学中的核心概念&#xff0c;也与现实生活如算法岗息息相关。鉴于全网数据结构文章良莠不齐且集成度不高&#xff0c;故开设本专栏&#xff0c;为初学者提供指引。 目录 基本概念数据结构为何面世算法基本数据类型抽象数据类型使用抽象数据类型的好处 数…

利用Pytorch预训练模型进行图像分类

Use Pre-trained models for Image Classification. # This post is rectified on the base of https://learnopencv.com/pytorch-for-beginners-image-classification-using-pre-trained-models/# And we have re-orginaized the code script.预训练模型(Pre-trained models)…

【SpringBoot】进阶之自定义starter(一起了解自定义starter的魅力)

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是君易--鑨&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的博客专栏《SpringBoot开发》。&#x1f3af;&#x1f3af;…

解决设备能耗管理问题,易点易动来帮忙!

设备能耗管理是现代企业可持续发展的重要环节&#xff0c;然而&#xff0c;许多企业在设备能耗管理方面面临一系列问题&#xff1a; 能耗数据收集困难&#xff1a;企业需要监控和管理大量设备的能耗情况&#xff0c;但传统的手动方式收集能耗数据耗时耗力&#xff0c;无法实时获…

Python中的TesserOCR:文字识别的全方位指南

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 文字识别在图像处理领域中起到了至关重要的作用&#xff0c;而TesserOCR&#xff08;Tesseract OCR的Python封装&#xff09;为开发者提供了一个强大的工具&#xff0c;使得文字识别变得更加便捷。本文将通过详细…

电声器件是什么

电声器件 电子元器件百科 文章目录 电声器件前言一、电声器件是什么二、电声器件的类别三、电声器件的应用实例四、电声器件的作用原理总结前言 电声器件在多种应用中起着重要作用,如家庭娱乐系统、音响设备、通信设备、汽车音响、舞台表演、声音检测和录音等领域。它们的设计…

新版Spring Security6.2案例 - Authentication用户名密码

前言&#xff1a; 前面有翻译了新版Spring Security6.2架构&#xff0c;包括总体架构&#xff0c;Authentication和Authorization&#xff0c;感兴趣可以直接点链接&#xff0c;这篇翻译官网给出的关于Authentication的Username/Password这页。 首先呢&#xff0c;官网就直接…

RHEL7.5编译openssl1.1.1w源码包到rpm包

openssl1.1.1w下载地址 https://www.openssl.org/source/ 安装依赖包 yum -y install curl which make gcc perl perl-WWW-Curl rpm-build wget http://mirrors.aliyun.com/centos-vault/7.5.1804/os/x86_64/Packages/perl-WWW-Curl-4.15-13.el7.x86_64.rpm rpm -ivh pe…

tuxera2023破解版免费下载 NTFS for Mac读写工具(附序列号)

Tuxera ntfs 2023 破解安装包是一个mac读写ntfs磁盘工具允许您访问&#xff0c;它允许您访问NFTS 驱动器上的文件。 该应用程序提供访问访问Mac 设备中NFTS 格式文件的驱动力&#xff0c;因此您有权基于格式文件进行无困难的访问Windows 数据。 在发生电力灾难或断电时使用防损…