我在想一个命名约定,准确地表达我正在设计的课程内正在进行的操作。在次要记录中,我试图在两个几乎相同的用户API之间做出决定。可翻转数据结构的模式名称?
这里的情况:
我建立一个科学的应用,其中中心数据结构的一个有三个阶段:1)的积累,2)分析,和3)查询执行。
在我的情况下,它是一个空间建模结构,内部使用KDTree在三维空间中划分点集合。每个点描述周围环境的一个或多个属性,对测量本身具有一定的置信度。
在向集合添加(可能大量的)测量之后,对象的所有者将查询它以获得适用字段内某个新数据点处的插值测量。
的API会是这个样子(代码是在Java中,但是这并不重要;代码分为三个部分,为清楚起见):
// SECTION 1:
// Create the aggregation object, and get the zillion objects to insert...
ContinuousScalarField field = new ContinuousScalarField();
Collection<Measurement> measurements = getMeasurementsFromSomewhere();
// SECTION 2:
// Add all of the zillion objects to the aggregation object...
// Each measurement contains its xyz location, the quantity being measured,
// and a numeric value for the measurement. For example, something like
// "68 degrees F, plus or minus 0.5, at point 1.23, 2.34, 3.45"
foreach (Measurement m : measurements) {
field.add(m);
}
// SECTION 3:
// Now the user wants to ask the model questions about the interpolated
// state of the model. For example, "what's the interpolated temperature
// at point (3, 4, 5)
Point3d p = new Point3d(3, 4, 5);
Measurement result = field.interpolateAt(p);
对于我的特定问题领域,它将可能在第2节中执行少量的增量工作(将点分割成平衡的KD树)。
并且在第3节中会出现少量工作(执行一些线性插值)。
但是,有一个巨大的工作量(构建内核密度估计和执行快速高斯变换,利用泰勒级数和埃尔米特功能,但这是完全跑题了)必须执行和3 之间部分2
有时过去,我只是使用lazy-evaluation来构造数据结构(在这种情况下,它将在第一次调用“interpolateAt”方法时使用),但如果用户调用“字段”。再次添加()“方法,我必须完全放弃这些数据结构并从头开始。
在其他项目中,我要求用户显式调用“object.flip()”方法,从“append mode”切换到“query mode”。这样设计的好处在于,用户可以更好地控制硬核计算开始时的确切时刻。但对于API消费者来说,跟踪对象的当前模式可能是一件令人讨厌的事情。此外,在标准用例中,调用者在开始发出查询后从不向该集合添加另一个值;数据聚合几乎总是完全在查询准备之前。
你们是如何处理像这样的数据结构设计的?
你喜欢让一个对象懒洋洋地执行它的重载分析,当新数据进入集合时抛弃中间数据结构吗?或者你是否要求程序员显式地将数据结构从追加模式转换为查询模式?
你知道这样的对象的任何命名约定吗?有没有我没有想到的模式?
上编辑:
似乎有关于我在示例中使用的类,命名为“ContinuousScalarField”一些困惑和好奇。
您可以通过阅读这些维基百科页面得到什么,我谈论的是一个不错的主意:
比方说,你想创建一个地形图(这不是我确切的问题,但它在概念上非常相似)。因此,您需要在一平方英里范围内进行一千次高度测量,但您的测量设备的海拔正负10米误差。
一旦你收集了所有的数据点,你喂他们进入不仅插值值的模式,但也考虑到每次测量的误差。
提请地形图,您查询您要画一个像素的每个点的高程模型。
至于单一类是否应该负责这两个追加和处理查询的问题,我不是100%肯定,但我认为是这样。
下面是一个类似的例子:HashMap和TreeMap类允许添加和查询对象。没有单独的接口用于添加和查询。
两个类也类似于我的例子中,因为内部数据结构具有以支持查询机制在持续的基础上得以维持。 HashMap类必须定期分配新内存,重新散列所有对象,并将对象从旧内存移动到新内存。 TreeMap必须使用红黑树数据结构持续保持树平衡。
唯一的区别是,我的类将表现最佳,如果它可以执行所有的计算,一旦知道数据集被关闭。
计算需要多长时间?你期望多少查询?当用户查询时,您不能保存(缓存)这些中间结果吗? – Newtopian 2008-10-29 18:37:55
你可以改变“可翻转” - 它几乎没有意义 - 并称之为“有状态”或更有意义的东西? – 2008-10-29 18:56:54
你对地图的比喻可能会误导你。HashMap和TreeMap背后算法的目标是在每次修改之后,结构处于查询的最佳状态。在你的情况下,你不想在每次mod之后完全优化你的结构,对吗? – erickson 2008-10-29 19:14:34