设计 PRIM 算法最有效的数据结构是什么?
What is the most efficient data structure for designing a PRIM algorithm?
我正在用 c++ 为其元素使用散列 table 设计图形。散列table 使用开放寻址并且图的边数不超过 50.000。我还设计了一个 PRIM 算法来找到图的最小生成树。我的 PRIM 算法为以下数据创建存储:
一个名为 Q
的 table 将所有节点放在开头。在每个循环中,访问一个节点,并在循环结束时从 Q 中删除它。
一个名为Key
的table,每个节点一个。必要时更改密钥(每个循环至少一次)。
一个名为Parent
的table,每个节点一个。在每次循环中,都会在这个table.
中插入一个新元素
一个名为 A
的 table。该程序在此处存储最小生成树的最终边。返回的是 table。
假设图形有 50.000 条边,创建这些 table 最有效的数据结构是什么?
我可以使用数组吗?
我担心每个数组的元素会太多。当然,我什至不考虑使用链表,因为访问每个元素都会花费很多时间。我可以使用散列 tables 吗?
但同样,元素太多了。我的算法适用于由几个节点(10 或 20)组成的图,但我对图由 40.000 个节点组成的情况持怀疑态度。非常感谢任何建议。
(因为评论有点长):问题的唯一部分似乎对于非常大的尺寸变得难看,是每个尚未选择的节点都有成本,您需要找到最低的每个步骤的成本,但是执行每个步骤会减少一些有效随机节点的成本。
当您想跟踪最低成本时,优先队列是完美的选择。删除成本最低的节点(您在每一步都这样做)是有效的。添加一些新可达的节点是有效的,就像您在任何步骤中所做的那样。但是在基本设计中,它并没有处理降低成本已经很高的几个节点的成本。
因此(经常需要功能更强大的优先级队列),我通常会创建一个指向对象的指针堆,并且在每个对象中都有其堆位置的索引。堆方法都会对对象进行回调,以便在其索引更改时通知它。堆还有一些外部方法调用,这些方法通常可能仅在内部调用,例如当现有元素的成本降低时,非常适合有效修复堆的方法。
我刚刚查看了标准版的文档
http://en.cppreference.com/w/cpp/container/priority_queue
看看我一直想添加的功能是否以我以前没有注意到的某种形式存在(或者已经添加到最近的一些 C++ 版本中)。据我所知,NO。优先级队列的大多数现实世界使用(当然是我的)需要一些小的额外功能,我不知道如何附加到标准版本上。所以我需要从头开始重写它,包括额外的功能。但这其实并不难。
我使用的方法已被许多人重新发明(我在 70 年代用 C 语言这样做,而不是第一个)。快速 google 搜索发现许多地方之一对我的方法的描述比我描述的更详细。
http://users.encs.concordia.ca/~chvatal/notes/pq.html#heap
我正在用 c++ 为其元素使用散列 table 设计图形。散列table 使用开放寻址并且图的边数不超过 50.000。我还设计了一个 PRIM 算法来找到图的最小生成树。我的 PRIM 算法为以下数据创建存储:
一个名为
Q
的 table 将所有节点放在开头。在每个循环中,访问一个节点,并在循环结束时从 Q 中删除它。一个名为
Key
的table,每个节点一个。必要时更改密钥(每个循环至少一次)。一个名为
Parent
的table,每个节点一个。在每次循环中,都会在这个table. 中插入一个新元素
一个名为
A
的 table。该程序在此处存储最小生成树的最终边。返回的是 table。
假设图形有 50.000 条边,创建这些 table 最有效的数据结构是什么?
我可以使用数组吗?
我担心每个数组的元素会太多。当然,我什至不考虑使用链表,因为访问每个元素都会花费很多时间。我可以使用散列 tables 吗?
但同样,元素太多了。我的算法适用于由几个节点(10 或 20)组成的图,但我对图由 40.000 个节点组成的情况持怀疑态度。非常感谢任何建议。
(因为评论有点长):问题的唯一部分似乎对于非常大的尺寸变得难看,是每个尚未选择的节点都有成本,您需要找到最低的每个步骤的成本,但是执行每个步骤会减少一些有效随机节点的成本。
当您想跟踪最低成本时,优先队列是完美的选择。删除成本最低的节点(您在每一步都这样做)是有效的。添加一些新可达的节点是有效的,就像您在任何步骤中所做的那样。但是在基本设计中,它并没有处理降低成本已经很高的几个节点的成本。
因此(经常需要功能更强大的优先级队列),我通常会创建一个指向对象的指针堆,并且在每个对象中都有其堆位置的索引。堆方法都会对对象进行回调,以便在其索引更改时通知它。堆还有一些外部方法调用,这些方法通常可能仅在内部调用,例如当现有元素的成本降低时,非常适合有效修复堆的方法。
我刚刚查看了标准版的文档
http://en.cppreference.com/w/cpp/container/priority_queue
看看我一直想添加的功能是否以我以前没有注意到的某种形式存在(或者已经添加到最近的一些 C++ 版本中)。据我所知,NO。优先级队列的大多数现实世界使用(当然是我的)需要一些小的额外功能,我不知道如何附加到标准版本上。所以我需要从头开始重写它,包括额外的功能。但这其实并不难。
我使用的方法已被许多人重新发明(我在 70 年代用 C 语言这样做,而不是第一个)。快速 google 搜索发现许多地方之一对我的方法的描述比我描述的更详细。 http://users.encs.concordia.ca/~chvatal/notes/pq.html#heap