1.故障树推理诊断项目中在故障树图形画好后要检查重复性,矛盾性和包含性。所以要把相同事件编号的节点进行推导,替换成最终只含与门,或门的表达式,即E1=A+B+C*D类似的形式。等价于数学算式中的只含有乘号和加好的最终表达式。
2.本文是比较两个表达式是否等价。比如a+b+c*d 与b+d*c+a等价(至于如何从故障树图形得到最终推导式不在此讨论)
3.首先是以加号来分割,将表达式分成不同的只含有乘号的子串,存入list中。下面代码中具体的函数参数,即是两个待比较的list
/// <summary>
/// 比较两个推导结果是否一样,比如a+b+c*d 与b+d*c+a
/// </summary>
/// <param name="thisDeduceId_list1">推导结果1</param>
/// <param name="thisDeduceId_list2">推导结果2</param>
/// <returns>相等返回true,不等返回false</returns>
private static bool compareTwoDeduce(List<string> thisDeduceId_list1, List<string> thisDeduceId_list2)//比较两个推导结果是否一样,比如a+b+c*d 与b+d*c+a
{
if (thisDeduceId_list1.Count != thisDeduceId_list2.Count)//长度不同,肯定是不同的推导
{
return false;
}
List<string> simple_list1 = new List<string>();//保存不带乘号的基本子元素,如A*B+C+D中的C,D
List<string> simple_list2 = new List<string>();//保存不带乘号的基本子元素,如A*B+C+D中的C,D
List<string> cheng_list1 = new List<string>();//保存带乘号的中间子元素,如A*B+C+D中的A*B
List<string> cheng_list2 = new List<string>();//保存带乘号的中间子元素,如A*B+C+D中的A*B
foreach (string st in thisDeduceId_list1)
{
if (st.Contains("*"))
{
cheng_list1.Add(st);
}
else
{
simple_list1.Add(st);
}
}
foreach (string st in thisDeduceId_list2)
{
if (st.Contains("*"))
{
cheng_list2.Add(st);
}
else
{
simple_list2.Add(st);
}
}
if (cheng_list1.Count != cheng_list2.Count || simple_list1.Count != simple_list2.Count)//长度不同,肯定是不同的推导
{
return false;
}
simple_list1.Sort();//排序
simple_list2.Sort();
if (!simple_list1.SequenceEqual(simple_list2))//排序后比较
{
return false;
}
List<string> sorted_cheng_list1 = new List<string>();//对cheng_list进行排序,然后保存在这个列表里。显示对每个子元素排序,例如A*C*B可能会排成A*B*C。然后对总体排序
List<string> sorted_cheng_list2 = new List<string>();
string[] temp;
foreach (string s in cheng_list1)
{
temp = s.Split('*');
Array.Sort(temp);//子元素例如(A*C*B)进行排序
string temStr = "";
foreach (string ss in temp)
{
temStr += ss;//排完序重新组合为一个string,中间的*号有没有都不影响比较,所以省略
}
sorted_cheng_list1.Add(temStr);
}
foreach (string s in cheng_list2)
{
temp = s.Split('*');
Array.Sort(temp);//子元素例如(A*C*B)进行排序
string temStr = "";
foreach (string ss in temp)
{
temStr += ss;//排完序重新组合为一个string,中间的*号有没有都不影响比较,所以省略
}
sorted_cheng_list2.Add(temStr);
}
sorted_cheng_list1.Sort();//对总体排序
sorted_cheng_list2.Sort();
if (!sorted_cheng_list1.SequenceEqual(sorted_cheng_list2))//排序后比较
{
return false;
}
return true;
}
在我的项目中具体判断是否有重复性,矛盾性,包含性处的调用代码如下:
if (compareTwoDeduce(thisDeduceCode_list1, thisDeduceCode_list2) == false)//比较两个推导结果是否相等
{
MessageBox.Show("出错!有矛盾性:事件" + event_list[i].event_code + "(" + event_list[i].event_dsc + ")推导出两个不同的结果", "请更正");
return -1;
}
else if (layer1 == layer2)//重复性
{
repeat++;
}
else//包含性
{
contain++;
}
还有
if (repeat >0 && contain>0)
{
DialogResult response2 = MessageBox.Show("出错!有重复性和包含性:事件"+repeatOrContainE_code+"这"+repeat+contain+"个事件都各自在不同位置推导出相同结果,但这并不影响诊断推理,您可以选择“是”继续执行,也可以选择“否”,返回修改", "请选择", MessageBoxButtons.YesNo,
MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
if (response2 == System.Windows.Forms.DialogResult.No)//选择了取消
{
return 0;//直接退出,不再执行后续语句
}
}
else if (repeat ==1 )
{
DialogResult response2 = MessageBox.Show("出错!有重复性:事件" + repeatOrContainE_code + "推导出相同结果,但这并不影响诊断推理,您可以选择“是”继续执行,也可以选择“否”,返回修改", "请选择", MessageBoxButtons.YesNo,
MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
if (response2 == System.Windows.Forms.DialogResult.No)//选择了取消
{
return 0;//直接退出,不再执行后续语句
}
}
else if (repeat > 1)
{
DialogResult response2 = MessageBox.Show("出错!有重复性:事件" + repeatOrContainE_code + "这" + repeat+"个事件都各自在不同位置推导出相同结果,但这并不影响诊断推理,您可以选“是”继续执行,也可以选择“否”,返回修改", "请选择", MessageBoxButtons.YesNo,
MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
if (response2 == System.Windows.Forms.DialogResult.No)//选择了取消
{
return 0;//直接退出,不再执行后续语句
}
}
else if (contain == 1)
{
DialogResult response2 = MessageBox.Show("出错!有重复性:事件" + repeatOrContainE_code + "推导出相同结果,但这并不影响诊断推理,您可以选择“是”继续执行,也可以选择“否”,返回修改", "请选择", MessageBoxButtons.YesNo,
MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
if (response2 == System.Windows.Forms.DialogResult.No)//选择了取消
{
return 0;//直接退出,不再执行后续语句
}
}
else if(contain>1)
{
DialogResult response2 = MessageBox.Show("出错!有重复性:事件" + repeatOrContainE_code + "这" + contain + "个事件都各自在不同位置推导出相同结果,但这并不影响诊断推理,您可以选“是”继续执行,也可以选择“否”,返回修改", "请选择", MessageBoxButtons.YesNo,
MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
if (response2 == System.Windows.Forms.DialogResult.No)//选择了取消
{
return 0;//直接退出,不再执行后续语句
}
}