【问题标题】:In Java, what collection is the most performant for a network of data?在 Java 中,对于数据网络来说,哪个集合的性能最高?
【发布时间】:2012-01-25 06:47:30
【问题描述】:

我有一个“实体”(对象)网络,每个都包含有关“下一个”(后续)实体是什么的信息,可以是从无到很多之间的任何内容。此外,“下一个”实体包含其“下一个实体”的信息(可以是全新的实体,也可以是刚刚链接到它的上一个实体)。

所以 A 知道 B 和 C 在哪里,B 知道 A、D 和 E 在哪里等等。注意 A 和 B 的双向方向。连接的数量和方向没有限制。

如果我必须经常(数千次)搜索实体,那么模拟这种网络的最佳(最高性能)集合是什么?如果我搜索的是字符串而不是对象,那么最好的集合是什么?这有什么不同吗?任何其他类型的实体会更快吗?

谢谢大家!

编辑:我要做的是在网络/图表中保存大量“记忆”(模拟中的历史事件),然后搜索某个记忆并跟踪与它的邻居和邻居的邻居等等,寻找符合我搜索模式的记忆“组合”。例如,我正在验证实体“A、B、C 和 A”是否按此顺序存在。

【问题讨论】:

  • 就图论而言,您希望在图上执行什么样的操作? (找到 2 个节点之间的路径?连接的组件?如果 2 个节点连接.. 等等)
  • 嗯...实际上完全不同的操作。我希望能够搜索某个节点(使用它的名称/键),然后转到它的直接邻居(“nextEntity”)及其邻居的邻居。当我这样做时,我必须检查节点之间的“距离”,这很可能是附加到每个节点具有的“邻居”列表的属性。广告我还想比较节点的属性。问题是,它不是最终结束的“树”,因为节点之间的关系允许圆圈 - 节点 A 和 B 可以双向连接,没有父子关系。
  • 尝试使用 Map> 将节点映射到其子节点。或者,您可以在 Node 类中使用带有 List 子级的 Node。然后你就可以对它们进行各种操作了。

标签: java performance collections neural-network


【解决方案1】:

就目前而言,您的问题相当模糊。如果您能以某种方式为您的搜索词定义一个“关键字”,您可以使用HashMap 数据结构(在java.util 中)作为一个非常快速的查找表。

最坏的情况是您必须使用深度优先搜索 (DFS) 或广度优先搜索 (BFS) 来搜索整个网络(技术术语是“图”)。

【讨论】:

  • 我要做的是在网络/图中保存大量的“记忆”(模拟中的历史事件),然后搜索某个记忆并按照连接到它的邻居和邻居的邻居等等,寻找符合我搜索模式的记忆“组合”。例如,我正在验证实体“A、B、C 和 A”是否按此顺序存在。
  • “广度优先”意味着我有某种树集合,但我没有“父子”关系。圈子是可能的。
  • 不,您可以在任何类型的图上进行 BFS,而不仅仅是在树上:en.wikipedia.org/wiki/Breadth-first_search
【解决方案2】:

怎么样:

Map<Entity, List<Entity>>

?

地图存储实体本身以及所有后继者(下一个和/或上一个)的列表。使用键访问映射值总是 O(1),这意味着在恒定时间内访问元素(它不依赖于映射中存储了多少元素)

如果您有实体应按特殊顺序(位置)放置的约束,这种方法肯定行不通。

【讨论】:

  • 但这是否意味着我将每个实体存储了多次(一次在地图中,然后在不同的列表中多次)?
  • 您将只存储对对象的引用(因此分配了堆栈上的内存)。对象本身只在堆上存储一次。
  • 太好了,我试试这个!谢谢!
【解决方案3】:

您是否需要搜索实体本身?如果是这样,作为一般解决方案,您可以创建一个 HashMap,其中键为与您的搜索条件相对应的类。实体将是一个值。

如果您要添加有关搜索的更多信息,则可以提出更充分的解决方案。

Ex1:实体具有数字属性,搜索条件是当属性 > 特定阈值时 - RBTReeMap 将是解决方案。

Ex2:您正在搜索实体序列 - 可以考虑使用图形搜索算法。

Ex3:您的实体结构与 FSA(有限状态自动机)非常相似。在这种情况下 - 此处的搜索是通过输入语言(而不是实体本身)完成的。解决方案是最小化自动机并使其具有确定性。

【讨论】:

  • 我只搜索一个实体,然后检查从那个实体开始的实体序列。图搜索算法听起来很有趣。
【解决方案4】:

我会专注于实体是什么,并为此定义一个类。如果您需要查找实体,只需在创建时将其注册到地图中即可。

类似这样的:

public class Entity {
    static Map<String, Entity> map = new HashMap<String, Entity>();

    String id;
    Set<Entity> nextEntities = new HashSet<Entity>();
    Set<Entity> prevEntities = new HashSet<Entity>();

    public Entity (String id) {
        this.id = id;
        map.put(id, this);
    }

    public static forId(String id) {
        return map.get(id);
    }
}

【讨论】:

  • 问题是,我没有任何“起始位置”,我首先需要搜索一个实体以从每次开始。这就是算法必须快速移动的地方。所以我正在寻找对象“xyz”,然后检查它的邻居和它的邻居的邻居等。
  • 谢谢,这看起来不错,我试试看。 “Map”比 tskuzzy 提出的“HashMap”快吗?
  • Map 只是一个由HashMap 实现的接口。但是波西米亚忘记初始化map:static Map&lt;String, Entity&gt; map = new HashMap&lt;String, Entity&gt;();
  • @hage 我没有“忘记”初始化它。我故意省略了它,就像我省略了 getter 和 setter 一样。我在这里交流课程设计——我只包含了与答案直接相关的代码。但如果这很重要,那很好 - 我已经更新了答案
  • @Bohemian 这没什么大不了的。我只是想澄清一下,因为你已经初始化了 nextEntitiesprevEntities
【解决方案5】:

在我看来,这听起来好像您遇到了“图形”类型的问题。也许您可以使用 neo4j (http://neo4j.org/) 来表示您的关系,然后使用它的 API 进行搜索?

【讨论】:

  • 哇,这看起来很有希望。我一定会仔细看看这个。谢谢!
  • 嗨,过去 2 天我一直在尝试 Neo4J,它看起来很有希望,但是当我模拟创建 1000 个节点的那一刻,我意识到这个过程有多慢……花了几个秒。我做错了什么还是真的是这样?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-01
  • 2019-12-05
  • 1970-01-01
  • 2015-02-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多