精华内容
下载资源
问答
  • AHP算法--java版
    千次阅读
    2015-01-05 14:09:31

    一个自己写的AHP简单算法,其实就是一些循环计算而已,记录下来,以后或许会用到:

    首先了解下什么是AHP


    层次分析法(Analytic Hierarchy Process,简称AHP)是美国运筹学家、匹兹堡大学T. L. Saaty教授在20世纪70年代初期提出的, AHP是对定性问题进行定量分析的一种简便、灵活而又实用的多准则决策方法。它的特点是把复杂问题中的各种因素通过划分为相互联系的有序层次,使之条理化,根据对一定客观现实的主观判断结构(主要是两两比较)把专家意见和分析者的客观判断结果直接而有效地结合起来,将一层次元素两两比较的重要性进行定量描述。而后,利用数学方法计算反映每一层次元素的相对重要性次序的权值,通过所有层次之间的总排序计算所有元素的相对权重并进行排序。该方法自1982年被介绍到我国以来,以其定性分析定量分析相结合地处理各种决策因素的特点,以及其系统灵活简洁的优点,迅速地在我国社会经济各个领域内,如能源系统分析、城市规划、经济管理、科研评价等,得到了广泛的重视和应用。


    以下是简单实现,包含一致性判断

    import java.util.Scanner;
    
    public class AHP {
    	
    	/*
    1	2	3
    1/2	1	2/3
    1/3	3/2	1
    
    	 *
    6
    1  1  1  4  1  1/2
    1  1  2  4  1  1/2
    1  1/2  1  5  3  1/2
    1/4  1/4  1/5  1  1/3  1/3
    1  1  1/3  3  1  1
    2  2  2  3  1  1
    	 */
    	public static void main(String[] args) {
    		System.out.println();
    		Scanner scanner = new Scanner(System.in);
    		int n = scanner.nextInt();
    		double d[][] = new double[n][n];
    		double temp[][] = new double[n][n];
    		for (int i = 0; i < n; i++) {
    			for (int j = 0; j < n; j++) {
    				double sToD = SToD(scanner.next());
    				d[i][j] = sToD;
    				temp[i][j] = sToD;
    			}
    		}
    
    		System.out.println("以下是判断矩阵");
    		// 得到判断矩阵
    		for (int i = 0; i < n; i++) {
    			for (int j = 0; j < n; j++) {
    				System.out.printf("%.2f\t", d[i][j]);
    			}
    			System.out.println();
    		}
    
    		// 1.对判断矩阵进行求和
    		System.out.println("列相加结果");
    
    		double w1[] = new double[n];
    		for (int i = 0; i < n; i++) {
    			for (int j = 0; j < n; j++) {
    				w1[i] = w1[i] + d[j][i];
    			}
    			System.out.printf("%.2f\t", w1[i]);
    		}
    
    		// 2.相除
    		System.out.println();
    		for (int i = 0; i < n; i++) {
    			for (int j = 0; j < n; j++) {
    				d[i][j] = d[i][j] / w1[j];
    			}
    		}
    		System.out.println("和积法第一步求出的结果");
    		for (int i = 0; i < n; i++) {
    			for (int j = 0; j < n; j++) {
    				System.out.printf("%.2f\t", d[i][j]);
    			}
    			System.out.println();
    		}
    
    		System.out.println("对第一步求出的结果进行 行相加");
    
    		System.out.println("行相加结果");
    
    		double w2[] = new double[n];
    		for (int i = 0; i < n; i++) {
    			for (int j = 0; j < n; j++) {
    				w2[i] = w2[i] + d[i][j];
    			}
    			System.out.printf("\t%.2f\n", w2[i]);
    		}
    
    		System.out.println("特征向量求解第一步 : 将上面的行相加的所有结果相加:");
    		double sum = 0.0;
    		for (int i = 0; i < n; i++) {
    			sum += w2[i];
    		}
    		System.out.printf("结果为sum = \t%.2f\n", sum);
    
    		System.out.println("将行结果与 sum 相除 得出结果为 :  ");
    		double w3[] = new double[n];
    		for (int i = 0; i < n; i++) {
    			w3[i] = w2[i] / sum;
    			System.out.printf("\t%.2f\n", w3[i]);
    		}
    
    		System.out.println();
    		System.out.println("用和积法计算其最大特征向量为:W = ");
    		// 以下是校验
    		System.out.printf("(");
    		for (int i = 0; i < n; i++) {
    			System.out.printf("%.2f ,", w3[i]);
    		}
    		System.out.printf(")");
    
    		System.out.println("\nBW = ");
    		double w4[] = new double[n];
    		for (int i = 0; i < n; i++) {
    			for (int j = 0; j < n; j++) {
    				w4[i] = w4[i] + temp[i][j] * w3[j];
    			}
    			System.out.printf("%.3f \t", w4[i]);
    		}
    		System.out.println("\n----------------------------------------");
    		double sum2 = 0.0;
    		for (int i = 0; i < n; i++) {
    			sum2 = sum2 + w4[i];
    		}
    		System.out.printf("得到sum2\t %.2f\n", sum2);
    
    		System.out.println("最大的特征向量为 :  ");
    
    		double result = 0.0;
    		for (int i = 0; i < n; i++) {
    			result = result + w4[i] / (6 * w3[i]);
    		}
    		System.out.printf(" %.2f \n", result);
    
    		System.out.println("\n判断矩阵一致性指标C.I.(Consistency Index)");
    		double CI = (result - n) / (n - 1);
    		System.out.printf(" %.2f \n", CI);
    
    		System.out.println("随机一致性比率C.R.(Consistency Ratio)。");
    
    		/*
    		 * 
    		 n  1  2  3  	4  		5	  6	  7		  8		 9	  10	  11
    		RI  0  0  0.58  0.90  1.12  1.24  1.32  1.41  1.45  1.49  1.51 
    		一般,当一致性比率 <0.1 时
    		的不一致程度在容许范围之内,可用其归一化特征向量
    		作为权向量,否则要重新构造成对比较矩阵,对  加
    		以调整
    		 */
    		double RI = 0.0;
    		switch (n) {
    		case 0:
    			RI=0;
    			break;
    		case 1:
    			RI=0;
    			break;
    		case 2:
    			RI=0;
    			break;
    		case 3:
    			RI=0.58;
    			break;
    		case 4:
    			RI=0.90;
    			break;
    		case 5:
    			RI=1.12;
    			break;
    		case 6:
    			RI=1.24;
    			break;
    		case 7:
    			RI=1.32;
    			break;
    
    		default:
    			break;
    		}
    		System.out.printf("C.R =  %.2f \n", CI / RI);
    		
    		scanner.close();
    	}
    
    	public static double SToD(String s) {
    		String[] p = s.split("/");
    		if (p.length > 1) {
    			return Double.parseDouble(p[0]) / Double.parseDouble(p[1]);
    		}
    		return Double.parseDouble(s);
    	}
    }
    
     这个题目是因为自己有个作业需要用到,为了避免每次都进行大量的运算,特此写了个程序来实现,有需要的同学自己复制代码进行计算(⊙o⊙)哦。
    更多相关内容
  • 主要给大家介绍了关于python实现AHP算法(层次分析法)的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 数模-改进AHP算法

    2021-10-25 12:23:29
    下面简单介绍一下AHP算法的基本概念: AHP是一种定性与定量相结合的系统化、层次化的分析方法,由美国的运筹学加Satty于20世纪70年代提处。 AHP是一种定性与定量相结合的系统化、层次化的分析方法[1],由...

    一、简简单单介绍一下AHP

      AHP(层次分析)算法作为数学建模中评价问题中求解的“万金油”,以方便构建且思路简单而受到大部分数模小白的青睐以及使用。下面简单介绍一下AHP算法的基本信息:

      AHP是一种定性与定量相结合的系统化、层次化的分析方法,由美国的运筹学加Satty于20世纪70年代提出。AHP自20世纪80年代初引入到我国以来,国内外相关研究者对其进行了大量的改进和完善,并获得了一系列的研究成果。这些成果主要集中在标度和一致性检验方法的改进、判断矩阵的构造以及修正、权重的求解、逆序问题、群决策问题、F-AHP问题、标度的分析比较问题等方面。在实际应用中,人们发现Satty教授提出的1-9标度法存在很多的缺陷。针对1-9标度法的不足,国内外学者一些改进的数字标度法。国外主要有1-5标度法、1-15标度法、x2标度法、槡x标度法等。国内主要有0-2标度法、-1-1标度法、-2-2标度法、0.1-0.9标度法、指数标度法、9/9-9/1和10/10-18/2分数标度法等。

      但是!AHP算法虽然简单好用,但作为低级的评价模型算法似乎并不受评委们的青睐,因此我们在使用它的时候,最好进行与题目相关的优化后再使用其进行求解,这样一来不仅降低评委嫌弃程度,也可以提高求解结果的正确性,鱼和熊掌兼得,实是妙哉。以下我们以2021数维杯国赛骑手评价体系的构建问题(即第一小问)进行相关演示。

    二、粘一下这个题目

    根据2020年6月发布的《2019中国即时配送行业发展报告》显示,2019年的即时配送行业的订单量以及用户群体,外卖骑手的数量也呈现一种直线上升的趋势。
    但是由于复杂的国内与国际经济环境及我国庞大的人口规模下外卖骑手间的竞争变得异常激烈,
    这给予了平台更多的订单配送提成压缩空间例如拼命压缩和延长上班时间来换取高收入,以骑手配送效率低下为理由逐步压缩外卖骑手的订单配送提成等。
    据调查显示,骑手在送外卖的过程中受到智能算法和数据分析的不断驱动,出现了违反交通规则的现象,
    朝着更快更廉价的趋势发展。同时商家也对平台的抽成反感并产生了部分商家为了盈利出现了料理包加热、食材不新鲜等问题,致使消费者也成为了受害群体。
    上述种种事实表明外卖行业中存在着严重的内卷现象。数据分析至关重要,但利用数据分析来掠夺弱势群体少有的财富和时间并不可取。
    请你通过数学建模的方法解决外卖平台、骑手、商家与消费者之间的如下问题:
    
    问题1:请充分考虑骑手的骑行安全与高质量服务等因素后,试制定一个合理的骑手配送时长设计方案,并提供对应的完成质量奖惩措施。

     三、问题分析

    通过研究如何制定一个合理的骑手配送时长设计方案,并提供对应的完成质量奖,可以为平台提供一个双向受益的选择,从而在不损害平台利益以及提高平台员工综合素质的同时使骑手得到合适的利益以保持良好的工作积极性。

    问题1属于规划决策类的数学问题,对于解决此类问题,我们一般寻找与决策相关的指标并对其分别进行权重计算,最后将其权重进行相应的处理之后依据题意构建相应的决策结果。

    通过网络资料搜集,我们可以得到如下的外卖骑手评价体系示意图:

     四、层次分析法于此处的使用过程

    (因为mathtype的公式不能直接copy过来,所以我们只能用图片展示有公式的部分了)

    所以判断矩阵B是模糊一致判断矩阵。

    通过大量数据评估以及调查得出10个一级指标的互补性判断矩阵A如图1.2所示

    矩阵A做变换得模糊一致矩阵B

    利用MATLAB计算10个一级指标得权重(编程代码详见附件1),权重结果为

    W=(0.1081 0.1061 0.0939 0.0838 0.1093 0.1213 0.1020 0.0807 0.1070 0.0878)

    利用相同的方法对二级指标进行权重计算,得到28个二级指标的权重为

    W1=(0.3904 0.3331 0.2765)            W2=(0.4019 0.3333 0.2648) W3=(0.5505 0.4495)                   W4=(0.2769 0.3446 0.3785)

    W5=(0.3669 0.2998 0.3333)            W6=(0.5505 0.4495)

    W7=(0.3449 0.4022 0.2529)             W8=(0.3220 0.3898 0.2882)

    W9=(0.3558 0.3558 0.2885)             W10=(0.3669 0.2998 0.3333)

    得到如下图1.2的各级指标权重图

    权重

    一级指标权重

    二级指标权重a

    二级指标权重b

    二级指标权重c

    时效性

    0.1081

    0.3904

    0.3331

    0.2765

    完整性

    0.1061

    0.4019

    0.3333

    0.2648

    准确性

    0.0939

    0.5505

    0.4495

    响应性

    0.0838

    0.2769

    0.3446

    0.3785

    安全性

    0.1093

    0.3669

    0.2998

    0.3333

    鲜活性

    0.1213

    0.5505

    0.4495

    经济性

    0.1020

    0.3449

    0.4022

    0.2529

    灵活性

    0.0807

    0.3220

    0.3898

    0.2882

    保障性

    0.1070

    0.3558

    0.3558

    0.2885

    移情性

    0.0878

    0.3669

    0.2998

    0.3333

    最后根据得到的各个指标权重进行相应的决策规划就好啦。

    五、MATLAB代码

    (层次分析法的代码大同小异,其实不同的优化思想主要体现在对于数据的预处理以及评判矩阵的确定上)

    B=[0.5,0.51,0.57,0.62,0.49,0.435,0.53,0.635,0.51,0.6;
        0.49,0.5,0.56,0.61,0.48,0.425,0.52,0.625,0.5,0.59;
        0.43,0.44,0.5,0.55,0.42,0.365,0.46,0.565,0.44,0.53;
        0.38,0.39,0.45,0.5,0.37,0.315,0.41,0.515,0.39,0.48;
        0.51,0.52,0.58,0.63,0.5,0.445,0.54,0.645,0.48,0.61;
        0.565,0.575,0.635,0.685,0.555,0.5,0.595,0.7,0.575,0.665;
        0.47,0.48,0.54,0.59,0.46,0.405,0.5,0.605,0.48,0.57;
        0.365,0.375,0.435,0.485,0.355,0.3,0.395,0.5,0.375,0.465;
        0.49,0.5,0.56,0.61,0.52,0.425,0.52,0.625,0.5,0.59;
        0.4,0.41,0.47,0.52,0.39,0.335,0.43,0.535,0.41,0.5];
    [V B]=eig(B);
    W=V(:,1)/sum(V(:,1))

    展开全文
  • AHP算法层次分析

    2017-12-21 17:03:37
    程序可用,AHP层次分析算法,适用于初学者,可用于评估模型中
  • 以层次分析法(AHP)递阶层次思想为主导,基于BP神经网络,结合指数评估法,提出了质量评估的一种改进算法:基于层次分析的神经网络算法,并给出了建立模型的方法和步骤,模型有效解决了精确率在武器质量评估中的...
  • matlab实现ahp算法.doc

    2021-12-08 23:28:00
    matlab实现ahp算法.doc
  • 基于数据挖掘的AHP算法在职业教育教学评价系统中的应用.pdf
  • AHP算法.rar

    2012-10-22 16:53:37
    AHP层次分析是数学建模中的一种定性定量的分析方法,在实际中广泛应用
  • 基于AHP算法的高校教师说课竞赛评价指标研究
  • AHP算法java实现

    热门讨论 2011-09-14 14:07:41
    java实现AHP算法,包括文档说明,算法介绍等ppt文档 欢迎使用
  • 对不确定型AHP算法进行了研究.本文根据模糊极值的思想,提出了不确定AHP问题中两两比较区间矩阵的一种新算法及新的总体排序方法.归纳总结了运用改进算法进行决策的详细步骤.并通过仿真实例说明了算法的可行性....
  • AHP算法的excel实现

    2013-06-04 11:34:50
    通过excel实现ahp算法,简单,易用,用于科研
  • 判断矩阵的建立和调整是AHP算法的关键。对Satty的1~9标度方法进行改进,引入3标度法建立判断矩阵。从正互反矩阵充分必要条件出发,提出判断矩阵不一致时的调整方法,以提高判断矩阵的一致性和减少计算量。该方法应用...
  • 基于AHP线性流形学习方法是通过适当的约束条件最小化目标函数来实现的,约束条件中对角矩阵的求解限制,使得公式不够灵活,于是考虑在对角矩阵求解时加入了指数参数,对公式进行泛化。通过人脸图像聚类实验,发现指数的...
  • python实现AHP算法(层次分析法)

    千次阅读 多人点赞 2020-09-07 21:26:56
    层次分析法(Analytic Hierarchy Process,AHP)由美国运筹学家托马斯·塞蒂(T. L. Saaty)于20世纪70年代中期提出,用于确定评价模型中各评价因子/准则的权重,进一步选择最优方案。该方法仍具有较强的主观性,...

    一、层次分析法原理

    层次分析法(Analytic Hierarchy Process,AHP)由美国运筹学家托马斯·塞蒂(T. L. Saaty)于20世纪70年代中期提出,用于确定评价模型中各评价因子/准则的权重,进一步选择最优方案。该方法仍具有较强的主观性,判断/比较矩阵的构造在一定程度上是拍脑门决定的,一致性检验只是检验拍脑门有没有自相矛盾得太离谱。

    相关的理论参考可见wiki百科

    二、代码实现

    需要借助Python的numpy矩阵运算包,代码最后用了一个b1矩阵进行了调试,相关代码如下,具体的实现流程已经用详细的注释标明,各位小伙伴有疑问的欢迎留言和我一起讨论。

    import numpy as np
    class AHP:
        """
        相关信息的传入和准备
        """
    
        def __init__(self, array):
            ## 记录矩阵相关信息
            self.array = array
            ## 记录矩阵大小
            self.n = array.shape[0]
            # 初始化RI值,用于一致性检验
            self.RI_list = [0, 0, 0.52, 0.89, 1.12, 1.26, 1.36, 1.41, 1.46, 1.49, 1.52, 1.54, 1.56, 1.58,
                            1.59]
            # 矩阵的特征值和特征向量
            self.eig_val, self.eig_vector = np.linalg.eig(self.array)
            # 矩阵的最大特征值
            self.max_eig_val = np.max(self.eig_val)
            # 矩阵最大特征值对应的特征向量
            self.max_eig_vector = self.eig_vector[:, np.argmax(self.eig_val)].real
            # 矩阵的一致性指标CI
            self.CI_val = (self.max_eig_val - self.n) / (self.n - 1)
            # 矩阵的一致性比例CR
            self.CR_val = self.CI_val / (self.RI_list[self.n - 1])
    
        """
        一致性判断
        """
    
        def test_consist(self):
            # 打印矩阵的一致性指标CI和一致性比例CR
            print("判断矩阵的CI值为:" + str(self.CI_val))
            print("判断矩阵的CR值为:" + str(self.CR_val))
            # 进行一致性检验判断
            if self.n == 2:  # 当只有两个子因素的情况
                print("仅包含两个子因素,不存在一致性问题")
            else:
                if self.CR_val < 0.1:  # CR值小于0.1,可以通过一致性检验
                    print("判断矩阵的CR值为" + str(self.CR_val) + ",通过一致性检验")
                    return True
                else:  # CR值大于0.1, 一致性检验不通过
                    print("判断矩阵的CR值为" + str(self.CR_val) + "未通过一致性检验")
                    return False
    
        """
        算术平均法求权重
        """
    
        def cal_weight_by_arithmetic_method(self):
            # 求矩阵的每列的和
            col_sum = np.sum(self.array, axis=0)
            # 将判断矩阵按照列归一化
            array_normed = self.array / col_sum
            # 计算权重向量
            array_weight = np.sum(array_normed, axis=1) / self.n
            # 打印权重向量
            print("算术平均法计算得到的权重向量为:\n", array_weight)
            # 返回权重向量的值
            return array_weight
    
        """
        几何平均法求权重
        """
    
        def cal_weight__by_geometric_method(self):
            # 求矩阵的每列的积
            col_product = np.product(self.array, axis=0)
            # 将得到的积向量的每个分量进行开n次方
            array_power = np.power(col_product, 1 / self.n)
            # 将列向量归一化
            array_weight = array_power / np.sum(array_power)
            # 打印权重向量
            print("几何平均法计算得到的权重向量为:\n", array_weight)
            # 返回权重向量的值
            return array_weight
    
        """
        特征值法求权重
        """
    
        def cal_weight__by_eigenvalue_method(self):
            # 将矩阵最大特征值对应的特征向量进行归一化处理就得到了权重
            array_weight = self.max_eig_vector / np.sum(self.max_eig_vector)
            # 打印权重向量
            print("特征值法计算得到的权重向量为:\n", array_weight)
            # 返回权重向量的值
            return array_weight
    
    
    if __name__ == "__main__":
        # 给出判断矩阵
        b = np.array([[1, 1 / 3, 1 / 8], [3, 1, 1 / 3], [8, 3, 1]])
    
        # 算术平均法求权重
        weight1 = AHP(b).cal_weight_by_arithmetic_method()
        # 几何平均法求权重
        weight2 = AHP(b).cal_weight__by_geometric_method()
        # 特征值法求权重
        weight3 = AHP(b).cal_weight__by_eigenvalue_method()
    
    
    
    展开全文
  • BP-AHP算法的MATLAB实现

    2009-12-08 21:08:25
    在做项目时做的,给了我不少帮助,里边是基于AHP的BP网络,代码有详细解释
  • 网络上有十分专业的ahp算法分析软件,其结构类似于SPSS,不管是输入还是输出都十分规范,过程中用到的矩阵明明白白,但唯一的缺点就是,想使用这个软件必须得亲手建立矩阵,而生活中没有谁会因为要做一个简单的决策...

    开发背景:

    ahp 又名层次分析法,是一个多因素多层次的决策算法。为了将层次分析算法的流程简易化,将算法的作用生活化,于是我在一个夜深人静的晚上准备抽空做这个软件。网络上有十分专业的ahp算法分析软件,其结构类似于SPSS,不管是输入还是输出都十分规范,过程中用到的矩阵明明白白,但唯一的缺点就是,想使用这个软件必须得亲手建立矩阵,而生活中没有谁会因为要做一个简单的决策去写枯燥的矩阵,去学习层次分析,因此我用python的tkinter做GUI,以点击的方式,自动为用户生成多个选择框,无需频繁构建矩阵。

    开发工具:

    编程语言:python,所用模块:tkinter,matplotlib,numpy,PIL,seaborn。操作系统:windows。

    算法简介:

    层次分析法(Analytic Hierarchy Process,简称AHP)是美国运筹学家、匹兹堡大学T. L. Saaty教授在20世纪70年代初期提出的, AHP是对定性问题进行定量分析的一种简便、灵活而又实用的多准则决策方法。它的特点是把复杂问题中的各种因素通过划分为相互联系的有序层次,使之条理化,根据对一定客观现实的主观判断结构(主要是两两比较)把专家意见和分析者的客观判断结果直接而有效地结合起来,将一层次元素两两比较的重要性进行定量描述。而后,利用数学方法计算反映每一层次元素的相对重要性次序的权值,通过所有层次之间的总排序计算所有元素的相对权重并进行排序。该方法自1982年被介绍到我国以来,以其定性分析定量分析相结合地处理各种决策因素的特点,以及其系统灵活简洁的优点,迅速地在我国社会经济各个领域内,如能源系统分析、城市规划、经济管理、科研评价等,得到了广泛的重视和应用。

    实现方法:

    层次分析法(ahp)需要输入两个层次,分别为方案层,准则层。最终返回一个层次,目标层。

    为了不麻烦用户去输入矩阵,而是通过简单的选择我们后台帮助用户补全矩阵,仔细观察ahp算法中的方案层和准则层,他们实际上都是对称矩阵,只需要得到‘一半’的矩阵,后续用python实现它的对称即可,而这‘一半’的矩阵,又都是两两因素层的因素,或者准则层的准则的比值,这一点完全可以靠多个选择题来收集数据。

    得到数据后,将其加工成准则层和方案层的矩阵,按照ahp算法的流程:建立层次结构模型,构造比较判别矩阵,计算单排序向量和一致性检测,总的排序选优。这部分我写了完整的分析流程。

    import numpy as np
    
    class Ahp_method(object):
        def __init__(self,array_rule,list_item):
            if array_rule.shape[0] != array_rule.shape[1]:
                raise Exception('你的准则层矩阵不够方')
            for i in list_item:
                if i.shape[0] != i.shape[1]:
                    raise Exception('你的方案层某矩阵不够方')
    
            self._array_rule = array_rule  # 准则层矩阵
            self._lsit_item = list_item  # 包含多个方案层矩阵的列表
            self._character : float  # 最大特征值
            self._dr : int  = self._array_rule.shape[0]  # 准则层层矩阵的维度
            self._di : int  # 方案层矩阵的维度
            self.CI : float  # 一致性指标
            self.CR : float  # 一致性比率
            self.CR_RULE = [0,0,0,0.58,0.90,1.12,1.26,1.32,1.41,1.45,1.49,1.52,1.54]
    
        def get_character(self):
            '''计算特征值'''
            self._character = np.round(max(np.linalg.eig(self._array_rule)[0]),3)
            return self._character
    
        def get_CI(self):
            self.CI = (self._character - self._dr) / (self._dr - 1)
            return  self.CI
    
        def get_CR(self):
            self.CR = self.get_CI()/self.CR_RULE[self._dr]
            return self.CR
    
        @staticmethod
        def get_ar(lst):
            '''
            输入一维列表, 返回转换成对称矩阵后的维度
            :param lst:
            :return:n:维度
            '''
            l,v,d = len(lst),1,1
            while True:
                if v == l:
                    return d + 1
                if v > l:
                    raise Exception('传入的矩阵存在错误')
                v += d + 1
                d += 1
    
        @staticmethod
        def ret_np(ori, roun:int=3):
            '''
            :param ori:ret value()返回的字典
            :param n: 维度
            :return: array
            '''
            n = Ahp_method.get_ar(ori)
            lst, res = [], []
            for v in ori:
                lst.append(v)
            ind = 0
            for i in range(n):
                inner = []
                for j in range(n):
                    if i == j:
                        inner.append(1)
                    elif i < j:
                        inner.append(lst[ind])
                        ind += 1
                    elif i > j:
                        inner.append(round(1 / res[j][i], roun))
                res.append(inner)
            return np.array(res)
    
        def get_one(self,array):
            '''得到某个矩阵的标准化特征向量'''
            d = array.shape[0]
            lst_root = []
            for i in range(d):
                lst_root.append(Ahp_method.multi(array[i])**(1/d))  # 每行乘积的d次方根
            lst_sum = sum(lst_root)
            final = np.array([np.round(i/lst_sum,3) for i in lst_root])
            print('final',final)
            return final
    
        @staticmethod
        def multi(n):
            result = 1
            for i in n:
                result = result * i
            return result
    
        def check(self):
            '''准则层向量的一致性检验'''
            self.get_character()
            cr = self.get_CR()
            if not cr < 0.1:
                return 0,f'未通过一致性检验,检验结果为{self.CR}>0.1'
            else:
                return 1,f'一致性检验结果为{self.CR},小于0.1'
    
        '''得到所有矩阵的标准化特征向量'''
        def get_all(self):
            self._array_rule_character = self.get_one(self._array_rule)
            self._list_item_character = []
            for i in range(len(self._lsit_item[0][0])):
                buf = []
                for j in [self.get_one(i) for i in self._lsit_item]:
                    buf.append(j[i])
                self._list_item_character.append(np.array(buf[:]))
                buf.clear()
    
    
        def get_final(self):
            '''最终排序权值'''
            self.res = [i.dot(self._array_rule_character.T) for i in self._list_item_character]
            return self.res
    
        def process(self):
            print(self.check())
            self.get_all()
            return self.get_final()

    这一部分依靠numpy库可以轻松实现,numpy不只支持数组,它更支持矩阵,求逆,求特征向量,求矩阵运算都有十分强大的api,此处不做赘述。

    得到总的排序选优结果后,用matplotlib+seaborn实现柱状图的显示和结果的美化,将输出的结果储存到本地,用tkinter打开,优化用户体验。(其实用户就是我,就我自己用。。。)

    细节回顾:

    整个流程看起来非常简单,在我第一天做这东西的时候,我预计是一个晚上做完,由于这个原因,我就当他是个小demo,根本没准备维护他,或者想到要解耦,架构什么的更没有想到,所以就是一口气顺着往下写,再加上tkinter不是非常专业的GUI工具,前后端分离性较差,写着写着就有了屎山代码的味儿,尽管我第一天是各种注释各种写class封装。

    然后悲剧来了,有时候遇到小麻烦不说,主要变量不好找,才七百行的代码就分了仨文件,硬着头皮给他干完了。

    在写这个小软件的过程中也有些珍贵的东西:

    1.循环中为容器添加多参数的匿名函数函数名,容易出现bug。见第一篇博

    2.pyinstaller打包exe,在其他操作系统运行时,程序中matplotlib用到的字体找不到,这个的解决方法是直接将自己做图表用到的字体复制到根目录,用相对路径的方式导入字体。

    3.其他操作系统或电脑打开该GUI布局错乱,解决方法:统一布局方式,不要将pack布局和place混合使用。

    4.在其他计算机运行时,tkinter中的字体丢失,目前没找到办法,是个bug。

    5.tkinter真滴就自己玩玩好,真想写个让自己心情舒畅的东西,还是用web好。

    6.tkinter和matplotlib不大对付,他俩一同时出来好像就要打架,解决方法当然是matplotlib先存储,然后用tkinter打开存储的图片。

    软件使用方法:

    1.打开抉择.exe。

     2.进入首页,run。

     3.点击箭头选择准则层数量。

     4.填写准则层内容(此处我选择的是对书籍的挑选标准,假如我准备买书关心的是这三个准则),点击NEXT。

    5.填写方案层,此处略。

    6.按要求填写,按照你的两层输入,系统自动生成一些问题 ,回答后得到结果(此处为准则层的问题),如图,左边为准则层的益处和有趣,你更偏向哪个?就点击哪个,距离中间越远的按钮,表示程度越深,一般不要点击太深,因为这是按照ahp 的标度尺13579做的按钮,一般点蓝色或者淡蓝色即可,除非你梵蒂冈要和美国比GDP,你可点击红色。图中第三行的1/12表示一共有十二个问题,现在是第一个问题。

     7.等待进度条,numpy计算起来有多快肯定不用我说,做这个的意义,懂得都懂,嘿嘿,就是好看。tkinter不能直接展示gif,不过可以用canvas容器,PIL打开图像,将其迭代器打开,放在画布里循环展示图片。

    8.结果如下,按图中来说哆啦A梦是这三本里最适合我的图书了,不过摸着良心说话,我偏袒它了。

    9.一致性比率:小于0.1即为可信,通过一致性检验,他的意义就是,用户输入的数据并不自相矛盾。上图中未通过一致性比率, 是因为我在输入准则层数据的时候做了一个自相矛盾的选择,比如a>b,b>c,但是当比较a和c的时候,我选择了a<c,这样会导致一定程度的不可信,但结局确实比较符合我的心里预期,如果非给我看着三本书,我首选是看会哆啦A梦,然后是数据挖掘,最后是三国演义。

    10.额外功能,换肤。

    总结:

    这是一个python开发,核心算法为ahp,主要价值为简化用户输入,将算法日常化的exe软件,Windows和Ubuntu的平台都可以使用,缺点是在不同的环境中可能出现字体丢失,布局轻微变形的情况,但不影响功能的使用。目前简易实现ahp算法的sdk以及具体资源准备在CSDN上传,过审可能要几天,粗略估计应该只有我一个人会用它,不过我觉得这个东西还是很有意义的。最起码我不用因为选择困难症发愁了。

    PS:完整代码就不发了, 因为没有完整解耦的缘故,整个流程看起来会比较枯燥。再简单的项目,都不能想着一口气写完,不然麻烦大大滴。

    展开全文
  • 层次分析法 一个实现 AHP 多标准方法的 Java 库。
  • AHP算法MATLAB代码

    千次阅读 2020-04-04 00:01:54
    我把AHP算法代码写到博客里面方便B站的朋友参考,也放了B站对这个代码使用的视频,不会用的可以点开链接去看,然后1P是原理视频大家也可以看看,免费拿走使用的时候,别忘了关注点赞评论一下博客和B站up鸭谢谢!
  • 用Matlab实现AHP算法1.MATLAB的基本内容MATLAB(MATrix LABoratory,矩阵实验室的缩写)是一种特殊用途的计算机程序优化执行工程和科学计算。它开始为旨在执行矩阵数学程式的生活,但多年来它已发展成为一个灵活的...
  • 层次分析法(AHP算法简介

    千次阅读 2021-11-01 14:13:23
    层次分析法(AHP)是美国运筹学家萨蒂于上世纪70年代初,为美国国防部研究“根据各个工业部门对国家福利的贡献大小而进行电力分配”课题时,应用网络系统理论和多目标综合评价方法,提出的一种层次权重决策分析方法...
  • 用Matlab实现AHP算法

    2021-04-23 09:27:32
    用Matlab实现AHP算法 1.MATLAB的基本内容 MATLAB(MATrix LABoratory,矩阵实验室的缩写)是一种特殊用途的计算机程序优化执行工程和科学计算。它开始为旨在执行矩阵数学程式的生活,但多年来它已发展成为一个灵活...
  • ahp算法matlab实现

    2011-08-09 19:44:13
    使用matlab实现基于层次分析(aph)算法
  • 使用Python语言实现AHP算法,运行代码需预先安装numpy包,Python3以上版本
  • 使用Matlab实现AHP算法

    千次阅读 2013-02-01 16:42:39
    clc,clear  fid=fopen('txt3.txt','r');  n1=6;n2=3;  a=[];  for i=1:n1  tmp=str2num(fgetl(fid));  a=[a;tmp]; %读准则层判断矩阵 end  for i=1:n1  str1=char(['b',int2str...str2=char(['b',
  • 数学建模常用算法—层次分析法(AHP)

    千次阅读 2020-07-12 16:08:33
    优点 AHP的主要特点是通过建立递阶层次结构,把人类的判断转化到若干因 素两两之间重要度的比较上,从而把难于量化的定性判断转化为可操作的重 要度的比较上面。在许多情况下,决策者可以直接使用AHP进行决策,极大...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,063
精华内容 425
关键字:

ahp算法

友情链接: 鼠标自动点击器.rar