【矿大】中国矿业大学 CUMT 信息安全管理与工程2024春季学期 OpenJudge OJ 问题 N: 攻击图

文章描述了一个面向对象的编程实现,用于计算网络中主机的风险,包括最大风险概率、累计风险概率以及sigma值的计算。通过输入主机数量、路径数量、风险概率和权重,程序计算每个主机的最终最大风险和累计风险。
摘要由CSDN通过智能技术生成

题目

题目不全的地方α=0.5

样例输入

3
1
0.1974
2
0.0987 0.0493
1
0.0987
1 4 2 3 5 5 5 4
3 3 2 3 4 5 5 5
2 4 2 3 4 5 5 4
0.4 0.3 0.3

样例输出

0.1174 0.1291

结果保留4位小数

题解

这题由于有明显的面向对象特征,所以我采用封装主机类的方式来完成

根据题目要求可以分为几个步骤

1.输入和初始化

得到主机数量和分别的路径数量和风险概率

主机数量用静态变量存起来备用,路径数量和风险概率存在各自的成员变量里

得到输入的同时,应该计算出每个主机的主机最大风险概率和主机累计风险概率

double Host::GetMax(vector<double> m)
{
	double max = m.at(0);
	for (int i = 1; i < m.size(); i++)
	{
		if (max < m.at(i))
		{
			max = m.at(i);
		}
	}
	return max;
}

void Host::GetAccumulateRisk_P()
{
	double res = 1;
	for (int i = 0; i < path_num; i++)
	{
		res *= (1 - path_P.at(i));
	}
	res = 1 - res;
	accumulate_risk_P = res;
}

由于最大风险概率就是求最大值,将它设为静态成员函数备用

2.得到指标计算σ

计算σ需要多个指标队列,因此此方法也设计为静态

void Host::GetSigma(vector<Host*> group)
{
	vector<double> good;
	for (int i = 0; i < 8; i++)
	{
		vector<double> tem;
		for (int j = 0; j < host_num; j++)
		{
			tem.push_back(group.at(j)->GetIndex().at(i));
		}
		good.push_back(GetMax(tem));
	}
	double maxDifference = -1;
	double minDifference = 10000;
	for (int i = 0; i < host_num; i++)
	{
		for (int j = 0; j < 8; j++)
		{
			double tem = abs(group.at(i)->GetIndex().at(j) - good.at(j));
			if (maxDifference < tem)
			{
				maxDifference = tem;
			}
			if (minDifference > tem)
			{
				minDifference = tem;
			}
		}
	}
	for (int i = 0; i < host_num; i++)
	{
		double sum = 0;
		for (int j = 0; j < 8; j++)
		{
			sum += ((minDifference + 0.5 * maxDifference) / (abs(group.at(i)->GetIndex().at(j) - good.at(j)) + 0.5 * maxDifference));
		}
		group.at(i)->SetSigma(sum / 8);
	}
}

这一步有一个注意点:

在计算Δmax和Δmin时,计算的并不是单个主机的指标和参考序列的最大与最小差值,而是所有指标差值的最大与最小

3.最终计算

得到了每一个主机的σ后即可进行系统运算

void Host::ComputeMaxRisk()
{
	max_risk = max_risk_P * m_sigma;
}

void Host::ComputeAccumulateRisk()
{
	accumulate_risk = accumulate_risk_P * m_sigma;
}

用公式计算出最大风险值和累计风险值 

for (int i = 0; i < n; i++)
	{
		ser.at(i)->ComputeMaxRisk();
		ser.at(i)->ComputeAccumulateRisk();
	}

	double system_max_risk = 0;
	double system_accumulate_risk = 0;
	for (int i = 0; i < n; i++)
	{
		system_max_risk += ser.at(i)->GetW() * ser.at(i)->GetMaxRisk();
		system_accumulate_risk += ser.at(i)->GetW() * ser.at(i)->GetAccumulateRisk();
	}

然后将其分别乘上每个主机的权重,就得到了最终的系统最大风险值和系统累计风险值

代码

#include <iostream>
#include <vector>
#include <math.h>

using namespace std;

class Host
{
public:
	Host(int num, vector<double> P);
	//主机数量
	static int host_num;

	//得到指标
	void SetIndex(vector<double> index);
	vector<double> GetIndex() const;

	//设置权重
	void SetW(double w);
	double GetW() const;

	//填写sigma值
	void SetSigma(double sigma);
	//计算sigma
	static void GetSigma(vector<Host*> group);

	//计算最大风险值和累计风险值
	void ComputeMaxRisk();
	void ComputeAccumulateRisk();

	//获得两个风险值
	double GetMaxRisk() const;
	double GetAccumulateRisk() const;

private:
	//路径数量
	int path_num;
	//每条路径的风险
	vector<double> path_P;
	//最大风险概率
	double max_risk_P;
	//累计风险概率
	double accumulate_risk_P;
	
	//最大风险值
	double max_risk;
	//累计风险值
	double accumulate_risk;

	//计算最大值
	static double GetMax(vector<double> m);
	//计算累计风险概率
	void GetAccumulateRisk_P();

	//八个指标
	vector<double> m_index;

	//主机权重
	double m_w;

	//sigma值
	double m_sigma;
};

Host::Host(int num, vector<double> P)
{
	path_num = num;
	path_P = P;
	max_risk_P = GetMax(path_P);
	GetAccumulateRisk_P();
}

void Host::SetIndex(vector<double> index)
{
	m_index = index;
}

void Host::SetW(double w)
{
	m_w = w;
}

double Host::GetW() const
{
	return m_w;
}

vector<double> Host::GetIndex() const
{
	return m_index;
}

void Host::SetSigma(double sigma)
{
	m_sigma = sigma;
}

void Host::ComputeMaxRisk()
{
	max_risk = max_risk_P * m_sigma;
}

void Host::ComputeAccumulateRisk()
{
	accumulate_risk = accumulate_risk_P * m_sigma;
}

double Host::GetMaxRisk() const
{
	return max_risk;
}

double Host::GetAccumulateRisk() const
{
	return accumulate_risk;
}

double Host::GetMax(vector<double> m)
{
	double max = m.at(0);
	for (int i = 1; i < m.size(); i++)
	{
		if (max < m.at(i))
		{
			max = m.at(i);
		}
	}
	return max;
}

void Host::GetAccumulateRisk_P()
{
	double res = 1;
	for (int i = 0; i < path_num; i++)
	{
		res *= (1 - path_P.at(i));
	}
	res = 1 - res;
	accumulate_risk_P = res;
}

void Host::GetSigma(vector<Host*> group)
{
	vector<double> good;
	for (int i = 0; i < 8; i++)
	{
		vector<double> tem;
		for (int j = 0; j < host_num; j++)
		{
			tem.push_back(group.at(j)->GetIndex().at(i));
		}
		good.push_back(GetMax(tem));
	}
	double maxDifference = -1;
	double minDifference = 10000;
	for (int i = 0; i < host_num; i++)
	{
		for (int j = 0; j < 8; j++)
		{
			double tem = abs(group.at(i)->GetIndex().at(j) - good.at(j));
			if (maxDifference < tem)
			{
				maxDifference = tem;
			}
			if (minDifference > tem)
			{
				minDifference = tem;
			}
		}
	}
	for (int i = 0; i < host_num; i++)
	{
		double sum = 0;
		for (int j = 0; j < 8; j++)
		{
			sum += ((minDifference + 0.5 * maxDifference) / (abs(group.at(i)->GetIndex().at(j) - good.at(j)) + 0.5 * maxDifference));
		}
		group.at(i)->SetSigma(sum / 8);
	}
}

int Host::host_num = 0;

int main()
{
	//主机数量
	int n;
	cin >> n;
	Host::host_num = n;

	//批量创建主机
	vector<Host*> ser;
	for (int i = 0; i < n; i++)
	{
		int m;
		cin >> m;
		vector<double> tem1;
		for (int j = 0; j < m; j++)
		{
			double tem2;
			cin >> tem2;
			tem1.push_back(tem2);
		}
		Host* newHost = new Host(m, tem1);
		ser.push_back(newHost);
	}

	for (int i = 0; i < n; i++)
	{
		vector<double> tem;
		for (int j = 0; j < 8; j++)
		{
			double tem2;
			cin >> tem2;
			tem.push_back(tem2);
		}
		ser.at(i)->SetIndex(tem);
	}

	for (int i = 0; i < n; i++)
	{
		double tem;
		cin >> tem;
		ser.at(i)->SetW(tem);
	}

	Host::GetSigma(ser);
	for (int i = 0; i < n; i++)
	{
		ser.at(i)->ComputeMaxRisk();
		ser.at(i)->ComputeAccumulateRisk();
	}

	double system_max_risk = 0;
	double system_accumulate_risk = 0;
	for (int i = 0; i < n; i++)
	{
		system_max_risk += ser.at(i)->GetW() * ser.at(i)->GetMaxRisk();
		system_accumulate_risk += ser.at(i)->GetW() * ser.at(i)->GetAccumulateRisk();
	}

	printf_s("%.4f %.4f", system_max_risk, system_accumulate_risk);

	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值