ڼС
梦回起点
做你害怕做的事,你会发现:不过如此
本站基于WordPress—主题by 设计窝
冀ICP备15003737号
梦回起点
Copyright © 2015-2024 All rights reserved.

层次分析法指标权重的确定(C语言实现)

这个代码写了好几个小时了,  主要是层次分析法以前听都没听说过,所以要一点一点查,经过几个小时的学,然后开工,最后就形成了下面的残次品,全部寻常代码,没有任何特殊的地方,没有整理之前测试了一遍,然后整理出来了一个函数,没时间了,就这样吧。

/*************************看我 否则后果自负*************************
	功能:层次分析法指标权重的确定
	语言:C语言
	编译器:GCC4.8  0错误  0警告
	系统:windows7 X64 SP1
	完成时间:2016年3月11日
	作者:独行
	QQ:5591795
	个人网站:www.initm.com
	版权声明:此源码可随意修改,复制,发布,转载。
		  但是请不要删除本信息,部分复制请注明出处!
	已知问题:	1.采用和法粗略计算最大特征根和特征向量,存在误差,可能因为
				该误差导致一致性不通过的问题。
				2.需要满足方案层的每个方案与准则层全部元素相连,如果出现
				权重为0的情况将会产生计算错误!解决该问题,除了移动矩阵
				我还没有想到更好的办法,因为对矩阵不是很熟悉所以暂时不解决。
				3.少部分代码没有考虑重用,因为代码简单也不折腾了。
***********************我是没羞没臊的分割线**************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
//ri表
double ri[12] = {0, 0, 0, 0.58, 0.90, 1.12, 1.24,
				 1.32, 1.41, 1.45, 1.49, 1.51};
/*sum和法求正互反阵最大特征根和特征向量*/
double sum(double (*A)[9], int n, double* w)
{//注:9这个数据来自百度文库,认为每层不应该超过9个
	int i = 0, j = 0;
	double s = 0.0;
	double At[9][9] = {0};
	double Aw[9] = {0};
	for (i = 0; i < n; i++){
		s = 0;
		for (j = 0; j < n; j++){
			s = A[j][i] + s;
		}
		for (j = 0; j < n; j++){
			At[j][i] = A[j][i] / s;
		}
	}
	//计算w
	for (i = 0; i < n; i++){
		w[i] = 0;
		for (j = 0; j < n; j++){
			w[i] = At[i][j] + w[i];
		}
		w[i] /= n;
	}
	printf("\n");
	//计算Aw
	for (i = 0; i < n; i++){
		Aw[i] = 0;
		for (j = 0; j < n; j++){
			Aw[i] = A[i][j]*w[j] + Aw[i];
		}
	}
	s = 0;
	for (i = 0; i < n; i++){
		s = Aw[i] / w[i] + s;
	}
	return s / (double)n;
}

void create_matrix(double (*M)[9], int n, char (*s)[100], char* d)
{
	int i, j, t, f = 'n';
	i = j = t = 0;
	while('Y' != f && 'y' != f ){
			printf("请根据提示输入标度(1-9) 分数直接写负数(如1/5就写-5)。\n");
			/**************
			比如5*5矩阵  你需要输入“1”位置的数据
						0 1 1 1 1
						0 0 1 1 1
						0 0 0 1 1
						0 0 0 0 1
						0 0 0 0 0
			***************/
			for (i = 0; i < n; i++){
				M[i][i] = 1;
				for (j = i+1; j < n; j++){
					printf("请输入<%s>和<%s>对{%s}的标度:", s[i], s[j],d);
					scanf("%d", &t);
					while('\n' != getchar());
					if(t < -9 || t > 9){
						printf("非法数值!");
						exit(-1);
					}
					if(t < 0){
						M[j][i] = -t;
						M[i][j] = 1.0 / M[j][i];
					}else{
						M[i][j] = t;
						M[j][i] = 1.0 / M[i][j];
					}
				}
			}
			printf("请确认数据:\n");
			for(i = 0; i < n; i++){
				printf("-------");
			}
			printf("--\n");
			for (i = 0; i < n; i++){
				for (j = 0; j < n; j++){
					printf("| %4.2lf ", M[i][j]);
				}
				printf("|\n");
			}
			for (i = 0; i < n; i++){
				printf("-------");
			}
			printf("--\n");
			printf("确认以上数据?(Y/N)");
			f = getchar();
			while('\n' != getchar());
		}
		f = 'n';
}

int create_layer(const char* lname, char (*name)[100])
{
	int i = 0, j = 0 , f = 'n', n = 0;
	do{
		printf("请输入<%s>层个数(不超过9个):", lname);
		scanf("%d", &n);
		while('\n' != getchar());
		if(n <= 0 || n > 9){
			printf("输入不合法!");
			exit(-1);
		}
		for (i = 0; i < n; i++){
			printf("请输入第(%d)个%s名称:", i + 1, lname);
			fgets(name[i], 99, stdin);
			name[i][strlen((const char*)name[i])-1] = 0; //去回车
		}
		printf("请确认方案层名称:\n");
		for (i = 0; i < n; i++){
			printf("%10s\t", name[i]);
		}
		printf("\n确认以上数据?(Y/N)");
		f = getchar();
		while('\n' != getchar());
	}while('Y' != f && 'y' != f );
	return n;
}

int main()
{
/*************************第0步 准备****************************/
	double A[9][9] = {0},B[9][9][9];
	double w[9] = {0}, w3[9][9] = {0},wz[9] = {0};
	double ci = 0, cr = 0, y = 0;
	double ci3[9] = {0}, cr3[9] = {0}, y3[9] = {0};
	char name[9][100] = {0}, mname[100] = {0}, fname[9][100];
	int n = 0, n3 = 0, i = 0, j = 0, k = 0, t = 0;
/******************第一步 建立层次结构模型*********************/

		printf("请输入目标层名称:");
		fgets(mname, 99, stdin);
		mname[strlen(mname)-1] = 0; //去回车
		n = create_layer("准则", name);
		
/*****************第二步 两两比较得判断矩阵*******************/

	while(1){
		create_matrix( A, n, name, mname);
		
/***************第三步 进行层次单排序及其一致性检验****************/	

		//和法求w和y(λ)
		y = sum(A, n, w);
		ci = (y - n) / (n - 1.0);
		cr = ci / ri[n];
		printf("CI为%lf, CR为%lf, λ = %lf\n", ci, cr, y);
		if(cr < 0.1){
			printf("CR < 0.1 >> 一致性检验通过!\n");
			break;
		}else{
			printf("一致性检验未通过,请重新输入判断矩阵!\n");
		}
	}
	printf("W2如下:\n");
	for (i = 0; i < n; i ++){
		printf("%lf   ", w[i]);
	}
	printf("\n");
	
/*******************第四步 层次总排序及其一致性检验*********************/

	n3 = create_layer("方案", fname);
	for (k = 0; k < n; k++){
		while(1){
			create_matrix(B[k], n3, fname, name[k]);
			y3[k] = sum(B[k], n3, w3[k]);
			ci3[k] = (y3[k] - n3) / (n3 - 1.0);
			cr3[k] = ci3[k] / ri[n];
			printf("CI为%lf, CR为%lf, λ = %lf\n", ci3[k], cr3[k], y3[k]);
			if(cr3[k] < 0.1){
				printf("CR < 0.1 -> 一致性检验通过!\n");
				break;
			}else{
				printf("一致性检验未通过,请重新输入判断矩阵!\n");
			}
		}
	}
	for (i = 0; i < n3; i++){
		wz[i] = 0;
		for (j = 0; j < n; j++){
			wz[i] = w3[i][j] * w[j] + wz[i];
		}
	}
	printf("W3如下:\n");
	for (i = 0; i < n3; i++){
		for (j = 0; j < n; j++){
			printf("%lf     ", w3[i][j]);
		}
		printf("\n");
	}
	printf("\n");
	printf("方案层对目标层的组合权向量为:(");
	for (i = 0; i < n3; i++){
		printf("%lf,", wz[i]);
	}
	printf("\b )\n");
	t = wz[0];
	for (i = 1; i < n3; i++){
		if(t < wz[i]){
			t = wz[i];
			j = i;
		}
	}
	printf("所有因素综合起来应选择<%s>\n", fname[j]);
	
	return 0;
}
2016-03-11
                         
  1. 一匹马赛克

    很有帮助!! 😳

发表回复