java 实现 AHP

自己测试,误差很小

package com.shuzhi.ahp;

import java.math.BigDecimal;
import java.util.Arrays;

public class AHPComputeWeight {
    /**
     * @param args
     */
    public static void main(String[] args) {
        /** a为N*N矩阵 */
        double[][] a = new double[][] {
                /*{1.00,5.00,3.00},
                {0.20,1.00,0.33},
                {0.33,3.00,1.00}*/
                //{7.00, 0.14, 3.00,1.00 }

                {1.00,0.33,0.20,0.33},
                {3.00,1.00,0.33,1.00},
                {5.00,3.00,1.00,3.00},
                {3.00,1.00,0.33,1.00}

        };
        int N = a[0].length;
        double[] weight = new double[N];
        AHPComputeWeight instance = AHPComputeWeight.getInstance();
        instance.weight(a, weight, N);
        System.out.println(Arrays.toString(weight));

    }

    // 单例
    private static final AHPComputeWeight acw = new AHPComputeWeight();

    // 平均随机一致性指针
    private double[] RI = { 0.00, 0.00, 0.58, 0.90, 1.12, 1.21, 1.32, 1.41,
            1.45, 1.49 };

    // 随机一致性比率
    private double CR = 0.0;

    // 最大特征值
    private double lamta = 0.0;

    /**
     * 私有构造
     */
    private AHPComputeWeight() {

    }

    /**
     * 返回单例
     *
     * @return
     */
    public static AHPComputeWeight getInstance() {
        return acw;
    }

    /**
     * 计算权重
     *
     * @param a
     * @param weight
     * @param N
     */
    public void weight(double[][] a, double[] weight, int N) {
        // 初始向量Wk
        double[] w0 = new double[N];
        for (int i = 0; i < N; i++) {
            w0[i] = 1.0 / N;
        }

        // 一般向量W(k+1)
        double[] w1 = new double[N];

        // W(k+1)的归一化向量
        double[] w2 = new double[N];

        double sum = 1.0;

        double d = 1.0;

        // 误差
        double delt = 0.00001;

        while (d > delt) {
            d = 0.0;
            sum = 0;

            // 获取向量
            //int index = 0;
            for (int j = 0; j < N; j++) {
                double t = 0.0;
                for (int l = 0; l < N; l++)
                    t += a[j][l] * w0[l];
                // w1[j] = a[j][0] * w0[0] + a[j][1] * w0[1] + a[j][2] * w0[2];
                w1[j] = t;
                sum += w1[j];
            }

            // 向量归一化
            for (int k = 0; k < N; k++) {
                w2[k] = w1[k] / sum;

                // 最大差值
                d = Math.max(Math.abs(w2[k] - w0[k]), d);

                // 用于下次迭代使用
                w0[k] = w2[k];
            }
        }

        // 计算矩阵最大特征值lamta,CI,RI
        lamta = 0.0;

        for (int k = 0; k < N; k++) {
            lamta += w1[k] / (N * w0[k]);
        }

        double CI = (lamta - N) / (N - 1);

        if (RI[N - 1] != 0) {
            CR = CI / RI[N - 1];
        }

        // 四舍五入处理
        lamta = round(lamta, 3);
        CI = round(CI, 3);
        CR = round(CR, 3);

        for (int i = 0; i < N; i++) {
            w0[i] = round(w0[i], 4);
            w1[i] = round(w1[i], 4);
            w2[i] = round(w2[i], 4);
        }
        // 控制台打印输出

        System.out.println("lamta=" + lamta);
        System.out.println("CI=" + CI);
        System.out.println("CR=" + CR);

        // 控制台打印权重
        System.out.println("w0[]=");
        for (int i = 0; i < N; i++) {
            System.out.print(w0[i] + " ");
        }
        System.out.println("");

        System.out.println("w1[]=");
        for (int i = 0; i < N; i++) {
            System.out.print(w1[i] + " ");
        }
        System.out.println("");

        System.out.println("w2[]=");
        for (int i = 0; i < N; i++) {
            weight[i] = w2[i];
            System.out.print(w2[i] + " ");
        }
        System.out.println("");
    }

    /**
     * 四舍五入
     *
     * @param v
     * @param scale
     * @return
     */
    public double round(double v, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b = new BigDecimal(Double.toString(v));
        BigDecimal one = new BigDecimal("1");
        return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 返回随机一致性比率
     *
     * @return
     */
    public  double getCR() {
        return CR;
    }
}

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AHP(层次分析法)是一种多层次决策方法,用于在多个选项之间进行决策。以下是使用Java实现AHP算法的一些步骤: 1. 定义标准矩阵,即将不同的决策因素分为等级,并确定它们之间的相对权重。 例如,我们可以使用二维数组来表示标准矩阵。假设我们有3个因素A、B、C,其A对于B、C的相对重要性为2:1,而B对于C的相对重要性为3:1,则标准矩阵可以表示为: double[][] matrix = { {1.0, 2.0, 1.0/3.0}, {0.5, 1.0, 1.0/3.0}, {3.0, 3.0, 1.0} }; 2. 计算矩阵的一致性指标和随机一致性指标。AHP要求矩阵必须满足一致性,否则无法得到可靠的结果。计算矩阵一致性的方法是计算一致性指标CI,以及与随机一致性指标CR进行比较。 例如,我们可以使用下面的代码来计算矩阵的一致性指标: double[] weights = AHP.calculateWeights(matrix); double ci = AHP.calculateCI(matrix, weights); double cr = AHP.calculateCR(matrix); 3. 根据计算出来的权重,进行决策。 例如,我们可以使用下面的代码来获取权重,然后使用它们来进行决策: double[] weights = AHP.calculateWeights(matrix); int bestOptionIndex = AHP.getBestOptionIndex(weights); 其,getBestOptionIndex方法返回具有最高权重的选项的索引。 下面是完整的AHP实现示例代码: ```java import java.util.Arrays; public class AHP { public static void main(String[] args) { double[][] matrix = { {1.0, 2.0, 1.0/3.0}, {0.5, 1.0, 1.0/3.0}, {3.0, 3.0, 1.0} }; double[] weights = calculateWeights(matrix); System.out.println("Weights: " + Arrays.toString(weights)); int bestOptionIndex = getBestOptionIndex(weights); System.out.println("Best option index: " + bestOptionIndex); } public static double[] calculateWeights(double[][] matrix) { int n = matrix.length; double[] weights = new double[n]; for (int j = 0; j < n; j++) { double sum = 0.0; for (int i = 0; i < n; i++) { sum += matrix[i][j]; } double columnSum = 0.0; for (int i = 0; i < n; i++) { matrix[i][j] /= sum; columnSum += matrix[i][j];

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值