数学模型小作业(Lamchester模型-无增援正规战模型)

//--------------------------------------------------------------------------------------------------------------------
//数学模型小作业(Lamchester模型-无增援正规战模型)
//题目描述:
//01.早在第一次世界大战时期,F.W.Lamchester就提出了预测战争结局的数学模型,这个模型假设:
//02.a.胜利与否只取决于两个因素:兵力因素和战斗力因素.
//03.b.兵力因素增减有如下情况:减少:战斗减员和非战斗减员;增员:后备力量的增援.
//04.c.战斗力因素即杀伤对方的能力,包括:射击率,命中率,战争类型(正规战或游击战等)等.
//05.考虑两方的兵力数量随时间的函数,建立微分方程,有:
//06.[x(t)]'=-f(x,y)-α*x+u(t).
//07.[y(t)]'=-g(x,y)-β*y+v(t).
//07.其中:f(x,y)-甲方的战斗减员率.
//08.     g(x,y)-乙方的战斗减员率.
//09.     α-甲方的非战斗减员率.
//10.     β-乙方的非战斗减员率.
//11.     u(t)-甲方的增员率.
//11.     v(t)-乙方的增员率.
//01.只考虑最简单的情况:没有非战斗减员α,β=0;也没有增援u(t),v(t)=0.
//01.正规战f(x,y)=ay,g(x,y)=bx;a-乙方的战斗力系数;b-甲方的战斗力系数.
//02.微分方程得到简化,通过积分可以得到以x,y为变量的轨迹方程:a*y*y-b*x*x=k,k=a*y0*y0-b*x0*x0.
//03.也可解出关于时间t的两方兵力函数:
//04.x(t)=0.5*{[x0-y0*sqrt(a/b)]*e^(sqrt(a*b)*t)+[x0+y0*sqrt(a/b)]*e^(-sqrt(a*b)*t)}.
//05.y(t)=0.5*{[y0-x0*sqrt(b/a)]*e^(sqrt(a*b)*t)+[y0+x0*sqrt(b/a)]*e^(-sqrt(a*b)*t)}.
//程序编制要求:
//1.甲方乙方初始兵力数量x0,y0交互读取.
//2.甲方乙方战斗力系数a,b交互读取.
//3.根据两方的初始兵力数量和战斗力系数绘制两方兵力随时间变化曲线.
//--------------------------------------------------------------------------------------------------------------------
#include <graphics.h>//包含Easyx模拟TC的BGI绘图库头文件
#include <math.h>//包含数学运算头文件
#include <iostream.h>//
#define DD 40//宏定义标题边框距离
#define DW 10//宏定义宽度边框距离
#define DH 10//宏定义高度边框距离
#define DC 200//宏定义控件区域宽度
#define nx 10//宏定义x轴刻度数量
#define ny 15//宏定义y轴刻度数量
#define c1 RGB(38,47,86)//宏定义辅助线颜色1
#define c2 RGB(38,47,86)//宏定义辅助线颜色2
#define c3 RGB(255,255,255)//宏定义文字及边框颜色
#define cc1 RGB(255,0,0)//宏定义曲线颜色1(红色)
#define cc2 RGB(0,255,0)//宏定义曲线颜色2(绿色)
#define cc3 RGB(255,255,0)//宏定义曲线颜色3(黄色)
//定义结构体-------------------------------------------------------------------------------------------------------
typedef struct points
{
	double x,y;//定义双精度变量
}DPOINT;//结束结构体
//定义全局变量-----------------------------------------------------------------------------------------------------
int W = GetSystemMetrics(SM_CXSCREEN);//获取整个屏幕右下角X坐标
int H = GetSystemMetrics(SM_CYSCREEN);//屏幕Y坐标 	
char is1[20]="100.0";//预定义:1.[A]初始兵力x0
char is2[20]="0.3";//2.[A]战斗力系数b
char is3[20]="100.0";//3.[B]初始兵力y0
char is4[20]="0.2";//4.[B]战斗力系数a
char is9[20]="1.0";//9.[AB]时间查询
char is5[20],is6[20],is7[20],is8[20],is10[20],is11[20],is12[20],is13[20];//定义字符数组(存储字符串)
double d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15,flag,dmax,ta,tb,to;//定义双精度变量(存储计算值)
double i=0,j=0,k=0;//
//函数声明---------------------------------------------------------------------------------------------------------
void sub_frame();//绘制框架子函数
void sub_calculate();//计算数据子函数
void func_A(double t,double *a);//A的兵力函数
void func_B(double t,double *b);//B的兵力函数
void cease_a(double *ta);//A的兵力消耗时间
void cease_b(double *tb);//B的兵力消耗时间
void cease_o(double *to);//
//主函数-----------------------------------------------------------------------------------------------------------
void main()
{
	sub_frame();//绘图初始化
	MOUSEMSG m;//定义鼠标消息 
	while(true)//循环
	{
		m=GetMouseMsg();//获取一条鼠标消息 
		switch(m.uMsg)//根据获得的消息选择分支
		{
		case WM_LBUTTONDOWN://鼠标左键单击时判断数据输入
			{
				//判断鼠标位置是否在指定的控件区域
				//A.获取原始数据(横坐标在输入区域时输入数据)-------------------------------
				if(m.x>=W-DW-DC && m.x<=W-DW)
				{
					//1.[A]初始兵力x0:-----------------------------------------------------
					if(m.y>=H-DH-16*36+1 && m.y<=H-DH-15*36-1)//
					{
						InputBox(is1,9,"请输入数据");//读入数据
						setfillcolor(BLACK);
						fillrectangle(W-DW-DC+DC/2+10,H-DH-16*36+1,W-DW,H-DH-15*36);
						outtextxy(W-DW-DC+DC/2+15,H-DH-16*36+15,is1);//写控件字符串
					}//结束if
					//2.[A]战斗力系数b:-----------------------------------------------------
					if(m.y>=H-DH-15*36+1 && m.y<=H-DH-14*36-1)//
					{
						InputBox(is2,9,"请输入数据");//读入数据
						setfillcolor(BLACK);
						fillrectangle(W-DW-DC+DC/2+10,H-DH-15*36+1,W-DW,H-DH-14*36);
						outtextxy(W-DW-DC+DC/2+15,H-DH-15*36+15,is2);//写控件字符串
					}//结束if
					//3.[B]初始兵力y0:-----------------------------------------------
					if(m.y>=H-DH-14*36+1 && m.y<=H-DH-13*36-1)//
					{
						InputBox(is3,9,"请输入数据");//读入数据
						setfillcolor(BLACK);
						fillrectangle(W-DW-DC+DC/2+10,H-DH-14*36+1,W-DW,H-DH-13*36);
						outtextxy(W-DW-DC+DC/2+15,H-DH-14*36+15,is3);//写控件字符串
					}//结束if
					//4.[B]战斗力系数a:-----------------------------------------------
					if(m.y>=H-DH-13*36+1 && m.y<=H-DH-12*36-1)//
					{
						InputBox(is4,9,"请输入数据");//读入数据
						setfillcolor(BLACK);
						fillrectangle(W-DW-DC+DC/2+10,H-DH-13*36+1,W-DW,H-DH-12*36);
						outtextxy(W-DW-DC+DC/2+15,H-DH-13*36+15,is4);//写控件字符串
					}//结束if
					//9.[AB]时间查询:-----------------------------------------------------
					if(m.y>=H-DH-8*36+1 && m.y<=H-DH-7*36-1)//
					{
						InputBox(is9,9,"请输入数据");//读入数据
						setfillcolor(BLACK);
						fillrectangle(W-DW-DC+DC/2+10,H-DH-8*36+1,W-DW,H-DH-7*36);
						outtextxy(W-DW-DC+DC/2+15,H-DH-8*36+15,is9);//写控件字符串
					}//结束if
				}//结束if(横坐标在输入区域时输入数据)
				sub_frame();//重绘框架
				//B.计算并绘图(横坐标在绘图区域时计算绘图)---------------------------------
				if(m.x>=DW && m.x<=W-DW-DC)
				{
					sub_calculate();//调用计算绘图函数
				}//结束if
				break;//
			}//结束case(结束鼠标左键单击事件消息处理)
		case WM_RBUTTONDOWN://鼠标移动的时候画个空心的圆
			return;//返回while
		}//结束switch(结束鼠标消息)
	}//结束while
}//结束主函数
//绘制框架子函数
void sub_frame()
{
	//1.全屏效果---------------------------------------------------------------------------
	initgraph(W,H);//初始化绘图窗口
	HWND hWnd = GetHWnd();//获取窗口句柄
	LONG style = GetWindowLong(hWnd,-16);//获得窗口风格
	style = style & ~WS_CAPTION & ~WS_SIZEBOX; //窗口全屏显示且不可改变大小
	SetWindowLong(hWnd,-16,style);//设置窗口风格
	SetWindowPos(hWnd, NULL,0,0,W,H,SWP_NOZORDER);//改变窗口位置,尺寸和Z序
	//ShowCursor(FALSE);//显示时隐藏鼠标
	//------------------------------------------------------------------------------------
	//2.绘制工作区边框
	setcolor(c3);
	rectangle(DW,DD,W-DW,H-DH);//外边框
	rectangle(W-DW-DC,DD,W-DW,H-DH);//控件区域边框
	//3.输出标题
	setfont(16,0,"黑体");
	outtextxy(5,10,"数学模型小作业(Lamchester模型-无增援正规战模型)");
	//4.输出简单说明
	RECT r={W-DW-DC+10,DD+10,W-DW-10,H-DH-10};//
	setfont(12,0,"宋体");//
	drawtext("数学模型小作业:\n \n \
				Lamchester模型-无增援正规战模型\
				\
				\n\n\
				操作说明:\n\n\
				鼠标左键  : 数据输入\n\
				鼠标右键  : 退出程序\n\
			\n\
			1~4为输入数据   5~8为计算数据\n\
			\n\n\
			\n\n\
			\
			\n", &r, DT_WORDBREAK);//
	//5.调整说明文字下面的矩形控件
	int c_h=36;//定义控件高度
	int c_x1=W-DW-DC,c_x2=W-DW;//控件左右x坐标
	int c_y1=H-DH;//第1个控件下y坐标
	for(int i=1;i<=16;i++)
	{
		rectangle(c_x1,c_y1,c_x2,c_y1-c_h);//
		c_y1=c_y1-c_h;
	}//结束for
	//6.绘制控件说明文字
	outtextxy(c_x1+10,H-DH-16*c_h+15,"1.[A]初始兵力x0:");//输出字符串模拟控件文字
	outtextxy(c_x1+10,H-DH-15*c_h+15,"2.[A]战斗力系数b:");//输出字符串模拟控件文字
	outtextxy(c_x1+10,H-DH-14*c_h+15,"3.[B]初始兵力y0:");//输出字符串模拟控件文字
	outtextxy(c_x1+10,H-DH-13*c_h+15,"4.[B]战斗力系数a:");//输出字符串模拟控件文字	
	outtextxy(c_x1+10,H-DH-12*c_h+15,"5.[AB]平局条件k:");//输出字符串模拟控件文字
	outtextxy(c_x1+10,H-DH-11*c_h+15,"6.[AB]计算胜利方:");//输出字符串模拟控件文字	
	outtextxy(c_x1+10,H-DH-10*c_h+15,"7.[AB]作战时间:");//输出字符串模拟控件文字
	outtextxy(c_x1+10,H-DH-9*c_h+15,"8.[AB]剩余兵力:");//输出字符串模拟控件文字
	outtextxy(c_x1+10,H-DH-8*c_h+15,"9.[AB]时间查询:");//输出字符串模拟控件文字
	outtextxy(c_x1+10,H-DH-7*c_h+15,"10.[A]剩余兵力:");//输出字符串模拟控件文字	
	outtextxy(c_x1+10,H-DH-6*c_h+15,"11.[B]剩余兵力:");//输出字符串模拟控件文字
	//7.初始化原始数据
	outtextxy(W-DW-DC+DC/2+60,H-DH-16*36+15,is1);//写控件字符串
	outtextxy(W-DW-DC+DC/2+60,H-DH-15*36+15,is2);//写控件字符串
	outtextxy(W-DW-DC+DC/2+60,H-DH-14*36+15,is3);//写控件字符串
	outtextxy(W-DW-DC+DC/2+60,H-DH-13*36+15,is4);//写控件字符串
	outtextxy(W-DW-DC+DC/2+60,H-DH-8*36+15,is9);//写控件字符串
	//8.说明曲线颜色
	//------------------------------------------------------------
    setcolor(cc1);//说明曲线颜色
	line(W-DW-DC+10,H-DH-4*c_h+15,W-DW-DC+0.35*DC,H-DH-4*c_h+15);
	setcolor(cc2);//说明曲线颜色
	line(W-DW-DC+10,H-DH-3*c_h+15,W-DW-DC+0.35*DC,H-DH-3*c_h+15);
	setcolor(cc3);//说明曲线颜色
	line(W-DW-DC+10,H-DH-2*c_h+15,W-DW-DC+0.35*DC,H-DH-2*c_h+15);
	//------------------------------------------------------------
	setcolor(c3);//说明文字颜色
	outtextxy(W-DW-DC+0.4*DC,H-DH-4*c_h+10,"1.时间-[A]兵力曲线");//写控件字符串
	outtextxy(W-DW-DC+0.4*DC,H-DH-3*c_h+10,"2.时间-[B]兵力曲线");//写控件字符串
	outtextxy(W-DW-DC+0.4*DC,H-DH-2*c_h+10,"3.[A->B]兵力对比曲线");//写控件字符串
    //------------------------------------------------------------
}//结束子程序
//计算数据子函数
void sub_calculate()
{
	//1.原始数据转化为双精度数
	d1=atof(is1);//1.[A]初始兵力x0
	d2=atof(is2);//2.[A]战斗力系数b
	d3=atof(is3);//3.[B]初始兵力y0
	d4=atof(is4);//4.[B]战斗力系数a
	d9=atof(is9);//9.[AB]时间查询
	//2.根据数据计算要求项目---------------------------------------------------------------------------
	dmax=d3;
	if(d1>=d3){dmax=d1;}//最大兵力
	d5=d4*d3*d3-d2*d1*d1;//5.[AB]平局条件k
	if(d5>0)
	{
		d6=-1;//B胜
		cease_a(&ta);//计算作战时间
		d7=ta;
		func_B(d7,&d8);//10.[B]剩余兵力
	}//6.[AB]计算胜利方
	else if(d5==0)
	{
		d6=0;//平局
		//cease_o(&to);//计算作战时间
		d7=to;
		d8=0.0;//10.[B]剩余兵力
	}//7.[AB]作战时间
	else if(d5<0)
	{
		d6=1;//A胜
		cease_b(&tb);//计算作战时间
		d7=tb;
		func_A(d7,&d8);//10.[A]剩余兵力
	}//8.[AB]剩余兵力
	func_A(d9,&d10);//10.[A]剩余兵力
	func_B(d9,&d11);//11.[B]剩余兵力
	//3.将计算结果转化为字符串--------------------------------------------------------------------------
	gcvt(d5,6,is5);//
	gcvt(d6,6,is6);//
	gcvt(d7,6,is7);//
	gcvt(d8,6,is8);//
	gcvt(d10,6,is10);//
	gcvt(d11,6,is11);//
	//cout<<d5<<"_"<<d10<<"_"<<d11<<"_"<<ta<<"_"<<tb<<endl;//
	//4.绘制工作区坐标线
	//画x1轴刻度标线及文字---------------------------
	double value;//定义双精度变量
	char stt[10];//定义字符数组
	double xstep=(W-2*DW-DC)/(1.0*nx);//x方向步长(nx个刻度)(对应的绘图单位)
	double ystep=(H-DH-DD)/(1.0*ny);//y方向步长(ny个刻度)(对应的绘图单位)
	for(int i=0;i<=nx;i++)
	{
		setcolor(c1);//竖直辅助线颜色
		line(DW+xstep*i,H-DH,DW+xstep*i,DD);//画竖直小刻度线
		setcolor(c3);//文字颜色
		value=xstep*i*(1.0*d7)/(W-2*DW-DC);//所在的刻度数值
		gcvt(value,5,stt);//将浮点数value转换为字符串stt
		outtextxy(DW+xstep*i-10,H-DH-20,stt);//在规定的位置放置字符串
	}//结束for
	//画x2轴刻度标线及文字---------------------------
	for(i=0;i<=nx;i++)
	{
		setcolor(c3);//文字颜色
		value=xstep*i*(1.0*d1)/(W-2*DW-DC);//所在的刻度数值
		gcvt(value,5,stt);//将浮点数value转换为字符串stt
		outtextxy(DW+xstep*i-10,DD+20,stt);//在规定的位置放置字符串
	}//结束for
	//画y轴刻度标线及文字---------------------------
	for(i=0;i<=ny;i++)
	{
		setcolor(c2);//水平辅助线颜色
		line(DW,DD+ystep*i,W-DW-DC,DD+ystep*i);//画水平小刻度线
		setcolor(c3);//文字颜色
		value=ystep*(ny-i)*(1.0*dmax)/(H-DH-DD);//所在的刻度数值
		gcvt(value,3,stt);//将浮点数value转换为字符串stt
		outtextxy(DW+15,DD+ystep*i+5,stt);//在规定的位置放置字符串
	}//结束for
	//5.重新绘制工作区边框
	setcolor(c3);
	rectangle(DW,DD,W-DW,H-DH);//外边框
	rectangle(W-DW-DC,DD,W-DW,H-DH);//控件区域边框
	//6.将字符串写入控件中
	setfillcolor(BLACK);
	//------------------------------------------------------------
	fillrectangle(W-DW-DC+DC/2+40,H-DH-12*36+1,W-DW,H-DH-11*36);
	outtextxy(W-DW-DC+DC/2+45,H-DH-12*36+15,is5);//写控件字符串
	//------------------------------------------------------------
	fillrectangle(W-DW-DC+DC/2+40,H-DH-11*36+1,W-DW,H-DH-10*36);
	outtextxy(W-DW-DC+DC/2+45,H-DH-11*36+15,is6);//写控件字符串
	//------------------------------------------------------------
	fillrectangle(W-DW-DC+DC/2+40,H-DH-10*36+1,W-DW,H-DH-9*36);
	outtextxy(W-DW-DC+DC/2+45,H-DH-10*36+15,is7);//写控件字符串
	//------------------------------------------------------------
	fillrectangle(W-DW-DC+DC/2+40,H-DH-9*36+1,W-DW,H-DH-8*36);
	outtextxy(W-DW-DC+DC/2+45,H-DH-9*36+15,is8);//写控件字符串
	//------------------------------------------------------------
	fillrectangle(W-DW-DC+DC/2+40,H-DH-7*36+1,W-DW,H-DH-6*36);
	outtextxy(W-DW-DC+DC/2+45,H-DH-7*36+15,is10);//写控件字符串
	//------------------------------------------------------------
	fillrectangle(W-DW-DC+DC/2+40,H-DH-6*36+1,W-DW,H-DH-5*36);
	outtextxy(W-DW-DC+DC/2+45,H-DH-6*36+15,is11);//写控件字符串
	//7.获取时间从(0~d7)变化时的变化曲线------------------------------------------------
	double x_scale=(W-2*DW-DC)*0.1/(1.0*d7);//每个数学单位x对应的屏幕单位
	double y_scale=(H-DH-DD)*1.0/(1.0*dmax);//每个数学单位y对应的屏幕单位
	double x_scale1=(W-2*DW-DC)/(1.0*d1);//每个数学单位x对应的屏幕单位
	double n1,n2;//
	DPOINT *p1;//定义指向点表的指针
	DPOINT *p2;//定义指向点表的指针
	DPOINT *p3;//定义指向点表的指针
	p1=new DPOINT[1000];//定义N1点表
	p2=new DPOINT[1000];//定义N2点表
	p3=new DPOINT[1000];//定义N2点表
	for(int j=0;j<=d7*10.0;j++)//时间从(0~d7)变化
	{
		func_A(0.1*j,&n1);//10.[A]剩余兵力
		func_B(0.1*j,&n2);//11.[B]剩余兵力
		p1[j].x=DW+j*x_scale;
		p1[j].y=H-DH-n1*y_scale;
		p2[j].x=DW+j*x_scale;
		p2[j].y=H-DH-n2*y_scale;
		p3[j].x=DW+n1*x_scale1;
		p3[j].y=p2[j].y;
	}//结束for
	//8.绘制时间从(0~d7)变化时的变化曲线---------------------------------------------------
	setcolor(cc1);//曲线颜色1
	for(j=0;j<=d7*10.0-1;j++)//
	{
		line(p1[j].x,p1[j].y,p1[j+1].x,p1[j+1].y);
	}//结束for
	setcolor(cc2);//曲线颜色2
	for(j=0;j<=d7*10.0-1;j++)//
	{
		line(p2[j].x,p2[j].y,p2[j+1].x,p2[j+1].y);
	}//结束for
	setcolor(cc3);//曲线颜色3
	for(j=0;j<=d7*10.0-1;j++)//
	{
		line(p3[j].x,p3[j].y,p3[j+1].x,p3[j+1].y);
	}//结束for
}//结束子函数
//--------------------------------------------------------------------------------------------------
void func_A(double t,double *a)
{
	*a=0.5*( (d1-d3*sqrt(d4*1.0/d2))*exp(t*sqrt(d2*d4))+(d1+d3*sqrt(d4*1.0/d2))*exp(0.0-t*sqrt(d2*d4)) );//
}//结束子函数
//----------------------------------------------
void func_B(double t,double *b)
{
	*b=0.5*( (d3-d1*sqrt(d2*1.0/d4))*exp(t*sqrt(d2*d4))+(d3+d1*sqrt(d2*1.0/d4))*exp(0.0-t*sqrt(d2*d4)) );//
}//结束子函数
//---------------------------------------------------------------------------------------------------
void cease_a(double *ta)
{
	i=0.0;//
	double fa=d1;
	while(fa>=0.0)
	{
		func_A(i,&fa);//
		i=i+0.0001;//
	}//结束while
	*ta=i;//存储时间
}//结束子函数
void cease_b(double *tb)
{
	i=0.0;//
	double fb=d3;
	while(fb>=0.0)
	{
		func_B(i,&fb);//
		i=i+0.0001;//
	}//结束while
	*tb=i;//存储时间
}//结束子函数
void cease_o(double *to)
{
	i=0.0;//
	double fa=0;
	while(fa<=d1)
	{
		func_A(i,&fa);
		i=i+0.0001;//
	}//结束while
	*to=i;//存储时间
}//结束子函数
//*/
//--------------------------------------------------------------------------------------------------------------------

  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值