Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • wang/pn4ecss
1 result
Select Git revision
Show changes
Commits on Source (2)
model CarSharingSystemSimplified
model CarSharingSystemCaseStudy
// Parameters
parameter Integer numCars = 10 "Number of cars in the system";
parameter Integer numUsers = 5 "Number of users in the system";
parameter Integer numUsers = 1 "Number of users in the system";
parameter Real userArrivalRate = 1.0 "User arrival rate (users per time unit)";
parameter Real returnRate = 0.5 "Car return rate";
parameter Real chargingTime = 1.0 "Time to fully charge a car";
parameter Real usageTime = 1.0 "Car usage time by a customer";
parameter Real userPatience = 2.0 "Maximum waiting time for users";
parameter Real userPatience = 10.0 "Maximum waiting time for users";
// State variables for objectives
Real totalWaitingTime(start=0) "Total waiting time for users";
Real carUtilization(start=0) "Car utilization over time";
Real carsInUse(start=0) "Number of cars in use";
// Discrete Variables for Intermediate Calculations
discrete Real waitingTimeIncrement(start=0);
discrete Real carUtilizationIncrement(start=0);
Real totalCarsRented(start=0) "Total number of cars rented";
discrete Integer usersLeaving(start=0);
// Discrete Place: Number of free places in the station
PNlib.Components.PD PSCii(nIn = 1, nOut = 1) annotation(
......@@ -38,10 +36,10 @@ model CarSharingSystemSimplified
PNlib.Components.PD PSDi(nIn = 1, nOut = 2, startTokens = numUsers) annotation(
Placement(transformation(origin = {-270, 10}, extent = {{-10, -10}, {10, 10}})));
// Deterministic transition: User demand “not satisfied” at station
PNlib.Components.TD TUNi(nIn = 1) annotation(
PNlib.Components.TD TUNi(nIn = 1, delay = userPatience) annotation(
Placement(transformation(origin = {-180, 10}, extent = {{-10, -10}, {10, 10}})));
// Stochastic Transition: User demand arrival at station
PNlib.Components.TES TUDi(nOut = 1, distributionType = PNlib.Types.DistributionType.Exponential, h = 1/userPatience) annotation(
PNlib.Components.TES TUDi(nOut = 1, distributionType = PNlib.Types.DistributionType.Exponential, h = 1/userArrivalRate) annotation(
Placement(transformation(origin = {-314, 10}, extent = {{-10, -10}, {10, 10}})));
// Stochastic Transition: Car return to station Si by user. Then, the car is in a charging situation
PNlib.Components.TES TCCi(nIn = 2, nOut = 1, distributionType = PNlib.Types.DistributionType.Exponential, h = 1/chargingTime) annotation(
......@@ -84,23 +82,15 @@ model CarSharingSystemSimplified
Placement(transformation(origin = {-356, 208}, extent = {{-10, -10}, {10, 10}})));
equation
// Objective Equations
// totalWaitingTime = numUsers * userPatience * (1 - returnRate); // Total waiting time is number of users multiplied by their patience
// carUtilization = (numUsers * usageTime) / (numCars * (usageTime + chargingTime + (1 / returnRate))); // Car utilization is based on usage time
// Objective Equations
// Calculate waiting time when users leave without getting a car
when change(PSDi.t) then
waitingTimeIncrement = (pre(PSDi.t) - PSDi.t) * userPatience;
totalWaitingTime = pre(totalWaitingTime) + waitingTimeIncrement;
// Update total waiting time when users leave
when change(PSDi.tokenFlow.outflow[2]) then
usersLeaving = PSDi.tokenFlow.outflow[2]; // Number of users leaving
totalWaitingTime = pre(totalWaitingTime) + usersLeaving * userPatience;
end when;
// Calculate car utilization
when change(PSRi.t) then
carsInUse = numCars - PSRi.t;
carUtilizationIncrement = carsInUse * usageTime / (numCars * (time + Modelica.Constants.eps));
carUtilization = pre(carUtilization) + carUtilizationIncrement;
// Update total number of cars rented
when change(PSRi.tokenFlow.outflow[1]) then
totalCarsRented = PSRi.tokenFlow.outflow[1];
end when;
// Connections
......@@ -153,7 +143,7 @@ equation
connect(TUSp.outPlaces[1], PCU.inTransition[2]) annotation(
Line(points = {{106, -6}, {2, -6}, {2, 0}}, thickness = 0.5));
annotation(
uses(PNlib(version = "3.0.0")),
uses(PNlib(version = "3.0.0"), Modelica(version = "4.0.0")),
Diagram(graphics = {Text(origin = {-337, -14}, extent = {{3, 0}, {-3, 0}}, textString = "text"), Text(origin = {-304, 192}, extent = {{42, -20}, {-42, 0}}, textString = "Station subnet"), Rectangle(origin = {-245, 103}, lineColor = {0, 0, 255}, lineThickness = 0.5, extent = {{-103, 71}, {103, -71}}), Rectangle(origin = {-257, 5}, lineColor = {0, 255, 0}, lineThickness = 0.5, extent = {{-91, 23}, {91, -23}}), Text(origin = {-304, -20}, extent = {{42, -20}, {-42, 0}}, textString = "User demand subnet"), Rectangle(origin = {224, 30}, lineColor = {0, 170, 255}, lineThickness = 0.5, extent = {{-132, 72}, {132, -72}}), Text(origin = {121, 136}, extent = {{57, -48}, {-57, 0}}, textString = "User Demand (park) subnet"), Polygon(origin = {342, 55}, lineColor = {255, 85, 255}, lineThickness = 0.5, points = {{-154, 111}, {-154, 57}, {32, 57}, {32, -139}, {142, -139}, {142, 137}, {-154, 137}, {-154, 127}, {-154, 111}}), Text(origin = {273, 201}, extent = {{-81, 25}, {81, -25}}, textString = "Car Maintenance (Center) subnet"), Rectangle(origin = {293, -77}, lineColor = {85, 85, 0}, lineThickness = 0.5, extent = {{-145, 87}, {145, -87}}), Text(origin = {227, -176}, extent = {{-73, 20}, {73, -20}}, textString = "Car-Sharing Park (Center) subnet"), Text(extent = {{-16, 40}, {-16, 40}}, textString = "text"), Text(origin = {-38, 62}, extent = {{-26, 16}, {26, -16}}, textString = "Cars in use"), Text(origin = {-339, 67}, extent = {{-37, 35}, {37, -35}}, textString = "Charging of cars"), Text(origin = {-204, 63}, extent = {{-32, 7}, {32, -7}}, textString = "Cars are ready")}, coordinateSystem(extent = {{-380, 240}, {500, -200}})),
version = "");
end CarSharingSystemSimplified;
end CarSharingSystemCaseStudy;
......@@ -42,3 +42,29 @@ This model generates some stochastic user (demands), you can simulate:
Here you will find a gif to visualize the simulation result.
![](./PN4ECSS.gif)
## How Tokens are Generated and Flow Through the Model
#### 1. User Arrival and Demand (TUDi and TUDp)
* Tokens representing user demand are generated at the `TUDi` and `TUDp` transitions, which simulate user arrivals at the station and park, respectively. The rate of token generation is governed by an exponential distribution based on `userPatience`.
#### 2. Users Waiting (PSDi)
* Arriving users are represented as tokens in the `PSDi` place, where they wait for available cars. If cars are available, tokens (users) will move to the `TUSi` transition where they pick up a car.
#### 3. Car Pickup and Usage (TUSi and PCU)
* Tokens (users) that successfully pick up cars move to the `PCU` place, representing cars in use by customers. This transition reduces the number of tokens in the `PSRi` place (cars ready) and increases the tokens in `PCU` (cars in use).
#### 4. Car Return and Charging (TCCi, TCRi, and PSCii)
* After usage, cars are returned and go through a charging process. The `TCCi` transition moves tokens from `PCU` to `PSCii` (charging state). Once charging is complete, tokens move through `TCRi` back to `PSRi` (cars ready).
#### 5. Car Maintenance (TCM, TMPR, and PCM)
* Occasionally, cars require maintenance. The `TCM` transition moves tokens to `PCM` (cars under maintenance). After maintenance, tokens move back to the `TMPR` transition, eventually returning to the pool of available cars.
#### 6. User Departure (TUNi and TUNp)
* If a user waits too long for a car, they leave the system. This is represented by the `TUNi` and `TUNp` transitions, which move tokens from the `PSDi` place without satisfying their demand.
\ No newline at end of file