我在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.h和OfflineHeuristic.cc找到整个代码。课程class A
,State
,ActionState
中的信息无关紧要。我已经尝试了可能的修复但仍然,地图THTS
一直充满零值。从其他类调用的方法是heuristic
。
编辑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;
}