Reputation: 4318
I am trying to implement this POMDP solver with given examples for my decision making problem and I followed the documentation in the repository to build different relevant classes and functions in the header file
class SimpleState: public State {
public:
int position;
int context;
int time;
SimpleState();
SimpleState(int _position, int _context, int _time) :
rat_position(_position),
context(_context),
time(_time) {
}
SimpleState(int _state_id);
~SimpleState();
std::string text() const;
};
SimpleState::SimpleState() {
}
class StarMazeProblem : public DSPOMDP,
public MDP {
protected:
std::vector<std::vector<std::vector<State> > > transition_probabilities_; //state, action, [state, weight]
mutable MemoryPool<SimpleState> memory_pool_;
std::vector<SimpleState*> states_;
mutable std::vector<ValuedAction> mdp_policy_;
public:
enum {CENTER = 0, RIGHT = 1, LEFT = 2};
public:
StarMazeProblem();
int NumStates() const;
void ComputeDefaultActions(std::string type) const;
ParticleUpperBound* CreateParticleUpperBound(std::string name = "DEFAULT") const;//?
ScenarioUpperBound* CreateScenarioUpperBound(std::string name = "DEFAULT",
std::string particle_bound_name = "DEFAULT") const;
ScenarioLowerBound* CreateScenarioLowerBound(std::string name = "DEFAULT",
std::string particle_bound_name = "DEFAULT") const;
}
and in the starmaze.cpp
file the relevant lines are
int StarMazeProblem::NumStates() const {
return CONTEXT * POSITIONS * TIME;
}
void StarMazeProblem::ComputeDefaultActions(string type) const {
cerr << "Default action = " << type << endl;
if (type == "MDP") {
const_cast<StarMazeProblem*>(this)->ComputeOptimalPolicyUsingVI();
int num_states = NumStates();
default_action_.resize(num_states);
double value = 0;
for (int s = 0; s < num_states; s++) {
default_action_[s] = policy_[s].action;
value += policy_[s].value;
}
} else {
cerr << "Unsupported default action type " << type << endl;
exit(0);
}
}
ScenarioLowerBound* StarMazeProblem::CreateScenarioLowerBound(string name,
string particle_bound_name="DEFAULT") const {
const DSPOMDP* model = this;
const StateIndexer* indexer = this;
const StatePolicy* policy = this;
ScenarioLowerBound* bound = NULL;
if (name == "TRIVIAL" ) {
bound = new TrivialParticleLowerBound(this);
} else if (name == "RANDOM") {
bound = new RandomPolicy(this,
CreateParticleLowerBound(particle_bound_name));
} else if (name == "MODE" || name == "DEFAULT") {
ComputeDefaultActions("MDP");
bound = new ModeStatePolicy(model, *indexer, *policy,
CreateParticleLowerBound(particle_bound_name));
} else {
cerr << "Unsupported scenario lower bound: " << name << endl;
exit(1);
}
return bound;
}
here I got the following error for the above code:
src/starmaze.cpp:301:36: error: passing 'const std::vector<int>' as 'this' argument discards qualifiers [-fpermissive]
default_action_.resize(num_states);
^
In file included from /opt/local/include/gcc7/c++/vector:64:0,
from ../../../include/despot/interface/lower_bound.h:4,
from ../../../include/despot/core/builtin_lower_bounds.h:4,
from src/starmaze.h:3,
from src/starmaze.cpp:1:
/opt/local/include/gcc7/c++/bits/stl_vector.h:689:7: note: in call to 'void std::vector<_Tp, _Alloc>::resize(std::vector<_Tp, _Alloc>::size_type) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::size_type = long unsigned int]'
resize(size_type __new_size)
^~~~~~
I have basic c++ knowledge and I could not figure out the reason for the error since I followed the examples. Any suggestion?
Upvotes: 1
Views: 1922
Reputation: 117298
You've made ComputeDefaultActions()
const
-qualified, but there is very little that says that it should be.
ComputeOptimalPolicyUsingVI()
which is not const
-qualified since it changes the internal state of *this
. You've worked around that by casting away const
on this
- but that function resize
s policy_
to also be NumStates()
big which ComputeDefaultActions()
depends on - otherwise the internal loop would be very dangerous.default_action_
by resize
ing it and by assigning its elements. This may be a mistake, if the computation made is actually meant to not change *this
but ... (see next bullet)*this
. The computed value
is just dropped at the end of the calculation and it's not even used internally in the function. Either make the function return value
or remove value
completely.Suggested changes:
#include <algorithm>
#include <stdexcept>
void StarMazeProblem::ComputeDefaultActions(string type) { // non-const
cerr << "Default action = " << type << endl;
if (type == "MDP") {
ComputeOptimalPolicyUsingVI(); // no casting needed
default_action_.resize(policy_.size()); // dependency made clear
// Use the standard transform function:
std::transform(policy_.begin(), policy_.end(), default_action_.begin(),
[](const auto& p) { return p.action; });
} else {
// friendlier than exit():
throw std::runtime_error("Unsupported default action type " + type);
}
}
Upvotes: 1
Reputation: 116
I've looked over this code several times, and cannot find where default_action_
is declared as a const std::vector<int>
. This leads me to assume (based on the fact that the compiler recognizes it as such) that the variable is declared in one of the parent classes: public DSPOMDP, public MDP
.
const vector<int>
This issue is pretty straight-forward.
You cannot change a const std::vector<Ty>
The whole point of making something const is to prevent the programmer from changing it.
Whatever you are trying to do here, you should consider copying the vector data into a new vector, and make the changes to it in the copy.
Okay so let's say you decided to do the naughty deed and remove const from the *.h file wherever it may be. You'll still have an issue (see below)
This is if you removed const from the vector
The default_action_.resize(num_states);
is going to cause the compiler to yell at you.
The issue here is now your method StarMazeProblem::ComputeDefaultActions()
is specified as const. This means you cannot change your class instance in any way from within that function/class method. What you are doing is modifying the default_action_ vector by calling resize()
on it. This inevitably changes the class instance which is forbidden because your method is declared const and your default_action_ vector is declared somewhere in your class hierarchy. Additionally you are changing the vector directly by assigning it to an rvalue (See code below)
int num_states = NumStates();
default_action_.resize(num_states); // <---- default_action_ cannot be modified
for (int s = 0; s < num_states; s++) {
default_action_[s] = policy_[s].action; // <---- default_action_ cannot be modified
value += policy_[s].value;
}
You need a copy of the vector you are trying to modify. Going into h files and changing them without knowing 100% exactly what you are doing is never the answer. Making a temporary vector in the class method, copying the data to it, and manipulating the copy is completely allowed and will not give you any compiler errors; however, this approach may completely avoid your official goal. It looks like you are really trying to change the default_action_ vector and that almost seems like your true goal here.
It's hard for me to give you a definitive answer on this specific topic. Mainly because I do not know what this entire class hierarchy does or what it is for exactly (I briefly looked over the code in the link provided.)
What you'll need to do ultimately is determine why you are trying to change that vector, and why it was made const by the original developers. Then you can determine if there is a better way other than explicitly removing the constness of the vector.
If you are still trying to make changes to the class instance read below
This solution part has to do with the qualifier of the class you are dealing with.
You can either remove the constant qualifier from the class method if it is absolutely necessary to make changes to the class instance from within that method.
OR
Find an alternative method for what you are trying to do, and break it up into multiple method calls on the class instance.
Upvotes: 5