流水作业调度完整代码
4-流水作业调度

流水作业调度问题(不能直接使用动态规划法的例子)流水作业调度的定义:设有n个作业,每一个作业i均被分解为m项任务: T i1, T i2, ┅, T im(1≤i≤n,故共有n m个任务),要把这些任务安排到m台机器上进行加工。
如果任务的安排满足下列3个条件,则称该安排为流水作业调度:1. 每个作业i的第j项任务T ij (1≤i≤n, 1≤j≤m)只能安排在机器P j上进行加工;2. 作业i的第j项任务T ij(1≤i≤n, 2≤j≤m)的开始加工时间均安排在第j-1项任务T i,j-1加工完毕之后;(任何一个作业的任务必须依次完成,前一项任务完成之后才能开始着手下一项任务)3. 任何一台机器在任何一个时刻最多只能承担一项任务。
最优流水作业调度:设任务T ij在机器P j上进行加工需要的时间为t ij。
如果所有的t ij (1≤i≤n, 1≤j≤m)均已给出,要找出一种安排任务的方法,使得完成这n个作业的加工时间为最少。
这个安排称之为最优流水作业调度。
完成n个作业的加工时间:从安排的第一个任务开始加工,到最后一个任务加工完毕,其间所需要的时间。
优先调度:允许优先级较低的任务在执行过程中被中断,转而去执行优先级较高的任务。
非优先调度:任何任务一旦开始加工,就不允许被中断,直到该任务被完成。
流水作业调度一般均指的是非优先调度。
非优先调度可看成是特殊的优先调度:所有任务的优先级均相同。
7 5 8e.g. (t ij)= 2 2 60 7 4注意:t ij为0表示作业i无须在机器P j上进行加工、即该道工序可以省略。
已经证明,当机器数(或称工序数)m≥3时,流水作业调度问题是一个NP-hard问题(e.g分布式任务调度)。
(粗糙地说,即该问题至少在目前基本上没有可能找到多项式时间的精确最优算法。
)∴目前仅当m=2时,该问题可有多项式时间的算法。
为方便起见,记t i1为a i(作业i在P1上加工所需时间),t i2为b i(作业i在P2上加工所需时间)。
双机流水作业调度问题(Johnson算法)

双机流⽔作业调度问题(Johnson算法)问题定义:双机流⽔作业调度:总共有n个作业,作业i分为两个内容,需要按顺序先后在机器A和机器B上完成,分别需要时间a i,b i来完成,⼀台机器只能同时进⾏⼀项作业,问完成所有作业所需的最⼩时间。
多机流⽔作业调度:⼀个作业需要在⼤于两台机器上先后完成,是NP-hard问题。
解法:问题就是求最佳作业序列。
设前i项作业所需的时间为C i,可以得出以下式⼦c i=a1+b1,i=1 max c i−1,∑i j=1a j+b i,2≤i≤n可以证明,对于相邻两项i和j,如果min(a i,b j)<min(a j,b i)则i项放前⾯更优。
将a i和b i的关系分为<,=,>三类,可以得到如下排列顺序:1.当a i<b i,a j<b j时,a i≤a j,应该按a升序排序2.当a i=b i,a j=b j时,随意排列。
3.当a i>b i,a j>b j时,b i≥b j,应该按b降序排序。
同样可以证明,a i<b i的项应该排在最前,然后是a i=b i的项,最后是a i>b i的项。
代码:{{}//P1248,给定n,ai,bi,求最⼩⽤时和对应序列#include <bits/stdc++.h>using namespace std;const int maxn=1e5+5;typedef long long ll;struct node{int a,b,d,id;bool operator<(const node &v)const {if(d!=v.d)return d<v.d;else if(d==-1){return a<v.a;}else{return b>v.b;}}}p[maxn];int main () {int n;scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&p[i].a);for(int i=1;i<=n;i++){scanf("%d",&p[i].b);p[i].id=i;int cha=p[i].a-p[i].b;if(cha==0)p[i].d=0;else p[i].d=cha<0?-1:1;}sort(p+1,p+1+n);ll ans=0,dt=0;for(int i=1;i<=n;i++){ans+=p[i].a;dt=max(0ll,dt-p[i].a);dt+=p[i].b;}ans+=dt;printf("%lld\n",ans);for(int i=1;i<=n;i++){if(i>1)printf(" ");printf("%d",p[i].id);}puts("");}Processing math: 100%。
调度算法C语言实现

调度算法C语言实现调度算法是操作系统中的重要内容之一,它决定了进程在系统中的运行方式和顺序。
本文将介绍两种常见的调度算法,先来先服务(FCFS)和最短作业优先(SJF),并用C语言实现它们。
一、先来先服务(FCFS)调度算法先来先服务(FCFS)调度算法是最简单的调度算法之一、它按照进程到达的先后顺序进行调度,即谁先到达就先执行。
实现这个算法的关键是记录进程到达的顺序和每个进程的执行时间。
下面是一个用C语言实现先来先服务调度算法的示例程序:```c#include <stdio.h>//进程控制块结构体typedef structint pid; // 进程IDint arrivalTime; // 到达时间int burstTime; // 执行时间} Process;int maiint n; // 进程数量printf("请输入进程数量:");scanf("%d", &n);//输入每个进程的到达时间和执行时间Process process[n];for (int i = 0; i < n; i++)printf("请输入进程 %d 的到达时间和执行时间:", i);scanf("%d%d", &process[i].arrivalTime,&process[i].burstTime);process[i].pid = i;}//根据到达时间排序进程for (int i = 0; i < n - 1; i++)for (int j = i + 1; j < n; j++)if (process[i].arrivalTime > process[j].arrivalTime) Process temp = process[i];process[i] = process[j];process[j] = temp;}}}//计算平均等待时间和平均周转时间float totalWaitingTime = 0; // 总等待时间float totalTurnaroundTime = 0; // 总周转时间int currentTime = 0; // 当前时间for (int i = 0; i < n; i++)if (currentTime < process[i].arrivalTime)currentTime = process[i].arrivalTime;}totalWaitingTime += currentTime - process[i].arrivalTime;totalTurnaroundTime += (currentTime + process[i].burstTime) - process[i].arrivalTime;currentTime += process[i].burstTime;}//输出结果float avgWaitingTime = totalWaitingTime / n;float avgTurnaroundTime = totalTurnaroundTime / n;printf("平均等待时间:%f\n", avgWaitingTime);printf("平均周转时间:%f\n", avgTurnaroundTime);return 0;```以上程序实现了先来先服务(FCFS)调度算法,首先根据进程的到达时间排序,然后依次执行每个进程,并计算总等待时间和总周转时间。
0018算法笔记——【动态规划】流水作业调度问题与Johnson法则

1、问题描述:n个作业{1,2,…,n}要在由2台机器M1和M2组成的流水线上完成加工。
每个作业加工的顺序都是先在M1上加工,然后在M2上加工。
M1和M2加工作业i所需的时间分别为ai和bi。
流水作业调度问题要求确定这n个作业的最优加工顺序,使得从第一个作业在机器M1上开始加工,到最后一个作业在机器M2上加工完成所需的时间最少。
2、问题分析直观上,一个最优调度应使机器M1没有空闲时间,且机器M2的空闲时间最少。
在一般情况下,机器M2上会有机器空闲和作业积压2种情况。
设全部作业的集合为N={1,2,…,n}。
S是N的作业子集。
在一般情况下,机器M1开始加工S中作业时,机器M2还在加工其他作业,要等时间t后才可利用。
将这种情况下完成S中作业所需的最短时间记为T(S,t)。
流水作业调度问题的最优值为T(N,0)。
设π是所给n个流水作业的一个最优调度,它所需的加工时间为aπ(1)+T’。
其中T’是在机器M2的等待时间为bπ(1)时,安排作业π(2),…,π(n)所需的时间。
记S=N-{π(1)},则有T’=T(S,bπ(1))。
证明:事实上,由T的定义知T’>=T(S,bπ(1))。
若T’>T(S,bπ(1)),设π’是作业集S在机器M2的等待时间为bπ(1)情况下的一个最优调度。
则π(1),π'(2),…,π'(n)是N的一个调度,且该调度所需的时间为aπ(1)+T(S,bπ(1))<aπ(1)+T’。
这与π是N的最优调度矛盾。
故T’<=T(S,bπ(1))。
从而T’=T(S,bπ(1))。
这就证明了流水作业调度问题具有最优子结构的性质。
由流水作业调度问题的最优子结构性质可知:从公式(1)可以看出,该问题类似一个排列问题,求N个作业的最优调度问题,利用其子结构性质,对集合中的每一个作业进行试调度,在所有的试调度中,取其中加工时间最短的作业做为选择方案。
将问题规模缩小。
多级调度代码与结果截图

#include <iostream>using namespace std;#define T 7 //作业数#define T1 8#define A 3 //机器数extern void max_time(int m[][T1],int M1);extern void reveal(int m[][T1],int M1);extern void row_sum(int m[][T1],int M1);extern int min_time(int m[][T1],int M1);//将作业按占用的机器时间由大到小排序void sort(int n,int t[]){for (int i=0;i<n-1;i++){ for (int k=i;k<n;k++){if (t[i]<t[k]){int temp;temp = t[i];t[i] = t[k];t[k] = temp;}}}}void row_sum(int m[][T1],int M1){//并求出各个机器完成作业的时间,并将其分别存在二维数组每行的最后位置f or (int z=0;z<M1;z++) {m[z][T] = 0;for (int k=0;k<T;k++){if(m[z][k] == 0) break;elsem[z][T] = m[z][k] + m[z][T];}}}//显示每台机器调度的作业情况void reveal(int m[][T1],int M1){f or (int i=0;i<M1;i++){cout<<"第"<<i+1 <<"台机器完成的作业时间分别是:"<<endl;for(int k=0;k<T;k++){if(m[i][k] == 0) break;elsecout<<m[i][k]<<" ";}cout<<endl;cout<<"花费的总时间是:"<<m[i][T]<<endl;cout<<endl;}}//作业数小于机器数的调度的情况void set_work1(int M1,int m[][T1],int N,int n[]){f or (int i=0;i<N;i++)m[i][0] = n[i];r eveal(m,A);m ax_time(m,A);}//作业数大于机器数的调度的情况void set_work2(int M1,int m[][T1],int N,int n[]){f or (int i=0;i<N;i++){row_sum(m,M1);int temp = min_time(m,A);int num;int q;num = 0;//找到该机器调度的下一个作业应存放的位置for ( q=0;q<T;q++){if(m[temp][q] > 0) //该位置已存放作业num++; //则移动到该行的下一位置}m[temp][num] = n[i];m[temp][T] +=m[temp][num];}r eveal(m,A);m ax_time(m,A);}//寻找机器内已有作业共占用时间最少的机器序号int min_time(int m[][T1],int M1){i nt minTime = 0;for (int i=0;i<M1;i++){if (m[minTime][T] > m[i][T] )minTime = i;}return minTime;}//调度完成后求出机器内已有作业共占用时间最多的机器序号,//其完成作业的总时间即所有作业完成的时间void max_time(int m[][T1],int M1){i nt maxTime = m[0][T];f or (int i=0;i<M1;i++){if(maxTime < m[i][T])maxTime = m[i][T];}c out<<"所有作业均已完成的时间:"<<maxTime<<endl;}void main(){i nt t[T] = {22,11,45,3,6,57,71};i nt m[A][T1] = {0,0};i nt i;c out<<"未排序的作业顺序为: ";f or(i=0;i<T;i++)cout<<t[i]<<" ";c out<<endl<<endl;s ort(T,t); //将作业按占用的机器时间由大到小排序c out<<"排序后的作业顺序为:";f or(i=0;i<T;i++)cout<<t[i]<<" ";cout<<endl;i f (A > T) //作业数小于机器数set_work1(A,m,T,t);e lseset_work2(A,m,T,t);}用户屏幕:。
作业调度算法源代码

作业调度算法源代码#include <stdio.h>#include <stdlib.h>#define ReadyLimit 5typedef struct job{int id;int needtime;int arrivetime;int starttime;int finishtime;int remainder;float priority;struct job *next;} jobnode,*jobnodeptr;jobnodeptr joblist,readylist,runlist,collectlist; int systime;void init(void){joblist=(jobnodeptr)malloc(sizeof(jobnode)); joblist->id=-1;joblist->next=NULL;readylist=(jobnodeptr)malloc(sizeof(jobnode)); readylist->id=-1;readylist->next=NULL;collectlist=(jobnodeptr)malloc(sizeof(jobnode));collectlist->id=-1;collectlist->next=NULL;runlist=NULL;systime=-1;}void file2joblist(void){FILE *fp;jobnodeptr p,q;int i,j;fp=fopen("input.txt","rt");if (!fp){printf("Can't open file");exit(1);}p=joblist;fscanf(fp,"%d",&i);for (j=0;j<i;j++){q=(jobnodeptr)malloc(sizeof(jobnode));fscanf(fp,"%d%d%d",&q->id,&q->needtime,&q->arrivetime); q->starttime=0;q->finishtime=0;q->remainder=q->needtime;q->priority=-1.0;p->next=q;p=q;}p->next=NULL;fclose(fp);}void jobdispatch(void)/*作业调度*/{jobnodeptr p,q;int count=0;float maxpri;p=readylist;/*计算readylist中进程的个数*/while (p->next){count++;p=p->next;}if (count>=ReadyLimit) return;p=joblist->next;/*计算已到达作业的响应比*/while (p){if (p->arrivetime<=systime)p->priority=(systime-p->arrivetime)/(float)p->needtime; p=p->next;}while (count<ReadyLimit){maxpri=-1.0;p=joblist;q=NULL;while (p->next){if (p->next->priority > maxpri){maxpri = p->next->priority; q = p;}p=p->next;}if (q){p=q->next;q->next=p->next;p->next=NULL;q=readylist;while (q->next)q=q->next;q->next=p;p->starttime=systime;count++;}else break;}}void processdispatch(void)/*进程调度*/{runlist=readylist->next;if (runlist) {readylist->next=runlist->next;runlist->next=NULL;}}void running(void)/*模拟运行*/{jobnodeptr p;if (runlist){printf("%4d:%-4d ",systime,runlist->id);runlist->remainder--;if (runlist->remainder){p=readylist;while (p->next)p=p->next;p->next=runlist;}else{runlist->finishtime=systime;p=collectlist;while (p->next&& (p->next->starttime < runlist->starttime) /*&& (p->next->id < runlist->id)*/)p=p->next;runlist->next=p->next;p->next=runlist;}runlist=NULL;}else printf("%4d:idle ",systime);}void display(void)/*显示信息*/{jobnodeptr p;printf("id----- need--- arrive- start-- finish-\n");p=collectlist->next;while (p){printf("%-7d %-7d %-7d %-7d %-7d\n",p->id,\p->needtime,p->arrivetime,p->starttime,p->finishtime); p=p->next;}}void freeall(void){jobnodeptr p,q;p=collectlist;while (p){q=p;p=p->next;free(q);}free(joblist);free(readylist);}int main(void){init();file2joblist();while (1){systime++;jobdispatch();processdispatch();running();if (joblist->next==NULL && readylist->next==NULL)break;}printf("\n\n"); display();freeall();getchar();return 0;}。
算法设计与分析——流水作业调度(动态规划)

算法设计与分析——流⽔作业调度(动态规划)⼀、问题描述N个作业{1,2,………,n}要在由两台机器M1和M2组成的流⽔线上完成加⼯。
每个作业加⼯的顺序都是先在M1上加⼯,然后在M2上加⼯。
M1和M2加⼯作业i所需的时间分别为ai和bi,1≤i≤n。
流⽔作业⾼度问题要求确定这n个作业的最优加⼯顺序,使得从第⼀个作业在机器M1上开始加⼯,到最后⼀个作业在机器M2上加⼯完成所需的时间最少。
⼆、算法思路直观上,⼀个最优调度应使机器M1没有空闲时间,且机器M2的空闲时间最少。
在⼀般情况下,机器M2上会有机器空闲和作业积压2种情况。
最优调度应该是:1. 使M1上的加⼯是⽆间断的。
即M1上的加⼯时间是所有ai之和,但M2上不⼀定是bi之和。
2. 使作业在两台机器上的加⼯次序是完全相同的。
则得结论:仅需考虑在两台机上加⼯次序完全相同的调度。
设全部作业的集合为N={1,2,…,n}。
S是N的作业⼦集。
在⼀般情况下,机器M1开始加⼯S中作业时,机器M2还在加⼯其他作业,要等时间t后才可利⽤。
将这种情况下完成S中作业所需的最短时间记为T(S,t)。
流⽔作业调度问题的最优值为T(N,0)。
这个T(S,t)该如何理解?举个例⼦就好搞了(⽤ipad pencil写的...没贴类纸膜,太滑,凑合看吧)1、最优⼦结构T(N,0)=min{ai + T(N-{i}, bi)}, i∈N。
ai:选⼀个作业i先加⼯,在M1的加⼯时间。
T(N-{i},bi}:剩下的作业要等bi时间后才能在M2上加⼯。
注意这⾥函数的定义,因为⼀开始⼯作i是随机取的,M1加⼯完了ai之后,要开始加⼯bi了,这⾥M1是空闲的可以开始加⼯剩下的N-i个作业了,但此时M2开始加⼯bi,所以要等bi时间之后才能重新利⽤,对应到上⾯函数T(s,t)的定义的话,这⾥就应该表⽰成T(N-{i},bi), 所以最优解可表⽰为T(N,0)=min{ai + T(N-{i}, bi)}, i∈N,即我们要枚举所有的⼯作i,使这个式⼦取到最⼩值。
流水线作业问题解决的代码

流水线作业调度问题Time Limit: 1000 ms Case Time Limit: 1000 ms Memory Limit: 64 MBDescriptionN个作业{1,2,………,n}要在由两台机器M1和M2组成的流水线上完成加工。
每个作业加工的顺序都是先在M1上加工,然后在M2上加工。
M1和M2加工作业i所需的时间分别为ai和bi,1≤i≤n。
流水作业高度问题要求确定这n个作业的最优加工顺序,使得从第一个作业在机器M1上开始加工,到最后一个作业在机器M2上加工完成所需的时间最少。
Input输入包括若干测试用例,每个用例输入格式为:第1行一个整数代表任务数n,当为0时表示结束,或者输入到文件结束(EOF)第2行至第n+1行每行2个整数,代表任务在M1,M2上所需要的时间Output输出一个整数,代表执行n个任务的最短时间Sample InputOriginal Transformed11 2Sample OutputOriginal Transformed3思路:这一题的难度还是相当不小的。
首先是一个两道工序的流水线排序问题(“同顺序”排序问题)。
用Johnson算法来解决两道工序的流水线排序相对比较简单易懂,而且可以得到最优解。
Johnson算法的大致内容如下:(1)从加工时间矩阵中找出最短的加工时间。
(2)若最短的加工时间出现在M1上,则对应的工件尽可能往前排;若最短加工时间出现在M2上,则对应工件尽可能往后排。
然后,从加工时间矩阵中划去已排序工件的加工时间。
若最短加工时间有多个,则任挑一个。
(3)若所有工件都已排序,停止。
否则,转步骤(1)。
加工时间矩阵即为所有工件分别在两道工序上加工所需时间。
M1为工序1,M2为工序2(进入工序2之前,工序1必须完工)。
Johnson算法之所以能求出最优解,是因为:1.所有工件没开始加工时,只能加工工序1,工序2不得不空着。
2.我们只能利用工序2的加工过程尽量省去工序1的时间。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
int b =0, c = 0;
for (int a = 0; a < NUM; a++)
{
if (temp[a].type == 0)//count
b++;// num of type 0
else
c++;// num of type 1
}
JOB* wo = new JOB[b];
JOB* rk = new JOB[c];
{
for (int a = 0; a < NUM; a++)
{
cout << a + 1 << ":\n A:";
cin >> temp[a].a;
cout << " B:";
cin >> temp[a].b;
temp[a].type = temp[a].a > temp[a].b ? 1 : 0;//a>b 1 or 0
{
cout << "请输入要加工的工件数量:";
cin >> NUM;
JOB* work=new JOB[NUM];
cout << "请输入数据:\n";
Input(work);
Sort(work);
Order(work);
Output(work);
delete work;
return 0;
}
void Sort( JOB* temp )
{
JOB job = rk[m];
rk[m] = rk[n];
rk[n] = job;
}
for (int m = 0; m < b; m++)
temp[m] = wo[m];
for (int m = b ,n=0; m < NUM; m++,n++)
temp[m] = rk[n];
}
void Input( JOB* temp )
else
k = j + temp[a].b;
}
cout << "花费的时间是:" << k<<endl;
}
void Order(JOB* temp)
{
cout << "加工顺序为:";
for (int a = 0; a < NUM; a++)
{
cout<<setw(3)<<temp[a].index;
//流水作业调度.cpp :定义控制台应用程序的入口点。
#include"stdafx.h"
#include <iostream>
#include<iomanip>
using namespace std;
static int NUM;
struct JOB
{
int a;// 1st
int b;// 2nd
}
cout << "\n\n";
}
bool type;//mark a>b or b>a
int index;//save initial subscript
};
void Sort( JOB* );
void Input( JOB* );
void Output(JOB*);
void Order(JOB*);
int _tmain(int argc, _TCHAR* argv[])
b = c = 0;
for (int a = 0; a < NUM; a++)//divide
{
if (temp[a].type == 0)
wo[b++] = temp[a];
else
rk[c++] = temp[a];
}
//sort wo
for (int m = 0; m < b; m++)
for (int n = m + 1; n < b; n++)
temp[a].index = a + 1;
}
}
void Output(JOB* temp)
{
int j, k;
j = [0].a;
k = j + temp[0].b;
for (int a = 1; a < NUM; a++)
{
j += temp[a].a;
if (j < k)
k = k + temp[a].b;
if (wo[n].a < wo[m].a)
{
JOB job=wo[m];
wo[m] = wo[n];
wo[n] = job;
}
//sort rk
for (int m = 0; m < c; m++)
for (int n = m + 1; n < c; n++)
if (rk[n].b > rk[m].b)