1

我有一个非常特殊的问题,很难将其分解为几行代码和几句话,但我会尝试这样做。我目前正在开发一种用于实时优化过程工厂警报的软件。每次出现新警报时,软件都会从服务器接收新警报。其中几个警报具有相同的根本原因,我的软件会分析这些警报并将它们分组(如果它们彼此相关)。我的问题是将新警报与旧警报进行比较。我将旧警报存储在一个全局列表中,并在它们出现时将新警报附加到此列表中。必须分析新警报是否可以与其自身和旧警报分组。旧警报无需再次重新组合。例如,我有三个旧的 (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 个工作小时,但该软件仍然只是比较彼此之间的新警报,而不是将其链接到旧警报。分组算法有几页长,我试图尽可能地分解它。如果有人能给我一个建议,我做错了什么,我会很高兴,因为我对这个问题很生气。这是我第一次真正被困在这个项目中,并且我正在为这个软件编程三个多月。

亲切的问候拉里莫

4

2 回答 2

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

两者的区别在于,内部循环只查看组,但从不主动与其他新项目进行比较,但如果发现未分组到现有组的 Item ,它会得到一个新组,并且 NEXT警报将与旧组一起与该新组进行比较。效果相同,算法略有不同。

于 2012-08-01T21:01:02.353 回答
0

我不完全理解你的算法。我会用一个

Dictionary<ALARM_ITEM, HashSet<ALARM_ITEM>>

作为数据结构,其中值是事件组,键是每个组的代表。当一个新的警报a到达时,算法将是

  1. 对于每个键k,检查是否ak
    • 如果是这样,将其添加到存储在的哈希集中k并中断
  2. 否则,创建一个values包含 just的新哈希集a,并添加(a, values)到字典中

换句话说,您将警报组存储在一个字典中,其键是组的“代表”警报。要添加新警报,您只需将其与代表性警报进行比较。


这假设 ifabbc然后ac。如果不是这种情况,则不一定有一致的方式对警报进行分组。如果是这种情况,那么分组关系是等价的,因此算法将起作用。

于 2012-08-01T17:04:27.997 回答