📄 macmanage.h
字号:
#include "iostream.h"
#include "math.h"
#include "stdlib.h"
#include "time.h"
//任务类,记录任务的信息
class task
{
public :
//任务初始化
task ( ) { time = 0 ; next = NULL ; }
//任务计划执行时间
int time ;
//记录下一个要执行的任务(实质只是为了用来完成mac对任务进行堆栈链表存储要求)
task * next ;
} ;
//机器类
class mac
{
friend class wplace ;
protected :
//该机器计划将要执行的任务
task * bList ;
//正在执行任务,距离完成的时间
int r_time ;
//计划要执行的任务的数量
int task_num ;
//计划任务队列的最后一个任务
task * eList ;
//一个八位标志寄存器,每位意义如下
//第0位为排序位,如果已经排序则标志为:1;没有排序或曾经排序但被破坏了,标志为0
//若第0位为1,则第1位为升降排序标志:升序为1,降序为0,是状态标志
//若第0位为0,则第1位为升降排序标志:升序为1,降序为0,是排序时用来判断排序类型的标志,默认为0
//即若不指明排序类型,将以降序排序
//第3位删除标志位,用以标示删除任务方式,当删除标志位为1时删除所有任务时间为tm的任务
//当删除标志位为0时删除所有任务时间为tm的任务中的一个任务
//其他位暂时间留空
char mask ;
//交换tmp后面两个元素的位置的位置
void exch ( task * tmp );
//修改任务暂存器
void set_reg ( task * tmp ) ;
public :
//返回正在执行任务剩余时间
int Get_rTime ( ) { return r_time ; }
//作业标志,为true则在工作,为false则不在工作
bool is_work ;
//返回任务表头
task * get_bList ( ) { return bList ; }
//获得任务数
int get_tasknum ( ) { return task_num ; }
//该机器正在执行的任务
task doing ;
//任务暂存器,用以暂存函数调用过程中返回的任务时间,而next指针域不为暂存器使用
task tmp_reg ;
//该机器计划执行的任务的总时间
long all_time ;
//若第0位为0,则第1位为升降排序标志:升序为1,降序为0,是排序时用来判断排序类型的标志,默认为0
//对任务列表按任务时间进行排序
void sort ( ) ;
//加入任务
void add_task ( task tmp ) ;
//删除任务,删除任务时间为tm的任务,当删除标志位为1时删除所有任务时间为tm的任务
//当删除标志位为0时删除所有任务时间为tm的任务中的一个任务,返回设置tmp_reg
void del_task ( int tm ) ;
//初始化机器
//设置标志寄存器
void set_mask ( int bit , bool value = true ) ;
//获得指定标志位值
short int get_mask ( int bit ) ;
//输出任务表内容
void show ( ) ;
//初试化变量
mac ( ) ;
~mac ( ) ;
//求得在0-d范围中,任务时间最接近d/2的任务
int get_midofd ( int d ) ;
//求得在0-d范围内,另一机器一任务任务时间与本机器任务时间任务之差,最接近d/2的两任务
//结果存储在各自的任务暂存器中
int get_midofd_twomac ( mac &other , int d ) ;
//根据计划执行任务
bool DoTask ( ) ;
//执行任务一时间片
bool DoOnePiece ( ) ;
};
//执行任务一时间片
bool mac ::DoOnePiece ( )
{
//检查执行条件是否成立
if ( r_time == 0 )
return false ;
r_time -- ;
all_time -- ;
return true ;
}
//根据计划执行任务
bool mac ::DoTask ( )
{
/*-----------------------------------------------*/
//检查是否符合条件执行任务
//1.机器并没有任务在执行
if ( r_time != 0 )
return false;
//2.检查是否有计划任务
if ( task_num < 1 )
return false;
/*-----------------------------------------------*/
//条件成立,可以执行任务
//获得要执行任务(长作业优先),并将其出列
sort ( ) ;
del_task ( bList ->next ->time ) ;
//执行任务
r_time = tmp_reg.time ;
doing.time = tmp_reg.time ;
all_time = all_time + r_time ;
return true ;
/*-----------------------------------------------*/
}
//求得在0-d范围内,另一机器一任务任务时间与本机器任务时间任务之差,最接近d/2的两任务
//结果存储在各自的任务暂存器中
int mac ::get_midofd_twomac ( mac & other , int d )
{
task * tmp1 = bList ->next ;
task * tmp2 = other.bList ->next ;
int dt = -1 ;
if ( tmp1 == NULL || tmp2 == NULL )
return -1 ;//操作失败
while ( tmp1 != NULL )
{
while ( tmp2 != NULL )
{
if ( tmp1 ->time > tmp2 ->time && tmp1 ->time - tmp2 ->time <= d )
{
if ( abs ( tmp1 ->time - tmp2->time - ( d + 1 ) / 2 ) < dt || dt < 0 )
{
dt = abs ( tmp1 ->time - tmp2 ->time - ( d + 1 ) / 2 );
set_reg ( tmp1 ) ;
other.set_reg ( tmp2 ) ;
}
}
tmp2 = tmp2 ->next ;
}
tmp2 = other.bList ->next ;
tmp1 = tmp1 ->next ;
}
if ( dt != -1 )
return 1 ;
return dt ;
}
//求得在0-d范围中,任务时间最接近d/2的任务
int mac::get_midofd ( int d )
{
task * tmp = bList ->next ;
int r = -1 ;
if ( tmp == NULL )
return -1 ;
while ( tmp != NULL )
{
if ( tmp ->time < d &&
( abs ( tmp ->time - ( d + 1 ) / 2 ) < abs ( r - ( d + 1 ) / 2 ) || r < 0 ) )
{
r = tmp ->time ;
}
tmp = tmp ->next ;
}
return r ;
}
//初始化
mac ::mac ( )
{
//任务表的表头指向任务暂存器,但在对任务列表进行操作的时候不能对任务表表头进行任何改动
bList = &tmp_reg ;
eList = bList ;
all_time = 0 ;
task_num = 0 ;
r_time = 0 ;
mask = 0 ;
//将标志寄存器的所有标志置为默认
}
//设置标志寄存器第bit位为value
void mac ::set_mask ( int bit , bool value )
{
if ( bit > 7 || bit < 0 )
return ;
char tmp ;
tmp = 0 ;
if ( value )
tmp = 1 ;
else
tmp = 0 ;
//左移tmp第一位到第bit位,即左移7-bit位
tmp = tmp << ( 7 - bit );
mask = mask | tmp ;
}
short int mac ::get_mask ( int bit )
{
if ( bit > 7 || bit < 0 )
return -1;
char tmp ;
tmp = mask >> ( 7 - bit ) ;
tmp = tmp & 1 ;
if ( tmp != 0 )
return 1 ;
return 0 ;
}
//加入任务tmp
void mac ::add_task ( task tmp )
{
task * ntask = new task ;
*ntask = tmp ;
//任务表已经被排序
if ( get_mask ( 0 ) && bList ->next != NULL )
{
task * temp = bList ;
//升序
if ( get_mask ( 1 ) )
{
while ( temp ->next != NULL && tmp.time > temp ->next ->time )
{
temp = temp ->next ;
}
ntask ->next = temp ->next ;
temp ->next = ntask ;
}
//降序
else
{
while ( temp ->next != NULL && tmp.time < temp ->next ->time )
{
temp = temp ->next ;
}
ntask ->next = temp ->next ;
temp ->next = ntask ;
}
}
else//任务表尚未排序
{
//将任务插在表头
ntask ->next = bList ->next ;
bList ->next = ntask ;
}
if ( ntask ->next == NULL )
eList = ntask ;
//修改相关属性量
all_time = all_time + (long)ntask->time ;
task_num ++ ;
}
mac ::~mac ( )
{
task * tmp ;
if ( bList ->next != NULL )
{
tmp = bList ->next ;
bList ->next = tmp ->next ;
delete tmp ;
}
}
//删除时间为tm的任务,有两模式有寄存器相应位决定
void mac ::del_task ( int tm )
{
task * tbl = bList ;
task * tmp = NULL ;
//删除所有执行时间为tm的任务
if ( get_mask ( 2 ) )
{
while ( tbl ->next != NULL )
{
if ( tbl ->next ->time == tm )
{
tmp = tbl ->next ;
tbl ->next = tmp ->next ;
if ( tmp ->next == NULL )
eList = tbl ;
/****************************************/
//修改删除带来的影响,任务数,总任务时间
task_num -- ;
all_time = all_time - ( long ) tmp->time ;
/****************************************/
set_reg ( tmp ) ; //返回所删除至寄存器
delete tmp ;
}
else
{
tbl = tbl ->next ;
}
}
}
//删除执行时间为tm的一个任务
else
{
while ( tbl ->next != NULL )
{
if ( tbl ->next ->time == tm )
{
tmp = tbl ->next ;
tbl ->next = tmp ->next ;
if ( tmp ->next == NULL )
eList = tbl ;
/****************************************/
//修改删除带来的影响,任务数,总任务时间
task_num -- ;
all_time = all_time - ( long ) tmp->time ;
/****************************************/
set_reg ( tmp ) ;
delete tmp ;
break ;//删除一个后就退出遍历
}
else
{
tbl = tbl ->next ;
}
}
}
//还原删除类型默认标志
set_mask ( 2 , false ) ;
}
//交换tmp后面两个元素的位置的位置
void mac ::exch ( task * tmp )
{
task * t1 ;
task * t2 ;
t1 = tmp ->next ;
t2 = t1 ->next ;
if ( t1 == NULL || t2 == NULL )
return ;
tmp ->next = t2 ;
t1 ->next = t2 ->next ;
t2 ->next = t1 ;
}
//任务排序,冒泡排序法
void mac ::sort ( )
{
int i , j ;
task * tmp = bList ->next ;
if ( get_mask ( 0 ) )
return ; //已经排序,所以返回
if ( get_mask ( 1 ) )
{
for ( i = 0 ; i < task_num - 1 ; i ++ )
{
tmp = bList ;
for ( j = 0 ; j < task_num - i - 1 ; j++ )
{
if ( tmp ->next ->time > tmp ->next -> next ->time )
exch ( tmp ) ;
tmp = tmp ->next ;
}
}
}
else
{
for ( i = 0 ; i < task_num - 1 ; i ++ )
{
tmp = bList ;
for ( j = 0 ; j < task_num - i - 1 ; j++)
{
if ( tmp ->next ->time < tmp ->next -> next ->time )
exch ( tmp ) ;
tmp = tmp ->next ;
}
}
}
//重置eList
tmp = bList ;
while ( tmp ->next != NULL )
tmp = tmp ->next ;
eList = tmp ;
//修改排序标志位
set_mask ( 0 ) ;
}
//显示任务机器计划任务(只在控制台模式有效)
void mac ::show ( )
{
task * tmp = bList ->next ;
if ( tmp == NULL )
cout << "无任务执行状态" ;
while ( tmp != NULL )
{
cout << tmp ->time << " " ;
tmp = tmp ->next ;
}
cout << endl ;
}
//设置寄存器内容
void mac ::set_reg ( task * tmp )
{
if ( tmp == NULL )
return ;
task * t = tmp_reg.next ;
tmp_reg = *tmp ;
tmp_reg.next = t ;
}
//车间类
class wplace
{
protected :
//执行任务的机器数
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -