题
我将不胜感激帮助下一个多重容器调试一些奇怪的行为。偶尔,集装箱似乎停止排序。这是一个罕见的错误,只有一些模拟明显的时间长了以后,我就短想法。 (我是一个业余程序员 - 各类建议,欢迎。)
我的容器是保持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
。用于set
或multiset
密钥需要严格的弱序 - 和double
确实不的(通常)满足该要求(也没有任何其它IEEE浮点型)