LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
ldes_engine.h File Reference

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"
Include dependency graph for ldes_engine.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.

Detailed Description

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:

  • THE BUDGET IS SERVICE COMPLETIONS, not simulated time and not arrivals.
  • WARMUP IS MSER-5 over EVENT-SPACED observations, interval maxEvents / 1000 completions, truncation chosen on the AGGREGATE queue length with a per-series fallback (the closed-network case, whose constant total carries no transient signal).
  • THE ESTIMATORS ARE TIME-WEIGHTED AND TRUNCATION-DIFFERENCED: QLen and Util are (integral at the end - integral at the truncation) / elapsed, never an unweighted mean of the per-interval averages, which overweights congested epochs because they contain more events per unit time.
  • RESPONSE TIME IS THE FULL TALLY. getAvgResponseTime averages every observation including the warmup ones, so Little's law holds only up to the warmup mass. That is the reference's behaviour, mirrored rather than corrected, or the two engines would disagree on a short run.
  • THE SOURCE ROW OF TN IS THE NOMINAL ARRIVAL RATE, not a measured one.

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.