LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
fluid_is_single_queue.m
1function [isSingleQueue, fluidInfo] = fluid_is_single_queue(sn)
2%FLUID_IS_SINGLE_QUEUE Check if network is a valid single-queue topology for MFQ
3%
4% [isSingleQueue, fluidInfo] = FLUID_IS_SINGLE_QUEUE(sn)
5%
6% Validates that the network structure is suitable for the MFQ solver.
7% MFQ requires: Source -> single Queue -> Sink topology with single server.
8%
9% Parameters:
10% sn (struct): Network structure from Network.getStruct()
11%
12% Returns:
13% isSingleQueue (logical): True if topology is valid for MFQ
14% fluidInfo (struct): Contains topology information and error message if invalid
15
16 fluidInfo = struct();
17 fluidInfo.errorMsg = '';
18 fluidInfo.sourceIdx = [];
19 fluidInfo.queueIdx = [];
20 fluidInfo.sinkIdx = [];
21 fluidInfo.sourceStation = [];
22 fluidInfo.queueStation = [];
23
24 % Check 1: Must have at least one open class
25 if ~any(isinf(sn.njobs))
26 fluidInfo.errorMsg = 'Not an open model - all classes are closed';
27 isSingleQueue = false;
28 return;
29 end
30
31 % Work at the node level (like fj_isfj.m does)
32 % Find Source, Queue, and Sink nodes
33 sourceNodeIdx = find(sn.nodetype == NodeType.Source);
34 queueNodeIdx = find(sn.nodetype == NodeType.Queue);
35 sinkNodeIdx = find(sn.nodetype == NodeType.Sink);
36
37 % Check: exactly one source
38 if length(sourceNodeIdx) == 0
39 fluidInfo.errorMsg = 'No source node found';
40 isSingleQueue = false;
41 return;
42 elseif length(sourceNodeIdx) > 1
43 fluidInfo.errorMsg = sprintf('Multiple source nodes found (%d)', length(sourceNodeIdx));
44 isSingleQueue = false;
45 return;
46 end
47
48 % Check: exactly one sink
49 if length(sinkNodeIdx) == 0
50 fluidInfo.errorMsg = 'No sink node found';
51 isSingleQueue = false;
52 return;
53 elseif length(sinkNodeIdx) > 1
54 fluidInfo.errorMsg = sprintf('Multiple sink nodes found (%d)', length(sinkNodeIdx));
55 isSingleQueue = false;
56 return;
57 end
58
59 % Check: exactly one queue
60 if length(queueNodeIdx) == 0
61 fluidInfo.errorMsg = 'No queue node found';
62 isSingleQueue = false;
63 return;
64 elseif length(queueNodeIdx) > 1
65 fluidInfo.errorMsg = sprintf('Multiple queue nodes found (%d) - MFQ supports single queue only', length(queueNodeIdx));
66 isSingleQueue = false;
67 return;
68 end
69
70 % Get station indices (for stations that exist)
71 sourceStation = sn.nodeToStation(sourceNodeIdx);
72 queueStation = sn.nodeToStation(queueNodeIdx);
73
74 % Check: Single-server or infinite-server constraint
75 c = sn.nservers(queueStation);
76 if c > 1 && c < Inf
77 fluidInfo.errorMsg = sprintf('Multi-server queue (c=%d) not supported - MFQ requires c=1 or c=Inf', c);
78 isSingleQueue = false;
79 return;
80 end
81
82 % Check: No self-loops (independence assumption)
83 % Check routing matrix for self-loops in the queue station
84 K = sn.nclasses;
85 for k = 1:K
86 % Check if queue routes back to itself
87 rtIdx = (queueStation - 1) * K + k;
88 if sn.rt(rtIdx, rtIdx) > 0
89 fluidInfo.errorMsg = 'Self-loop detected at queue - violates independence assumption';
90 isSingleQueue = false;
91 return;
92 end
93 end
94
95 % All checks passed
96 fluidInfo.sourceIdx = sourceNodeIdx;
97 fluidInfo.queueIdx = queueNodeIdx;
98 fluidInfo.sinkIdx = sinkNodeIdx;
99 fluidInfo.sourceStation = sourceStation;
100 fluidInfo.queueStation = queueStation;
101 isSingleQueue = true;
102end
Definition mmt.m:92