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));
}
}
}