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

Random queueing-network generation: the C++ twin of MATLAB @NetworkGenerator, the JAR jline.gen.NetworkGenerator and the native Python line_solver.gen.network_generator. More...

#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstddef>
#include <functional>
#include <string>
#include <vector>
#include "line/lang/dist_fitters.h"
#include "line/lang/lang_types.h"
#include "line/lang/qn/network_builder.h"
#include "line/lang/qn/network_struct.h"
#include "line/util/error.h"
#include "line/util/matrix.h"
#include "line/util/rng_ssj.h"
Include dependency graph for network_generator.h:

Go to the source code of this file.

Classes

class  line::gen::NetworkGenerator< T >
 A random qn::Network<T> source, configured once and then drawn from. More...

Namespaces

namespace  line
 Conservation laws of a layered queueing network, enumerated from its structure.
namespace  line::gen

Enumerations

enum class  line::gen::TopologyKind { line::gen::Rand , line::gen::Cyclic }
 The two topology generators the reference ships, randGraph and cyclicGraph. More...

Functions

Matrix< double > line::gen::rand_spanning_tree (std::size_t num_vertices, rng::JavaRandom &r)
 randSpanningTree(n): vertex i (i >= 1) is attached to a uniformly chosen earlier vertex, which is a uniform draw over the labelled rooted trees this construction reaches, and always a tree rooted at 0.
Matrix< double > line::gen::rand_graph (std::size_t num_vertices, rng::JavaRandom &r)
 randGraph(n): a random strongly connected digraph on n vertices, as a random spanning tree closed up by strongConnect and then relabelled by a random permutation (without which vertex 0 would always be the DFS root).
Matrix< double > line::gen::cyclic_graph (std::size_t num_vertices)
 cyclicGraph(n): the single cycle 0 -> 1 -> ... -> n-1 -> 0.
std::vector< double > line::gen::randfixedsumone (std::size_t num_elems, rng::JavaRandom &r)
 randfixedsumone(n): n probabilities summing to exactly 1.
std::vector< int > line::gen::randintfixedsum (int s, int n, rng::JavaRandom &r)
 randintfixedsum(s, n): n STRICTLY POSITIVE integers summing to s.

Detailed Description

Random queueing-network generation: the C++ twin of MATLAB @NetworkGenerator, the JAR jline.gen.NetworkGenerator and the native Python line_solver.gen.network_generator.

WHAT IT PRODUCES. A qn::Network<T> with numQueues queues, numDelays delay stations, numOClass open classes and numCClass closed classes, wired over a random strongly connected topology, with random service laws, random scheduling, random routing and (optionally) random ClassSwitch nodes on the links. It is the model source the test suites, the benchmark sweeps and the solver-comparison harnesses draw from, so the shapes it can emit matter more than any single draw: every arm of the reference is reproduced, including the multi-chain class-switch masks and the load bands.

HOW IT DIFFERS FROM THE REFERENCES, and this is deliberate:

  1. ONE SEEDED STREAM. MATLAB, the JAR and Python all leave part of the draw on a source setSeed does not reach – the JAR's randGraph builds its own new Random() and Collections.shuffle uses the shared static one, and MATLAB's randGraph draws from the global stream while the object seeds nothing at all. A seeded run there is reproducible in its service laws and not in its topology. Here EVERY draw, the spanning tree and both permutations included, comes from one rng::JavaRandom, so set_seed(s) reproduces the whole model. The consequence is that this port is NOT sample-path identical to the JAR or MATLAB at a shared seed; it is a DISTRIBUTIONAL port, and the parity claim is over the family of models it can emit, not over one draw. Do not baseline a seeded golden across the codebases from this generator.
  2. LINKS ARE A ROUTING MATRIX, NOT addLink. The reference calls model.addLink(a, b) and then setProbRouting/setRouting; this port has no addLink – qn::Network::link(P) derives the connection graph from the routing matrix itself (see network_struct.h, the RAND expansion). So a RANDOM-routed (node, class) pair is given its arcs in P as well as its strategy: the arcs are what make the pair connected, and route_eff then overwrites the probabilities with the uniform split RAND means. The two spellings describe the same model.
  3. THE REJECTION TEST IS STRUCTURAL. The JAR resamples when sn_refresh_visits throws a message containing "no recurrent flow"; no such throw exists any more in any codebase, so that gate is dead code there. This port tests what the gate was meant to test: after the struct is materialised, EVERY CLOSED CHAIN must actually visit its own reference station. A closed chain stranded in a component that does not contain its reference station gets zero visits there, its visit vector is not normalisable, and the model is not a valid closed network – such a draw is discarded and resampled, up to max_generate_attempts().
  4. initializeStates IS NOT A FIELD HERE. Its only effect in the JAR is to force getStruct() so the rejection test has something to test; this port materialises the struct unconditionally for exactly that reason. The C++ model has no per-node setState to fill in either: an initial state is declared through Network::set_state_prior, over a state SPACE rather than one row, so there is nothing here to port the flag onto.

ARITHMETIC. Every random quantity is drawn as a double (the reference draws are nextDouble/nextInt) and lifted into T, so the generator instantiates at exact arithmetic as well. The one transcendental step is the HyperExp moment fit, which is done in double and its three parameters lifted, the same bargain sn_aggregate_chains strikes for the same reason.

Definition in file network_generator.h.