How to model a time-dependent vehicle routing problem with time windows in octapy? - optaplanner

I am looking to model a vehicle routing problem with time windows on OctaPy. Specifically, this problem involves traffic enforcement on public roads, so parking wardens need to survey carparks and road segments and visit them more than once during a 24-hour period.
I refer to the answer in the following question as foundation to develop my problem:
Is it possible to create a VRP solution using NetworkX?
I have a few questions regarding the modelling:
How does OctaPy model time-dependency, that is a different edge weight representing travel duration depending on the time of day?
How do I model the demand points if each point needs to be visited X times?
If a demand point is to be visited X times, how can I enforce a time window gap such that the duration between visits is at least a fixed duration (e.g. 1 hour)?

OptaPy models time-dependency the way you model time-dependency. That is, whatever you use to model time-dependency (may it be an edge, a list, a matrix, a class, etc.), OptaPy can use it in its constraints.
If X is known in advance, for each demand point, you create X copies of it and put it in the #problem_fact_collection_property field. If X is not known in advance, consider using real-time planning (https://www.optapy.org/docs/latest/repeated-planning/repeated-planning.html#realTimePlanning).
This depends on how you implement your time dependency. This would be easier when OptaPy supports the new VariableListener API for List Variable (as well as the builtin list shadow variables) that OptaPlanner has. Until then, you need to do the calculation in a function. Make Edge a #planning_entity and give it a inverse relation shadow variable (https://www.optapy.org/docs/latest/shadow-variable/shadow-variable.html#bidirectionalVariable). Add a method get_arrival_time(edge) to Vehicle that get the estimated time of visit for a given Edge in its visited_edges_list.
def less_than_one_hour_between(visit_1: Edge, visit_2: Edge):
visit_1_arrival_time = visit_1.vehicle.get_arrival_time(visit_1)
visit_2_arrival_time = visit_2.vehicle.get_arrival_time(visit_2)
duration = visit_2_arrival_time - visit_1_arrival_time
return timedelta(hours=0) <= duration <= timedelta(hours=1)
def one_hour_between_consecutive_visits(constraint_factory):
return (
constraint_factory.for_each(Edge)
.join(Edge, Joiners.equal(lambda edge: edge.graph_from_node),
Joiners.equal(lambda edge: edge.graph_to_node))
.filter(lambda a, b: a is not b and less_than_one_hour_between(a, b))
.penalize('less than 1 hour between visits', HardSoftScore.ONE_HARD)

Related

What's the fastest way to find if a point is in one of many rectangles?

So basically im doing this for my minecraft spigot plugin (java). I know there are already some land claim plugins but i would like to make my own.
For this claim plugin i'd like to know how to get if a point (minecraft block) is inside a region (rectangle). i know how to check if a point is inside a rectangle, the main problem is how to check as quickly as possible when there are like lets say 10.000 rectangles.
What would be the most efficient way to check 10.000 or even 100.000 without having to manually loop through all of them and check every single rectangle?
Is there a way to add a logical test when the rectangles get generated in a way that checks if they hold that point? In that case you could set a boolean to true if they contain that point when generated, and then when checking for that minecraft block the region (rectangle) replies with true or false.
This way you run the loops or checks when generating the rectangles, but when running the game the replies should happen very fast, just check if true or false for bool ContainsPoint.
If your rectangles are uniformly placed neighbors of each other in a big rectangle, then finding which rectangle contains point is easy:
width = (maxX-minX)/num_rectangles_x;
height = same but for y
idx = floor( (x - minX)/width );
idy = floor( (y - minY)/height );
id_square = idx + idy*num_rectangles_x;
If your rectangles are randomly placed, then you should use a spatial acceleration structure like octree. Then check if point is in root, then check if point is in one of its nodes, repeat until you find a leaf that includes the point. 10000 tests per 10milliseconds should be reachable on cpu. 1 million tests per 10ms should be ok for a gpu. But you may need to implement a sparse version of the octree and a space filling curve order for leaf nodes to have better caching, to reach those performance levels.

How to determine when to accelerate and decelerate to reach a given destination?

I'm creating a computer game in which there is a computer-controlled car that needs to travel along a straight line (thus making this problem effectively 1-dimensional) and reach a destination coming to a rest at 0 velocity. This car "thinks" every second and decides whether (and by how much) to accelerate or decelerate.
To summarize, I want the car to accelerate as strongly as possible and then stop as rapidly as possible.
Here are the variables that the car must respect:
- RemainingDistance = Our current remaining distance to the destination in meters.
- Velocity = Our current velocity towards the destination in meters/second.
- MaxVelocity = The maximum speed the car can reach.
- Acceleration = The change in velocity per second. The car can change its acceleration every second to any number in the range [0, Acceleration].
- Deceleration = The change in velocity per second. The car can change its deceleration every second to any number in the range [0, Deceleration].
So to be as clear as I can, here's the math that runs every second to update the car simulation:
Acceleration = some amount between [Deceleration, Acceleration] as chosen by the computer
Velocity = Velocity + Acceleration
RemainingDistance = RemainingDistance - Velocity
So my question is: Every time the car "thinks", what formula(s) should it use to determine the ideal value of Acceleration in order to reach its destination (with a 0 final velocity) in as little time as possible?
(In the event that the car's initial velocity is too high and it can't decelerate fast enough to achieve 0 velocity by the time it reaches its destination, then it should come to a rest as close as possible to the destination.)
Please let me know if you have any questions.

Redeclaring two Medium packages in One system component

I am new to modelica, and i don't have this much experience in it, but i got the basics of course. I am trying to model a micrfluidic network. The network consists of two sources of water and oil, controlled by two valves. The flow of the two mediums interact at a Tjunction and then into a tank or chamber. I don't care about the fluid properties of the mixture because its not my purpose. My question is how do redeclare two medium packages (water and oil) in one system component such as the Tjunction or a tank in order to simulate the system. In my real model, the two mediums doesn't meet, becuase every medium passes through the channels at a different time.
I attached the model with this message. Here's the link.
https://www.dropbox.com/s/yq6lg9la8z211uc/twomediumsv2.zip?dl=0
Thanks for the help .
I don't think you can redeclare a medium during simulation. In your case (where you don't need the mixing of the two fluids) you could create a new medium, for instance called OilWaterMixture, extending from Modelica.Media.Interfaces.PartialMedium.
If you look into the code of PartialMedium you'll see that it contains a lot of partial ("empty") functions that you should fill in in your new medium model. For example, in OilWaterMixture you should extend the function specificEnthalpy_pTX to return the specific enthalpy of your water/oil mixture, for a certain water/oil mixture (given by the mass fraction vector X). This could be done by adding the following model to the OilWaterMixture package:
redeclare function extends specificEnthalpy_pTX "Return specific enthalpy"
Oil = Modelica.Media.Incompressible.Examples.Essotherm650;
Water = Modelica.Media.Water.StandardWater;
algorithm
h_oil := Oil.h_pT(p,T);
h_water := Water.specificEnthalpy_pT(p,T);
h := X[0]*h_oil + X[1]*h_water;
end specificEnthalpy_pTX;
The mass fraction vector X is defined in PartialMedium and in OilWaterMixture you must define that it has two elements.
Again, since you are not going to actually use the mixing properties but only mass fraction vectors {0,1} or {1,0} the simple linear mixing equation should be adequate.
When you use OilWaterMixture in the various components, the error log will tell you which medium functions they need. So you probably don't need to extend all the partial functions in PartialMedium.

SUMO - simulating traffic scenario

How can I simulate continuous traffic flow from historical data which consists of:
1. Vehicle ID;
2. Speed;
3. Coordinates
without knowing the routes of each vehicle ID.
This is a commonly asked questions but probably hasn't been answered here before. Unfortunately the answer largely depends on the quality of your input data mainly on the frequency / distance of your location updates (it would be also helpful if there is a time stamp to each datum) and how precise the locations fit your street network. In the best case there is a location update on each edge of the route in the street network and you can simply read off the route by mapping the location to the street. This mapping can be done using the python sumolib coming with sumo:
import sumolib
net = sumolib.net.readNet("myNet.net.xml")
route = []
radius = 1
for x, y in coordinates:
minDist, minEdge = min([(dist, edge) for edge, dist in net.getNeighboringEdges(x_coordinate, y_coordinate, radius)])
if len(route) == 0 or route[-1] != minEdge.getID():
route.append(minEdge.getID())
See also http://sumo.dlr.de/wiki/Tools/Sumolib#locate_nearby_edges_based_on_the_geo-coordinate for additional geo conversion.
This will fail when there is an edge in the route which did not get hit by a data point or if you have a mismatch (for instance matching an edge which goes in the "wrong" direction). In the former case you can easily repair the route using sumo's duarouter.
> duarouter -n myNet.net.xml -r myRoutesWithGaps.rou.xml -o myRepairedRoutes.rou.xml --repair
The latter case is considerably harder both to detect and to repair because it largely depends on your definition of a wrong edge. There are almost clear cases like hitting suddenly the opposite direction (which still can happen in real traffic) and a lot of small detours which are hard to decide and deserve a separate answer.
Since you are asking for continuous input you may also be interested in doing this live with TraCI and in this FAQ on constant input flow.

Optaplanner - timewindow is not fulfilled

I am using OptaPlanner for a business related optimization.
Concerning 6.1.0. Final version: When I modify the optimization problem, so that a vehicle has to arrive inside of a time window (with earliest possible and latest possible arrival time, punished by hardscores when too early or too late) and when I take only 1 vehicle with two customers, whereby timewindow 1 is much earlier than timewindow 2 (end of timewindow 1 + travelling time to customer 2 < start of timewindow 2) then the vehicle meets the timewindow 1 exactly at earliest time, but the arrival at customer 2 is too early.
The vehicle (2363) starts from depot 270 first to customer 13 (time window is 8:50-10:50) and arrives exactly at 8:50. The working duration there is 75 min. The departure is at 10:05 and the vehicle arrives at 10:12 at customer 16 (time window is 15:45-17:45).
In some business cases it is better to wait instead to arrive too early.
How can I force the vehicle to WAIT, so that it arrives at the location of next customer in time?
PS: The circles show the time window of possible arrival time (inner circle: 0-12h, outer circle: 12-24h). Times and distances between locations are determined from GraphHopper
So you want to wait at the previous standstill (= the previous customer or the depot), instead of at the current customer?
In the OptaPlanner VRP example, departureTime = arrivalTime + duration. So arrivalTime is a shadow variable (based on previousStandstill) and departureTime is just a calculation on top of that (so departureTime itself is not shadow variable, because it isn't even a field (or put differently because it's not a java variable it's cannot be a planning variable (genuine or shadow)).
In your variant, make departureTime a shadow variable too, defined as follows: departureTime = Math.max((arrivalTime + duration), nextCustomer.readyTime - drivingTime). That new shadow variable (and therefor it's VariableListener) depends on the planning variables arrivalTime and nextCustomer. So a shadow var depending on shadow vars.
Notice how there's NO cycle in this proposal: nextCustomer.readyTime is used, but readyTime is a problem fact.
You might need to upgrade to 6.2.0.CR2 or higher for this, because 6.1 might not yet support shadow variables that depend on shadow variables (I don't recall any more). I also fear that optaplanner doesn't automatically reorder variable listener triggering yet to follow the hierarchy (feel free to make a jira about that), so that means you'll have to declare the getters with variable listeners as follows: previousStandstill, nextCustomer, arrivalTime, departureTime.
VariableListener triggering order will be formalized more in future versions.