【问题标题】:Sorting Items by a Cyclical Sequence Number按循环序列号排序项目
【发布时间】:2012-02-24 10:14:38
【问题描述】:

我正在开发一种算法来重新排序传输中的数据包。每个数据包在 [0, 256) 中都有一个关联的序列号。第一个数据包的序列号可以取其中任何一个值,之后下一个数据包取下一个值,下一个数据包取其后的值,依此类推(在 255 之后翻转)。

数据包的序列号,按照正确的顺序,如下所示,其中“n”是第一个数据包的序列号:

n, n+1, n+2, ..., 254, 255, 0, 1, 2, ..., 254, 255, 0, 1, 2, ..., 254, 255, 0 , 1, ...

每个数据包到达其目的地时都会被赋予一个时间戳,并且它们都大致按顺序到达。 (我没有确切的数字,但给定一个按到达时间戳排序的数据包列表,可以肯定地说,一个数据包与其在列表中由其序列号指示的位置相距不超过五个位置。)

鉴于电信的普及及其对计算机科学发展的历史重要性,我觉得我不可能是第一个处理此类问题的人。那么我的问题是:

  1. 在给定一个循环变化的密钥的情况下,是否有一种众所周知的算法可以重新排序近似有序的序列(例如上述算法)?

  2. 此算法是否有一种变体可以容忍大块的缺失项?让我们假设这些块可以是任意长度。我特别担心丢失 256 件或更多的物品。

我对第一个算法有一些想法,但对第二个没有。然而,在我投入工时来验证我的算法是否正确之前,我想确保贝尔实验室(或其他任何地方)的某个人在 30 年前还没有做得更好。

【问题讨论】:

    标签: algorithm sorting language-agnostic telecommunication


    【解决方案1】:

    我不知道这个解决方案是否真的在任何地方使用,但这是我会尝试的(假设没有丢失数据包,最多“改组”五个位置,最大序列号为 255):

    n = 0;
    max_heap h = empty;
    while( true ) do
      while( h.top().index != 0 ) do
        p = next_packet;
        i = n - p.seq;
        if( i > 0 ) i = i - 255;
        h.add( i, p );
      done
    
      p = h.pop();
      n = n + 1;
      p.increase_indexes( 1 );
      // Do something with it
    done
    

    基本上,在优先级队列中,我们存储了在最后处理的数据包和仍在等待处理的数据包之间有多少数据包。队列将保持非常小,因为数据包在进入时会尽快处理。此外,增加键也非常简单,因为不需要对堆进行重新排序。

    我不确定您如何适应丢失的数据包。最有可能通过使用一些超时或最大偏移量,然后将数据包声明为“下一个”并相应地更新堆。

    但是,如果您错过超过 256 个数据包,我认为这个问题根本不可能发生。取子序列

    127,130,128,129
    

    这可能有多种原因

    1) 数据包 128 和 129 出现故障,应重新排序

    2)丢包128和129,然后丢253包,所以顺序正确

    3) 1 和 2 的混合

    【讨论】:

    • 如果我们不能保证第一个数据包的序列号(我相信在您的示例中为n)为0,您将如何做出规定?在最坏的情况下:如果数据包 255 先发送,但数据包 0 和 1 先到达会怎样?
    • 嗯,不确定。实际上,根据我的经验,我认为这个问题并不常见。通常序列号要大得多来解释这一点。我在序列号中见过这么低的东西的唯一地方是连接的 gsm-sms,它高达 255 AFAIK。然而,在包装之前,这是每个发送者 256 条短信,即使有不同的编码,也允许在连接的短信中使用更大的序列号。一些协议甚至具有全局唯一 ID。选择这么小的范围的原因是什么?
    • 长话短说,序列号从来都不是用来重建传输的。数据最初是通过短串行电缆传输的。序列号主要是一个调试工具和完整性检查。然后,突然之间,项目需求发生了变化,但这个功能早就被冻结了。我想如果我检查特定的数据集并且可以表征平均传输速率(我怀疑它接近每秒
    【解决方案2】:

    有趣的问题!

    我的解决方案是根据到达时间对数据包进行排序,并根据数据包编号在本地循环排序一个元素窗口(比如 10)。您可以通过多种方式对此进行细化。如果两个连续的数据包编号(根据到达时间排列)之间的差异大于某个阈值,您可能会在它们之间设置障碍(即您不能跨障碍排序)。此外,如果数据包之间的时间差(根据到达时间排列)大于某个阈值,您可能需要设置障碍(这应该可以解决问题 2)。

    【讨论】:

      【解决方案3】:

      使用优先队列。

      每次收到每个数据包后:

      • 将其放入队列中。
      • 重复删除队列的顶部元素,只要它是您正在等待的元素。

      第二个问题:

      • 一般来说,不,没有办法解决。
      • 如果数据包到达有一定的周期性(例如:期望每20ms有一个数据包),那么您可以轻松检测到这一点,清理队列,在收到5个数据包后,您将知道如何再次处理......

      【讨论】:

      • 澄清:1)我应该使用什么作为优先级队列中的键? 2) 我怎么知道哪个数据包应该先来?
      • a) 您可以使用序列号,在这种情况下,您必须以循环方式进行比较...(255
      猜你喜欢
      • 2016-04-12
      • 1970-01-01
      • 2018-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-25
      • 2018-08-22
      相关资源
      最近更新 更多