按间隔有效索引对象的结构

时间:2017-10-22 11:47:41

标签: algorithm go data-structures

我目前正在玩CRF-ish工作的一些想法,我知道我需要帮助。

最小问题

我有一堆功能对象(想想像神经网一样昂贵的东西)。它们被应用到线性缓冲区(想象一个float s或byte s的数组)但是以不同的间隔。所以它们看起来像那样(将开始和结束视为"将对象应用于buf[Start:End]":

| Object | Start | End |
|--------|-------|-----|
| A      | 0     | 4   |
| B      | 4     | 10  |
| C      | 13    | 15  |

区间特征

  • 可能会有一些跳过(例如,请参阅C的开头与B的结尾)
  • 肯定会有间隔的变化,包括正面或负面(例如,B可能会从[4:10]更改为[4:12]
  • 发生这种情况时,可能必须重新应用与间隔关联的对象。
  • 如果间隔更改与另一个间隔重叠,则必须重新应用这两个对象。例如,如果B从[4:10]更改为[3:12],则必须将A应用于范围[0:3],并且必须将B应用于范围[3:12]
  • 根据操作,还必须更新下游间隔,但不一定必须重新应用对象。例如,如果是插入更改了B的间隔范围,则C的间隔范围也将增加2,但不会触发重新应用C.

计划特征

  • 间隔变化很大(它是机器学习训练循环)。
  • 支持的间隔更新形式有:insert,delete,shiftleft,shiftright。后两者与插入/删除相同,但应用于间隔的末尾。
  • 对间隔的更改通常以元组(索引和大小)或单个索引的形式出现。
  • 功能的应用是相当昂贵的操作并且受CPU限制。
  • 然而,由于我正在使用Go,一些互斥量+ goroutine解决了大部分问题(有一些更好的点,但大量的swarths可以忽略)。
  • 一个纪元可以有5-60个间隔 - 对象对。
  • 缓冲区是线性的,但不一定是连续的。

任务

任务可归纳如下:

  1. 按索引查询:返回间隔和与间隔相关联的对象
  2. 更新间隔:必要时还必须更新下游(这是大多数情况)
  3. 插入新的间隔:还必须更新下游
  4. 我尝试过什么

    • 以间隔作为关键字映射。这是一个坏主意,因为我必须知道某个给定的索引是否在一个区间内
    • 跟踪开始的线性结构。当我意识到可能会跳过时,立即发现了一个错误。
    • 带有"孔的线性结构"跟踪开始。事实证明这与绳索相似。
    • 绳索和跳过列表。结束重构我对skiprope包适用于字符串的内容。更多牦牛剃须。耶。
    • 间隔/细分树。实施是一个婊子。我还尝试了gods/augmentedtree的具体变体,但实际上无法使呼叫支持正常工作以进行评估。

    问题

    是否有任何我错过的良好数据结构会使这些任务变得更容易?

    我错过了一些非常明显的事情吗?

    一位朋友建议我查找增量编译方法,因为它类似。使用的类比是Roslyn将以远程方式解析/重新分析文本片段。这与我的问题非常相似 - 只需使用令牌的线性缓冲区替换浮点数的线性缓冲区。

    问题是我无法找到关于Roslyn如何做到这一点的任何有用信息。

1 个答案:

答案 0 :(得分:1)

此解决方案的内存效率并不高,但如果我理解正确,它应该允许相对简单地实现您想要的功能。

  1. 保留所有函数对象的数组或切片funcs,以便它们各自具有规范整数索引,并且可以通过该索引查找。

  2. 保留一小部分整数s,它与浮动缓冲区的大小始终相同;它将缓冲区中的特定索引映射到函数片中的“函数索引”。您可以使用-1表示不属于任何间隔的数字。

  3. 保留一对(int,int)对intervals,使intervals[i]包含存储在funcs[i]的函数的起始端索引。

    < / LI>

    我相信这可以让您实现所需的功能而不会有太多麻烦。例如,要按索引i进行查询,请查找s[i],然后返回funcs[s[i]]intervals[s[i]]。当缓冲区发生更改时,也请更改s,在sintervals切片之间进行交叉引用,以确定相邻的时间间隔是否受到影响。我很乐意更详细地解释这一部分,但我并不完全理解间隔更新的要求。 (当您执行间隔插入时,它是否对应于底层缓冲区中的插入?或者您只是更改哪些缓冲区元素与哪些函数相关联?在这种情况下,插入是否会在下一个间隔开始时导致删除?大多数方案应该有效,但它会改变程序。)