LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
sn_region_members.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012-2026, QORE Lab, Imperial College London
3 * All rights reserved.
4 */
5#ifndef LINE_API_SN_SN_REGION_MEMBERS_H
6#define LINE_API_SN_SN_REGION_MEMBERS_H
7
8/**
9 * @file
10 * @ingroup api_sn
11 * Port of matlab/src/api/sn/sn_region_members.m.
12 *
13 * Which stations belong to finite-capacity region `f`, 0-based. Membership is
14 * DECLARED (`sn.regionmembers`, here `Region::members`) and only inferred when
15 * the declaration is absent: a station is then a member iff some entry of its
16 * capacity row, or its memory cap, is not the -1 "unbounded" sentinel.
17 *
18 * The inference cannot see a member station left wholly unbounded, which is
19 * precisely why the declaration exists and is preferred. A caller that infers
20 * membership when the flags are present would silently shrink the region and
21 * admit jobs the region forbids.
22 *
23 * ARITHMETIC: none. Structural.
24 */
25
26#include <cstddef>
27#include <vector>
28
30
31namespace line {
32namespace api {
33
34/**
35 * The membership mask of region `f` (0-based), one entry per station.
36 *
37 * Returns an empty mask when the model declares no such region, which is the
38 * reference's behaviour of leaving `mask` empty rather than raising.
39 */
40template <class T>
41std::vector<bool> sn_region_members(const qn::NetworkStruct<T>& sn, std::size_t f) {
42 std::vector<bool> mask;
43 if (f >= sn.regions.size()) return mask;
44 const typename qn::NetworkStruct<T>::Region& rg = sn.regions[f];
45 mask.assign(sn.nstations, false);
46 bool declared = false;
47 for (std::size_t i = 0; i < rg.members.size(); ++i)
48 if (rg.members[i]) declared = true;
49 for (std::size_t i = 0; i < sn.nstations; ++i) {
50 if (declared) {
51 mask[i] = i < rg.members.size() && rg.members[i];
52 continue;
53 }
54 bool in = false;
55 if (i < rg.cap.size())
56 for (std::size_t r = 0; r < rg.cap[i].size(); ++r)
57 if (rg.cap[i][r] != -1.0) in = true;
58 if (i < rg.maxmem.size() && rg.maxmem[i] != -1.0) in = true;
59 mask[i] = in;
60 }
61 return mask;
62}
63
64/** The same membership as 1-based station indices, the form most callers want. */
65template <class T>
66std::vector<std::size_t> sn_region_member_list(const qn::NetworkStruct<T>& sn, std::size_t f) {
67 const std::vector<bool> mask = sn_region_members(sn, f);
68 std::vector<std::size_t> out;
69 for (std::size_t i = 0; i < mask.size(); ++i)
70 if (mask[i]) out.push_back(i + 1);
71 return out;
72}
73
74} // namespace api
75} // namespace line
76
77#endif // LINE_API_SN_SN_REGION_MEMBERS_H
A network plus its refreshed NetworkStruct.
std::vector< bool > sn_region_members(const qn::NetworkStruct< T > &sn, std::size_t f)
The membership mask of region f (0-based), one entry per station.
std::vector< std::size_t > sn_region_member_list(const qn::NetworkStruct< T > &sn, std::size_t f)
The same membership as 1-based station indices, the form most callers want.
A queueing network and its refreshed NetworkStruct.
FINITE CAPACITY REGIONS, MATLAB's refreshRegions output.
std::vector< std::vector< double > > cap
(nstations x nclasses+1), -1 = unbounded
std::vector< double > maxmem
per member station, -1 = unbounded
std::vector< bool > members
membership, independent of the caps