Optimization 如何表示二元关系

Optimization 如何表示二元关系,optimization,data-structures,poset,Optimization,Data Structures,Poset,我计划创建一个表示严格偏序集的类,并且我假设建模其接口的最自然的方法是作为二进制关系。这将提供如下功能: bool test(elementA, elementB); //return true if elementA < elementB void set(elementA, elementB); //declare that elementA < elementB void clear(elementA, elementB); //forget that elementA <

我计划创建一个表示严格偏序集的类,并且我假设建模其接口的最自然的方法是作为二进制关系。这将提供如下功能:

bool test(elementA, elementB); //return true if elementA < elementB
void set(elementA, elementB); //declare that elementA < elementB
void clear(elementA, elementB); //forget that elementA < elementB
void applyTransitivity(); //if test(a,b) and test(b, c), then set(a, c)
bool checkIrreflexivity(); //return true if for no a, a < a
bool checkAsymmetry(); //return true if for no a and b, a < b and b < a
bool测试(elementA,elementB)//如果elementA
可能的功能如下:

bool test(elementA, elementB); //return true if elementA < elementB
void set(elementA, elementB); //declare that elementA < elementB
void clear(elementA, elementB); //forget that elementA < elementB
void applyTransitivity(); //if test(a,b) and test(b, c), then set(a, c)
bool checkIrreflexivity(); //return true if for no a, a < a
bool checkAsymmetry(); //return true if for no a and b, a < b and b < a
void applyTransitivity()//如果测试(a,b)和测试(b,c),则设置(a,c)
bool-checkireflexicity()//如果没有a,a
简单的实现是有一个配对列表,这样(a,b)表示atest将是线性时间。也许作为列表的哈希映射更好


然而,理想情况下,内存中的表示本质上会强制
applyTransitivity
始终“有效”,并且不允许创建导致反射性或对称性的边。换句话说,数据结构的自由度表示严格偏序集的自由度。有没有一种已知的方法可以做到这一点?或者,更现实地说,是否有一种方法可以检查是否具有周期性,并在每次调用
set
clear
时分期和迭代保持传递性,从而降低执行正确性的成本。有可行的实施方案吗?

好的,让我们来谈谈实现裸机刮削的微效率,你可以选择你想进入的深渊有多深。在这个架构级别上,没有像哈希映射和列表这样的数据结构,甚至没有数据类型,只有内存中的位和字节

另外,通过查看DAG的常用表示法,您还可以在此处找到许多有关表示法的信息。然而,大多数普通销售代表的设计更多的是为了方便,而不是为了提高效率

这里,我们希望
a
的数据与邻接数据融合到单个内存块中。因此,您希望将与
a
相关的项的“列表”存储在
a的
自己的内存块中,这样我们就可以在单个缓存行中访问
a
和与
a
相关的所有元素(如果这些相关元素可能也适合于同一缓存线,则会获得额外的分数,但这是一个NP难问题)

您可以通过将32位索引存储在
a
中来实现这一点。如果我们将级别提高一点,并使用C作为示例,我们可以像这样对此类对象进行建模:

struct Node
{
    // node data
    ...
    int links[]; // variable-length struct
};
这使得
节点
成为一个可变长度的结构,其大小甚至地址都可能发生变化,因此我们需要额外的间接级别来获得稳定性并避免失效,例如索引的索引(如果您控制内存分配器/数组,并且它是纯连续的),或指针的索引(或某些语言中的引用)

这使得您的测试函数仍然涉及线性时间搜索,但与
a
相关的元素数量呈线性关系,而不是与元素总数呈线性关系。因为我们使用了可变长度结构,
a
及其相邻索引可能适合单个缓存线,并且
a
很可能会我已经在缓存中了,只是为了进行查询

这与您的哈希映射存储列表的基本思想类似,但没有列表开销的爆炸,也没有哈希查找(这可能是固定时间,但速度不如从同一内存块访问到
a
的连接).最重要的是,它对缓存的友好程度要高得多,这通常会在几个周期和数百个周期之间产生差异

现在,这意味着您仍然需要卷起袖子,自己检查循环之类的事情。如果您想要一个更直接、更方便地建模问题的数据结构,您会发现图形数据结构更适合于围绕有向边的形式化旋转。然而,这些比e更方便效率高

如果您需要容器是通用的,并且<代码> A<代码>可以是任何给定的类型T,那么您就可以总是用C++(现在使用C++)包装它:

模板
结构体类型
{
T节点_数据;
int links[1];//VLS,不一定实际存储1个元素
};
并且仍然将这一切都融合到一个内存块中。我们需要新的放置来保存C++对象语义,并可能关注这里的对齐。

可传递性检查总是涉及某种类型的搜索(广度优先或深度优先)。我认为没有任何代表可以避免这种情况,除非您想要记忆/缓存潜在的大量可传递数据


在这一点上,如果你想深入深渊,找到一个很难维护和理解的解决方案,你应该拥有一些非常快的东西。不幸的是,我发现这并不像拥有一辆速度非常快的汽车那样让女士们印象深刻,但它可以让你的软件运行得非常非常非常快。

我喜欢将事情保持在较低水平以提高缓存性能的想法。我希望读操作比写操作更常见,因此我认为我还将在混合中添加二进制搜索以获得额外的魅力。