Team Formation using Drools Planner - drools-planner

Advice on whether it would be possible to implement this is Drools Planner:
The problem involves team formation.
Strong constraints:
Students must be placed in N groups
Each group must contain X group members
Weak Constraints (possible ordered or weighted):
Each group must have a member that has a Maths score > Y
Each group must consist of members all with the same interest
(weak constraints may need to be added at runtime)

Yes, it looks a lot like the Manners2009 example, which is about assign each seat (= group spot) of each table (= group) to a guest (= student) and make sure that each table (= group) has at least 1 democrat (= student with Maths score > Y). Then just add a soft constraint for the same interest rule.
The Manners2009 example isn't up to date with the us of generic move factories in 5.4.0.Final (it will be in 5.5.0.Beta1) and uses a SimpleScore instead of HardAndSoftScore, so also take a look at the curriculum course example for inspiration.
To avoid a "score trap" (see manual) on the soft constraint of the same interest rule, I suspect you 'll have to use the swapPillarMove too (on top of the normal changeMove and swapMove's).

Related

Always valid domain model entails prefixing a bunch of Value Objects. Doesn't that break the ubiquitous language?

The principle of always valid domain model dictates that value object and entities should be self validating to never be in an invalid state.
This requires creating some kind of wrapper, sometimes, for primitive values. However it seem to me that this might break the ubiquitous language.
For instance say I have 2 entities: Hotel and House. Each of those entities has images associated with it which respect the following rules:
Hotels must have at least 5 images and no more than 20
Houses must have at least 1 image and no more than 10
This to me entails the following classes
class House {
HouseImages images;
// ...
}
class Hotel {
HotelImages images;
}
class HouseImages {
final List<Image> images;
HouseImages(this.images) : assert(images.length >= 1),
assert(images.length <= 10);
}
class HotelImages {
final List<Image> images;
HotelImages(this.images) : assert(images.length >= 5),
assert(images.length <= 20);
}
Doesn't that break the ubiquitous languages a bit ? It just feels a bit off to have all those classes that are essentially prefixed (HotelName vs HouseName, HotelImages vs HouseImages, and so on). In other words, my value object folder that once consisted of x, y, z, where x, y and z where also documented in a lexicon document, now has house_x, hotel_x, house_y, hotel_y, house_z, hotel_z and it doesn't look quite as english as it was when it was x, y, z.
Is this common or is there something I misunderstood here maybe ? I do like the assurance it gives though, and it actually caught some bugs too.
There is some reasoning you can apply that usually helps me when deciding to introduce a value object or not. There are two very good blog articles concerning this topic I would like to recommend:
https://enterprisecraftsmanship.com/posts/value-objects-when-to-create-one/
https://enterprisecraftsmanship.com/posts/collections-primitive-obsession/
I would like to address your concrete example based on the heuristics taken from the mentioned article:
Are there more than one primitive values that encapsulate a concept, i.e. things that always belong together?
For instance, a Coordinate value object would contain Latitude and Longitude, it would not make sense to have different places of your application knowing that these need to be instantiated and validated together as a whole. A Money value object with an amount and a currency identifier would be another example. On the other hand I would usually not have a separate value object for the amount field as the Money object would already take care of making sure it is a reasonable value (e.g. positive value).
Is there complexity and logic (like validation) that is worth being hidden behind a value object?
For instance, your HotelImages value object that defines a specific collection type caught my attention. If HotelImages would not be used in different spots and the logic is rather simple as in your sample I would not mind adding such a collection type but rather do the validation inside the Hotel entity. Otherwise you would blow up your application with custom value objects for basically everything.
On the other hand, if there was some concept like an image collection which has its meaning in the business domain and a set of business rules and if that type is used in different places, for instance, having a ImageCollection value object that is used by both Hotel and House it could make sense to have such a value object.
I would apply the same thinking concerning your question for HouseName and HotelName. If these have no special meaning and complexity outside of the Hotel and House entity but are just seen as some simple properties of those entities in my opinion having value objects for these would be an overkill. Having something like BuildingName with a set of rules what this name has to follow or if it even is consisting of several primitive values then it would make sense again to use a value object.
This relates to the third point:
Is there actual behaviour duplication that could be avoided with a value object?
Coming from the last point thinking of actual duplication (not code duplication but behaviour duplication) that can be avoided with extracting things into a custom value object can also make sense. But in this case you always have to be careful not to fall into the trap of incidental duplication, see also [here].1
Does your overall project complexity justify the additional work?
This needs to be answered from your side of course but I think it's good to always consider if the benefits outweigh the costs. If you have a simple CRUD like application that is not expected to change a lot and will not be long lived all the mentioned heuristics also have to be used with the project complexity in mind.

Proper modeling on UML class diagram

In an UML class diagram:
a) Do you have to state attributes that are aggregated? Or is it enough with the arrows indicating aggregation?
b) Do I have to add "id" as an attribute or is it a given?
Thanks.
You are using a shared aggregation in the picture. That does not have any defined semantics as per UML 2.5 (see p. 110). If you need a composite aggregation the diamond must be filled. In that case the aggregated object will be deleted along with the aggregating one (the latter must assure that constraint). In your model it makes no sense. No employee aggregates a department. Even vice versa I would have doubts or at least reason for discussion.
An id is only needed if it has a business purpose (e.g. an article number). If you transform your model to a database you introduce an artificial id for technical reasons. But on an abstract business level they are not modeled.
Your models only differ in the use of attributes for associated classes. The B variant is preferred. But you need to place the attributes as role names towards the associated classes (as -department and -branch). What you have placed in the middle of the connectors is rather the association name. Badly chosen with the + in front. Naming associations is rarely needed. So get rid of that. Role names shall be placed near the class that takes the role. Also it's a good idea to use the dot-notation to show that the roles represent owned properties. Just place a small black dot near the left hand side of both (near where the role names should go).
As for the dot-notation UML 2.5 states on p. 18:
Dot notation is used to denote association end ownership, where the dot shows that the Class at the other end of the line owns the Property whose type is the Class touched by the dot. See 11.5.4 for details of Association notation and 11.5.5 for examples.
Also as JimL. commented the A-version uses associations plus attributes which introduces redundancy. This is not illegal but likely not intended and at least leads to confusion.

DEAP cooperative coevolution

I don't quite understand the example of cooperative coevolution described in the documentation for DEAP.
What is the target_set, that appears when evaluating individual fitness ?
Why is the line for updating fitness
ind.fitness.values = toolbox.evaluate([ind] + r, target_set)
rather than
ind.fitness.values = toolbox.evaluate([ind])
?
How I understand it is that the evaluation of an individual from a certain species can only be done in the context of other individuals from all other species.
The individuals that will "help" in the evaluation of other species are the representatives.
In the first generation, no evaluations have been made so the representatives are chosen randomly. After the evaluation of a certain species, its representative is chosen as the fittest one.
To answer your question, I would implement the evaluation function such that it receives a list of individuals, each one from a different species and as they say "possibly some other arguments". Since the individual from the species being currently evaluated will always be in the first index of the list in [ind] + r, I don't see a clear reason to send the target_set variable as well (moreover, they did not set it in their code).

self-referencing core data model for specific use case

I have seen other posts that self-referencing a core data entity is possible, but I feel my use case is a little different and I am having a hard time understanding how to wire things up.
I have a Person entity and I want to track 2 things:
- an array of Person entities whose profile the user "visited"
- an array of Person entities who have viewed "this" users profile
The inverse logic is making it hard to understand.
I have User A, User B.
If user A visits user B, the following relationships should be set up:
- User A's visited profiles shows User B.
- User B should see that user A visited him.
This is a To-Many relationship as things are "interesting" only when you know who you followed and who's following you... :-)
Am I making this more complex than it is? :-(
What I tried:
Person Entity
-visitedProfiles : inverse is viewedProfiles (To-Many relationship)
-viewedProfiles : inverse is visitedProfiles (To-Many relationship)
Result:
User A --> User B (user A visists user B)
User A sees User B in BOTH (visitedProfiles and viewedProfiles) relationship.
Side-effect:
Also, regardless of how many profiles I visit, "visitedProfiles" and "viewedProfiles" always has only 1 item in the array (ie. the last profile I visited)
It's not an especially complicated case. I personally find your choice of words a bit confusing, though. "viewedProfiles" and "visitedProfiles" don't sound like inverses of each other to me. How about "viewedProfiles" and "viewers" instead?
Regardless of the word choice, though, set up the relationships as you have described. If you add B to "viewers of A", then B's "viewedProfiles" will also be updated.
Your side effect of knowing the most recent view/visit takes a little extra work. You could use an ordered relationship for the viewers/viewees; that feels like the simplest thing to do. Or you could add a new entity, a Visit, which notes the viewer, the viewee, and the time/date of the visit. But that second approach is indeed more complicated.
Your definition of the relationships looks OK. You can call either
[a addVisitedProfilesObject:b];
or
[b addViewedProfilesObject:a];
to add b to a.visitedProfiles and a to b.viewedProfiles.

Modelling a vending box using Alloy

I am trying to model a vending machine program using alloy . I wish to create a model in which I could insert some money and provide the machine a selection option for an item and it would provide me the same and in case the money supplied is less then nothing would be provided .
Here I am trying to input a coin along with a button as input and it should return the desired item from the vending machine provided the value ie. amount assigned to each item is provided as input. So here button a should require ten Rs, button b requires 5 rs, c requires 1 and d requires 2 . The op instance is the item returned once the money required is inserted. opc is the balance amount of coins to be returned. ip is input button and x is money input . How can I provide an instance such that it intakes multiple coins as input and also if the amount is greater than the item cost then it should return a no of coins back. If I could get some help it'll be greatly appreciated.
If I were you, I'd proceed by asking myself what kinds of entities I care about; you've done that (signatures for coins and items -- do you also need some notion of a customer?).
Next, I'd ask myself what constitutes a legal state for the system -- sometimes it helps to think about it backwards by asking what would constitute an illegal or unacceptable state.
Then I'd try to define operations -- you've already mentioned insertion of money and selection of an item -- as transitions from one legal state of the system to the next.
At each stage I'd use the Analyzer to examine instances of the model and see whether what I'd done so far makes sense. One example of this pattern of defining entities, states, and state transitions in that order is given in the Whirlwind Tour chapter of Daniel Jackson's Software Abstractions -- if you have access to that book, you will find it helpful to review that chapter.
Good luck!
module vending_machines
open util /ordering[Event]
fun fst:Event{ordering/first}
fun nxt:Event->Event{ordering/next}
fun upto[e:Event]:set Event{prevs[e]+e}
abstract sig Event{}
sig Coin extends Event{}
pred no_vendor_loss[product:set (Event-Coin)]
{
all e:Event | let pfx=upto[e] | #(product&pfx)<=#(Coin&pfx)

Resources