📄 ģ
字号:
// 模拟View.cpp : implementation of the CMyView class
//
#include "stdafx.h"
#include "模拟.h"
#include "模拟Doc.h"
#include "模拟View.h"
#include <math.h>
#include <mshtml.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMyView
IMPLEMENT_DYNCREATE(CMyView, CHtmlView)
BEGIN_MESSAGE_MAP(CMyView, CHtmlView)
//{{AFX_MSG_MAP(CMyView)
ON_WM_TIMER()
ON_COMMAND(ID_MENU_PARAMETER, OnSetParameter)
ON_COMMAND(ID_BUTTON_BEGAIN, OnButBegain)
ON_COMMAND(ID_FILE_BEGAIN, OnFileBegain)
ON_COMMAND(ID_FILE_STOP, OnFileStop)
ON_COMMAND(ID_BUTTONEND, OnButtonEnd)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CHtmlView::OnFilePrint)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMyView construction/destruction
CMyView::CMyView()
{
// TODO: add construction code here
hasBegain=FALSE;
hasEnd=FALSE;
Length=500;
Marrvt=0.5;
Mservt=1.0;
}
CMyView::~CMyView()
{
}
BOOL CMyView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CHtmlView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CMyView drawing
void CMyView::OnDraw(CDC* pDC)
{
CMyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
void CMyView::OnInitialUpdate()
{
CHtmlView::OnInitialUpdate();
// TODO: This code navigates to a popular spot on the web.
// change the code to go where you'd like.
//Navigate2(_T("http://www.microsoft.com/visualc/"),NULL,NULL);
LoadFromResource(IDR_HTML1);
}
/////////////////////////////////////////////////////////////////////////////
// CMyView printing
/////////////////////////////////////////////////////////////////////////////
// CMyView diagnostics
#ifdef _DEBUG
void CMyView::AssertValid() const
{
CHtmlView::AssertValid();
}
void CMyView::Dump(CDumpContext& dc) const
{
CHtmlView::Dump(dc);
}
CMyDoc* CMyView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc)));
return (CMyDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CMyView message handlers
void CMyView::Init()
{
if(hasBegain && !hasEnd)//正在运行
{
MessageBox("正在模拟,如需重新开始请先停止!");
return;
}
hasBegain=TRUE;
hasEnd=FALSE;
if(Length<0){
MessageBox("请先进行参数设置");
return;
}
Tnum=0; //当前模拟时间
ChangeQueue_num=0; //换队的顾客数目
LeaveQueue_num=0; //因为排满而离开的顾客数目
noWait_num=2; //没有等待就可以服务的顾客数
wait_num=4; //需要等待才可以接受服务的顾客数目
leaveServer_num=0; //享受完服务的顾客数目
TotalWaitT=0; //享受完服务的顾客总共等待时间
TotalServerT=0; //享受完服务的顾客总共接受服务的时间
for(int i=0;i<TEL;i++)
{
//初始化服务台
server[i].status=TRUE; //处于忙状态
server[i].begainBusyT=0;
server[i].sumBusyT=0;
//初始化队列
queue[i].length=3;
queue[i].client[0].arriveT=0;
queue[i].client[0].serverT=0;
queue[i].client[0].leaveT=-1; //等于-1代表还没有发生
queue[i].client[1].arriveT=0;
queue[i].client[1].serverT=-1;
queue[i].client[1].leaveT=-1;
queue[i].client[2].arriveT=0;
queue[i].client[2].serverT=-1;
queue[i].client[2].leaveT=-1;
queue[i].client[3].arriveT=-1;
queue[i].client[3].serverT=-1;
queue[i].client[3].leaveT=-1;
CString str;
str.Format("1%d",i+1);
ShowPic(str);
str.Format("2%d",i+1);
ShowPic(str);
str.Format("3%d",i+1);
ShowPic(str);
}
ArrivePara=(float)(1-exp(Tinterval*-1/Marrvt));
srand( (unsigned)time( NULL ) );
SetTimer(1,60,0);
}
void CMyView::Stop()
{
KillTimer(1);
//更新画面
for(int i=0;i<MAXLEN;i++)
{
for(int j=0;j<TEL;j++)
{
CString str;
str.Format("%d%d",i+1,j+1);
ShowPic(str,FALSE);
}
}
hasEnd=TRUE;
}
void CMyView::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
Tnum++;
int i,j;
int irandnum=0;
float frandnum=0.0;
irandnum=rand();
frandnum=(float)irandnum/(float)RAND_MAX;
//已经产生了一个顾客的随机数
if(frandnum<ArrivePara)
{
//此时产生顾客到达事件
Arrive();
}
for(i=0;i<TEL;i++)
{
if(queue[i].length>0)
{
irandnum=rand();
frandnum=(float)irandnum/(float)RAND_MAX;
if(frandnum<ServerPara)
{
//此时队列i产生顾客离去事件
Epart(i);
}
}
}
//判断是否换队
for(i=0;i<TEL;i++)
{
for(j=i+1;j<TEL;j++)
{
if(queue[i].length-1>queue[j].length)
{
//由i换队到j
Jockey(i,j);
}else if(queue[j].length-1>queue[i].length)
{
//由j换队到i
Jockey(j,i);
}
}
}
CMyDoc *pDoc=GetDocument();
COleVariant var;
//report系统中平均顾客数
float temp=(float)(LeaveQueue_num+noWait_num+wait_num);
var=temp*10/Tnum;
pDoc->Report(1,var);
//report队列中的平均顾客数
temp=(float)(noWait_num+wait_num);
var=temp*10/Tnum/2;
pDoc->Report(2,var);
//report出纳员利用率
var=(float)TotalServerT/Tnum/2*100;
pDoc->Report(0,var);
if(Tnum>=Length*10){
KillTimer(1);
MessageBox("模拟结束");
}
CHtmlView::OnTimer(nIDEvent);
}
//顾客到达
void CMyView::Arrive()
{
CMyDoc *pDoc=GetDocument();
int i=0;
//如果队列全满了则离去
BOOL bFull=TRUE;
for(i=0;i<TEL;i++)
{
if(queue[i].length!=MAXLEN)
{
bFull=FALSE;
break;
}
}
if(bFull) //队都站满了
{
LeaveQueue_num++;
//Report 因排满而离开的顾客数
COleVariant var;
long temp=LeaveQueue_num;
var=temp;
pDoc->Report(4,var);
return;
}
//运行到此说明有位置可站
//寻找最短队列
int shortQueue=0; //初始化,认为0队列最短
for(i=1;i<TEL;i++)
{
if(queue[i].length<queue[shortQueue].length)
{
shortQueue=i;
}
}
//此时最短队为shortQueue
//所以排在shortQueue队
//如果shortQueue队队长为0,顾客可以直接接受服务
if(queue[shortQueue].length==0)
{
noWait_num++;
queue[shortQueue].length=1;
queue[shortQueue].client[0].arriveT=Tnum; //客户到达时间
queue[shortQueue].client[0].leaveT=-1; //离开时间
queue[shortQueue].client[0].serverT=Tnum; //开始接受服务时间
//这里用于调试
#ifdef _DEBUG
if(server[shortQueue].status==TRUE)
{
MessageBox("出错了,队长为0时,服务台也忙!");
}
#endif //_DEBUG
//设置服务台的状态即开始忙的时间
server[shortQueue].status=TRUE;
server[shortQueue].begainBusyT=Tnum;
//显示画面
CString str;
str.Format("1%d",shortQueue+1);
ShowPic(str);
}else{ //否则的话需要排队
wait_num++; //需要排队的顾客数加1
queue[shortQueue].length++; //队长加1
int len=queue[shortQueue].length-1; //因为数组从0开始
queue[shortQueue].client[len].arriveT=Tnum; //客户到达时间
queue[shortQueue].client[len].leaveT=-1; //离开时间
queue[shortQueue].client[len].serverT=-1; //开始接受服务时间
//显示画面
CString str;
str.Format("%d%d",len+1,shortQueue+1);
ShowPic(str);
}
}
//顾客离去
void CMyView::Epart(int nQueu)
{
queue[nQueu].client[0].leaveT=Tnum;
CMyDoc *pDoc=GetDocument();
COleVariant var;
//享受完服务的顾客数目+1
leaveServer_num++;
//设置享受完服务的顾客总共等待时间
#ifdef _DEBUG
if(queue[nQueu].client[0].serverT<0 || queue[nQueu].client[0].arriveT<0)
{
MessageBox("出错了,离去时开始服务时间或到达时间小于0!");
}
#endif //_DEBUG
//Report 总等待时间和平均等待时间
TotalWaitT+=queue[nQueu].client[0].serverT-queue[nQueu].client[0].arriveT;
long temp;
temp=TotalWaitT/10;
var=temp;
pDoc->Report(5,var);
float aveWaitT=(float)TotalWaitT/(float)leaveServer_num;
var=aveWaitT/10;
pDoc->Report(7,var);
//享受完服务的顾客总共接受服务的时间
#ifdef _DEBUG
if(queue[nQueu].client[0].serverT>queue[nQueu].client[0].leaveT)
{
MessageBox("出错了,开始服务时间>离开时间!");
}
#endif //_DEBUG
//Report 总接受服务时间和平均接受服务时间
TotalServerT+=queue[nQueu].client[0].leaveT-queue[nQueu].client[0].serverT;
temp=TotalServerT/10;
var=temp;
pDoc->Report(6,var);
float aveServeT=(float)TotalServerT/(float)leaveServer_num;
var=aveServeT/10;
pDoc->Report(8,var);
//用于测试
#ifdef _DEBUG
if(queue[nQueu].length<=0)
{
MessageBox("出错了,离去的队列队长为0!");
}
#endif //_DEBUG
//首先让队长-1
queue[nQueu].length--;
//用于测试
#ifdef _DEBUG
if(server[nQueu].status==FALSE)
{
MessageBox("出错了,队列有人的时候服务台状态为空闲!");
}
#endif //_DEBUG
//更新服务台
//如果离去后队长为0,则服务台处于空闲状态
if(queue[nQueu].length==0)
{
//设置服务台处于空闲状态
server[nQueu].status=FALSE;
server[nQueu].sumBusyT+=Tnum-server[nQueu].begainBusyT;
server[nQueu].begainBusyT=-1;
//显示画面
CString str;
str.Format("%d%d",1,nQueu+1);
ShowPic(str,FALSE);
}else{ //根新队列,让每个顾客向前移动
for(int i=0;i<queue[nQueu].length;i++)
{
queue[nQueu].client[i]=queue[nQueu].client[i+1];
}
//设置最前面的顾客的开始服务时间
queue[nQueu].client[0].serverT=Tnum;
//显示画面
CString str;
str.Format("%d%d",queue[nQueu].length+1,nQueu+1);//queue[nQueu].length为离去后的队长
ShowPic(str,FALSE);
}
}
//顾客换队
void CMyView::Jockey(int formQueu,int toQueu)
{
CMyDoc *pDoc=GetDocument();
COleVariant var;
//换队的人数加1
ChangeQueue_num++;
//Report换队人数
long temp=ChangeQueue_num;
var=temp;
pDoc->Report(3,var);
//离去的队队长-1
queue[formQueu].length--;
//到达的队队长+1
queue[toQueu].length++;
int len1,len2;
//离去的顾客
len1=queue[formQueu].length+1;
//到达的顾客
len2=queue[toQueu].length;
//更新队列中的顾客属性
queue[toQueu].client[len2]=queue[formQueu].client[len1];
//如果len2=1,说明这个队在换队之前没人,需要根新服务台状态
if(len2==1)
{
//根新服务台状态
server[toQueu].status=TRUE;
server[toQueu].begainBusyT=Tnum;
//设置刚换队过来的人的开始服务时间
queue[toQueu].client[0].serverT=Tnum;
}
//显示画面
CString str;
str.Format("%d%d",len1,formQueu+1);
ShowPic(str,FALSE);
str.Format("%d%d",len2,toQueu+1);
ShowPic(str);
}
void CMyView::OnSetParameter()
{
// TODO: Add your command handler code here
CParaDlg m_Dlg;
//m_Dlg.UpdateData(FALSE);
if(m_Dlg.DoModal()==IDOK){
Length=m_Dlg.m_total_server_Time;
Marrvt=m_Dlg.m_ave_Arrive_Time;
//Mservt=m_Dlg.m_ave_Server_Time;
}
}
void CMyView::OnButBegain()
{
// TODO: Add your command handler code here
Init();
}
void CMyView::OnFileBegain()
{
// TODO: Add your command handler code here
Init();
}
void CMyView::OnFileStop()
{
// TODO: Add your command handler code here
Stop();
}
void CMyView::OnButtonEnd()
{
// TODO: Add your command handler code here
Stop();
}
void CMyView::ShowPic(CString id,BOOL isShow)
{
IDispatch* pDisp=GetHtmlDocument();
if(pDisp!=NULL)
{
IHTMLDocument2 *pHTMLDocument2;
HRESULT hr;
hr=pDisp->QueryInterface(IID_IHTMLDocument2,(void **)&pHTMLDocument2);
if(hr==S_OK)
{
IHTMLElementCollection *pColl=NULL;
hr= pHTMLDocument2->get_all(&pColl);
if(hr==S_OK && pColl!=NULL)
{
LONG celem;
hr=pColl->get_length(&celem);
if(hr==S_OK)
{
for(int i=0;i<celem;i++)
{
VARIANT varIndex;
varIndex.vt=VT_UINT;
varIndex.lVal=i;
VARIANT var2;
VariantInit(&var2);
IDispatch *pDisp;
hr=pColl->item(varIndex,var2,&pDisp);
if(hr==S_OK && !pDisp==NULL)
{
IHTMLElement *pElem;
hr=pDisp->QueryInterface(IID_IHTMLElement,(void**)&pElem);
if(hr==S_OK && !pElem==NULL)
{
BSTR bstr;
pElem->get_id(&bstr);
CString str=bstr;
if(str==id){
IHTMLTableCell *pCellElem;
hr=pDisp->QueryInterface(IID_IHTMLTableCell,(void **)&pCellElem);
if(hr==S_OK && pCellElem!=NULL){
if(isShow)
{
COleVariant var("#0000ff");
//var.bstrVal="#0000ff";
pCellElem->put_bgColor(var);
}else{
COleVariant var("#ffffff");
pCellElem->put_bgColor(var);
}
pCellElem->Release();
pCellElem=NULL;
}
}
pElem->Release();
pElem=NULL;
}
pDisp->Release();
}
}
}
pColl->Release();
}
pHTMLDocument2->Release();
}
pDisp->Release();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -