I'm modifying the vehicle routing Optaplanner example. Vehicles are replaced with individuals who have to travel around the city, but they can do so using different modes of transportation. So I have an attribute on the anchor (Vehicle in the example, Employee in my modified code) called modeOfTransportation.
When calculating the arrival time using the custom shadow variable listener from the example, I want to take the mode of transportation into account of course. But, when Optaplanner starts initialising my planning entities (consumers), it seems that they at first are not connected to an anchor. So I can't get my mode of transportation, and everything breaks down.
Any ideas on how to proceed?
Below is what I want to accomplish.
shadowVisit is my planning entity, shadowVisit.getEmployee() should give me the anchor.
Doing a shadowVisit.getEmployee()==null check seems to hang the entire solving process.
arrivalTime =
previousStopDepartureTime.plus(
shadowVisit.getLocation().getDistanceFrom(
shadowVisit.getPreviousStop().getLocation(), shadowVisit.getEmployee().getModeOfTransportation())
OK, so I figured out what the issue was.
My problem is overconstrained, and I implemented a dummy employee as the solution (see optaplanner: modifying vehicle routing to let customers be not served)
I had not set a modeOfTransportation for my dummy, causing the null pointers. Sometimes is just good to write down a problem, makes you think hard enough to solve it!
Thank you very much for your input Geoffrey
That's strange, because the chain principles guarantee that every chain has an anchor (see below).
Maybe your #CustomShadowVariable's sources attribute doesn't include the anchor shadow var, and your custom variable listener is called before the anchor shadow variable listener is called.
OptaPlanner guarantees that it will call one type of variable listener for all domain classes before calling the next type. The order of those types of variable listeners is determined by that sources attribute (see second image).
Related
I am trying to add moves selectors which consider the state of the current working solution. For example, suppose in the cloud balancing problem I was trying to make a move which preferentially moved a process onto a computer which already holds few processes. I have a shadow variable which tracks the number of processes on the computer, then I have a valueSelector which implements SelectionProbabilityWeightFactory that gives a higher weight to computers with fewer processes.
This setup works fine and produces the moves that I want. But it is terribly slow because it is updating the shadow variable far more often than I need it to. Since I am not using this shadow variable for scoring, I don't need it to be updated after every move attempted during the step. I only need the shadow variable to be updated after each accepted move (i.e. the end of the step).
Alternately, I could use a custom move factory, but that requires that every computer have its process count fully re-calculated at each step. This means I would lose the incremental calculation benefit I get with the shadow variables.
So is there a way to force shadow variables to update after each step, rather than after each move. Or is there a better way to track the status of the working solution for use in move selectors?
Bad news first:
It's not possible to have VariableListener only update a shadow variable per step and not per move. And it's unlikely we'll ever want to allow that particular change, as it would hurt the predictability and integrity of the state of the domain model between move iterations. This could create a lot of havoc, including multiple forms of corruptions, if used slightly incorrectly.
Good news next:
Yes, you need to calculate some state per step to generate moves efficiently. This is a common problem I've run into a few times before too.
But why put that on the domain model? It doesn't belong there.
It belongs on the the move selector. For example, if you use a MoveIteratorFactory, that has a method called phaseStarted() (called when the phase starts) and a method createRandomMoveIterator() (called when a step starts even with SelectionCacheType.JIT).
Some something like this should do the trick:
public class MyMoveIteratorFactory implements MoveIteratorFactory<...> {
default void phaseStarted(ScoreDirector<...> scoreDirector) {
}
Iterator<Move_> createRandomMoveIterator(ScoreDirector<...> scoreDirector, Random workingRandom) {
List<Computer> alreadyUsedComputerList = ...; // runs once per step
return new MyIterator(alreadyUsedComputerList, workingRandom);
}
Now, the plot thickens when multiple move selectors need to reuse the same calculation. That's where SupplyManager comes into play, which is not public API. But this is definitely a good requirement for our "move streams API" experiment that we'll do next year.
I am developing an incremental solver for rostering, the two planning entities are Assignment and Employee, worker has an #InverseRelationShadowVariable collection of assignments.
I have noticed a strange behaviour when using FULL_ASSERT.
At the start of the LS phase an EmployeeSwapMove is evaluated.
After that the listener is invoked which first retracts all assignments from Employee than inserts all assignments as per the move to the shadowed collection.
After that resetWorkingSolution is invoked, but the Employee has the Assignments before the move.
Optaplanner also logs, that the above move has been selected, but the Employee state (shadow collection) does not reflect that.
After that the score gets corrupted, of course.
The issue is not there when using FAST_ASSERT.
Can someone give me a hint?
I found out at last. In my Listener I messed up the after/beforeVariableChanged calls.
I am reading through the vehicle routing example (v 7.25.0) and have stumbled on some confusion regarding what is a problem fact vs planning entity.
The documentation in section 4.3.5.4 states:
A planning variable that is chained either:
- Directly points to a problem fact (or planning entity), which is called an anchor.
- Points to another planning entity with the same planning variable, which recursively points to an anchor.
And then right below it also states:
Every chain always has exactly one anchor. The anchor is a problem fact, never a planning entity.
This conflicting information leads to my confusion #1: is an anchor always a problem fact, or can it be a planning entity?
The reason I ask is because Vehicle (the anchor) implements Standstill which is defined in the vehicleRoutingSolverConfig.xml as:
<entityClass>org.optaplanner.examples.vehiclerouting.domain.Standstill</entityClass>
which leads me to believe that the Vehicle would "inherit" the planning entity property.
But then, I tried creating a drools rule that sets a hard constraint on the max # of customers associated to a vehicle using an instance method on Vehicle that returns the count by walking nextCustomer shadow variable until null, like:
when
Vehicle(totalCustomers > 5, $totalCustomers : totalCustomers)
then
scoreHolder.addHardConstraintMatch(kcontext, 5 - $totalCustomers)
and it doesn't seem to work: the hard constraints are violated and the hard score stays 0 (there are no other hard constraints, this was just a test -- also, I had the planner run for a very long time using CH + local search and breakpoints showed this method returning > 5 at various points in time including the final solution, so it wasn't just a configuration issue).
What am I missing?
Good point, thank you for pointing this mistake out in the docs.
I am fixing this as such:
Wrong: Every chain always has exactly one anchor. The anchor is a problem fact, never a planning entity.
Correct: Every chain always has exactly one anchor. The anchor is never an instance of the planning entity class that contains the chained planning variable.
I am reading https://github.com/walterhiggins/ScriptCraft/blob/master/docs/YoungPersonsGuideToProgrammingMinecraft.md and want to try it out with my son.
I see there is a list of events available, though, being new to this mod, I am not sure I can implement what I am thinking of.
Say, I have a territory around my castle, say, square of 300x300 blocks on a plain field. I know the coordinates of the square.
Now, can I track if any mob intersects the bounds from outside to inside?
If it's possible, what's the event I should look for?
Then, can I add some mechanism that would through something in the direction of the mob's position? How could it look like? Or, even just signalling that a mob is in the zone.
Generally, I want to track mobs and do perform some actions for events.
First and foremost, kudos for exploring this with your son.
I wish I could provide exacting details, but my familiarity with ScriptCraft is limited. However, given that is based on Spigot (not Forge, as suggested in the comments), I can provide an answer from that perspective. I’ll leave the nitty-gritty details of accessing POJOs to your expertise with JavaScript.
While player movements fire PlayerMoveEvent events, there is no corresponding event for other entities/mobs. If there were, it would be a matter of checking whether an entity’s location has breached your perimeter and handling it accordingly.
The simplest approach would be to define a function that calls getLivingEntities() on a World, iterator over the list to determine the type of entity and perform whatever actions are desired; say, announce that it has breached your barrier. This function would be registered as a scheduled task with the BukkitScheduler as a repeating synchronous task. I found this example for scheduling a task, though it is for a single delayed asynchronous task.
load(__folder + "../drone/drone.js");
load(__folder + "../core/scriptcraft.js");
Drone.extend("big",function(){
server.scheduler.scheduleAsyncDelayedTask(global.plugin,function(){
(new Drone()).box(1,500,100,500);
print("done");
});
});
On a large server with many entities, the approach would be optimized by accessing each Chunk containing the protected area and retrieving entities contained therein with getEntities().
I'm writing a game for Mac OS using cocos2D and Box2D. I've added a b2ContactListener subclass to my world as follows:
contactListener = new ContactListener();
world->SetContactListener(contactListener);
This works perfectly, but I am unsure of the best/accepted way to access the contact listener from other classes that don't currently have a direct reference to the contact listener.
I know I can pass a reference to other classes that need it, but what I was wondering is if there is a better way. More specifically, although I can't find a method to do this, is there some equivalent of this:
world->GetContactListener();
in Box2D?
The reason I am trying to do this is simply because I would prefer to move some game logic (i.e. whether a body is able to jump based on information from the contact listener) to the relevant classes themselves, rather than putting everything in the main gameplay class.
Thanks!
A contact listener just serves as an entry point for the four functions BeginContact, EndContact, PreSolve and PostSolve. Typically it has no member variables, so there is no reason to get it, because there is nothing to get from it.
When one of these functions is called during a world Step, you can make a note of which two things touched/stopped touching etc, but you should not change anything in the world right away, until the time step is complete.
I think the crux of this question is the method used to 'make a note' of which things touched, but that's really up to you and depends on what kind of information you need. For example if you're only interested in BeginContact, then the absolute simplest way might be to just store which two fixtures touched as a list of pairs:
std::vector< std::pair<b2Fixture*, b2Fixture*> > thingsThatTouched;
//in BeginContact
thingsThatTouched.push_back( make_pair(contact->GetFixtureA(), contact->GetFixtureB()) );
//after the time step
for (int i = 0; i < thingsThatTouched.size(); i++) {
b2Fixture* fixtureA = thingsThatTouched[i].first;
b2Fixture* fixtureB = thingsThatTouched[i].second;
// ... do something clever ...
}
thingsThatTouched.clear(); //important!!
For this to work you'll need to make the thingsThatTouched list visible from the contact listener function, so it could either be a global variable, or you could set a pointer to it in the contact listener class, or maybe have a global function that returns a pointer to the list.
If you need to keep track of more information such as what things stopped touching, or do something after the time step based on how hard things impacted when they touched etc, it will take a bit more work and becomes more specific. You might find these tutorials useful:
This one uses BeginContact/EndContact to update a list of which other things a body is touching, and uses it to decide if a player can jump at any given time:
http://www.iforce2d.net/b2dtut/jumpability
This one uses a similar method to look at what type of surfaces are currently under a car tire, to decide how much friction the surface has:
http://www.iforce2d.net/b2dtut/top-down-car
This one uses PreSolve to decide whether two bodies (arrow and target) should stick together when they collide, based on the speed of the impact. The actual 'sticking together' processing is done after the time step finishes:
http://www.iforce2d.net/b2dtut/sticky-projectiles
I think you simply can call GetContactList and then process all the contacts using iterator if you need to do it in some other place