上篇说明了原理,这篇就直接上核心代码了~
代码比较长,所以理解可能有点麻烦,核心思路就是计算选择的维度后遍历数据,逐步进行循环计算置信度,并淘汰每次循环后的最低值。
这里有一点要注意的,我一开始想用arraylist构造一个堆栈结构进行数据遍历的存储跟计算,因为这样效率比较高。。
但是后来发现,那么做的话,如果以后想要对类型跟因子的种类、数量进行修改的话,需要对代码进行大量重构才能实现功能的更新,而对于我朋友这样的代码苦手来说估计跟写天书差不多。。于是在实现的时候我放弃了部分效率,将每个类型单独设置一个数据表,然后每个表写入该类型所有的因子,最后通过在数据库读取这些表的形式进行数据的遍历计算。这样的话,后期想要更改类型跟因子,可以通过直接在数据库修改的方式进行处理,代码也不需要大改了。
(=。= 没办法额,毕竟不是每个人都会写代码的。。。)
namespace FManage
{
public partial class Analy : Form
{
private System.Windows.Forms.CheckBox[] checkBoxFactors;
private DataSet ds;
private int[] rowTables;
private int[] flag;
private int[] dimention;
private int[] fee;
private int p;
public Analy()
{
InitializeComponent();
this.panel1.SuspendLayout();
this.SuspendLayout();
//数据加载过程略
this.checkBoxFactors = new System.Windows.Forms.CheckBox[6];
//设置要素选择项
for (int i = 0; i < 6; i++)
{
this.checkBoxFactors[i] = new System.Windows.Forms.CheckBox();
this.checkBoxFactors[i].AutoSize = true;
this.checkBoxFactors[i].Location = new System.Drawing.Point(90 + i % 3 * 150, 28 + (int)Math.Floor(Convert.ToDouble(i / 3) * 40));
this.checkBoxFactors[i].Size = new System.Drawing.Size(84, 16);
this.checkBoxFactors[i].TabIndex = i + 1;
this.checkBoxFactors[i].UseVisualStyleBackColor = true;
this.panel1.Controls.Add(this.checkBoxFactors[i]);
}
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
private void Analy_Load(object sender, EventArgs e)
{
rowTables = new int[8];
for (int i = 0; i < 8; i++)
{
rowTables[i] = ds.Tables[i].Rows.Count;
}
dimention = new int[8];
for (int i = 0; i < 8; i++)
{
dimention[i] = ds.Tables[i].Rows.Count;
}
}
//计算选择维度
private void countfee(ref int[] fee)
{
int p;
for (int i = 0; i < dimention[7]; i++)
{
p = 0;
for (int j = 0; j < 7; j++)
{
if (flag[j] == 1)
fee[i] += System.Convert.ToInt32(ds.Tables[7].Rows[i].ItemArray[j + 1]) * (int)Math.Pow(10, p++);
}
}
}
private void CircleString(int a, int end, ref string[] finalString, ref int[] needle, string[][] tempString)
{
for (int i = 0; i < tempString[a].Length; i++)
{
needle[a] = i;
if (a == end - 1)
{
for (int j = 0; j < end; j++)
{
finalString[p++] = tempString[j][needle[j]];
}
}
else
{
CircleString(a + 1, end, ref finalString, ref needle, tempString);
}
}
}
private void CircleCalculationString(int a, int end, ref string[] finalCalculation, ref int[] needleCalculation, string[][] tempCalculation)
{
for (int i = 0; i < tempCalculation[a].Length; i++)
{
needleCalculation[a] = i;
if (a == end - 1)
{
for (int j = 0; j < end; j++)
{
finalCalculation[p++] = tempCalculation[j][needleCalculation[j]];
}
}
else
{
CircleCalculationString(a + 1, end, ref finalCalculation, ref needleCalculation, tempCalculation);
}
}
}
//计算支持度和置信度
private void buttonCalculate_Click(object sender, EventArgs e)
{
double zhichiduNumber = Convert.ToDouble(rank1.Text) / 100;
double zhixinduNumber = Convert.ToDouble(rank2.Text) / 100;
fee = new int[dimention[7]];
flag = new int[7];
flag[0] = 1;
for (int i = 0; i < 6; i++)
{
if (this.checkBoxFactors[i].Checked)
flag[i + 1] = 1;
else
flag[i + 1] = 0;
}
countfee(ref fee);
#region ShowString
string[][] tempString = new string[flag.Sum() - 1][];
int temp = 0;
for (int i = 0; i < flag.Sum() - 1; i++)
{
do { temp++; if (temp == 7)break; } while (flag[temp] == 0);
tempString[i] = new string[dimention[temp]];
for (int j = 0; j < dimention[temp]; j++)
{
tempString[i][j] = ds.Tables[temp].Rows[j].ItemArray[1].ToString();
}
}
int[] needleString = new int[flag.Sum() - 1];
for (int i = 0; i < flag.Sum() - 1; i++)
{
needleString[i] = 0;
}
int finalNumber = 1;
for (int i = 1; i < 7; i++)
{
if (flag[i] == 1)
finalNumber *= ds.Tables[i].Rows.Count;
}
DataTable showTable = new DataTable("showTable");
DataColumn finalCol = showTable.Columns.Add("ID", typeof(Int32));
finalCol.AllowDBNull = false;
finalCol.Unique = true;
for (int i = 1; i < 7; i++)
{
if (flag[i] == 1)
showTable.Columns.Add(ds.Tables[7].Columns[i + 1].ColumnName, typeof(String));
}
showTable.Columns.Add("支持度(%)", typeof(double));
showTable.Columns.Add("置信度(%)", typeof(double));
string[] showString = new string[finalNumber * (flag.Sum() - 1)];
p = 0;
CircleString(0, flag.Sum() - 1, ref showString, ref needleString, tempString);
DataRow showRow;
p = 0;
for (int i = 0; i < finalNumber; i++)
{
showRow = showTable.NewRow();
showRow[0] = i + 1;
for (int j = 0; j < flag.Sum() - 1; j++)
{
showRow[j + 1] = showString[p++];
}
showRow[flag.Sum()] = 0;
showRow[flag.Sum() + 1] = 0;
showTable.Rows.Add(showRow);
}
#endregion
#region Calculation
string[][] tempCalculation = new string[flag.Sum()][];
temp = 0;
for (int i = 0; i < flag.Sum(); i++)
{
tempCalculation[i] = new string[dimention[temp]];
for (int j = 0; j < dimention[temp]; j++)
{
tempCalculation[i][j] = ds.Tables[temp].Rows[j].ItemArray[0].ToString();
}
do { temp++; if (temp == 7)break; } while (flag[temp] == 0);
}
int[] needleCalculation = new int[flag.Sum()];
for (int i = 0; i < flag.Sum(); i++)
{
needleCalculation[i] = 0;
}
finalNumber = 1;
for (int i = 0; i < 7; i++)
{
if (flag[i] == 1)
finalNumber *= ds.Tables[i].Rows.Count;
}
DataTable calculationTable = new DataTable("calculationTable");
for (int i = 0; i < 7; i++)
{
if (flag[i] == 1)
calculationTable.Columns.Add(ds.Tables[7].Columns[i + 1].ColumnName, typeof(String));
}
string[] finalCalculation = new string[finalNumber * flag.Sum()];
p = 0;
CircleCalculationString(0, flag.Sum(), ref finalCalculation, ref needleCalculation, tempCalculation);
DataRow calculationRow;
p = 0;
for (int i = 0; i < finalNumber; i++)
{
calculationRow = calculationTable.NewRow();
for (int j = 0; j < flag.Sum(); j++)
{
calculationRow[j] = finalCalculation[p++];
}
calculationTable.Rows.Add(calculationRow);
}
#endregion
int[] objectiveFee = new int[finalNumber];
for (int i = 0; i < finalNumber; i++)
{
for (int j = 0; j < flag.Sum(); j++)
{
objectiveFee[i] += System.Convert.ToInt32(calculationTable.Rows[i].ItemArray[j]) * (int)Math.Pow(10, j);
}
}
double[,] times = new double[3, finalNumber / 2];
for (int i = 0; i < finalNumber / 2; i++)
{
for (int j = 0; j < dimention[7]; j++)
{
if (objectiveFee[i] == fee[j])
times[0, i]++;
}
}
for (int i = finalNumber / 2; i < finalNumber; i++)
{
for (int j = 0; j < dimention[7]; j++)
{
if (objectiveFee[i] == fee[j])
times[1, i - finalNumber / 2]++;
}
}
for (int i = 0; i < finalNumber / 2; i++)
{
times[2, i] = times[0, i] + times[1, i];
}
double[] zhichidu = new double[finalNumber / 2];
for (int i = 0; i < finalNumber / 2; i++)
{
zhichidu[i] = times[2, i] / 1000.0;
}
double[] zhixindu = new double[finalNumber / 2];
for (int i = 0; i < finalNumber / 2; i++)
{
if (times[2, i] > 0)
{
zhixindu[i] = ((int)(times[0, i] / times[2, i] * 10000)) / 10000.0;
}
else
zhixindu[i] = 0;
}
for (int i = 0; i < finalNumber / 2; i++)
{
showTable.Rows[i][flag.Sum()] = zhichidu[i];
showTable.Rows[i][flag.Sum() + 1] = zhixindu[i];
}
for (int i = 0; i < showTable.Rows.Count; i++)
{
showTable.Rows[i][0] = i + 1;
showTable.Rows[i][flag.Sum()] = (int)(Convert.ToDouble(showTable.Rows[i][flag.Sum()]) * 1000) / 10.0;
showTable.Rows[i][flag.Sum() + 1] = (int)(Convert.ToDouble(showTable.Rows[i][flag.Sum() + 1]) * 1000) / 10.0;
}
this.dataGridView1.DataSource = null;
this.dataGridView1.DataSource = showTable.DefaultView;
this.dataGridView1.Visible = true;
}
}
}