How do I use a Merit function in Gecode? - c++

I am trying to use a merit function for my branching in Gecode. In the MPG, the Gecode Manual, an example merit function is stated, and how to pass it to the branching. But I cannot figure out where to put the function. Should it be inside the script or outside? Right now I have put it next to the copy function, etc. I cannot find any example code where someone uses a merit function.
I get the following error:
program.cpp(247): error C2059: syntax error: '}'
program.cpp(247): error C2853: 'm': a non-static data member cannot have a type that contains 'auto'
program.cpp(259): fatal error C1004: unexpected end-of-file found
This is the code I am trying out:
// ...
branch(*this, workers, BOOL_VAR_MERIT_MIN(m), BOOL_VAL_MAX());
}
auto m = [](const Space& home, BoolVar x, int i) {
return i;
}
// ...
I know it is stupid to make a merit function that just returns the index, I am just trying to make the simplest merit function to work before I do what I want to do.

According to the Gecode documentation the merit function should return a double. As suggested by the type definition of BoolBranchMerit:
typedef std::function<double(const Space& home, BoolVar x, int i)> Gecode::BoolBranchMerit
To be safe, you might also want to declare m as being an Gecode::BoolBranchMerit. So I think the following should fix your example:
// ...
branch(*this, workers, BOOL_VAR_MERIT_MIN(m), BOOL_VAL_MAX());
}
BoolBranchMerit m = [](const Space& home, BoolVar x, int i) -> double {
return (double) i;
}
// ...

Related

C++ Changing the values of members of a const struct [duplicate]

This question already has answers here:
C/C++ changing the value of a const
(18 answers)
Closed 8 years ago.
I have a struct which is defined in types.h with the following code:
struct data_Variant {
FlightPlanSteeringDataRecord steeringData;
FlightPlanType flightPlan : 8;
MinitoteLegDataType legDataType : 8; // discriminent, either current or amplified
unsigned spare : 16;
union {
// currentLeg =>
CurrentLegDataRecord currentLegData;
// amplifiedLeg =>
AmplifiedLegDataRecord amplifiedLegData;
} u;
};
I am then trying to pass an instance of that struct as a parameter to a function in a C++ source file called dialogue.cpp:
void dialogue::update( const types::data_Variant& perfData){
...
}
I now want to change the value of some of the members of that struct inside this update() function. However, if I try doing this as I usually would, i.e.
perfData.etaValid = true;
I get a compile error which says: "C2166: l-value specifies const object". As I understand, this is because perfData has been declared as a constant variable. Am I correct in thinking this?
Since I didn't write this part of the code, but only want to use it to update the value displayed on the GUI, I don't really want to change the perfData variable by removing the const keyword, in case I break something else. Is there any way to change the value of a variable that has been declared as const?
I have tried declaring the same struct variable in another part of the code, without using the const keyword, to see if I can change the values of some of its members there... i.e. in Interface.cpp, I have added the following code to a function called sendData():
types::data_Variant& perfData;
perfData.steering.etaValid = true;
perfData.steering.ttgValid = true;
However, I now get the following compile errors on these lines:
error C2653: 'types' is not a class or namespace name
error C2065: data_Variant: undeclared identifier
error C2065: 'perfData': undeclared identifier
error C2228: left of '.steering' must have class/ struct/ union
Is there a way of updating the values of this struct? If so, how should I do it, and what am I doing wrong here?
I have added the following function to the dialogue.cpp source file, as suggested in the answer:
void dialogue::setFPTTGandETAValidityTrue(
FlightPlanMinitoteTypes::FlightPlanMinitoteData_Variant& perfData)
{
SESL_FUNCTION_BEGIN(setFPTTGandETAValidityTrue)
perfData.steeringData.fpETAValid = true;
perfData.steeringData.fpTTGValid = true;
SESL_FUNCTION_END()
}
You could add a wrapper for yourself.
void myupdate(dialogue& dia, types::data_Variant& perfData)
{
perfData.etaValid = true;
dia.update(perfData);
}
Then call myupdate() instead of dialogue::update().
You declare
void dialogue::update( const types::data_Variant& perfData){
...
}
that const is a declaration of you saying: "I won't modify the referenced object in this function". If you want to modify it in dialogue::update you have to remove the const keyword. Wrapping is not a solution, in my opinion, makes the code harder to maintain. Also I vote against remove const with const_cast.
The correct solution is to remove const from method declaration if you want to modify the referenced object inside that function.

C++ std::sort custom compare function referencing to another list

I am a beginner in C++ and I don't know nor can find the way to address my problem.
I'm trying to sort my vector in an unusual way and fail to do so.
pointsToVisit - list of Point objects that can have their start time and end time.
visitedPoints - list of indexes of Point objects from pointsToVisit vector
I'd like to sort my visitedPoints vector by values of respective Points
BeeHive
std::vector<Point> pointsToVisit;
std::vector<Route> routes;
Route
std::vector<int> visitedPoints;
My attemp is below:
bool BeeHive::isPointsVisitStartPrior (int i, int j) { return (pointsToVisit.at(i).startTime<pointsToVisit.at(j).startTime); }
Route BeeHive::sortRouteByStartTime(int routeIndex){
Route route2 = Route();
route2.setStartTime(routes.at(routeIndex).getStartTime());
route2.setVisitedPoints(routes.at(routeIndex).getVisitedPoints());
std::sort(route2.getVisitedPoints().begin()+1, route2.getVisitedPoints().end(), isPointsVisitStartPrior);
evaluateRoute(route2);
return route2;
}
And I get such errors:
Error 5 error C3867: 'BeeHive::isPointsVisitStartPrior': function call missing argument list; use '&BeeHive::isPointsVisitStartPrior' to create a pointer to member c:\vrp projekt\vrp\vrp\beehive.cpp 193 1 VRP
Error 6 error C2780: 'void std::sort(_RanIt,_RanIt)' : expects 2 arguments - 3 provided c:\vrp projekt\vrp\vrp\beehive.cpp 193 1 VRP
Example by which I tried to do my work is under this address: http://www.cplusplus.com/reference/algorithm/sort/
I'll be thankful for any help received.
Might it be possible, that creating bubble sort for my own purposes will substitute std::sort() decently?
isPointsVisitStartPrior is a member function, this cannot be used directly in sort. You have to either use a global function or a function-object.
If you have access to C++ 11 features, you can use a lambda:
std::sort(route2.getVisitedPoints().begin()+1, route2.getVisitedPoints().end(),
[&](int i, int j){ return isPointsVisitStartPrior(i, j); });
You can also make a functor object with an operator(), something like
class VisitedPointsCompararer {
public:
VisitedPointsCompararer(const std::vector<Point>& pointsToVisit): pointsToVisit(pointsToVisit) {
}
bool operator() (int i, int j) {
return pointsToVisit.at(i).startTime < pointsToVisit.at(j).startTime;
}
...
private:
const std::vector<Point>& pointsToVisit;
}
isPointsVisitStartPrior(int, int) is a member function. A such, while it looks like it takes two arguments, it really implicitly takes three: it also needs a BeeHive* on which to operate (the this pointer).
What you need to do is "bind" the BeeHive* to the call:
using namespace std::placeholders;
std::sort(route2.getVisitedPoints().begin()+1,
route2.getVisitedPoints().end(),
std::bind(&BeeHive::isPointsVisitStartPrior, this, _1, _2)
// ^^^^^^^^^ without C++11, there's also boost::bind
);
That will save off this as the first argument in the call to the three-argument function, and forward the next two arguments you call it with into the next two slots.
This is logically equivalent to:
std::sort(route2.getVisitedPoints().begin()+1,
route2.getVisitedPoints().end(),
[this](int i, int j){ return isPointsVisitStartPrior(i, j); }
);
Though with the lambda, the compiler may be able to inline the call for you.

Expected unqualified-id before 'double'/

I'm writing a program for a lab called Robot. When I compile it, I get this set of errors:
Robot.cpp:43:13: error: expected unqualified-id before 'double'
Robot.cpp:43:13: error: expected ')' before 'double'
The class is defined in the Robot.h header, and the code in the .cpp that's causing the problem looks like this:
/*
* Name: Robot (constructor)
*
* Creates the robot with the given maximum speed.
*/
Robot( double maxSpd )
{
MAX_SPEED = maxSpd;
traveled = 0 ;
elapsed = 0 ;
x = 0 ;
y = 0 ;
}
I can't figure out why the errors are there... and I also don't know what that error even means. How would I solve it?
I've managed to recreate your errors.
First of all, that semicolon after the signature has to go. It's declaring a function when you're trying to define one.
Robot(double maxSpd) {...} //no semicolon
SecondlyFirst of all, since this is outside of your class, you need to qualify it:
Robot::Robot(double maxSpd) {...}
Next, since MAX_SPEED is a constant, you need to put it in a member initializer:
Robot::Robot(double maxSpd)
: MAX_SPEED(maxSpd) {...}
Finally, you should move the rest of your assignments to the initializer list as well (not necessary, but good to do), keeping in mind that they should be listed in the order they are declared in the class definition:
Robot::Robot(double maxSpd)
: MAX_SPEED(maxSpd), traveled(0), elapsed(0), x(0), y(0) {
//body, which, from your example, would now be empty
}
The possible problem could be that there is a semicolon before the open bracket. But without seeing the whole class, it would be difficult to say so.
If this code isn't inside the class declaration, you could possibly be missing a "Robot::" namespace specification before the "Robot()" constructor name.
Example:
Robot::Robot(double maxSpd)
{
MAX_SPEED = maxSpd;
traveled = 0;
elapsed = 0;
x = 0;
y = 0;
}

Anonymous Functions, "Parse Issue: Expected Expression"

I'm getting the titular error, but I can't for the life of me figure out how to resolve it. I've scoured the internet a fair bit, but for the most part I can't find anything that pertains directly to, or solves, the problem I'm having, and all the information I read about anonymous classes, seems to agree with the code I wrote.
The essence of what I'm trying to do is; I have a struct, and I want that struct to contain a function pointer. What I'm having trouble with is when I define an instance of the struct, I'm trying to create and pass an anonymous function to the struct. But it's giving me a compile error.
Anyways, here are the details of the actual problem, the error occurs on this line,
[&](int x) { this->moveLeft(); };
It says "Parse Issue: Expected expression" and points to the ']'
of the following code
Combatant::CharacterData Combatant::characters = {
/*Name */"SomeName",
/*Folder */"SomeFolder",
/*Offense */1.0f,
/*Defense */1.0f,
/*Combos */{
{KeyMemory(KeyMemory::MOVE_LEFT, KeyMemory::JUMP),
[&](int x) { this->moveLeft(); };
},
{KeyMemory(KeyMemory::MOVE_LEFT, KeyMemory::JUMP),
[&](int x) { this->moveLeft(); };
}
}
}
The CharacterData struct is defined by this code:
struct Combo {
KeyMemory controls;
void (*execute)(int);
};
struct CharacterData {
std::string name;
std::string folder;
float offense;
float defense;
Combo comboList[5];
};
Any help, would be much appreciated. ^_^
You might need to use a std::function<void(int)> to hold your lambda. (Particularly since you are using [&]).
Also, I'm not sure [&] actually makes sense in a global context. Maybe you should be passing in the object to call moveLeft on, and using []. Also, that change might let you use your simple function pointer instead of a std::function.
The problem turned out to be that Clang, which is the compiler used by Xcode/Apple doesn't yet support lambda functions. From what I read however the feature is coming in the future.

"__comp cannot be used as a function" c++ while trying next_permutation

I'm trying to do permutations with next_permutation from the stl, however I'm getting an error and I can't figure out how to fix it. I've tried googling, however the only results that come up are when people used the same function and function's variables name but thats not the case here.
Here's the error :
'__comp' cannot be used as a function
Here's the code :
struct rectangle{
int n;
int h;
int w;
};
bool check(const rectangle& rect1,const rectangle& rect2){
return rect1.n < rect2.n;
}
do{
//...
} while ( next_permutation(recs.begin(), recs.end(), check) ); // Getting error on this line.
Here's the full source code along with the sample input in case it's needed http://pastebin.com/eNRNCuTf
H = rec4.w + max(rec1.h, rec2.h, rec3.h);
You don't want to pass rec3.h there - The error message simply say that the 3rd argument to max can't be used as a function. I believe you intended:
H = rec4.w + max(max(rec1.h, rec2.h), rec3.h);