⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 macmanage.h

📁 一个简单的机器调度模拟程序。根据任务的时长
💻 H
📖 第 1 页 / 共 2 页
字号:
#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 + -