![]() |
LINE Solver (C++)
Templated C++ port of the LINE queueing solver
|
The NATIVE LDES discrete-event engine. More...
#include <algorithm>#include <cmath>#include <cstddef>#include <cstdint>#include <functional>#include <limits>#include <map>#include <numeric>#include <queue>#include <random>#include <string>#include <vector>#include "line/lang/qn/network_struct.h"#include "line/solvers/ldes/ldes_busyperiod.h"#include "line/solvers/ldes/ldes_cache.h"#include "line/solvers/ldes/ldes_region.h"#include "line/solvers/ldes/ldes_spn.h"#include "line/solvers/ldes/ldes_sampler.h"#include "line/solvers/ldes/ldes_station.h"#include "line/solvers/ldes/ldes_stats.h"#include "line/solvers/wrappers/ldes/ldes_options.h"#include "line/util/error.h"#include "line/util/matrix.h"Go to the source code of this file.
Classes | |
| struct | line::ldes::engine::Event |
| One scheduled event. More... | |
| struct | line::ldes::engine::EventLater |
| Later-is-greater, so the priority queue pops the earliest event. More... | |
| struct | line::ldes::engine::RouteEntry |
| One routing alternative out of a (node, class) pair. More... | |
| struct | line::ldes::engine::RouteDest |
| One destination NODE of a (node, class) pair, with the class it switches to. More... | |
| struct | line::ldes::engine::StationState |
| One station's mutable state. More... | |
| struct | line::ldes::engine::StationState::BalkRule |
| Balking: the (min, max, probability) triples an arrival consults. More... | |
Namespaces | |
| namespace | line |
| namespace | line::ldes |
| namespace | line::ldes::engine |
Enumerations | |
| enum class | line::ldes::engine::Role { line::ldes::engine::Source , line::ldes::engine::Queue , line::ldes::engine::Delay , line::ldes::engine::Synchronization } |
| Station roles this engine simulates. More... | |
| enum | line::ldes::engine::EventKind { line::ldes::engine::EV_DEPARTURE = 0 , line::ldes::engine::EV_FIRING = 6 , line::ldes::engine::EV_SWITCHOVER = 1 , line::ldes::engine::EV_SETUP = 2 , line::ldes::engine::EV_RETRIAL = 3 , line::ldes::engine::EV_RENEGE = 4 , line::ldes::engine::EV_ARRIVAL = 5 , line::ldes::engine::EV_BREAKDOWN = 7 } |
| Event tags, ordered so that a service completion precedes an arrival scheduled for the same instant. More... | |
Functions | |
| template<class T> | |
| void | line::ldes::engine::ldes_engine_reject (const qn::NetworkStruct< T > &sn, const LdesOptions &o) |
| Refuse, by name, every model outside this engine's scope. | |
| template<class T> | |
| LdesResult | line::ldes::ldes_engine_solve_one (const qn::NetworkStruct< T > &sn, const LdesOptions &o) |
| Simulate sn in process and return the same record the subprocess client parses out of an ldes-result document. | |
| template<class T> | |
| LdesResult | line::ldes::ldes_engine_solve (const qn::NetworkStruct< T > &sn, const LdesOptions &o) |
| Simulate sn, over independent REPLICATIONS when options.replications > 1. | |
The NATIVE LDES discrete-event engine.
WHAT THIS IS. solvers/wrappers/ldes/solver_ldes.h is a CLIENT: it writes a model.json, runs the Java engine as a subprocess and parses the result back. This header is the engine itself, in process, and is the C++ twin of jline/solvers/ldes/handlers/Solver_ssj.java. Do not confuse the two directories – wrappers/ldes/ shells out, ldes/ simulates.
WHAT IT COVERS TODAY. Networks over Source, Queue, Delay, Router, ClassSwitch, Logger and Sink; every renewal, Markovian and trace-driven service law the language carries (see ldes_sampler.h); the buffered disciplines FCFS, LCFS, SIRO, HOL, the LCFS priority variants, SJF, LJF, SEPT, LEPT, EDD, EDF, INF; the preemptive disciplines FCFSPR/PI, LCFSPR/PI, their PRIO variants, SRPT, SRPTPRIO, PSJF, FB, LRPT, SETF and FSP, in both resume and restart; the sharing disciplines PS, DPS, GPS, their priority variants and LPS; multi-server stations; class priorities; finite station and per-class capacity with DROP; balking and reneging; load dependence (sn.lldscaling) and class dependence (sn.cdscaling); open and closed classes; class switching; G-network NEGATIVE and CATASTROPHE signals, with their batch-size law and removal policy; and confidence intervals by overlapping or non-overlapping batch means.
WHAT IT REFUSES, by name, in ldes_engine_reject (this list was rewritten on 2026-08-01 against the code; the tranche that followed the first draft added most of what the old text said was missing): the EXT discipline; a REPLY signal, whose synchronous call holds a server this engine does not model; a blocking rule that is neither DROP, BAS nor BBS; a continuously shared server or an NHPP under SLOTTED mode, neither of which lands on the slot lattice; and any node kind outside Source, Sink, Queue, Delay, Router, ClassSwitch, Logger, Cache, Place and Transition. POLLING, PAS, FSP, SETF, EDD and EDF ARE simulated, as are caches, Petri nets, fork-join, finite capacity regions, retrial orbits, setup/delay-off, MAPt/PHt, slotted time, transient runs, busy periods and replications. SERVER BREAKDOWNS are simulated as of 2026-08-15: NetworkStruct::breakdownparam carries the two clocks and the degraded downServiceRates, and the engine runs the outage as a state-dependent rate change – a zero multiplier stalls the job in service with its residual intact, a positive one is the degraded server – so a job is interrupted and never evicted. They are refused under SLOTTED mode, where the failure and repair epochs would have to land on the lattice too. Each refusal is a definite feature with a definite semantics, and serving one as though it were something else produces a run that finishes and reports numbers no downstream test can distinguish from correct ones.
WHAT IS TRANSCRIBED FROM THE JAVA ENGINE, because these choices decide the numbers and not just the speed:
RANDOMNESS, AND HOW FAR IT NOW AGREES WITH THE JAVA ENGINE. The generators are no longer Mersenne Twisters: ldes_sampler.h draws every renewal family from rng::Mrg32k3a, a bit-exact reproduction of SSJ's MRG32k3a, through the inverse-CDF quantiles of ldes_ssj_variates.h, and every Markovian family from rng::JavaRandom through the transcribed Map_sample.MapSampler walk, because the reference sends those two families to those two generators. What is NOT yet aligned is stream OWNERSHIP: Solver_ssj seeds one stream per (node, class) from seed + offset, while this engine still carries three streams for the whole run (arrivals, services, routing). Until that is matched a fixed seed does not reproduce the Java sample path, so a cross-engine test must still compare means against a tolerance derived from the standard error rather than element by element. The seed bands are kept separate per role (arrivals, services, routing) for the reason the Java engine separates them: one shared stream makes the routing draw the very uniform that generated the interarrival time, which correlates a probabilistic split with the gap length and biases the destinations in opposite directions.
Definition in file ldes_engine.h.