【问题标题】:How to call a function from another class, where the function uses local variable如何从另一个类调用函数,其中函数使用局部变量
【发布时间】:2016-08-05 04:10:31
【问题描述】:

我有两个课程MaxFlowMinMaxFlow

MaxFlow 使用 boost graph 从网络拓扑创建图:

class MaxFlow {
 public:
  MaxFlow : g_() { createGraph(); } //constructor
  void createGraph();
  void modifyGraph(); // modify the graph to use boost maxflow algorithm
  int maxFlowAlgo(); // use g_ and some other util local variables
 private:
  Graph g_;
  ...   // some other helper containers created during createGraph()
}

MaxFlow 维护一个局部变量g_,因为我们只需要一个实例来完成这里的所有工作。 MinMaxFlow 迭代图中的每条边以找到最小的最大流量,如果我们失败了 edge(将容量设置为 0):

class MinMaxFlow {
 public:
  int getMinMaxFlow() {
    int minMaxFlow = INT_MAX;
    MaxFlow maxFlowObj; // create a new obj
    maxFlowObj.modifyGraph(); // I suppose this modify current obj
    for (auto edge : graph_edges) {
      // maxFlowAlgo will return incorrect value after several runs
      int maxFlowVal = maxFlowObj.maxFlowAlgo();
      int minMaxFlow = std::min(minMaxFlow, maxFlowVal);
    }
    return minMaxFlow;
  }
}

现在的问题是,maxFlowAlgo 是基于类MaxFlow 中的局部变量g_,当我在MinMaxFlow 中创建新对象maxFlowObj 时,调用maxFlowObj.maxFlowAlgo() 将使用它自己的数据,这使得结果不可预测。 所以我的问题是:如果方法在MaxFlow 中使用局部变量,我该如何使用属于第二类MaxFlow 中的MaxFlow 的方法(如maxFlowAlgo)?

更新:我发现问题出在boost::boykov_kolmogorov_max_flow,我使用捆绑属性并将容量属性映射传递给它,但是这个算法不仅会修改容量属性映射,还会修改我原来的边缘容量变量!现在的解决方法是我必须在运行算法之前存储容量值并在它之后恢复它们。应该不会修改原来的成员吧?

【问题讨论】:

  • g_ 不是局部变量,而是成员变量。有区别。
  • 您可以将g_ 变量设为静态,以便您的类的所有实例“共享”它。这可能会有所帮助:Static Members
  • 了解什么是局部变量、类成员和静态类成员。使g_ 简单地static 不会立即使您的代码正确。为什么maxFlowAlgo“多次运行后返回不正确的值”?我想应该是const。您不要在循环中使用 edge 变量。也许,这条边是打算在迭代开始时删除并在最后添加的?
  • @GeorgeSovetov 谢谢。我在想删除边缘,但它可能会使提升图不稳定。因此,我通过将边缘容量设置为 0 来使用一种解决方法。我发现问题发生在我调用 boost max flow 算法之后。我将 boykov_kolmogorov_max_flow 和 bundle 属性用于 capacity_property_map。它将修改一些边缘容量。我看不出有任何理由。该算法不应该修改任何图形元素,对吧?
  • @EmersonXu 我会留下答案。

标签: c++ boost-graph max-flow


【解决方案1】:

在这种情况下,可以更改边缘容量。

有时算法不会修改输入数据。另一方面,最好更改现有数据以节省资源(内存),因为更改后的数据是有意义的。执行最大流算法后,边缘容量为剩余容量;换句话说,当图被流量饱和时,每条边还剩下多少容量。至少一个边缘将具有零剩余容量;当第二次算法执行后,由于图形饱和,它将返回零。

如果你想多次运行最大流算法,你必须保存初始图并在每次运行算法时复制它。每次在循环迭代开始时,您都必须重建您的图形或从保留的图形中复制它。

由于您多次运行算法,您可能希望在不同的图表上运行它。您可能想要复制图形并将边容量设置为零。

【讨论】:

  • 是的。我已经通过构建一个默认的基础图解决了这个问题。修改它,运行 maxflow 算法,恢复它,并对每个边缘组重复这三个步骤。它现在运行完美。再次感谢您的见解。
【解决方案2】:

看来你问的是XY Problem

如果你想maintains a local variable g_ since we only need one instance,你应该使用Singleton Design Pattern,而不是在需要时创建实例。

【讨论】:

    猜你喜欢
    • 2019-03-30
    • 1970-01-01
    • 1970-01-01
    • 2019-07-03
    • 1970-01-01
    • 2017-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多