简体   繁体   中英

Updating a vector of vectors stored in a map

I have a following design in ah :

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;
}

and in 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;
     }
}

while I call updateCoefficients from a method defined in 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;
    } 
} 

The problem is that the vector coefs in the map heuristic is not being updated but whenever updateCoefficients is called, all the vectors are 0s as they are when they are initialized. What am I doing wrong?

The idea is to have class A as a base that contains all the methods and variables that have to be used and to define different updateCoefficients methods in child classes that inherit the base from class A .

EDIT

OK, so the whole code can be found here OfflineHeuristic.h and OfflineHeuristic.cc . Information in classes State , ActionState , THTS are irrelevant. I've tried the possible fixes but still, map heuristic is constantly filled with zero values. The method that's being called from other classes is offlineHeuristic->learn(state, action, reward) .

EDIT 2

The error was actually in another place, in the code logic. Making the code pasted above actually correct. I'll leave the question in case anyone run into a problem like that. Or, if that is not a good thing to do, please let me know so I delete the question.

The reason why heuristic is not updated is because you need to call A::foo twice. First call it will be initialized with zero, and only the next call will update them;

So may be changing code like this will be a solution:

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);
} 

And the rest of your code works - data is updated. You can 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;               

Output:

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 

It seems to me that you're using base class method, make it pure virtual to avoid errors. virtual void updateCoefficients( ... ) = 0;

Working as expected.

// 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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM