My problem is a modification of the Capacitated Vehicle Routing Problem (CVRP) that will eventually include time windows as well.
Since time windows are already built into the examples, it shouldn't be too hard for me to figure them out. However, I need to change one of the core constraints of the CVRP examples, and I'm a bit lost on how to do it.
My Model
In the system I'm trying to model, a Vehicle can leave its Depot, go to several different Customers, and load up on material. However, where my model differs from the examples is that the Vehicle can visit any Depot mid-chain to deposit its current load.
Issues
I've been going over the documentation trying to figure out how to do this, and my basic understanding so far is that I'd have to change the definition of Depot (maybe by implementing Standstill) to be able to be part of the chain of places the vehicle visits, and/or maybe just integrate Depot into Customer with some kind of special rule that a visit to a Depot empties the vehicle instead of increasing the demand.
I've also been looking at shadow variables and variable listeners, but I don't know if that's the right way to go. It's all a little confusing.
Can anyone offer some tips or advice, or point me in the right direction as to where to start before I dig myself too far into a hole?
Based on Geoffrey's suggestion, rename your Vehicle class to VehicleTrip and let it point to the previous and the next trip by giving it a value previousVehicleTrip and nextVehicleTrip, and give it a variable start time and end time (code examples in Kotlin):
class VehicleTrip(
...,
var startTime: LocalDateTime? = null,
var endTime: LocalDateTime? = null,
val previousVehicleTrip?: VehicleTrip = null,
val nextVehicleTrip?: VehicleTrip = null
) : Standstill {
...
}
You can set these values when initiating your VehicleTrips. When you get a StackOverFlowError based on the VehicleTrip.hashCode(), simply override the hashCode() function of the VehicleTrip class. (Maybe someone has a better suggestion for dealing with this?)
Updating the shadow variables.
In your Customer class, you should have a variable arrivalTime (like in the CVRPTW example) which is a custom shadow variable. In the listener class of this variable you usually only update the arrival time of a vehicle at a customer, and the arrival times of the customers that come next in this trip. Now, you also need to update all the times of the trips that come after the trip your current customer is in.
For example, you might have two trips VT1 and VT2, and three customers C1, C2, and C3. When changing from
VT1 - C1 - VT2 - C2 - C3
to
VT1 - C2 - C1 - VT2 - C3
the things you want updated are (in order)
C2.arrivalTime
C1.arrivalTime
VT1.endTime
VT2.startTime
C3.arrivalTime
VT2.endTime
Notice that in the TimeWindowedCustomer example, the variable listener only does steps 1. and 2., so we have to add steps 3. until 6.
To do this, start by adding #CustomShadowVariable annotations to the start and end times of VehicleTrip (and don't forget to mark VehicleTrip as a planning entity), which uses the same variable listener class as the time windowed customer:
class VehicleTrip(
...,
#CustomShadowVariable(
variableListenerRef = PlanningVariableReference(
entityClass = TimeWindowedCustomer::class,
variableName = "arrivalTime"
))
var startTime: LocalDateTime? = null,
...
) : Standstill {
...
}
Now in the ArrivalTimeUpdatingVariableListener class, you can add steps 3. until 6. similar to how steps 1. and 2. are implemented. Make sure that you keep the order of updating these variables, and that you notify the ScoreDirector when changing a variable with the beforeVariableChanged() and afterVariableChanged() methods.
Related
If we have a Class Book and we want to calculate the score of a Book following some rules like "if the number of pages is lower than X then we need to substract Y from the score" and using an Hexagonal Architecture. Should we place this method calculateScore() in a separate Service in case this logic changes in the future using different fields or this reponsibility should be in the Domain itself?
1st approach
package com.xxx.domain;
[...]
public class Book {
[...]
public Double score() {
[...]
}
[...]
}
2nd approach
package com.xxx.application;
[...]
public interface ScoreService {
[...]
void calculateScore(Book book);
[...]
}
Should we place this method calculateScore() in a separate Service in case this logic changes in the future using different fields or this reponsibility should be in the Domain itself?
First the clean architecture is very clear when it comes to the question "Where should business logic be placed?".
Application agnostic business logic in the entities layer.
Application specific business logic in the use case layer.
But I think your question is about something a bit different, it's about anemic or rich domain models. I can't tell you every of my thoughts here, but I have written down most of them in the blog I linked in the sentence before.
The condensed statement of mine is
rich domain models combine data and logic while anemic models separate them.
Let's think about the anemic way...
If you place the logic in a separate service it usually means that you have to expose all properties of the book. You will make them public or at least package scope if the service is in the same package.
Your question also focuses on change. You make the statement that logic changes can be better handled if the logic is put in a separate service. That's true, but it comes at a cost.
It's true that an anemic model let you add logic easier, but it is also true that each logic (each service) must have the same interpretation of the anemic model. I mean each service must know how to modify the data structure properly to keep it consistent and that will be hard to maintain when the number of services grows.
But implementing the service can also be a good intermediate step, because it will give you a hint about cohesion. The cohesion usually shows you where to place a method. E.g.
public class ScoreService {
public BookScore calculateScore(Book book, BookRentals rentals){
int pageCount = book.getPageCount();
Author author = book.getAuthor();
// calculate a new value based on pageCount and the author
// ...
OtherValue ov = book.getSomeOtherValue();
// do something with ov
int rentalCount = rentals.getCountSince(someDate);
// ... and so on
}
}
When you look at the calculateScore above you will recognize that there are a lot of get invocations on Book and less on BookRentals. This is a hint that most of the data that calculateScore needs is placed in the Book. Thus the calculateScore's cohesion is higher to Book and the method might be placed in the Bookclass. E.g.
public class Book {
public BookScore getScore(BookRentals rentals){
int pageCount = this.getPageCount();
Author author = this.getAuthor();
// calculate a new value based on pageCount and the author
// ...
OtherValue ov = this.getSomeOtherValue();
// do something with ov
int rentalCount = rentals.getCountSince(someDate);
// ... and so on
}
}
The difference is obvious:
the number of method parameters decreases. Maybe you apply DDD and Book is an aggregation root and also has access to BookRentals. Then your parameters might decrease to zero.
Since most of the properties that getScore needs are located in the Book class, you might want to lower their visibilily to private. So that uncontrolled access is not allowed.
One question that often arises when developers put the logic in the entities is: "How can an entity access data from a data store?"
My solution is to just pass a repository to the methods that need it. E.g.
public class Book {
public BookScore getScore(BookRentalRepository repo){
// ...
int rentalCount = repo.getRentalCountSince(this, someDate);
}
}
Whatever way you want to go, anemic or rich, keep the logic in a POJO. Also keep in mind that a POJO can be more than a simple data structure.
I hope my answer helps you to make a decision for your specific application.
If the calc of the score depends only on the book state, i would create a method in the book entity to calc it.
Otherwise, if it depends on other domain objects also, i would create a domain service for calculating it.
Regarding to persist the score. I would persist it just if the calc process is very complicated and takes a lot of time. Otherwise, I wouldn't persist it and calc it when need it.
In case you persist jt, you have to consider that you have to recalculate it and persist the new value every time the other values it depends on change too.
I would like to know whether the following use-case is intended to be solved with Optaplanner.
Problem description
Problem picture
There is a vehicle that needs to go from Start to End (location to location) over a mesh of nodes.
Nodes are connected with "nodeConnection" and there can be many nodeConnections between two nodes. NodeConnection also contains the price of that route.
I need a solution that tells me list of nodeConnections to take.
Number of NodeConnections that the vehicle will take is unknown. vehicle might go A - B and only take 1 NodeConnection, or go A - D and take 3 NodeConnections ( A-B connection B-C connection and then C-D connection)
What is required
Basically I'd like to give Optaplanner an input of 2 Nodes (locations) and a list of available NodeConnections and get back an "optimal" route for that input.
I'd like to know which route is cheapest, eg. in the provided image it's the one marked with a green line because total trip cost is 150.
What I tried
I thought that I could have NodeConnection collection as a #PlanningProperty, however that is currently not supported by OptaPlanner.
Then I came across planning variable not support Collect and tried to have a RouteNodeConnection as a many-to-many relation between a Route and a NodeConnection, eg. 1 route would have N NodeConnections - but we do not know how much, we just want the "best" route.
The problem at the moment is "telling" OptaPlanner what we want and setting up the Constraints.
VRP repository seemed similar but there are differences:
I only use 1 vehicle, not an entire fleet
no need to go back to the starting point
no need to calculate various distances since NodeConnection prices/distances are already defined
I read about chained #PlanningVariables and it seems that that approach must be taken here to create a chain of NodeConnections, however I am not sure how to setup the constraints and get OptaPlanner to actually return the best route.
Is this something that can be done with OptaPlanner or a more simpler solution might be enough here. I looked at Dijkstra's Algorithm to get the shortest path and then we'd have to figure out how to "weight" other constraints I will introduce later and so on but OptaPlanner seems more fit for this problem - especially considering the fact that other than price, we're most likely going to have additional 5 hard and over 10 soft constraints that would be hard to "weigh" in graph algorithms.
Any tips on how to approach this problem are very welcome.
Classes for reference:
public class Node {
private String Name;
}
public class NodeConnection {
private Node StartPosition;
private Node EndPosition;
private BigDecimal Price;
}
public class Route {
private Node Start;
private Node End;
private BigDecimal RoutePrice;
private List<NodeConnection> NodeConnections;
}
// "Many-to-many" relation
public class RouteNodeConnection {
private Route Route;
private NodeConnection NodeConnection;
}
For example 1 employee class is there contains employee id and employee name,and i created object for this employee class, then here 2 threads are there, these 2 threads want to execute the same employee object, then what problem will occur?
If 1 thread(t1) changes the value of employee id to 1 and another thread(t2) change the value of employee id to 2, then what problem will occur? and how to resolve it?
I checked in internet and i got it as race condition, but didn't understand completely.
Here thread names are t1,t2 and employee class is
public class Employee{
private int employeeid;
private string empname;
}
employee object creation:
Employee employee = new Employee()
if 1 thread(t1) changes the value of employee id to 1 and another thread(t2) change the value of employee id to 2, then what problem will occur?
That scenario is called a data race. If two threads each set the same variable to one value or another, then the end result will be that the variable holds one value or the other. It is not actually possible for two threads to store to the same location at the same time: The memory system will serialize the stores. So, the outcome depends on which one went first and which one went second.
There's no practical way to predict which one will go first and which will go second, so that means there's no practical way to predict the outcome. In most programs, that's considered to be a Bad Thing.
and how to resolve it?
That's up to you. Really! There is no correct answer to which thread should win the race. Usually, we "resolve" the problem by designing our programs so that their behavior doesn't depend on data races.
In your example, you have two threads that are trying to do two incompatible things. They both want to assign the same variable, but they disagree on what its value should be. That's a sign of Bad Design. It probably means that you haven't really thought about what that variable stands for in your program, or you haven't really thought about why or when it should ever be changed.
P.S., If a field of an Employee object holds an employee's ID, then it almost certainly should be a final field.
Sorry for the slightly demented wording of this question, but I'm very new to agent-oriented thinking (are these 'patterns'?) and only slightly less new to java, and I'm struggling with what feels like a very basic problem.
I'm doing a lot of this 'intuitively' (i.e. blindly) rather than trying to understand someone else's code - partly because I struggle to understand code that's 'above my level', but also because I hope doing it 'my way' will help me appreciate the right way later.
Basically, I'm modelling an agent (a robot vacuum) in an environment (a House). A House contains a collection (HashMap) of Rooms. A House has a method getRoom(int key) that returns a Room matching the given key. The Agent has a State, which at this point keeps track of a room ID (which is also the key in the House), which is the room the robot is 'in' for the purposes of navigating the world; a State also describes whether or not the room is known to be dirty. When the agent is constructed, it's initialised with an ID (It must be created 'in a room'), but it is not given the dirty/clean status of the Room. I want the agent to check for dirt - this would involve invoking the getRoom() method in House. However, with the Java I've learned so far, I don't know how to do this. I know I could access that method by creating a House inside java, or by making the method static, but those won't work - the agent needs to know about the SPECIFIC house that is in memory, the one that has been initialised with Rooms.
tl;dr: How can an Agent object obtain a reference to an object that is stored in a HashMap inside another Environment object?
P.S here is my imagined model for the 'higher level' perspective enabled by this approach:
I kind of intuitively wanted the Agent to be wholly responsible for its own precepts and behaviours, so that the code higher up would look more like:
agent.percieve() //agent checks the room it thinks its in for dirt and exits
if (agent.gotDirt()) agent.clean() //agent activates its cleaning device if it found dirt in this room
if (agent.gotDirt() == false) agent.move() //agent picks an exit and leaves the room
The vacuum cleaner (i.e. what you call an "Agent", but why name it like this since it's, in fact, a vacuum cleaner?) simply needs a reference to the House object it belongs to:
// a single House is constructed
House house = new House();
// omitted: add rooms to the house...
// create a first vacuum cleaner for the house. A reference to the house is given to this cleaner
VacuumCleaner vacuumCleaner = new VacuumCleaner(house);
System.out(vacuumCleaner.isRoomClean(2)); // prints false, because room 2 is full of dirt
vacuumCleaner.cleanRoom(2);
System.out(vacuumCleaner.isRoomClean(2)); // prints true, because the vacuum cleaner removed the dirt from room 2
// now let's create a second vacuum cleaner for the same house
VacuumCleaner vacuumCleaner2 = new VacuumCleaner(house);
System.out(vacuumCleaner2.isRoomClean(2)); // prints true, because room 2 has no dirt: it has previously been removed from the room by the first vacuum cleaner.
EDIT
And here's how the VacuumCleaner class would look like:
public class VacuumCleaner
/**
* The house that this vacuum cleaner cleans
*/
private House house;
public VacuumCleaner(House houseToClean) {
this.house = houseToClean;
}
public boolean isRoomDirty(int roomId) {
// find the room in the house, and see if it contains dirt
}
public void cleanRoom(int roomId) {
// find the room in the house, and remove dirt from it
}
}
My question is about scalable logic branching.
Is there an elegant way to do branching logic trees in java (although I've always thought that they look more like root systems, but that's beside the point). I'm trying to develop a very simple text based adventure game as a side project to my studies, but I'm not sure what the best way to go about navigating these large logic systems is.
What I'm trying currently is an array that holds four values: stage, location, step, choice.
[EDIT - added choice variable to store user choice, changed name to reflect actual name in my code so that I don't get confused later]
int[] decisionPoint = {stage, location, step, choice};
A stage is supposed to represent a single major part of the tree.
A location is supposed to represent my location within the tree.
A step is supposed to represent my progress through a given location.
Choice is the user input
At the moment, since I'm only dealing with a single tree, stage isn't being used much. Location and step are working well, but any time I get into a decision within a step the system breaks down.
I could keep creating more and more variables to represent deeper and deeper layers into the tree, but I feel like Java probably provides a better solution somewhere.
Currently, I'm using switch statements to figure out where in the program I am based on the values stored in nextQuestion. Is there something better? Or, is there a way to extend the array beyond what I'm using here to make it a bit more polymorphic (in the methods for the individual questions/text/whatever could I just have it create a larger array from a smaller one? Could I pass a smaller array as an argument but define the parameter as a larger array?)
//Switch example
switch(LocationTracker.getLocation()) { //start location finding switch
case 1 : //Location 1
switch (LocationTracker.getStep()) {//start location1 switch
case 1 :
location1s1(graphicsStuff);
break;
case 2 :
location1s2(graphicsStuff);
break;
} break; //end location1 switch
case 2 : //Location 2
switch (LocationTracker.getStep()) {
//same stuff that happened above
} break;
Everything I find online just brings me to irrelevant pages about different online survey creators that I can use. If I could view their source-code that'd be kind of nice, but since I can't, I'm hoping you guys can help. :)
[EDIT]
Wow, what a nice response in such a short time at such an early hour!
I'll try to go into very explicit detail about how I'm solving the problem right now. It's worth mentioning that this does technically work, it's just that every time I need a branch inside a branch I have to create another variable inside a string array to keep track of my position, and really I'm just fishing for a solution that doesn't need an infinitely expanding string as the program becomes more and more complex.
Right now I have a program with 5 classes:
The Main Class which starts the GUI
The GUI class which provides three services: userInput, userOptions, and outputArea.
The DecisionTreeStage1 class which handles the logic of my problem at the moment (using switch statements).
The LocationTracker class which is designed to track my location within the DecisionTreeStage1 class
The DialogueToOutput class which changes the options that the users have, and also updates the output fields with the results of their actions.
Special point of interest:
I want to have multiple decision branches at some point, and one main tree (maybe call it Yggdrasil? :D). For now, the DecisionTreeStage1 represents a very isolated system that isn't planning to go anywhere. I hope to use the stage variable stored in my array to move from one major branch to the next (climbing the tree if you will). My current implementation for this just uses nested switch statements to decide where I'm going. This imposes an annoying limitation: every time my path gets deeper and deeper I need another variable in my array to store that data. For example:
//Switch example deeper
switch(LocationTracker.getLocation()) { //start location finding switch
case 1 : //Location 1
switch (LocationTracker.getStep()) {//start location1 switch
case 1 :
switch(LocationTracker.getChoice()) {//Make a decision at this step based on the user choice
Given this example, what if the user choice doesn't just lead to some logic? (In this case, just an update to the outputArea) What if it leads to ANOTHER branching path? And that leads to another branching path? Eventually, I would want all paths to converge on the same spot so that I could move to the next "stage."
My real hope is to make this problem infinitely scalable. I want to be able to go as deep into one branch as I need to, without having to create a static and arbitrary number of variable declarations in my decisionPoint array every time.
I haven't been able to find much information about this, like I said.
Let me try presenting this question: Are there any other branching logic statements other than:
if(something)
stuff;
else
otherStuff;
and
switch(something) {
case 1:
stuff;
break;
case 2:
otherStuff;
break;
And if so, what are they?
PS - I know about the ternary if statement in Java, but it doesn't seem useful to what I'm doing. :)
You can build normal tree structures in Java, similar to the trees that can be built in C. Regardless if object references are theoretically pointers or not, they substitute pointers nicely in the tree constructions:
class Node {
Node left;
Node right;
Node parent;
}
You can also build graphs (cyclic graphs including) and linked lists no problem. There is no any obvious reason why large structures should have problems (apart from that object reference uses some memory).
Instead of returning a value, you could return an Callable which just needs to be executed. This can then be chained (theoretically infinitely)
You can have a LocationEvaluation for example which could return a SpecificLocationEvaluator which in turns returns one of StepEvaluation or ChoiceEvaluator or somesuch. All of these would implement the Callable interface.
Depending on how you do it, you could have strict type checking so that a LocationEvaluation always returns a SpecificLocationEvaluator or it can generic and then you can chain any of then in any order.
Once you build the structure, out, you would essentially have a tree which would be traversed to solve it.
I don't understand the problem adequately to be able to provide more concrete implementation details - and apologies if I misunderstood some of the branching (i.e. the names of the classes / steps above)