0
votes

I want to insert vehicles via an source block into a specific plant. My plants are a population based on an agent type where I want to program a generally applicable logic.
The arrival is defined by an arrival rate (e.g. 5 per week) which I want to read from the database. The database consists of the following columns: start (Name of the plant where the vehicle should start), depatures_per_week (rate), destination (destination of vehicle).

For example:

  1. start= city1, depatures_per_week = 2, destination= dest1
  2. start= city1, depatures_per_week = 0.5, destination= dest2

Now I have 2 rates for one source block. I want to add them up to one rate and write the destination according to the departures per week in the variable v_destination of the vehicle. So 0.2 % would get the dest2 and 0.8 % the dest1.

How can I write a code to define the destinations of the vehicles according to the individual rates?

Thanks!

2
Sample data and desired results would make what you are saying intelligible to other people.Gordon Linoff

2 Answers

0
votes

If you're willing to assume that the sources can be modeled as Poisson processes, then you can generate them at their combined rate, and break them out to component destinations proportionally to the rate of the individual destinations, as you noted.

For your example, city1 has a combined rate λc = (λd1 + λd2) = 2 + 0.5 = 2.5. Of those, proportions λd1 / λc = 2/2.5 = 0.8 and λd2 / λc = 0.5/2.5 = 0.2 should be routed to destinations 1 and 2, respectively. So generate shipments at rate 2.5, and then generate a U, a Uniform(0,1) random number. If U <= 0.8, this shipment goes to dest1, otherwise it goes to dest2.

This generalizes in the number of destinations. If destinations d1, d2, and d3 have proportions p1, p2, and p3, then route them to d1 when U <= p1, d2 when p1 < U <= p2, and d3 otherwise. In other words, use a sequence of if/else logic comparing with the cumulative proportions.

0
votes

First, it seems you need to obtain the probability for each destination given the source. You can do this using a subquery which you consecutively join to the main query, or by using a window function. Personally I find the window function a bit clearer, so here is an example using a window function

 SELECT
      start,
      destination,
      depatures_per_week / SUM(depatures_per_week) OVER (
            PARTITION BY start
            ORDER BY  destination
            ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
      ) * 100 as percentage
 FROM trains

Full example:

postgres=# select start, destination,     departures_per_week / 
SUM(departures_per_week) OVER (  PARTITION BY start  ORDER BY  destination     
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) * 100 as percentage  
from (values ( 'city1', 2.0, 'dest1') , ('city1', 0.5, 'dest2' )) as 
trains(start, departures_per_week, destination);
 start | destination |       percentage
-------+-------------+-------------------------
 city1 | dest1       | 80.00000000000000000000
 city1 | dest2       | 20.00000000000000000000
(2 rows)

It's possible to construct Window functions in QueryDSL SQL using WindowFunction. Window functions are not available in JPA however.