Unable to fix score trap issue in Optaplanner for a variation of the Task Scheduling Problem - scheduling

I am working on a variation of the Task scheduling problem. Here are the rules:
Each Task has a start time to be chosen by the optimizer
Each Task requires multiple types of resources (Crew Members) who work in parallel to complete the task. i.e the task can start only when all required types of crew members are available.
There are multiple crew members of a certain type and the optimizer has to choose the crew member of each type for a task. Eg Task A requires an Electrician and a Plumber. There are many electricians and plumbers to choose from.
Here is my domain.
I have created a planning entity called TaskAssignment with 2 planning variables CrewMember and Starttime.
So, if a Task requires 3 types of crew members, then 3 TaskAssignment entities would be associated with it.
I placed a hard constraint to force the Starttime planning variable to be same for all the TaskAssignments corresponding to a particular task.
This works perfectly when I do not add any soft constraints (For example to reduce the total cost of using the resources). But when I add the soft constraint, there seems to be a violation of 1 hard constraint.
My guess if that this is due to a score trap because the starttimes are not changing as a set.
Note: I have tried to avoid using the PlanningList variable. Can anyone suggest a way to solve this issue ?

Your issue appears to be that your scoring function expects all employees on a given task to move simultaneously, but the solver actually moves them one by one. This is a problem in your domain model - it allows this situation to happen, because you only ever assign one employee at a time.
There are two ways of fixing this problem:
Fix your model, so that this is not allowed. For example, if you know that each task requires two people, let there be two variables on the entity, one for each employee. If there is a certain maximum of people per task, have a variable for each, and make them nullable, so that unassigned slots are not an issue. If you don't have a fixed amount of employees per task and you can not get to a reasonable maximum, then this approach will likely not work for you. In that case...
Write coarse-grained custom moves which always move all the employees together.

Related

avoid cache miss related to 1:N relationship in entity-component-system

How to avoid cache miss related to 1:N (pirateship-cannon) relationship in entity-component-system (ECS)?
For example, a PirateShip can have 1-100 cannons. (1:N)
Each cannon can detach/attach freely to any pirateship at any time.
For some reasons, PirateShip and Cannon should be entity.
Memory diagram
In around first time-steps, when ship/cannon are gradually created, the ECS memory looks very nice :-
Image note:
Left = low address, right = high address
Although there seems to be gaps, ShipCom and CannonCom are actually compact arrays.
It is really fast to access cannon information from ship and vice versa (pseudo code):-
Ptr<ShipCom> shipCom=....;
EntityPtr ship = shipCom; //implicitly conversion
Array<EntityPtr> cannons = getAllCannonFromShip(ship);
for(auto cannon: cannons){
Ptr<CannonCom> cannonCom=cannon;
//cannonCom-> ....
}
Problem
In later time-step, some ship / cannon are randomly created/destroyed.
As a result, Entity,ShipCom and CannonCom array has gap scattering around.
When I want to allocate them, I will get a random memory block from the pool.
EntityPtr ship = ..... (an old existing ship)
EntityPtr cannon = createNewEntity();
Ptr<CannonCom> cannonCom= createNew<CannonCom>(cannon);
attach_Pirate_Cannon(ship,cannon);
//^ ship entity and cannon tend to have very different (far-away) address
Thus, the "really fast" code above become bottom-neck. (I profiled.)
(Edit) I believe that the underlying cache miss also occur from different address between cannon inside the same ship.
For example (# is address of turret component),
ShipA has turret#01 to turret#49
ShipB has turret#50 to turret#99
In later timesteps, if turret#99 is moved to ShipA, it will be :-
ShipA has turret#01 to turret#49 + turret#99 (mem jump)
ShipB has turret#50 to turret#98
Question
What is a design pattern / C++ magic to reduce cache miss from frequently-used relation?
More information:
In real case, there are a lot of 1:1 and 1:N relationship. A certain relationship binds specifically to a certain type of component to a certain type of component.
For example, relation_Pirate_Cannon = (ShipCom:CannonCom), relation_physic_graphic = (PhysicCom:GraphicCom)
Only some of the relation are "indirect" often.
Current architecture has no limit on amount of Entity/ShipCom/CannonCom.
I don't want to restrict it in the beginning of program.
I prefer an improvement that not make game-logic coding harder.
The first solution that come to my mind is to enable relocation, but I believe it is the last resort approach.
A possible solution is to add another layer of indirection. It slows things down a bit, but it helps keeping compact your arrays and could help speeding up the whole thing. Profiling is the only way to know if it really helps.
That being said, how to do that?
Here is a brief introduction to sparse set and it's worth reading it before to proceed to better understand what I'm saying.
Instead of create relationships between items within the same array, use a second array to which to point.
Let's call the two arrays reverse and direct:
reverse is accessed through the entity identifier (a number, thus just an index in the array). Each and every slot contains an index within the direct array.
direct is accessed, well... directly and each slot contains the entity identifier (that is an index to access the reverse array) and the actual component.
Whenever you add a cannon, get its entity identifier and the first free slot in the direct array. Set slot.entity with your entity identifier and put in reverse[entity] the index of the slot. Whenever you drop something, copy the last element in the direct array to keep it compact and adjust the indexes so that relationships hold up.
The ship will store the indexes to the outer array (reverse), so that you are free to switch back and forth things within the inner array (direct).
What are advantages and disadvantages?
Well, whenever you access the cannons through the outer array, you have an extra jump because of the extra layer of indirection. Anyway, as long as you succeed in keeping low the number of accesses made this way and you visit the direct array in your systems, you have a compact array to iterate and the lowest number of cache misses.
How about sorting the entities to minimize cache misses ?
Everytime a cannon and/or ship is added/destroyed/moved sort the entities.
I am not sure if this is feasible in your ECS system;
it wouldn't be practical if you heavily depend on the entity indices, they would change everytime you sort.

how deal with atomicity situation

Hi imagine I have such code:
0. void someFunction()
1. {
2. ...
3. if(x>5)
4. doSmth();
5.
6. writeDataToCard(handle, data1);
7.
8. writeDataToCard(handle, data2);
9.
10. incrementDataOnCard(handle, data);
11. }
The thing is following. If step 6 & 8 gets executed, and then someone say removes the card - then operation 10 will not be completed successfully. But this will be a bug in my system. Meaning if 6 & 8 are executed then 10 MUST also be executed. How to deal with such situations?
Quick Summary: What I mean is say after step 8 someone may remove my physical card, which means that step 10 will never be reached, and that will cause a problem in my system. Namely card will be initialized with incomplete data.
You will have to create some kind of protcol, for instance you write to the card a list of operatons to complete:
Step6, Step8, Step10
and as you complete the tasks you remove the entry from the list.
When you reread the data from the disk, you check the list if any entry remains. If it does, the operation did not successfully complete before and you restore a previous state.
Unless you can somehow physically prevent the user from removing the card, there is no other way.
If the transaction is interrupted then the card is in the fault state. You have three options:
Do nothing. The card is in fault state, and it will remain there. Advise users not to play with the card. Card can be eligible for complete clean or format.
Roll back the transaction the next time the card becomes available. You need enough information on the card and/or some central repository to perform the rollback.
Complete the transaction the next time the card becomes available. You need enough information on the card and/or some central repository to perform the completion.
In all three cases you need to have a flag on the card denoting a transaction in progress.
More details are required in order to answer this.
However, making some assumption, I will suggest two possible solutions (more are possible...).
I assume the write operations are persistent - hence data written to the card is still there after card is removed-reinserted, and that you are referring to the coherency of the data on the card - not the state of the program performing the function calls.
Also assumed is that the increment method, increments the data already written, and the system must have this operation done in order to guarantee consistency:
For each record written, maintain another data element (on the card) that indicates the record's state. This state will be initialized to something (say "WRITING" state) before performing the writeData operation. This state is then set to "WRITTEN" after the incrementData operation is (successfully!) performed.
When reading from the card - you first check this state and ignore (or delete) the record if its not WRITTEN.
Another option will be to maintain two (persistent) counters on the card: one counting the number of records that began writing, the other counts the number of records that ended writing.
You increment the first before performing the write, and then increment the second after (successfully) performing the incrementData call.
When later reading from the card, you can easily check if a record is indeed valid, or need to be discarded.
This option is valid if the written records are somehow ordered or indexed, so you can see which and how many records are valid just by checking the counter. It has the advantage of requiring only two counters for any number of records (compared to 1 state for EACH record in option 1.)
On the host (software) side you then need to check that the card is available prior to beginning the write (don't write if its not there). If after the incrementData op you you detect that the card was removed, you need to be sure to tidy up things (remove unfinished records, update the counters) either once you detect that the card is reinserted, or before doing another write. For this you'll need to maintain state information on the software side.
Again, the type of solution (out of many more) depends on the exact system and requirements.
Isn't that just:
Copy data to temporary_data.
Write to temporary_data.
Increment temporary_data.
Rename data to old_data.
Rename temporary_data to data.
Delete the old_data.
You will still have a race condition (if a lucky user removes the card) at the two rename steps, but you might restore the data or temporary_data.
You haven't said what you're incrementing (or why), or how your data is structured (presumably there is some relationship between whatever you're writing with writeDataToCard and whatever you're incrementing).
So, while there may be clever techniques specific to your data, we don't have enough to go on. Here are the obvious general-purpose techniques instead:
the simplest thing that could possibly work - full-card commit-or-rollback
Keep two copies of all the data, the good one and the dirty one. A single byte at the lowest address is sufficient to say which is the current good one (it's essentially an index into an array of size 2).
Write your new data into the dirty area, and when that's done, update the index byte (so swapping clean & dirty).
Either the index is updated and your new data is all good, or the card is pulled out and the previous clean copy is still active.
Pro - it's very simple
Con - you're wasting exactly half your storage space, and you need to write a complete new copy to the dirty area when you change anything. You haven't given enough information to decide whether this is a problem for you.
... now using less space ... - commit-or-rollback smaller subsets
if you can't waste 50% of your storage, split your data into independent chunks, and version each of those independently. Now you only need enough space to duplicate your largest single chunk, but instead of a simple index you need an offset or pointer for each chunk.
Pro - still fairly simple
Con - you can't handle dependencies between chunks, they have to be isolated
journalling
As per RedX's answer, this is used by a lot of filesystems to maintain integrity.
Pro - it's a solid technique, and you can find documentation and reference implementations for existing filesystems
Con - you just wrote a modern filesystem. Is this really what you wanted?

State machine representation

I want to implement the GUI as a state machine. I think there are some benefits and some drawbacks of doing this, but this is not the topic of this questions.
After some reading about this I found several ways of modeling a state machine in C++ and I stuck on 2, but I don't know what method may fit better for GUI modeling.
Represent the State Machine as a list of states with following methods:
OnEvent(...);
OnEnterState(...);
OnExitState(...);
From StateMachine::OnEvent(...) I forward the event to CurrentState::OnEvent(...) and here the decision to make a transition or not is made. On transition I call CurrentState::OnExitState(...), NewState::OnEnterState() and CurrentState = NewState;
With this approach the state will be tightly coupled with actions, but State might get complicated when from one state I can go to multiple states and I have to take different actions for different transitions.
Represent the state machine as list of transitions with following properties:
InitialState
FinalState
OnEvent(...)
DoTransition(...)
From StateMachine::OnEvent(...) I forward the event to all transitions where InitialState has same value as CurrentState in the state machine. If the transition condition is met the loop is stopped, DoTransition method is called and CurrentState set to Transition::FinalState.
With this approach Transition will be very simple, but the number of transition count might get very high. Also it will become harder to track what actions will be done when one state receives an event.
What approach do you think is better for GUI modeling. Do you know other representations that may be better for my problem?
Here is a third option:
Represent the state machine as a transition matrix
Matrix column index represents a state
Matrix row index represents a symbol (see below)
Matrix cell represents the state machihe should transit to. This could be both new state or the same state
Every state has OnEvent method which returns a symbol
From StateMachine::OnEvent(...) events are forwarded to State::OnEvent which returns a symbol - a result of execution. StateMachine then based on current state and returned symbol decides whether
Transition to different state must be made, or
Current state is preserved
Optionally, if transition is made, OnExitState and OnEnterState is called for a corresponsing states
Example matrix for 3 states and 3 symbols
0 1 2
1 2 0
2 0 1
In this example if if machine is in any od the states (0,1,2) and State::OnEvent returns symbol 0 (first row in the matrix) - it stays in the same state
Second row says, that if current state is 0 and returned symbol is 1 transition is made to state 1. For state 1 -> state 2 and for state 2 -> state 0.
Similary third row says that for symbol 2, state 0-> state 2, state 1 -> state 0, state 2 -> state 1
The point of this being:
Number of symbols will likely be much lower than that of states.
States are not aware of each other
All transition are controlled from one point, so the moment you want to handle symbol DB_ERROR differently to NETWORK_ERROR you just change the transition table and don't touch states implementation.
I don't know if this is the kind of answer you are expecting, but I use to deal with such state machines in a straightforward way.
Use a state variable of an enumerated type (the possible states). In every event handler of the GUI, test the state value, for instance using a switch statement. Do whatever processing there needs to be accordingly and set the next value of the state.
Lightweight and flexible. Keeping the code regular makes it readable and "formal".
I'd personally prefer the first method you said. I find the second one to be quite counter-intuitive and overly complicated. Having one class for each state is simple and easy, if then you set the correct event handlers in OnEnterState and remove them in OnExitState your code will be clean and everything will be self contained in the corresponding state, allowing for an easy read.
You will also avoid having huge switch statements to select the right event handler or procedure to call as everything a state does is perfectly visible inside the state itself thus making the state machine code short and simple.
Last but not least, this way of coding is an exact translation from the state machine draw to whatever language you'll use.
I prefer a really simple approach for this kind of code.
An enumeration of states.
Each event handler checks the current state before deciding what action to take. Actions are just composite blocks inside a switch statement or if chain, and set the next state.
When actions become more than a couple lines long or need to be reused, refactor as calls to separate helper methods.
This way there's no extra state machine management metadata structures and no code to manage that metadata. Just your business data and transition logic. And actions can directly inspect and modify all member variables, including the current state.
The downside is that you can't add additional data members localized to one single state. Which is not a real problem unless you have a really large number of states.
I find it also leads to more robust design if you always configure all UI attributes on entry to each state, instead of making assumptions about the previous setting and creating state-exit behaviors to restore invariants before state transitions. This applies regardless of what scheme you use for implementing transitions.
You can also consider modelling the desired behaviour using a Petri net. This would be preferable if you want to implement a more complex behaviour, since it allows you to determine exactly all possible scenarios and prevent deadlocks.
This library might be useful to implement a state machine to control your GUI: PTN Engine

is it ok to combine multiple functions to a single operation in wsdl?

Is there a "rule" for this? What i'm wondering is there best practice that tells how to combine functions to an operation. For example SetRecord-operation: if id is specified for some kind of record the operation updates the record otherwise the operation creates the record. In this case return message would tell if insert or update was made, but would this be bad design (and if it is, why)?
Another example would be that there's contains-hierarchy of records and sometimes it's wanted to create all levels of hiearchy, sometimes 2 levels and sometime only 1. (bad) Example would be hiearchy car-seat-arm rest. Sometimes only a car or a single seat is created. Sometimes a car with 4 seats (each having 2 arm rests) is created. How this is supposed to map to wsdl-operations and types. If you have opinion i would like to know why? I must say that i'm bit lost here.
Thanks and BR - Matti
Although there's no problem on doing that, it violates some principles of good programming patterns.
Your methods and also your classes should do only one thing and no more then one. The Single Responsibility Principle says exactly that:
The Single Responsibility Principle (SRP) says that a class should
have one, and only one, reason to change. To say this a different way,
the methods of a class should change for the same reasons, they should
not be affected by different forces that change at different rates.
It may also violates some other principles, like:
Separation of concerns
Cohesion
I don't even have to say that it can lead to a lot of Code Smells like:
Long Method
Conditional Complexity
Check this good text.
I made some research and i think the answer above is presenting quite narrow view of wsdl inteface design. It is stupid to combine my question's example Insert and Update to Set in a way that the operation done is deduced on the data (checking if id or similar filled in request message). So in that kind of case it's bad because the interface is not really stating what will happen. Having 2 separate operations is much more clear and does not consume any more resources.
However combining operations can be a correct way to do things. Think about my hiearchical data example: It would require 13 request to have a car with 4 seats with all having both arm-rests. All border crossings should be expected as costly. So this one could be combined to single operation.
Read for example:
Is this the Crudy anti pattern?
and
http://msdn.microsoft.com/en-us/library/ms954638.aspx
and you will find out that your answer above was definitely over simplification and all programming principles can't be automatically applied in web service interface design.
Good example in SO-answer above is creating 1st order header and them orderitems with separate requests is bad because e.g. it can be slow and unreliable. They could be combined to
PlaceOrder(invoiceHeader, List<InvoiceLines>)
So the answer is: it depends what you are combining. Too low level CRUD-kinda thing is not way to go but also combining things not needed to be combined shouldn't be. Moreover defining clear interface with clear message structures that tells straight away what will be done is the key here instead of simplyfying it to multiple / single.
-Matti

iPhone: NSOperationQueue running operations serially

I have a singleton NSOperationQueue that handles all of my network requests. I'm noticing, however, that when I have one particularly long operation running (this particular operation takes at least 25 seconds), my other operations don't run until it completes.
maxConcurrentOperationCount is set to NSOperationQueueDefaultMaxConcurrentOperationCount, so I don't believe that's the issue.
Any reason why this would be happening? Besides spawning multiple NSOperationQueues (a solution that I'm not sure would work, nor am I sure it's a good idea), what's the best way to fix this problem?
Thanks.
According to the NSOperationQueue class referenceNSOperationQueueDefaultMaxConcurrentOperationCount means that "the default maximum number of operations is determined dynamically by the NSOperationQueue object based on current system conditions." I don't see anything that says the default will be > 1 (especially on a single-CPU system).
Try calling -setMaxConcurrentOperationCount: to explicitly set a larger value, and see if that helps.