我将不胜感激帮助下一个多重容器调试一些奇怪的行为。偶尔,集装箱似乎停止排序。这是一个罕见的错误,只有一些模拟明显的时间长了以后,我就短想法。 (我是一个业余程序员 - 各类建议,欢迎。)

我的容器是保持std::multiset结构一个Event

typedef std::multiset< Event, std::less< Event > > EventPQ;

Event结构排序可以通过double time成员:

struct Event {

 public:
explicit Event(double t) : time(t), eventID(), hostID(), s() {}
Event(double t, int eid, int hid, int stype) : time(t), eventID( eid ), hostID( hid ), s(stype) {}

  bool operator < ( const Event & rhs ) const {
    return ( time < rhs.time );
  }

  double time;
  ...
};

在程序通过添加具有无序次事件EventPQ currentEvents然后为了脱下事件期间迭代。很少,一些事件已被添加(与完全“合法”次)之后,事件开始得到的顺序执行的。

什么可以使事件永远不会得到正确排序? (或者什么可能搞乱了迭代器?)我已经检查了所有添加的事件时间是合法的(即,均超过当前的仿真时间),我也已经证实,不会因为两个事件发生的错误恰巧获得计划在同一时间。

我喜欢上建议,就如何通过这项工作。

用于执行和添加事件代码是下面的好奇:

  double t = 0.0;
  double nextTimeStep = t + EPID_DELTA_T;
  EventPQ::iterator eventIter = currentEvents.begin();

while ( t < EPID_SIM_LENGTH ) {

     // Add some events to currentEvents

     while ( ( *eventIter ).time < nextTimeStep ) { 

         Event thisEvent = *eventIter;
     t = thisEvent.time;
     executeEvent( thisEvent );
     eventCtr++;
     currentEvents.erase( eventIter );
     eventIter = currentEvents.begin();

  }

  t = nextTimeStep;
  nextTimeStep += EPID_DELTA_T;
}


void Simulation::addEvent( double et, int eid, int hid, int s ) {
  assert( currentEvents.find( Event(et) ) == currentEvents.end() );

  Event thisEvent( et, eid, hid, s ); 
  currentEvents.insert( thisEvent );
}

我要补充的是偶尔的事件,当被执行时,将删除从currentEvents其他事件。这是通过完成

double oldRecTime = 10.0; // gets defined legitimately in simulation
EventPQ::iterator epqItr = currentEvents.find( Event(oldRecTime) );
assert( currentEvents.count( Event(oldRecTime) ) == 1 );
currentEvents.erase( epqItr );

即使这个代码看起来还好,我想知道其他的方式我可以检查这是怎么回事 - I'm目前使用了大量的断言()和cout <<检查

有帮助吗?

解决方案 3

在该模拟中,在那里我有评论

// Add some events to currentEvents

事件被添加到进行中...。 (希望这是明确的。)如果添加一个事件,发生在队列的顶部属于,我相信它搞砸了迭代器指向currentEvents.begin()。我的内心,而循环之前重置迭代器,事情似乎工作。

我会更新这个问题,如果这个结果并非是解决办法,或者有其他问题,我这里有。

由于所有这些谁评论;它可以帮助我了解我应该如何接近这些问题。

其他提示

您事件处理周期未能检查队列是否为空。否则,一切都看起来不错(或多或少)。

但是,如果你在你的currentEvents队列中的事件的冒了出来,这种行为是未定义。很可能它自身表现为某物的显示为事件正被处理的顺序进行。

事实上,关联容器我看到“大致圆形”的数据结构来表示它们,在一定意义上的一些实现,如果你忽视了控制序列的末尾,继续迭代,你的迭代器将出现在的开始序列。难道像你的情况是怎么回事?

另一个问题立即出现在你的代码连接:如果新的事件到来到队列与time值比“当前”时间的情况下,会发生什么?我不认为这会捕捉你的代码这种情况下,任何检查。显然,如果出现这种情况,即如果一些事件到达“为时已晚”,他们可能很容易得到的顺序处理了,无论你如何实现它。

如果可能的话,我建议改变你使用的一个关键某种整数类型,而不是double。用于setmultiset密钥需要严格的弱序 - 和double确实的(通常)满足该要求(也没有任何其它IEEE浮点型)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top