i want a change on one planning variable on one planning entity to affect the same variable on certain other instances of the same planning enitity. in my case, I have a planning entity called taskResourceAllocation that has a planning variable called taskStartIndex, and i want a change to the taskStartIndex on one taskResourceAllocation to be reflected on the other taskResourceAllocations that belong to the same task, and to all the taskResourceAllocations that belong to other tasks of the same activity.
Can i annotate the taskStartIndex with both a #planningVariable and a #CustomShadowVariable ?
i saw the exam example in the sources which uses casting from exam to leading exam and following exam and shadows the change of period from the leading exam to the following exams and thought about going with that approach but i'm not sure that it suits me, as i am afraid of duplicating entities...
Sounds like you want a genuine planning variable on Task (which is then a planning entity too, don't forget it in your solver config) and then have a shadow variable on every taskResourceAllocation of that task. I doubt if that even needs to be a shadow variable, you might just be able to do getTask().getStartIndex().
But a genuine planning variable cannot be a shadow variable at the same time.
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 learned in another question that BaseUnits must be singletons. This has a number of disadvantages, including making client code a bit harder to work with (you have to store the singleton somewhere and provide access to it), and making it harder to serialize code e.g. via Fuel.
What is the benefit of this constraint? (I'm assuming it's so that users are safe if they load two Aconcagua clients which define e.g. BaseUnit subclass: #Pound differently)
In practice, is it worth it, or would it be better to treat BaseUnits like value objects? Especially in light of the fact that the paper itself uses expressions like 1 dollar, which already precludes units with the same name.
I wrote something about it in the other post.
Units are not really Singletons (as Singleton is defined in the gang of four book), and the idea is not to create a class per unit but to instantiate BaseUnit or DerivedUnit, etc., per unit you need.
So, for example you can create:
meter := BaseUnit named: 'meter'.
centimeter := ProportionalDerivedUnit basedUnit: meter convertionFactor: 1/100
named: 'centimeter'.
And then write:
1*meter = (100*centimeter)
that will return true.
As I post in the other question, equality is defined as the default, therefore identity is used.
So, you can do two things to make equality works:
To have well know objects (using global variables or a global root object to access them as Chalten does)
Modify #= in Unit and make two units equal if the have the same name (or create a subclass with this definition of #=)
The main reason to use the default #= implementation are:
It is the more generic solution
Units (in real life) are unique, so it make sense to be unique in the model
It make sense to have one "meter" object instead of creating one each time you need it.
The main disadvantage is like you see, that the first time you see it could be kind of problematic to understand, but again, you only need to have a way to access to the object and problem solved.
Regarding Fuel, the problem can be solved saving the root object that defined all units (like TimeUnit in Chalten) or implementing option 2) :-)
Hope this help! Let me know if you have more questions!
I have solved a problem using optaPlanner using incremental java in which one planning variable and one planning Entity,
But now in our project there is requirement in which many planning variables like we have to find the best Room(capacity, isAC etc etc) , Car(totalSeatsLeft , isAC etc etc ) and we do not know how many of resources are , Because everyday we need to add more resources as per the user requirement like conference room facility etc, So give me some idea so that we can make the Domain for Opta Planner.
Thanks.
Each planning variable in an entity needs to be field. Currently OptaPlanner does not support having an array (or list) which is a planning variable. It's unclear if we 'll ever want to do that (because it introduces other issues).
Why doesn't something like this work?
#PlanningEntity class Event {
long eventId;
long eventName;
#PlanningVariable Car car;
#PlanningVariable Room room;
}
lately I'm having the feeling that instances variables have the same problems of global variables, I googled about this and found this old article that more or less describes the potential problem i'm seeing.
What good practices do you use to avoid that the same problems of global variables affect instance variables or class variables?
Classes are much smaller than global structure so the impact of an instance variable is much smaller. By keeping small class sizes and adhering closely to the single responsibility principle, much of the downside of a global variable is averted. If the instance variable is created from a passed in parameter then I often make that parameter required in the constructor making the dependency explicit. Also the instance variable is encapsulated well, never being directly modified outside of the instance's methods making it very easy to determine where the instance variable is modified. Finally the instance variable must make sense to the class as a whole or must be private.
Instance variables are only accessible within a specific class. So to prevent instance variables being used too widely, keep classes small. If a class grows large, decide if parts of it that can be refactored into another, smaller class, that the original class uses.
Nor Instance variables nor global variables nor any kind of variable have "problems"... They are all tools. The problem is that sometimes a lot of programmers choose to use the "wrong tool". You have to think carefully what your choices mean, so you can make the right choice.
Using a global variable for something, like CurrentUserName... Means that you are saying that he CurrentUserName is something universally know. And that "there can be only one" CurrentUserName at each time. And that will probably be false if you ever want to allow to users to be logged at the same time (unless you get really lucky, and both users have the same name)...
A realted wrong use with instance variables is if you put the e-mail address of a User as an instance variable, and you then realize that each user can have multiple e-mail addresses.
I'd also give an example with inheritance, because I think it'll make it more clear:
A related problem with inheritance is for example if you are modeling the typical Student, Teacher problem, and you try making Student a subclass of Person and Teacher a subclass of Person. And then you realize that some persons might be both...
Student inheriting from Person is a static relationship that can't be changed at runtime. And Student and Teachers aren't static relationships... A person can be neither, and then start being a student, and then start being a teacher, and then stop being both, and yet it'll always be the same person, and that model can't handle that....
Coming back to the user, the user is "associated" with multiple e-mails account... If you put an instance variable you are stating that he is just "associated" with a single e-mail account, and you are contradicting your problem domain, and that's why you'll have problem...
The same applies if you say there is just a globally known current user name....
The problem in all cases is that you have a problem domain, and you are modeling it wrong... You have to make your program, and your model, behave similar to the problem domain.... If you don't do it, you'll have problems, whichever tool you choose to solve your problem.
BTW: I also think that User having a list of e-mail address is wrong, but that's for an entirely different set of motives. I'd actually use a
class ContactInformation
{
User contact;
EMailAddress email;
}
and remember that objects don't "own" nor "have" other objects... That's an implementation decision... Objects just "know" other objects...
I’ve been persuaded by Eric Evans’ book and am integrating DDD into my framework. All basic elements (services, repositories, bounded contexts, etc) have been implemented and now I’m looking for feedback on how to correctly integrate this.
I have some business logic which has to be performed when an entity is created or modified. This example is a very simple one. Most business logic will become much more complex.
This business logic can be split up into the following actions:
Update calculated fields;
Update a child record inside the aggregate root. When creating the aggregate root this entails creating a default child record. When updating the aggregate root this entails removing the existing child record and creating a new one if a specific field on the aggregate root has changed;
Propagate start and end date of the aggregate root to the start and end date of the child records inside the aggregate root. These must be kept in sync under certain circumstances;
Propagate a field of the aggregate root to a different aggregate root.
My first attempt is to put all of this on the aggregate root, but I feel this is not going to work. I have the following problems integrating this logic:
All these actions have to be completed as a single whole and should not be made available as separate actions. This has the result that this is going to be very difficult to test (TDD);
I am not clear on whether any of these actions can be moved out to a service. The reason for this is that they make no sense outside of the aggregate root, but it would make TDD a lot easier;
Some logic changes depending on whether a new entity is created or an existing one is modified. Should I put these two branches inside the update logic or should I make two entirely different paths that share the business code that does not differentiate based create/modify.
Any help on the above issues would be greatly appreciated and other feedback in general.
The algorithm you've described should remain in the aggregate root, elsewise you end up with an anemic domain model, excepting propagating a field to another aggregate root where I will describe what I think you should do later.
As far as TDD is concerned, a method with "package" access on the aggregate root (e.g. "calculate()", should coordinate the entire action, which either the service or repository object would normally call. This is what tests should exercise in conjunction with setting different combinations of instance variables. The aggregate root should expose its instance variables, the children collection, and each child should expose its instance variables, through getters - this allows tests to validate their state. In all cases if you need to hide information make these getters package or private access and use your unit testing framework to make them public for the purpose of testing.
For your testing environment consider mocking the repository objects (you're using dependency injection right?) to return hard coded values. Short of this consider using something like dbunit to work with a database in a known state.
As far as logic changes are concerned create vs. modify, are you referring to how to persist or is there an actual algorithm to consider? If the former, I would make the repository responsible, if the latter I would make two separate methods (e.g. "calculateCreate()" & "calculateUpdate()") which calculate() would delegate as appropriate.
Also, there's a concurrency issue to think about as well because it sounds as if calculated values rely on mutable fields. So either need to have careful locking or aggregate roots that can only be used by a client once at a time. This also applies to propagating a field across aggregates - I would probably use the repository for this purpose - but you need to think carefully on how this should or should not impact other clients who are using the repository object.