我有一个非常特殊的问题,很难将其分解为几行代码和几句话,但我会尝试这样做。 我目前正在研究一种用于过程工厂中的警报的实时优化的软件。每次出现新警报时,软件都会从服务器接收新警报。其中一些警报具有相同的根本原因,我的软件会分析这些警报并将它们分组,如果它们彼此相关。 我的问题是将新警报与旧警报进行比较。我将旧警报存储在全局列表中,并在出现时将新警报附加到此列表中。 必须分析新警报是否可以与自己和旧警报分组。旧警报不需要再次重新组合。 作为一个例子,我有三个旧(o)警报和三个新警报(n)。 该列表看起来像o1 o2 o3 n1 n2 n3。现在必须将n1与o1,o2,o3,n2和n3进行比较。 n2必须与o1,o2,o3和n3进行比较,依此类推。
我使用以下代码执行此操作:
List<ALARM_ITEM> puffer = new List<ALARM_ITEM>();
puffer.AddRange(localOldAlarmList);
puffer.AddRange(localNewAlarmList);
localMergedList = puffer;
int mainListCounter = localOldAlarmList.Count;
for (; mainListCounter < localMergedList.Count; mainListCounter++)
{
/*if there are new elements just these elemnts will be used as static items*/
ALARM_ITEM staticAlarmItem = localMergedList[mainListCounter];
for (int j = -1; j <= 1; j += 2)
{
if (j < 0)
counterRunner = localOldAlarmListLength - 1;
else
counterRunner = mainListCounter + 1;
//Check against any ALARM_ITEM in timeframe
bool inTimeframe = true;
while (inTimeframe)
{
if ((counterRunner >= localMergedList.Count) || (counterRunner) < 0)
break;
ALARM_ITEM groupCandidate = new ALARM_ITEM();
groupCandidate = localMergedList[counterRunner];
//... several if clauses
MergeTwoAlarmGroups(staticAlarmItem, groupCandidate);
if (j < 0)
counterRunner -= 1;
else
counterRunner += 1;
}
}
}
现在我该怎么说...我现在修改了这个方法大约36个工作小时,但软件只是比较彼此之间的新警报,并没有将它与旧警报联系起来。分组算法有几页长,我试图尽可能地将其分解。如果有人能给我一个建议我做错了什么我会很高兴因为我对这个问题感到生气。这是我第一次真正陷入这个项目,而且我正在编写这个软件超过三个月。
亲切的问候 Larimow
答案 0 :(得分:1)
好的......让我们看看我是否可以尝试一下,其中大部分将是伪代码,所以这里是:
List listOfAllAlarms //a specific subset contianing a representative instance of EACH old alarm GROUP!!, and the new alarms
List listOfNewAlarms //Only the new alarms
foreach (alarm a in listOfNewAlarms)
{
foreach (alarm b in listOfAllAlarms)
{
if (a.Equals(b))
continue;
Group = //compare a and b
if (Group != null) //new group
//Assign a to group b
}
}
重要的一点是两组,以及你循环它们的方式。在外部列表中,您只能查看最新的警报。在内部列表中,您将与全局警报集进行比较。我实际上更喜欢将新警报保留在分组集之外,但我确实理解您可能会在所有属于一个组的新警报列表中结束多个警报,但它不是已存在的组。如果你可以将它们分开,我会更喜欢这样做:
List listOfAlarmGroups //a specific subset contianing a representative instance of only the already existing old alarm groups
List listOfNewAlarms //Only the new alarms
foreach (alarm a in listOfNewAlarms)
{
Group G = null;//set -> ReSet G
foreach (alarm b in listOfAlarmGroups)
{
G = //compare a and b
if (G != null)
break;//found the group
}
if (G != null)
//assign a to group G
else
{
//create new group for a
//add new group to listOfAlarmGroups
}
}
两者之间的区别在于内部循环仅查看组,但从不主动与其他新项目进行比较,但如果找到的项目未分组到现有组,则会获得一个新组, NEXT警报将与旧组进行比较。效果相同,算法略有不同。
答案 1 :(得分:0)
我不完全理解你的算法。我会用
Dictionary<ALARM_ITEM, HashSet<ALARM_ITEM>>
作为数据结构,其中值是事件组,键是每个组的代表。当新警报a
到达时,算法将
k
,检查a
是否与k
分组
k
并打破values
的新哈希集a
,并将(a, values)
添加到词典换句话说,您将警报组存储在一个字典中,其键是组的“代表性”警报。要添加新警报,您只需将其与代表警报进行比较。
这假定如果a
组b
和b
组合c
,则a
组合c
。如果不是这种情况,则不一定采用一致的方式对警报进行分组。如果是这种情况,则分组关系为equivalence,因此算法将起作用。