Critic赋值法-权重设计算法

http://www.doc88.com/p-4082292004105.html

这篇文章中提到了这个算法,大部分没有问题,最终结果好像有问题。


这里的j应该从0开始。

最终正确的值是:

0.12428049575680716 0.18122064375975747 0.36197534555846139 0.12500118965834886 0.20752232526662504

https://wenku.baidu.com/view/835a6a6baef8941ea76e05eb.html

这是另外一篇关于此算法的。我用程序验证没有问题。


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CRITIC
{
    public partial class Form1 : Form
    {
        private DataTable dt;
        private double[] m_fcs;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            dt = new DataTable();
            dt.Columns.Add("ZS",typeof(double));
            dt.Columns.Add("FY", typeof(double));
            dt.Columns.Add("YQ", typeof(double));
            dt.Columns.Add("ZU", typeof(double));
            dt.Columns.Add("SW", typeof(double));

            m_fcs = new double[dt.Columns.Count];

            var dr1 = dt.NewRow();
            dr1.ItemArray = new object[] {0.4830,13.2682,0,4.3646,5.1070 };
            //dr1.ItemArray = new object[] { 23.2,30.5,25.4,22.2,19.2 };
            dt.Rows.Add(dr1);

            var dr2 = dt.NewRow();
            dr2.ItemArray = new object[] { 0.4035, 13.4909, 39.0131, 3.6151, 5.5005 };
            //dr2.ItemArray = new object[] {25.7,32.5,27.3,24.1,20.2 };
            dt.Rows.Add(dr2);

            var dr3 = dt.NewRow();
            dr3.ItemArray = new object[] { 0.8979, 25.7776, 9.0513, 4.8920, 7.5342 };
            //dr3.ItemArray = new object[] { 25.8,30.2,27.1,22.9,20.7 };
            dt.Rows.Add(dr3);

            var dr4 = dt.NewRow();
            dr4.ItemArray = new object[] { 0.5927, 16.0245, 13.2935, 4.4529, 6.5913 };
            //dr4.ItemArray = new object[] { 24.4,32.2,26.5,22.7,18.6 };
            dt.Rows.Add(dr4);

            /*var dr5 = dt.NewRow();
            dr5.ItemArray = new object[] { 0.5927, 16.0245, 13.2935, 4.4529, 6.5913 };
            dr5.ItemArray = new object[] { 25.4, 33, 25.9, 23.9, 17.9 };
            dt.Rows.Add(dr5);*/

            this.dataGridView1.DataSource = dt;
            this.dataGridView1.Refresh();


            GetNormalize(dt, 0, true);
            GetNormalize(dt, 1, true);
            GetNormalize(dt, 2, false);
            GetNormalize(dt, 3, true);
            GetNormalize(dt, 4, true);
            //GetNormalize(dt);
            this.dataGridView1.Refresh();

            for (int i = 0; i < m_fcs.Length; i++)
            {
                var t = GetColumnData(dt, i);
                m_fcs[i] = GetVariance(t);
            }
        }

        private double[] GetColumnData(DataTable dt, int columnIndex)
        {
            double[] t = new double[dt.Rows.Count];
            for (var i = 0; i < t.Length; i++)
            {
                t[i] = (double)dt.Rows[i][columnIndex];
            }
            return t;
        }
        private double[] GetRowData(DataTable dt, int rowIndex,bool round=false)
        {
            double[] t = new double[dt.Columns.Count];
            for (var i = 0; i < t.Length; i++)
            {
                t[i] = (double)dt.Rows[rowIndex][i];
                if (round)
                    t[i] = Math.Round(t[i], 2);
            }
            return t;
        }

        #region 标准化
        private void GetNormalize(DataTable dt, int columnIndex, bool maxIsBetter)
        {
            var t = GetColumnData(dt, columnIndex);
            double max = t.Max();
            double min = t.Min();
            if (maxIsBetter)
            {
                for (var i = 0; i < t.Length; i++)
                {
                    t[i] = (t[i] - min) / (max - min);
                }
            }
            else
            {
                for (var i = 0; i < t.Length; i++)
                {
                    t[i] = (max - t[i]) / (max - min);
                }
            }
            for (var i = 0; i < t.Length; i++)
            {
                dt.Rows[i][columnIndex] = t[i];
            }
        }
        private void GetNormalize(DataTable dt)
        {
            for (var i = 0; i < dt.Columns.Count; i++)
            {
                var t = GetColumnData(dt, i);
                double max = t.Max();
                for (var j = 0; j < t.Length; j++)
                {
                    dt.Rows[j][i] = t[j] / max;
                }
            }
        }
        #endregion

        private double ComputeRelationship(DataTable dt, int column1, int column2)
        {
            double sum1 = 0;
            double sum2 = 0;
            for (var i = 0; i < dt.Rows.Count; i++)
            {
                sum1 += (double)dt.Rows[i][column1];
                sum2 += (double)dt.Rows[i][column2];
            }
            sum1 /= dt.Rows.Count;
            sum2 /= dt.Rows.Count;

            double top1 = 0;
            double btn1 = 0;
            double btn2 = 0;
            for (var i = 0; i < dt.Rows.Count; i++)
            {
                var t1= (double)dt.Rows[i][column1];
                var t2= (double)dt.Rows[i][column2];
                top1 += (t1 - sum1)*(t2 - sum2);
                btn1 += (t1 - sum1) * (t1 - sum1);
                btn2 += (t2 - sum2) * (t2 - sum2);
            }
            return top1  / Math.Sqrt(btn1 * btn2);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            DataTable dt1 = this.dataGridView1.DataSource as DataTable;
            var dt2 = new DataTable();
            for (var i = 0; i < dt1.Columns.Count; i++)
            {
                dt2.Columns.Add("T" + i, typeof(double));
            }
            for (var i = 0; i < dt1.Columns.Count; i++)
            {
                dt2.Rows.Add(dt2.NewRow());
            }
            for (var i = 0; i < dt.Columns.Count; i++)
            {
                dt2.Rows[i][i] = 1;
                for (var j = i + 1; j < dt.Columns.Count; j++)
                {
                    dt2.Rows[j][i] = dt2.Rows[i][j] = ComputeRelationship(dt1, i, j);
                }
            }

            int rountCount = dt2.Columns.Count;
            double[] rowSum = new double[rountCount];
            for (var i = 0; i < rountCount; i++)
            {
                double[] items1 = GetRowData(dt2, i);
                var sum = GetSum(items1);
                rowSum[i] = (dt2.Columns.Count - sum) * m_fcs[i];
            }
            double allSum = GetSum(rowSum);
            var dr = dt2.NewRow();
            object[] items = new object[rountCount];
            //double[] finalValue = new double[] {0.12191,0.16497,0.38126,0.13543,0.19683 };
            for (var i = 0; i < dt2.Columns.Count; i++)
            {
                items[i] = rowSum[i] / allSum;
                //finalValue[i] = (rowSum[i] / allSum) / finalValue[i];
            }
            dr.ItemArray = items;
            dt2.Rows.Add(dr);

            this.dataGridView2.DataSource = dt2;
            this.dataGridView2.Refresh();
        }
        private double GetSum(double[] value)
        {
            double sum = 0;
            for (var i = 0; i < value.Length; i++)
                sum += value[i];
            return sum;
        }
        private double GetVariance(double[] values)
        {
            double fc = 0;
            double sumValue = 0;
            for (var i = 0; i < values.Length; i++)
            {
                fc += values[i] * values[i];
                sumValue += values[i];
            }
            sumValue = sumValue / values.Length;
            double t1 = fc - values.Length * sumValue * sumValue;

            return Math.Sqrt(t1 / (values.Length-1));
        }

    }
}


你可能感兴趣的:(算法)