![]() |
LINE Solver (C++)
Templated C++ port of the LINE queueing solver
|
Port of the event half of MATLAB's +State package: the successor states an event produces at one node, with their rates and probabilities. More...
#include <cmath>#include <cstddef>#include <limits>#include <algorithm>#include <functional>#include <utility>#include <vector>#include "line/lang/lang_types.h"#include "line/lang/qn/network_struct.h"#include "line/api/mam/map_moment.h"#include "line/lang/qn/polling_info.h"#include "line/lang/qn/state.h"#include "line/util/error.h"Go to the source code of this file.
Classes | |
| struct | line::qn::EventOutcome< T > |
| What one event produces at one node: the successor rows, their rates and their probabilities, all three the same length. More... | |
| struct | line::qn::RowLayout< T > |
| How a station's state row splits into [buffer | server | local vars]. More... | |
| struct | line::qn::ReplyBlockInfo |
| Where node ind keeps its reply-block counters inside the local vars. More... | |
| struct | line::qn::PrioPop< T > |
| The population the *PRIO disciplines actually share the server among. More... | |
| struct | line::qn::ModeEvent< T > |
| One half of a GLOBAL synchronization: a mode event at a node. More... | |
| struct | line::qn::GlobalSync< T > |
| A GLOBAL synchronization: an SPN mode event and the place arcs it drives. More... | |
| struct | line::qn::GlobalOutcome< T > |
| What one global event produces: a whole network state per outcome. More... | |
| struct | line::qn::SyncEvent< T > |
| One half of a synchronization: an event at a node, in a class. More... | |
| struct | line::qn::Sync< T > |
| One synchronization: an ACTIVE event and the PASSIVE event it drives. More... | |
Namespaces | |
| namespace | line |
| namespace | line::qn |
Enumerations | |
| enum class | line::qn::EventType |
| The events a state can undergo, with the values of MATLAB EventType. More... | |
Functions | |
| template<typename T> | |
| void | line::qn::tag_last (EventOutcome< T > &out, std::size_t start_cls, std::size_t preempt_cls) |
| Tag the successor row just appended to OUT: START_CLS begins service on it and PREEMPT_CLS is displaced by it, either 0 for none. | |
| template<typename T> | |
| void | line::qn::pad_tags (EventOutcome< T > &out) |
| Bring the tag vectors up to one entry per successor, so a caller can index them exactly like space. | |
| template<class T> | |
| std::pair< T, std::vector< T > > | line::qn::to_marginal_aggr (const NetworkStruct< T > &sn, std::size_t ind, const std::vector< T > &state_i) |
| Port of State.toMarginalAggr: the job counts of one node's state row, without the per-phase detail to_marginal also computes. | |
| template<class T> | |
| bool | line::qn::is_physical_capacity (const NetworkStruct< T > &sn, std::size_t ist, std::size_t cls) |
| Port of State.isPhysicalCapacity: true when the bound at (ist, class) is a PHYSICAL capacity rather than a state-space CUTOFF on an open class. | |
| template<class T> | |
| bool | line::qn::arrival_is_lost (const NetworkStruct< T > &sn, std::size_t ist, std::size_t cls) |
| Port of State.arrivalIsLost: true when an arrival that finds no room is LOST, false when it must BLOCK the upstream instead. | |
| template<class T> | |
| RowLayout< T > | line::qn::row_layout (const NetworkStruct< T > &sn, std::size_t ind, std::size_t width) |
| template<class T> | |
| std::vector< T > | line::qn::entry_phase_dist (const NetworkStruct< T > &sn, std::size_t ist, std::size_t cls) |
| The entry-phase distribution pie{ist}{class}: which phase a service STARTS in. | |
| template<class T> | |
| void | line::qn::polling_get (const PollingInfo< T > &pi, const std::vector< T > &var, std::size_t srvclass, std::size_t &pos, std::size_t &swk, long &ctr) |
| Defined below; the polling branches of ARV, DEP and SWITCH use these. | |
| template<class T> | |
| std::vector< T > | line::qn::polling_set (const PollingInfo< T > &pi, std::vector< T > var, std::size_t pos, std::size_t swk, long ctr) |
| Write (pos, swk, ctr) back into the local-variable block. | |
| template<class T> | |
| void | line::qn::polling_next (const PollingInfo< T > &pi, std::size_t pos, const std::vector< long > &nbuf, std::size_t R, bool arrived, std::size_t &q, int &mode, long &budget) |
| Port of State.pollingNext: where the server goes from buffer pos. | |
| template<class T> | |
| void | line::qn::polling_land (const NetworkStruct< T > &sn, std::size_t ist, const PollingInfo< T > &pi, std::size_t q, int mode, long budget, const std::vector< T > &buf, const std::vector< T > &srv, const std::vector< T > &var, const RowLayout< T > &L, std::vector< std::vector< T > > &rows, std::vector< T > &probs) |
| Port of State.pollingLand: the states the walk lands in, with weights. | |
| template<class T> | |
| double | line::qn::reply_blocked (const NetworkStruct< T > &sn, std::size_t ind, const std::vector< T > &var) |
| Defined below; the reply block subtracts held servers in the ARV branch. | |
| template<class T> | |
| ReplyBlockInfo | line::qn::reply_block_info (const NetworkStruct< T > &sn, std::size_t ind) |
| Defined below; the departure branch records a server held for a reply. | |
| template<class T> | |
| EventOutcome< T > | line::qn::after_event_station_pas (const NetworkStruct< T > &sn, std::size_t ind, const std::vector< T > &inspace, EventType event, std::size_t cls) |
| Defined below; the ARV and DEP branches divert to it before any slicing. | |
| template<class T> | |
| EventOutcome< T > | line::qn::after_event_station_arv (const NetworkStruct< T > &sn, std::size_t ind, const std::vector< T > &inspace, std::size_t cls) |
| Port of the ARV branch of State.afterEventStation: an arriving class-cls job joins node ind, whose local state is inspace. | |
| template<class T> | |
| std::pair< std::vector< T >, std::vector< T > > | line::qn::phase_rates (const NetworkStruct< T > &sn, std::size_t ist, std::size_t cls) |
| sn.mu and sn.phi for one (station, class), derived as MATLAB's Markovian.getMu / getPhi derive them from the (D0, D1) pair: | |
| template<class T> | |
| T | line::qn::lld_factor (const NetworkStruct< T > &sn, std::size_t ist, double n) |
| The limited-load-dependent multiplier at population n, 1 when unset. | |
| template<class T> | |
| T | line::qn::cd_factor (const NetworkStruct< T > &sn, std::size_t ist, const std::vector< T > &nir, std::size_t cls) |
| Port of State.cdclassfactor: the class-dependence multiplier of a class-cls rate at the per-class population nir. | |
| template<class T> | |
| PrioPop< T > | line::qn::prio_pop (const NetworkStruct< T > &sn, std::size_t ist, const Marginal< T > &m, std::size_t cls, double ni, double S) |
| Compute the *PRIO effective population; a no-op for every other discipline. | |
| template<class T> | |
| T | line::qn::service_share (const NetworkStruct< T > &sn, std::size_t ist, const Marginal< T > &m, std::size_t cls, double ni, double S) |
| Defined below; DEP and PHASE must share one definition of the share. | |
| template<class T> | |
| EventOutcome< T > | line::qn::after_event_station_dep (const NetworkStruct< T > &sn, std::size_t ind, const std::vector< T > &inspace, std::size_t cls, bool no_promote=false) |
| Port of the DEP branch of State.afterEventStation: a class-cls job completes service at station ind. | |
| template<class T> | |
| EventOutcome< T > | line::qn::after_event_station_phase (const NetworkStruct< T > &sn, std::size_t ind, const std::vector< T > &inspace, std::size_t cls) |
| Port of the PHASE branch of State.afterEventStation: service advances a phase WITHOUT completing. | |
| template<class T> | |
| EventOutcome< T > | line::qn::after_event_station_renege (const NetworkStruct< T > &sn, std::size_t ind, const std::vector< T > &inspace, std::size_t cls, const T &impatience_mu) |
| Port of the RENEGE branch: a WAITING class-cls job abandons the queue. | |
| template<class T> | |
| EventOutcome< T > | line::qn::after_event_station_retry (const NetworkStruct< T > &sn, std::size_t ind, const std::vector< T > &inspace, std::size_t cls, const T &retrial_mu, bool constant_policy=false) |
| Port of the RETRY branch: an ORBITING class-cls job retries entry. | |
| template<class T> | |
| EventOutcome< T > | line::qn::after_event_station_breakdown (const NetworkStruct< T > &sn, std::size_t ind, const std::vector< T > &inspace, bool up, const T &mu) |
| Port of the FAILURE and REPAIR branches: the server goes down, or comes back. | |
| template<class T> | |
| EventOutcome< T > | line::qn::after_event_fork (const NetworkStruct< T > &sn, std::size_t ind, const std::vector< T > &inspace, EventType event, std::size_t cls) |
| Port of State.afterEventFork: an event at a STATEFUL Fork node. | |
| template<class T> | |
| EventOutcome< T > | line::qn::after_event_join (const NetworkStruct< T > &sn, std::size_t ind, const std::vector< T > &inspace, EventType event, std::size_t cls) |
| Port of State.afterEventJoin: an event at a Join node of an FJ-augmented struct. | |
| template<class T> | |
| void | line::qn::rr_advance_row (const NetworkStruct< T > &sn, std::size_t ind, std::size_t cls, std::vector< std::vector< T > > &rows) |
| Port of State.afterEventStation's dispatch: the successors of one event at one station. | |
| template<class T> | |
| EventOutcome< T > | line::qn::after_event_router (const NetworkStruct< T > &sn, std::size_t ind, const std::vector< T > &inspace, EventType event, std::size_t cls) |
| Port of State.afterEventRouter: a Router holds a job for the instant it takes to decide where it goes. | |
| template<class T> | |
| EventOutcome< T > | line::qn::after_event_station (const NetworkStruct< T > &sn, std::size_t ind, const std::vector< T > &inspace, EventType event, std::size_t cls, bool no_promote=false, const T &aux_rate=num_traits< T >::from_int(0)) |
| template<class T> | |
| EventOutcome< T > | line::qn::after_event_transition (const NetworkStruct< T > &sn, std::size_t ind, const std::vector< T > &inspace, EventType event, std::size_t mode) |
| Port of State.afterEventTransition, the PHASE arm: one running server of the given mode advances its firing phase (cls is interpreted as the MODE, as in the reference). | |
| template<class T> | |
| EventOutcome< T > | line::qn::after_event (const NetworkStruct< T > &sn, std::size_t ind, const std::vector< T > &inspace, EventType event, std::size_t cls, bool no_promote=false, const T &aux_rate=num_traits< T >::from_int(0)) |
| Port of State.afterEvent: the successors of one event at one NODE. | |
| template<class T> | |
| std::pair< std::vector< std::size_t >, std::vector< T > > | line::qn::signal_batch_pmf (const NetworkStruct< T > &sn, std::size_t cls, std::size_t ntot) |
| Port of State.signalBatchPMF: the batch size a negative signal removes. | |
| template<class T> | |
| EventOutcome< T > | line::qn::after_event_station_signal (const NetworkStruct< T > &sn, std::size_t ind, const std::vector< T > &inspace, std::size_t cls) |
| Port of State.afterEventStationSignal: a G-network signal arrives. | |
| template<class T> | |
| std::pair< std::vector< std::size_t >, std::size_t > | line::qn::pass_and_swap (const std::vector< std::size_t > &c, std::size_t p, const std::vector< std::vector< bool > > &G) |
| Port of State.passAndSwap: the transition a service completion triggers at a pass-and-swap station (Dorsman and Gardner 2024, Sect. | |
| template<class T, class F> | |
| std::vector< double > | line::qn::pas_increments (const F &mu_fun, const std::vector< std::size_t > &c) |
| Port of State.afterEventStationPAS: events at a pass-and-swap station. | |
| template<class T, class F> | |
| void | line::qn::pas_tag_started (EventOutcome< T > &out, const F &mu_fun, const std::vector< std::size_t > &cold, const std::vector< std::size_t > &cnew) |
| Tag the successor just appended to OUT with the PAS positions that started service on it: those of CNEW that are served (Delta_mu > 0) and were not served in COLD. | |
| template<class T> | |
| EventOutcome< T > | line::qn::after_event_station_reply (const NetworkStruct< T > &sn, std::size_t ind, const std::vector< T > &inspace, std::size_t cls) |
| Port of State.afterEventStationReply: a REPLY signal completes a synchronous call at the station holding the server for it. | |
| template<class T> | |
| long | line::qn::polling_budget (const PollingInfo< T > &pi, long nbufq) |
| Port of State.pollingBudget: how many services this visit may perform. | |
| template<class T> | |
| EventOutcome< T > | line::qn::after_event_station_switch (const NetworkStruct< T > &sn, std::size_t ind, const std::vector< T > &inspace, std::size_t cls) |
| Port of the SWITCH branch: a polling server advances its switchover timer. | |
| template<class T> | |
| EventOutcome< T > | line::qn::after_event_cache (const NetworkStruct< T > &sn, std::size_t ind, const std::vector< T > &inspace, EventType event, std::size_t cls) |
| Port of State.afterEventCache: events at a Cache node. | |
| template<class T> | |
| std::vector< GlobalSync< T > > | line::qn::refresh_global_sync (const NetworkStruct< T > &sn) |
| Port of MNetwork.refreshGlobalSync: the ENABLE and FIRE synchronizations. | |
| template<class T> | |
| GlobalOutcome< T > | line::qn::after_global_event (const NetworkStruct< T > &sn, const NetState< T > &glspace, const GlobalSync< T > &gl) |
| Port of State.afterGlobalEvent: an SPN mode ENABLEs or FIREs. | |
| template<class T> | |
| std::vector< Sync< T > > | line::qn::refresh_sync (const NetworkStruct< T > &sn, const std::vector< std::vector< bool > > &impatience_classes=std::vector< std::vector< bool > >(), const std::vector< std::size_t > &breakdown_nodes=std::vector< std::size_t >()) |
| Port of MNetwork.refreshSync: the synchronization list. | |
| template<class T> | |
| GlobalOutcome< T > | line::qn::after_fj_event (const NetworkStruct< T > &sn, const FjSync< T > &e, const NetState< T > &gl) |
| Port of State.afterFJEvent: fire ONE entry of the fork firing list. | |
Port of the event half of MATLAB's +State package: the successor states an event produces at one node, with their rates and probabilities.
This is what turns the enumerated state space of state.h into a generator.
THE ACTIVE / PASSIVE CONVENTION. An event is ACTIVE at the node that schedules it and PASSIVE at the node that receives it – a DEP at one station IS the ARV at the next. Only the active half knows a rate, so the passive half returns the sentinel -1 and the generator assembly substitutes the active rate. The sentinel is unambiguous because a rate is never negative.
WHY PROBABILITIES ARE SEPARATE FROM RATES. One event can have several successors: an entering job picks its service phase, a signal picks the job it removes, a random-order queue picks whom to serve. The rate belongs to the event and the probability to the choice, so a single (state, event) pair yields a ROW of successors and the generator entry is rate * prob.
Definition in file state_events.h.