更新存储在地图中的矢量矢量

时间:2017-03-01 08:53:52

标签: c++ stdvector stdmap

我在a.h中有以下设计:

class A {
     virtual void updateCoefficients(std::string /*state*/, std::vector<std::vector<double>>& /*coefs*/,
                                    double /*reward*/) {}
protected: 
     std::map<std::string, std::vector<std::vector<double>>> heuristic;
}

class B : public A {
     virtual void updateCoefficients(std::string state, std::vector<std::vector<double>>& coefs,
                                   double reward) override;
}

a.cc

void B::updateCoefficients(std::string state, std::vector<std::vector<double>>& coefs,
                                   double reward) {
     for(unsigned i = 0; i < coefs.size(); i++) {
         coefs[i][0] += 1;
     }

     for(unsigned i = 0; i < coefs.size(); i++) {
         coefs[i][1] += 2;
     }
}

我从updateCoefficients中定义的方法调用class A

void A::foo(std::string state, std::string action, double const& reward) {
        if (heuristic.count(action)) {
            updateCoefficients(state, heuristic[action], reward);
        } else {
            std::vector<std::vector<double>> coefs(20, std::vector<double>(2, 0.0));
            heuristic[action] = coefs;
    } 
} 

问题是地图coefs中的向量heuristic没有被更新,但每当调用updateCoefficients时,所有向量都是0,因为它们在初始化时是。我究竟做错了什么?

我们的想法是让class A作为基础,包含必须使用的所有方法和变量,并在从{{1}继承基类的子类中定义不同的updateCoefficients方法}。

修改

好的,所以可以在OfflineHeuristic.hOfflineHeuristic.cc找到整个代码。课程class AStateActionState中的信息无关紧要。我已经尝试了可能的修复但仍然,地图THTS一直充满零值。从其他类调用的方法是heuristic

编辑2

错误实际上是在代码逻辑中的另一个地方。使上面粘贴的代码实际上是正确的。如果有人遇到这样的问题,我会留下问题。或者,如果这不是一件好事,请告诉我,所以我删除了这个问题。

2 个答案:

答案 0 :(得分:2)

启发式未更新的原因是因为您需要两次调用A :: foo。首先调用它将初始化为零,只有下一个调用将更新它们;

因此,改变这样的代码可能是一个解决方案:

void A::foo(std::string state, std::string action, double const& reward) {
      if (!heuristic.count(action)) {
            std::vector<std::vector<double>> coefs(20, std::vector<double>(2, 0.0));
            heuristic[action] = coefs;
      } 
      updateCoefficients(state, heuristic[action], reward);
} 

其余代码正常工作 - 数据已更新。你可以try it here

A* instance = new B();
instance->foo("aaa", "bbb", 123);
cout << "First call" << endl;

for (auto h : instance->heuristic)
    for (auto b : h.second)
        for (auto c : b)
            cout << c << " ";
cout << endl;               
instance->foo("aaa", "bbb", 123);
cout << "Second call" << endl;

for (auto h : instance->heuristic)
    for (auto b : h.second)
        for (auto c : b)
            cout << c << " ";
cout << endl;               

输出:

First call
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
Updated
1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 

答案 1 :(得分:1)

在我看来,你正在使用基类方法,使其成为纯虚拟以避免错误。 virtual void updateCoefficients( ... ) = 0;

按预期工作。

// Example program
#include <iostream>
#include <string>
#include <vector>
#include <map>

class A {
     virtual void updateCoefficients(std::string /*state*/, std::vector<std::vector<double>>& /*coefs*/,
                                    double /*reward*/) = 0;
protected: 
     std::map<std::string, std::vector<std::vector<double>>> heuristic;
public:
     void foo(std::string state, std::string action, double const& reward);
     virtual ~A() {}

};

void A::foo(std::string state, std::string action, double const& reward) {
        if (heuristic.count(action)) {
            updateCoefficients(state, heuristic[action], reward);
            std::cout << "exist\n";
            std::cout << heuristic[action][0][0] << '\n';
            std::cout << heuristic[action][0][1] << '\n';
        } else {
            std::vector<std::vector<double>> coefs(20, std::vector<double>(2, 0.0));
            heuristic[action] = coefs;
            std::cout << "not exist\n";
    } 
} 

class B : public A {
     virtual void updateCoefficients(std::string state, std::vector<std::vector<double>>& coefs,
                                   double reward) override;
public:
    virtual ~B() {}
};

void B::updateCoefficients(std::string state, std::vector<std::vector<double>>& coefs,
                                   double reward) {
     for(unsigned i = 0; i < coefs.size(); i++) {
         coefs[i][0] += 1;
         coefs[i][1] += 2;
     }
}

int main()
{
  A* a = new B();
  a->foo("aaa", "bbb", 2.0);
  a->foo("aaa", "bbb", 2.0);
  a->foo("aaa", "bbb", 2.0);
  delete a;
  return 0;
}