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

📄 computegame.cpp

📁 本程序为求解博弈纳什均衡解的源程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ComputeGame.cpp : implementation file
//

#include "stdafx.h"
#include "Game.h"
#include "ComputeGame.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CComputeGame dialog

//构造函数
CComputeGame::CComputeGame(CWnd* pParent /*=NULL*/)
	: CDialog(CComputeGame::IDD, pParent)
{
	//{{AFX_DATA_INIT(CComputeGame)
	m_aPolicyNum = 0;
	m_bPolicyNum = 0;
	//}}AFX_DATA_INIT
	// 双方博弈策略数目中间值
	m_aMidPolicyNum = 0;
	m_bMidPolicyNum = 0;

	// 博弈均衡解的个数
	m_gameResNum1 = 0;
	m_gameResNum2 = 0;
}


void CComputeGame::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CComputeGame)
	DDX_Control(pDX, IDC_AB_OPENCONFIG, m_abOpenConfig);
	DDX_Text(pDX, IDC_A_POLICYNUM, m_aPolicyNum);
	DDV_MinMaxInt(pDX, m_aPolicyNum, 1, 30);
	DDX_Text(pDX, IDC_B_POLICYNUM, m_bPolicyNum);
	DDV_MinMaxInt(pDX, m_bPolicyNum, 1, 30);
	DDX_Control(pDX, IDC_GAMERESULT, m_gameResult);
	DDX_Control(pDX, IDC_GAMEINPUT, m_gameInput);
	DDX_Control(pDX,IDC_GameResult2,m_gameResult2);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CComputeGame, CDialog)
	//{{AFX_MSG_MAP(CComputeGame)
	ON_BN_CLICKED(IDC_AB_OPENCONFIG, OnAbOpenconfig)
	ON_BN_CLICKED(IDC_CoputerCom, OnCoputerCom)
	ON_BN_CLICKED(IDC_AB_COMPUTE, OnAbCompute)
	ON_BN_CLICKED(IDC_Save, OnSave)
	ON_BN_CLICKED(IDC_Set, OnSet)
	ON_BN_CLICKED(IDC_AB_CLEAR, OnAbClear)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CComputeGame message handlers

//通过打开对话框,选择一个博弈文件,将博弈矩阵显示在博弈矩阵列表控制中
void CComputeGame::OnAbOpenconfig() 
{
	// TODO: Add your control notification handler code here
	CString sourceFileName, gameSrc, gameItemText, gameLineStr;
	int i, j, gameReadedBytes;
	CFile gameFile;

    
	// 定义打开对话框
	CFileDialog openDlg(TRUE,"",NULL,OFN_HIDEREADONLY|
		OFN_OVERWRITEPROMPT,
		"NFG(*.nfg)|*.nfg|(All Files(*.*)|*.*||",NULL);

	if(openDlg.DoModal() == IDOK)
 	{
		// 获取选择的文件名
		sourceFileName = openDlg.GetPathName();

		// 打开的文件格是否正确
		if(openDlg.GetFileExt().Compare("nfg") != 0)
			AfxMessageBox("博弈矩阵文件格式不正确!");
		else
		{
			//打开博弈文件
			gameFile.Open(sourceFileName, CFile::modeRead);
			gameReadedBytes = 0;

			// 获取我方/敌方的策略数目
			gameFile.SeekToBegin();
			CFileReadLine(&gameFile, &gameLineStr);
			
			//获得我方策略数
			gameSrc = gameLineStr.Left(gameLineStr.Find("x"));
			gameSrc = gameSrc.Right(gameSrc.GetLength() - gameSrc.ReverseFind(' ') - 1);
			m_aPolicyNum = atoi(gameSrc.GetBuffer(gameSrc.GetLength()));
		
			//获得敌方策略数
			gameSrc = gameLineStr.Right(gameLineStr.GetLength() -
										gameLineStr.Find("x") - 1);
			gameSrc = gameSrc.Left(gameSrc.Find(" "));
			m_bPolicyNum = atoi(gameSrc.GetBuffer(gameSrc.GetLength()));
			UpdateData(FALSE);
            

			// 根据我方/敌方的策略数目设置初始博弈矩阵
			OnABConfig();

			// 文件指针指向第二行数据
			gameReadedBytes += gameLineStr.GetLength();
			gameFile.Seek(gameReadedBytes, CFile::begin);

			// 文件指针定位到博弈数据
			while(CFileReadLine(&gameFile, &gameLineStr))
			{
				if(gameLineStr.Find(",") >= 0)
					break;
				else
				{
					gameReadedBytes += gameLineStr.GetLength();
					gameFile.Seek(gameReadedBytes, CFile::begin);
				}
			}

			// 读取博弈数据显示在LISTCTRL中
			for(j = 1; j < m_bPolicyNum + 1; j++)
			{
				for(i = 0; i < m_aPolicyNum; i++)
				{
					if(CFileReadLine(&gameFile, &gameLineStr))
					{
						gameSrc = "";
						gameItemText = "";
						gameSrc = gameLineStr.Left(gameLineStr.Find(","));
						gameSrc = gameSrc.Right(gameSrc.GetLength() - 5); //博弈数据1
						gameItemText.Insert(gameItemText.GetLength(), gameSrc);
						gameItemText.Insert(gameItemText.GetLength(), ",");
						gameSrc = gameLineStr.Right(gameLineStr.GetLength() - 
													gameLineStr.Find(",") - 2);
						gameSrc = gameSrc.Left(gameSrc.GetLength() - 3); //博弈数据2
						gameItemText.Insert(gameItemText.GetLength(), gameSrc);
						m_gameInput.SetItemText(i, j, gameItemText);
						gameReadedBytes += gameLineStr.GetLength();
						gameFile.Seek(gameReadedBytes, CFile::begin);
					}
				}
			}

			// 关闭博弈数据文件
			gameFile.Close();
		}
	}


}

BOOL CComputeGame::OnInitDialog() 
{
	CDialog::OnInitDialog();
	

	// 设置博弈输入为全行选择
	m_gameInput.SetExtendedStyle(LVS_EX_FULLROWSELECT);

	// 设置博弈输入LISTCTRL的单元格包含多个数据
	m_gameInput.SetOneValueInEdit(FALSE);
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

// 读取博弈文件的一行数据
int CComputeGame::CFileReadLine(CFile* file, CString* string)
{
	char tempBuf[15];
	CString readStr;
	int readNum, readedBytes, curPos;
	char enterStr[2];
	enterStr[0] = 0x0a;
	enterStr[1] = '\0';

	curPos = (int)file->GetPosition();
	*string = "";
	readedBytes = 0;

	while((readNum = file->Read(tempBuf, 30)) >= 1)
	{
		readStr = "";
		readStr.Insert(0, tempBuf);
		if(readStr.Find(enterStr) < 0)
		{
			*string = *string + readStr;
			readedBytes += readNum;
		}
		else
		{
			readStr = readStr.Left(readStr.Find(enterStr) + 1);
			*string = *string + readStr;
			break;
		}
		file->Seek(curPos + readedBytes, CFile::begin);
		tempBuf[0] = '\0';
	}

	file->Seek(curPos, CFile::begin);

	if(readStr.GetLength() >= 1)
		return readStr.GetLength();

	return 0;
}

// 删除博弈输入矩阵,即清除博弈矩阵控制列表中的内容
void CComputeGame::ClearGameInput()
{
	UpdateData();

	int i, j, delRowEnable, delColEnable;
	CHeaderCtrl* pHeaderCtrl = m_gameInput.GetHeaderCtrl();

	delRowEnable = 0;
	delColEnable = 0;
	if(m_aMidPolicyNum > 0)		delRowEnable = 1;
	if(m_bMidPolicyNum > 0)		delColEnable = 1;
	if(pHeaderCtrl != NULL)
	{
		if(pHeaderCtrl->GetItemCount() > 0)
			delColEnable = 1;
	}

	// 删除博弈输入的所有行
	if(delRowEnable > 0)
	{
		for(i = 0; i < m_aMidPolicyNum; i++)
		{
			m_gameInput.DeleteItem(m_gameInput.GetItemCount() - 1);
		}
	}

	// 删除博弈输入的所有列
	if(delColEnable > 0)
	{
		for(j = 0; j < m_bMidPolicyNum + 1; j++)
		{
			m_gameInput.DeleteColumn(m_bMidPolicyNum - j);
		}
	}
}

// 根据我方及敌方的策略数设置初始的博弈矩阵
void CComputeGame::OnABConfig()
{
	UpdateData();

	// 清除已有的博弈输入
	ClearGameInput();

	int i, j;
	CString colName, rowName, num, lines;
	BOOL bRowColValid;

	bRowColValid = FALSE;
    //判断我方策略数和敌方策略数须是否越界(此处限制在30以内的正整数)
	if((m_aPolicyNum >0 && m_aPolicyNum <= 30) &&
		(m_bPolicyNum >0 && m_bPolicyNum <= 30))
		bRowColValid = TRUE;

	// 根据双方策略数设置博弈列表
	if(bRowColValid)
	{
		// 增加行和列交叉项
		m_gameInput.InsertColumn(0, _T("我方/敌方"), LVCFMT_CENTER, 75);

		// 增加列
		for(j = 1; j < m_bPolicyNum + 1; j++)
		{
			num.Format("%d", j);
			colName = "策略" + num;
			m_gameInput.InsertColumn(j, colName, LVCFMT_CENTER, 100);
		}
		
		// 增加行
		for(i = 0; i < m_aPolicyNum; i++)
		{
			num.Format("%d", i + 1);
			rowName = "策略" + num;
			m_gameInput.InsertItem(i, rowName);
			for(j = 1; j < m_bPolicyNum + 1; j++)
				m_gameInput.SetItemText(i, j, "0,0");
		}

		// 设置博弈策略控件列表可在位编辑的列集合
		for(j = 1; j < m_bPolicyNum + 1; j++)
		{
			num.Format("%d", j);
			lines += num + ",";
		}
		m_gameInput.SetEditLines(lines);

		// 记录本次设置的行和列值,用于下次完全删除所有的行和列
		m_aMidPolicyNum = m_aPolicyNum;
		m_bMidPolicyNum = m_bPolicyNum;

		UpdateData();
	}	
}

//通过对敌我双方收益的比较,求解纳什均衡解
void CComputeGame::OnCoputerCom() 
{
	// TODO: Add your control notification handler code here
	bool equ1,equ2;//判断是否是均衡解,两者都为真时为均衡解
	double max;
	EquNum=0;
	CString num,colName;

	GetCtrlListData();

	//进行敌方双方的收益大小比较
	for(int i=0;i<m_aPolicyNum;i++)
		for(int j=0;j<m_bPolicyNum;j++)
		{
          equ1=true;
		  equ2=true;

		  //我方策略固定时,敌方采用不同策略时的收益大小比较
		  max=GameData[i][j][1];
		  for(int k=0;k<m_bPolicyNum;k++)
			  if(max<GameData[i][k][1])
			  {
				  equ1=false;
				  break ;
			  }
		  if(!equ1)
			  continue;
          //敌方策略固定时,我方采用不同策略时的收益大小比较
		  max=GameData[i][j][0];
		  for(int l=0;l<m_aPolicyNum;l++)
			  if(max<GameData[l][j][0])
			  {
				  equ2=false;
				  break;
			  }
          
		  //某一局势为纳什均衡解时,保存我方策略号、敌方策略号
          if((equ1 && equ2))
		  {
			  
			  Equ[EquNum][0]=i+1;
			  Equ[EquNum][1]=j+1;
			   EquNum++;
		  }

		}
	
    //在比较方法纳什均衡解控制列表框中显示纳什均衡解
	if(EquNum>0)
	{
		int i,j;
		if(m_gameResNum1 > 0)
	    	ClearGameResult();

		// 增加博弈结果序号
		m_gameResult.InsertColumn(0, _T("序号"), LVCFMT_CENTER, 60);

		// 增加我方列集合
		for(j = 0; j < m_aPolicyNum; j++)
		{
			num.Format("%d", j + 1);
			colName = "我方策略" + num;
			m_gameResult.InsertColumn(j + 1, colName, LVCFMT_CENTER, 100);
		}

		// 增加敌方列集合
		for(j = 0; j < m_bPolicyNum; j++)
		{
			num.Format("%d", j + 1);
			colName = "敌方策略" + num;
			m_gameResult.InsertColumn(j + m_aPolicyNum + 1, colName, LVCFMT_CENTER, 100);
		}

		//显示纳什均衡解对应的敌我双方策略号(纳什均衡解对应的策略号其值为1,其他的为0)
		for(i=0;i<EquNum;i++)
		{
			CString str;
			str.Format("%d",i+1);
			str="均衡"+str;
			m_gameResult.InsertItem(i,str);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -