贪心算法 -- 最小延迟调度

转自:https://blog.csdn.net/bqw18744018044/article/details/80285414

总结:

  首先,证明贪心的时候交换论证是万能的!其次,这一点如果要满足,也就是,如果你要用交换论证法,那么首先要保证交换逆序后,对其他的没有影响!如果有影响,那就只能像【POJ - 3253】Fence Repair 这道题一样,用优先队列去解决了。


1. 单区间调度问题
问题定义:存在单一资源,有一组以时间区间形式表示的资源请求reqs={req-1, req-2, …, req-n},第i个请求希望占用资源一段时间来完成某些任务,这段时间开始于begin(i)终止于end(i)。如果两个请求req-i和req-j在时间区间上没有重叠,则说这两个请求是相容的,求出这组请求的最大相容子集(最优子集)。举个例子:有一间多媒体课室,某一个周末有多个社团想要申请这间课室去举办社团活动,每个社团都有一个对应的申请时间段,比如周六上午8:00-10:00。求出这间课室在这个周末最多能满足几个社团的需求。

解决方案:贪心算法,优先选择最早结束的需求,确保资源尽可能早地被释放,把留下来满足其他需求的时间最大化。具体伪代码如下所示,算法结束后集合A中会保留所有相容请求,A的大小即是最大相容数量。

初始化R是所有需求的集合,A为空集
对R中的需求Ri,根据结束时间从早到晚排序
for Ri in R, do
  if Ri与A中的请求相容
    A = A并Ri
  endIf
endFor
return A

上述伪代码的C++实现如下,

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

const int MAX_SIZE = 100;

struct Request {
  int begin, end;
} req[MAX_SIZE];

bool operator<(const Request& req1, const Request& req2) {
  return req1.end < req2.end;
}

int main() {
  int requestNum;
  cin >> requestNum;
  if (requestNum > MAX_SIZE) {
    cout << "请求数量过多" << endl;
    return 0;
  }
  for (int i = 0; i < requestNum; ++i) {
    cin >> req[i].begin >> req[i].end;
  }

  sort(req, req + requestNum);

  vector<Request> rvec;
  rvec.push_back(req[0]);
  for (int i = 1; i < requestNum; ++i) {
    if (rvec[rvec.size() - 1].end <= req[i].begin) {
      rvec.push_back(req[i]);
    }
  }

  cout << "最大兼容量: " << rvec.size() << endl;
  return 0;
}

2. 多区间调度问题
问题定义:存在多个(或者无限多个)相同的资源,有一组以时间区间形式表示的资源请求reqs={req-1, req-2, …, req-n},第i个请求希望占用资源一段时间来完成某些任务,这段时间开始于begin(i)终止于end(i)。如果两个请求req-i和req-j在时间区间上没有重叠,则说这两个请求是相容的,用尽可能少的资源满足所有请求(求最优资源数量)。举个例子:有很多间课室,某个周末有多个社团需要申请课室办活动,每个社团都有一个对应的申请时间,求最少需要多少间课室才能够满足所有社团的需求(在这个问题之中时间重叠的社团需要安排在其他课室,即会使用到多个资源,需要考虑多个资源上的调度安排,故称为多区间调度)。

解决方案:贪心算法,将需求按照开始时间的早晚进行排序,然后开始为这些资源打标签,每个标签代表都一个资源,需求req-i被打上标签k表示该请求分配到的资源是k。遍历排序后的需求,如果一个需求与某个已分配资源上的其他安排不冲突,则把该需求也放进该资源的安排考虑中;如果冲突,那么应该要给此需求分配新的资源,已用资源数量加一。具体操作的伪代码如下所示。

对n个需求按照开始时间从早到晚进行排序
假设排序后的需求记为{R1, R2, ..., Rn}
初始化tagSize = 1;
for i=1 to n, do:
  tags = {1,2,...,tagSize};
  for j = 1 to i-1, do:
    if Rj与Ri时间区间重叠产生冲突:
      tags = tags - {Rj的标签};
    endIf
  endFor
  if tags为空集:
    tagSize += 1;
    将标签tagSize贴在Ri上
  EndIf
  else:
    在tags剩下的标签中随便挑一个贴给Ri
  endElse
endFor
此时每个请求上都贴有标签,每个标签对应其申请的资源编号,此时的tagSize就是至少需要的资源数量
return tagSize;


上述伪代码的C++实现如下:

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

const int MAX_SIZE = 100;

struct Request {
  int begin, end, tag;
} req[MAX_SIZE];

bool operator<(const Request& req1, const Request& req2) {
  return req1.begin < req2.begin;
}

int main() {
  int requestNum;
  cin >> requestNum;
  if (requestNum > MAX_SIZE) {
    cout << "请求数量过多" << endl;
    return 0;
  }
  for (int i = 0; i < requestNum; ++i) {
    cin >> req[i].begin >> req[i].end;
  }

  sort(req, req + requestNum);

  int tagSize = 1;
  req[0].tag = 0;
  bool tags[MAX_SIZE];
  for (int i = 1; i < requestNum; ++i) {
    memset(tags, 1, sizeof(tags));
    for (int j = 0; j < i; ++j) {
      if (req[j].end > req[i].begin) {
        tags[req[j].tag] = false;
      }
    }
    bool isTagsEmpty = true;
    int tag;
    for (int j = 0; j < tagSize; ++j) {
      if (tags[j]) {
        isTagsEmpty = false;
        tag = j;
        break;
      }
    }
    if (isTagsEmpty) {
      req[i].tag = tagSize;
      ++tagSize;
    } else {
      req[i].tag = tag;
    }
  }

  cout << "最小资源使用量: " << tagSize << endl;
  return 0;
}


3. 最小延迟调度问题
问题定义:存在单一资源和一组资源请求reqs={req-1, req-2, …, req-n},与前面两个问题不同,这里的资源从时刻0开始有效(开始接受申请,开始可以被使用),每个请求req-i都有一个截止时间ddl(i),每个请求都要占用资源一段连续的时间来完成任务,占用时间为time(i)。每个请求都希望自己能在ddl之前完成任务,不同需求必须被分在不重叠的时间区间(单一资源,同一时刻只能满足一个请求)。假设我们计划满足每个请求,但是允许某些请求延迟(即某个请求在ddl之后完成,延误工期),确定一种合理的安排,使得所有请求的延期时间中的最大值,是所有可能的时间安排情况中最小的。从时刻0开始,为每个请求req-i分配一个长度time(i)的时间区间,把区间标记为[begin(i), end(i)],其中end(i) = begin(i) + time(i)。如果end(i) > ddl(i),则请求req-i被延迟,延迟时间为delay(i) = end(i) - ddl(i);否则delay(i) = 0。合理安排需求,使得maxDelay = max{delay(1), delay(2), …, delay(n)}是所有可能的安排中最小的。

解决方案:贪心算法,按照截止时间ddl排序,越早截止的任务越早完成。该算法是一个没有空闲的最优调度,即从时刻0开始都有在处理请求,直到最后一个请求执行完释放资源之后才空闲。伪代码如下所示。

将需求按照截止时间进行排序
假设排序后的截止时间为ddl[1]<=...<=ddl[n]
start = 0;
maxDelay = 0;
for i = 1 to n, do:
  begin[i] = start;
  end[i] = start + time[i];
  start = end[i] + time[i];
  if maxDelay < end[i] - ddl[i]:
    L = end[i] - ddl[i];
  endIf
endFor
则每个任务安排的时间区间为[begin[i], end[i]],所有任务中最大的延迟为maxDelay,maxDelay为所有可能的任务安排中最小的延迟
return maxDelay;

上述代码的C++实现如下:

#include <iostream>
#include <algorithm>
using namespace std;

const int MAX_SIZE = 100;

struct Request {
  int time, ddl;
  int begin, end;
} req[MAX_SIZE];

bool operator<(const Request& req1, const Request& req2) {
  return req1.ddl < req2.ddl;
}

int main() {
  int requestNum;
  cin >> requestNum;
  if (requestNum > MAX_SIZE) {
    cout << "请求数量过多" << endl;
    return 0;
  }
  for (int i = 0; i < requestNum; ++i) {
    cin >> req[i].time >> req[i].ddl;
  }

  sort(req, req + requestNum);

  int start = 0, maxDelay = 0;
  for (int i = 0; i < requestNum; ++i) {
    req[i].begin = start;
    req[i].end = start + req[i].time;
    start += req[i].time;
    if (maxDelay < req[i].end - req[i].ddl) {
      maxDelay = req[i].end - req[i].ddl;
    }
  }

  cout << "最小的最大延迟: " << maxDelay << endl;
  return 0;
}

转自:https://blog.csdn.net/hongchh/article/details/52183614

代码格式不做调整,详情请去原博主博客中看。

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

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

相关文章

apache2+支持php7,Ubuntu14.04下配置PHP7.0+Apache2+Mysql5.7

Apache步骤一&#xff1a;安装apacheronyaoubuntu:~$ sudo apt install apache2安装好后&#xff0c;在浏览器上输入localhost(服务器端&#xff0c;请输入你的IP地址)&#xff0c;回车就会看到&#xff1a;PHP7.0步骤二&#xff1a;Ubuntu14.04下的默认源是PHP5.0&#xff0c;…

【CodeForces - 1051D】Bicolorings (dp,类似状压dp)

题干&#xff1a; You are given a grid, consisting of 22 rows and nn columns. Each cell of this grid should be colored either black or white. Two cells are considered neighbours if they have a common border and share the same color. Two cells AA and BB be…

【 HDU - 1796】How many integers can you find (容斥原理,二进制枚举或者dfs)

题干&#xff1a; Now you get a number N, and a M-integers set, you should find out how many integers which are small than N, that they can divided exactly by any integers in the set. For example, N12, and M-integer set is {2,3}, so there is another set {2,…

【CodeForces - 1027B 】Numbers on the Chessboard (没有营养的找规律题,无聊题)

题干&#xff1a; You are given a chessboard of size nnnn. It is filled with numbers from 11 to n2n2 in the following way: the first ⌈n22⌉⌈n22⌉ numbers from 11 to ⌈n22⌉⌈n22⌉ are written in the cells with even sum of coordinates from left to right f…

【CodeForces - 1060C】Maximum Subrectangle (思维,预处理前缀和,dp,枚举长度)

题干&#xff1a; You are given two arrays aa and bb of positive integers, with length nn and mmrespectively. Let cc be an nmnm matrix, where ci,jai⋅bjci,jai⋅bj. You need to find a subrectangle of the matrix cc such that the sum of its elements is at m…

【Codeforces 631C 】Report(单调栈,思维模拟)

题干&#xff1a; Each month Blake gets the report containing main economic indicators of the company "Blake Technologies". There are n commodities produced by the company. For each of them there is exactly one integer in the final report, that d…

【CodeForces - 215A】Bicycle Chain (水题)

题干&#xff1a; Vasyas bicycle chain drive consists of two parts: n stars are attached to the pedal axle, m stars are attached to the rear wheel axle. The chain helps to rotate the rear wheel by transmitting the pedal rotation. We know that the i-th sta…

ubuntu 在线安装php,ubuntu在线安装LNMP

一直以来个人安装lamp环境都是源码编译的&#xff0c;这个过程呢其实也要去经历的&#xff0c;但是毕竟占用时间久&#xff0c;有些时候在做一些测试环境的时候&#xff0c;可以在线安装比较快源码编译nginx可看往期&#xff1a;Nginx的安装对于lnmp的在线安装&#xff0c;如下…

【CodeForces - 215B 】Olympic Medal (数学,公式推导)

题干&#xff1a; The World Programming Olympics Medal is a metal disk, consisting of two parts: the first part is a ring with outer radius of r1 cm, inner radius of r2 cm, (0 < r2 < r1)made of metal with density p1 g/cm3. The second part is an i…

【CodeForces - 215C 】Crosses (思维,图形题)

题干&#xff1a; There is a board with a grid consisting of n rows and m columns, the rows are numbered from 1 from top to bottom and the columns are numbered from 1 from left to right. In this grid we will denote the cell that lies on row number i and co…

Scaffold php,GitHub - yiiplus/scaffold: scaffold是一个基于Yii2高级项目模版工程化实现的应用程序...

Yii 2 Scaffold Project Kit易加-脚手架(scaffold)是一个基于Yii2高级项目模版工程化实现的应用程序&#xff0c;它将更加高效、规范和工程化的满足项目开发的需求。DIRECTORY STRUCTUREcommonconfig/ contains shared configurationsmail/ contains view files for e-mailsmod…

oracle修改某个数据类型,Oracle 修改某个字段的数据类型三种方式

1.将该列设置为null,再修改其类型(这样会丢失数据)2.最简单的方法&#xff1a;假设你的表名为 tab_targetcreate table test as select * from tab_target whre 12;alter table test modify (col_name number(5));insert into test select * from tab_target;drop table tab_t…

【EOJ Monthly 2018.10 - B】 莫干山奇遇 (思维构造,数学,数组,贪心)(总结)

题干&#xff1a; Time limit per test: 2.0 seconds Memory limit: 512 megabytes 出题人当然是希望出的题目有关 oxx&#xff0c;于是想方设法给题目配上一些有关 oxx 的背景故事&#xff0c;使得它看起来不那么无趣。但有的时候却无法引入合适的小姐姐&#xff0c;使得 o…

有奶瓶的linux系统,用U盘启动BEINI(奶瓶)系统

用U盘启动&#xff1a;奶瓶(beini)这个系统&#xff0c;是一款基于Tiny Core Linux 搭建的无线网络安全测试系统&#xff0c;当然由于它是用来安全测试的系统&#xff0c;因此在安全方面自然有着强大的功能。而且&#xff0c;这个系统非常简便易学&#xff0c;因此现在已经逐渐…

【CodeForces - 227A】Where do I Turn? (计算几何,叉积判断直线拐向)

题干&#xff1a; Trouble came from the overseas lands: a three-headed dragon Gorynych arrived. The dragon settled at point C and began to terrorize the residents of the surrounding villages. A brave hero decided to put an end to the dragon. He moved from…

linux内核镜像sd卡,【原创】Linux QT镜像的制作--制作SD卡启动盘

最近买了个新的开发板&#xff0c;原生的是Android操作系统&#xff0c;需要自己少个启动盘&#xff0c;制作LinuxQT操作系统。新的开发板带这个制作的源文件&#xff0c;要先把这个文件拷贝到虚拟机Ubunbtu的共享目录下。打开share文件下显示文件如下&#xff1a;打开文件夹命…

【CodeForces - 227C】Flying Saucer Segments (思维)

题干&#xff1a; An expedition group flew from planet ACM-1 to Earth in order to study the bipedal species (its representatives dont even have antennas on their heads!). The flying saucer, on which the brave pioneers set off, consists of three sections. …

清楚linux缓存文件,Linux删除文件 清除缓存

相信很多测试 经常会经历开发叫你清除缓存这种事。那我们要怎么清呢&#xff1f;一、首先&#xff0c;确认你要清除的缓存在哪个目录下&#xff0c;然后切换到该目录下&#xff0c;比如 我现在知道我的的缓存目录是在newerp这个目录下&#xff0c;则如图二、然后 执行命令 rm -…

win10 linux安卓模拟器,genymotion安卓模拟器在Window10中使用的问题

最近一段时间&#xff0c;把系统升级到了win10&#xff0c;然后悲催的事情出现了&#xff0c;genymotion挂了&#xff0c;根本就不能启动&#xff0c;而且还是2.6版本的genymotion&#xff0c;下面我把遇到的问题总结一下&#xff1a;首先&#xff0c;在我的win10系统中&#x…

cross_compile = arm-linux-,cross compile grpc for arm

8种机械键盘轴体对比本人程序员&#xff0c;要买一个写代码的键盘&#xff0c;请问红轴和茶轴怎么选&#xff1f;This post will tell you how to cross compile gPRC static lib for ARM.前段时间尝试交叉编译gRPC遇到了不少的麻烦&#xff0c;写篇post记录一下。gRPCPreparat…