【问题标题】:Which is the best away to create and store cycles using c/c++?使用 c/c++ 创建和存储循环的最佳方法是什么?
【发布时间】:2018-03-27 15:59:43
【问题描述】:

使用 c/c++ 创建和存储循环的最佳方法是什么?

我有结构:

struct CYCLE {
    vector<Arc> route;
    float COST;
}

struct Arc {

    int i, j;
    Arc () {};
    Arc (const Arc& obj): i(obj.i), j(obj.j) {};
    Arc(int _i, int _j) : i(_i), j(_j) {}    

};

为了存储已经创建的循环,我考虑过使用:

vector<CYCLE> ConjCycles;

对于创建的每个循环,我需要验证该循环是否尚未添加到 ConjCycles。 周期:1-2-2-1;与循环相同:2-2-1-2。 我怎样才能检测到像这样的周期是一样的? 我考虑过使用地图来控制这一点。 但是,我不知道如何给循环设置一个key,让上面描述的两个循环有相同的key。

【问题讨论】:

  • 您能描述一下您所说的cycle是什么意思吗,它与dictionary有什么关系?
  • 这里的循环是车辆访问的顶点序列。一个循环必须在同一个顶点开始和结束,但一个顶点可以在一个循环中多次访问。
  • 那么比如1-2-3-4-1和1-3-2-4-1是同一个循环吗?如果是这样,您实际上是在尝试找到 2 个周期之间的“差异”,对吧?
  • 它们不一样。为了相同,循环必须具有相同的弧。
  • 1-2-3-4-1 与 3-4-1-2-3 周期相同。

标签: c++ key cycle


【解决方案1】:

您的循环表示中有很多冗余,例如。 G。循环1-3-2-4-1:

{ (1, 3), (3, 2), (2, 4), (4, 1) }

如果我们认为循环是循环图,那么您将边存储在数据结构中。相反,存储顶点会更有效:

struct Cycle
{
    std::vector<int> vertices;
};

您从vertices[n]vertices[n + 1] 隐式获得的边;最后一个顶点总是和第一个相同,所以不要显式存储它,那么最后一个边将是vertices[vertices.size() - 1]vertices[0]

请注意,这只是内部表示;您仍然可以从一系列边(Arcs)构建循环。您很可能会检查构造函数中的序列,如果它无效,则可能会抛出异常(但是,如果您不喜欢异常,还有其他选择......)。

那么你需要某种对等。我的建议是:

  1. 如果顶点数不相等,则循环不能相等。
  2. 它可能会缩短算法的其余部分(但这还需要评估!),如果您计算每个顶点 id 的出现次数,这些必须匹配
  3. 搜索每个循环的最小顶点 id,从这里开始,比较每个后续值,如果到达终点,则在向量中环绕。
  4. 如果序列匹配,你就完成了;但是,这还没有涵盖存在多个最小值的情况;如果发生这种情况,您可能只是重复该步骤,在一个周期中尝试下一个最小值,而在另一个周期中保持相同。您可以尝试与最大值并行执行相同操作,或者如果您已经计算过它们(见上文),请使用元素较少的最小值/最大值。

编辑:进一步改进(灵感来自 [Scheff] 对问题的评论):

我们最好从目前找到的相对最小值中选择某种绝对最小值,而不是重新尝试找到的每个最小值;如果x 的后继者小于y 的后继者,则相对最小值x 小于相对最小值y;如果两个后继者相等,则查看下一个后继者,依此类推。如果您发现多个绝对最小值(如果某个间接后继者等于初始最小值),那么您有一个序列,某个子循环会重复多次(1-2-3-1-2-3-1-2-3)。那么你选择哪个“绝对”最小值并不重要......

不过,您肯定会跳过上面的第 2 步。

在构造函数中找到最小值并将其存储。然后比较变得容易,您只需在两个周期中分别以各自的最小值开始...

【讨论】:

  • @Scheff 请参阅第 4 点...不过,您对这个问题的评论向我暗示了一些想法,以使我的算法更高效...
  • 感谢您的回答!但这不会在计算上很困难吗?因为,无论如何我都需要遍历所有向量 ConjCiclos 来确定新循环是否已经存在。
  • @LuizaReal 这就是为什么我建议在构造函数中(在编辑中)只计算一次最小值并存储它的索引,所以在比较期间你只需要在向量上迭代一次。您还可以计算哈希值(也在构造函数中),并且仅在哈希相等时才比较顶点(存在一些冲突的可能性......)。如果你保持你的向量排序,你可以做一个二分搜索,这进一步减少了工作量(O(log(n))而不是O(n))。
猜你喜欢
  • 1970-01-01
  • 2013-02-15
  • 2012-08-16
  • 2010-09-21
  • 1970-01-01
  • 2010-10-08
  • 2020-09-22
  • 2017-04-21
  • 2018-08-05
相关资源
最近更新 更多