【矿大】中国矿业大学 CUMT 信息安全管理与工程2024春季学期 OpenJudge OJ 问题 E: 三角模糊层次分析

题目

样例输入

3
0.5,0.5,0.5 0.2,0.3,0.4 0.1,0.2,0.3
0.6,0.7,0.8 0.5,0.5,0.5 0.3,0.4,0.5
0.7,0.8,0.9 0.5,0.6,0.7 0.5,0.5,0.5

样例输出

0.20833 0.35256 0.43910

题解

这个题目除了有很多勘误,整体解释的很清楚,按照步骤即可完成

一、构建三角模糊数

看到对于三角模糊数的一堆定义,就立马想到要构建它,方便未来计算

class TriangularFuzzy
{
public:
	TriangularFuzzy(double t_l, double t_m, double t_u);
	TriangularFuzzy();

	//重载运算符
	TriangularFuzzy operator+(const TriangularFuzzy& b);
	TriangularFuzzy operator-(const TriangularFuzzy& b);
	TriangularFuzzy operator*(const TriangularFuzzy& b);
	TriangularFuzzy operator/(const TriangularFuzzy& b);

	static TriangularFuzzy Symmetry(const TriangularFuzzy& a);

	double l;
	double m;
	double u;
};

TriangularFuzzy::TriangularFuzzy(double t_l, double t_m, double t_u)
	:l(t_l), m(t_m), u(t_u)
{
}

TriangularFuzzy::TriangularFuzzy()
	: l(0.0), m(0.0), u(0.0)
{
}

TriangularFuzzy TriangularFuzzy::operator+(const TriangularFuzzy& b)
{
	return TriangularFuzzy(this->l + b.l, this->m + b.m, this->u + b.u);
}

TriangularFuzzy TriangularFuzzy::operator-(const TriangularFuzzy& b)
{
	return TriangularFuzzy(this->l - b.l, this->m - b.m, this->u - b.u);
}

TriangularFuzzy TriangularFuzzy::operator*(const TriangularFuzzy& b)
{
	return TriangularFuzzy(this->l * b.l, this->m * b.m, this->u * b.u);
}

TriangularFuzzy TriangularFuzzy::operator/(const TriangularFuzzy& b)
{
	return TriangularFuzzy(this->l / b.u, this->m / b.m, this->u / b.l);
}

TriangularFuzzy TriangularFuzzy::Symmetry(const TriangularFuzzy& a)
{
	return TriangularFuzzy(1 - a.u, 1 - a.m, 1 - a.l);
}

重载了四个运算符,而且写了计算互补的方法


由于看到还有很多的计算行的和,我也一并写了一个全局方法,用来计算一行的和

template<typename T>
T Summation(vector<T> a)
{
	T* sum = new T();
	for (T& i : a)
	{
		*sum = *sum + i;
	}
	return *sum;
}

 二、3.单层次因素模糊权重计算

输入部分不用多说

题目要求从第三步到第六步,因此我们获得了一个矩阵

首先进行每一行求和,然后将结果数组放进求和函数,得到总和,计算得到三角模糊数形式的权重向量

//3、单层次因素模糊权重计算
	vector<TriangularFuzzy> sum;
	for (int i = 0; i < n; i++)
	{
		sum.push_back(Summation(mat.at(i)));
	}
	TriangularFuzzy tot_sum = Summation(sum);
	for (int i = 0; i < n; i++)
	{
		sum[i] = sum.at(i) / tot_sum;
	}

三、4.建立可能度矩阵

题目提到λ为0.5,因此直接用define将其定义,这一步存在一个较长的公式,不过有且只有一步

//4、建立可能度矩阵
	vector<vector<double>> P_mat;
	for (int i = 0; i < n; i++)
	{
		vector<double> tem1;
		for (int j = 0; j < n; j++)
		{
			tem1.push_back(LAMBD *
				max(1 - max((sum.at(j).m - sum.at(i).l) / 
					(sum.at(i).m - sum.at(i).l + sum.at(j).m - sum.at(j).l), 0.0), 0.0)
				+ (1 - LAMBD) * 
				max(1 - max((sum.at(j).u - sum.at(i).m) / 
					(sum.at(i).u - sum.at(i).m + sum.at(j).u - sum.at(j).m), 0.0), 0.0));
		}
		P_mat.push_back(tem1);
	}

四、5.计算模糊一致性矩阵

行求和后进行矩阵的填充

//5、计算模糊一致性矩阵
	vector<vector<double>> fuzzy_mat;
	vector<double> row_sum;
	for (int i = 0; i < n; i++)
	{
		row_sum.push_back(Summation(P_mat.at(i)));
	}

	for (int i = 0; i < n; i++)
	{
		vector<double> tem1;
		for (int j = 0; j < n; j++)
		{
			tem1.push_back((row_sum.at(i) - row_sum.at(j)) / (2 * (double(n) - 1)) + 0.5);
		}
		fuzzy_mat.push_back(tem1);
	}

 五、6.计算排序向量

由于我们有计算行之和的工具,不需要像题目里一样分两步,只需要一步即可,这一步也会得到最终结果,因此直接输出

//6、计算排序向量
	//直接输出
	for (int i = 0; i < n; i++)
	{
		printf_s("%.5f ", (Summation(fuzzy_mat.at(i)) + (double(n) / 2) - 1) / ((double(n) - 1) * double(n)));
	}

 代码

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

using namespace std;

#define LAMBD 0.5

class TriangularFuzzy
{
public:
	TriangularFuzzy(double t_l, double t_m, double t_u);
	TriangularFuzzy();

	//重载运算符
	TriangularFuzzy operator+(const TriangularFuzzy& b);
	TriangularFuzzy operator-(const TriangularFuzzy& b);
	TriangularFuzzy operator*(const TriangularFuzzy& b);
	TriangularFuzzy operator/(const TriangularFuzzy& b);

	static TriangularFuzzy Symmetry(const TriangularFuzzy& a);

	double l;
	double m;
	double u;
};

TriangularFuzzy::TriangularFuzzy(double t_l, double t_m, double t_u)
	:l(t_l), m(t_m), u(t_u)
{
}

TriangularFuzzy::TriangularFuzzy()
	: l(0.0), m(0.0), u(0.0)
{
}

TriangularFuzzy TriangularFuzzy::operator+(const TriangularFuzzy& b)
{
	return TriangularFuzzy(this->l + b.l, this->m + b.m, this->u + b.u);
}

TriangularFuzzy TriangularFuzzy::operator-(const TriangularFuzzy& b)
{
	return TriangularFuzzy(this->l - b.l, this->m - b.m, this->u - b.u);
}

TriangularFuzzy TriangularFuzzy::operator*(const TriangularFuzzy& b)
{
	return TriangularFuzzy(this->l * b.l, this->m * b.m, this->u * b.u);
}

TriangularFuzzy TriangularFuzzy::operator/(const TriangularFuzzy& b)
{
	return TriangularFuzzy(this->l / b.u, this->m / b.m, this->u / b.l);
}

TriangularFuzzy TriangularFuzzy::Symmetry(const TriangularFuzzy& a)
{
	return TriangularFuzzy(1 - a.u, 1 - a.m, 1 - a.l);
}

template<typename T>
T Summation(vector<T> a)
{
	T* sum = new T();
	for (T& i : a)
	{
		*sum = *sum + i;
	}
	return *sum;
}

int main()
{
	//输入所需值
	int n;
	cin >> n;
	vector<vector<TriangularFuzzy>> mat;
	for (int i = 0; i < n; i++)
	{
		vector<TriangularFuzzy> tem;
		for (int j = 0; j < n; j++)
		{
			char ig;
			double t_l;
			double t_m;
			double t_u;
			cin >> t_l >> ig >> t_m >> ig >> t_u;
			TriangularFuzzy tem2(t_l, t_m, t_u);
			tem.push_back(tem2);
		}
		mat.push_back(tem);
	}

	//3、单层次因素模糊权重计算
	vector<TriangularFuzzy> sum;
	for (int i = 0; i < n; i++)
	{
		sum.push_back(Summation(mat.at(i)));
	}
	TriangularFuzzy tot_sum = Summation(sum);
	for (int i = 0; i < n; i++)
	{
		sum[i] = sum.at(i) / tot_sum;
	}

	//4、建立可能度矩阵
	vector<vector<double>> P_mat;
	for (int i = 0; i < n; i++)
	{
		vector<double> tem1;
		for (int j = 0; j < n; j++)
		{
			tem1.push_back(LAMBD *
				max(1 - max((sum.at(j).m - sum.at(i).l) / 
					(sum.at(i).m - sum.at(i).l + sum.at(j).m - sum.at(j).l), 0.0), 0.0)
				+ (1 - LAMBD) * 
				max(1 - max((sum.at(j).u - sum.at(i).m) / 
					(sum.at(i).u - sum.at(i).m + sum.at(j).u - sum.at(j).m), 0.0), 0.0));
		}
		P_mat.push_back(tem1);
	}

	//5、计算模糊一致性矩阵
	vector<vector<double>> fuzzy_mat;
	vector<double> row_sum;
	for (int i = 0; i < n; i++)
	{
		row_sum.push_back(Summation(P_mat.at(i)));
	}

	for (int i = 0; i < n; i++)
	{
		vector<double> tem1;
		for (int j = 0; j < n; j++)
		{
			tem1.push_back((row_sum.at(i) - row_sum.at(j)) / (2 * (double(n) - 1)) + 0.5);
		}
		fuzzy_mat.push_back(tem1);
	}

	//6、计算排序向量
	//直接输出
	for (int i = 0; i < n; i++)
	{
		printf_s("%.5f ", (Summation(fuzzy_mat.at(i)) + (double(n) / 2) - 1) / ((double(n) - 1) * double(n)));
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值