1515# - Airline scheduling
1616# - Project selection and resource allocation
1717
18+ # Formatting constant
19+ LINE_WIDTH <- 60
20+
1821# ' Create an empty flow network
1922# ' @param n: Number of vertices
2023# ' @return: Flow network structure with adjacency list and capacity matrix
2124create_flow_network <- function (n ) {
22- list (
23- n = n ,
24- graph = vector(" list" , n ), # Adjacency list
25- capacity = matrix (0 , nrow = n , ncol = n ), # Capacity matrix
26- flow = matrix (0 , nrow = n , ncol = n ) # Flow matrix
27- )
25+ # Use environment to allow in-place (by-reference) mutation without superassignment
26+ env <- new.env(parent = emptyenv())
27+ env $ n <- n
28+ env $ graph <- vector(" list" , n ) # Adjacency list
29+ env $ capacity <- matrix (0 , nrow = n , ncol = n ) # Capacity matrix
30+ env $ flow <- matrix (0 , nrow = n , ncol = n ) # Flow matrix
31+ return (env )
2832}
2933
3034# ' Add edge to flow network
@@ -55,24 +59,30 @@ bfs_level_graph <- function(network, source, sink) {
5559 n <- network $ n
5660 level <- rep(- 1 , n )
5761 level [source ] <- 0
58-
59- queue <- c(source )
60-
61- while (length(queue ) > 0 ) {
62- u <- queue [1 ]
63- queue <- queue [- 1 ]
64-
62+
63+ # O(1) queue using head/tail indices; BFS enqueues each vertex at most once
64+ queue <- integer(n )
65+ head <- 1
66+ tail <- 1
67+ queue [tail ] <- source
68+ tail <- tail + 1
69+
70+ while (head < tail ) {
71+ u <- queue [head ]
72+ head <- head + 1
73+
6574 for (v in network $ graph [[u ]]) {
6675 # Check if edge has residual capacity and v is not visited
6776 residual_capacity <- network $ capacity [u , v ] - network $ flow [u , v ]
68-
77+
6978 if (level [v ] == - 1 && residual_capacity > 0 ) {
7079 level [v ] <- level [u ] + 1
71- queue <- c(queue , v )
80+ queue [tail ] <- v
81+ tail <- tail + 1
7282 }
7383 }
7484 }
75-
85+
7686 return (level )
7787}
7888
@@ -108,9 +118,9 @@ dfs_send_flow <- function(network, u, sink, level, flow, start) {
108118 )
109119
110120 if (pushed_flow > 0 ) {
111- # Update flow
112- network $ flow [u , v ] << - network $ flow [u , v ] + pushed_flow
113- network $ flow [v , u ] << - network $ flow [v , u ] - pushed_flow
121+ # Update flow (environment enables in-place mutation)
122+ network $ flow [u , v ] <- network $ flow [u , v ] + pushed_flow
123+ network $ flow [v , u ] <- network $ flow [v , u ] - pushed_flow
114124 return (pushed_flow )
115125 }
116126 }
@@ -194,21 +204,21 @@ dinic_max_flow <- function(network, source, sink) {
194204# ' @param network: Original network (optional, for displaying edges)
195205print_max_flow <- function (result , network = NULL ) {
196206 cat(" Maximum Flow Result:\n " )
197- cat(strrep(" =" , 60 ), " \n\n " )
207+ cat(strrep(" =" , LINE_WIDTH ), " \n\n " )
198208 cat(sprintf(" Maximum Flow: %g\n " , result $ max_flow ))
199209 cat(sprintf(" Iterations: %d\n\n " , result $ iterations ))
200210
201211 cat(" Minimum Cut Edges:\n " )
202- cat(strrep(" -" , 60 ), " \n " )
212+ cat(strrep(" -" , LINE_WIDTH ), " \n " )
203213 if (length(result $ min_cut_edges ) > 0 ) {
204214 cat(sprintf(" %-15s %-15s %-15s\n " , " From" , " To" , " Capacity" ))
205- cat(strrep(" -" , 60 ), " \n " )
215+ cat(strrep(" -" , LINE_WIDTH ), " \n " )
206216 total_cut_capacity <- 0
207217 for (edge in result $ min_cut_edges ) {
208218 cat(sprintf(" %-15d %-15d %-15g\n " , edge $ from , edge $ to , edge $ capacity ))
209219 total_cut_capacity <- total_cut_capacity + edge $ capacity
210220 }
211- cat(strrep(" -" , 60 ), " \n " )
221+ cat(strrep(" -" , LINE_WIDTH ), " \n " )
212222 cat(sprintf(" Total Cut Capacity: %g\n " , total_cut_capacity ))
213223 } else {
214224 cat(" No cut edges found\n " )
@@ -223,9 +233,9 @@ print_max_flow <- function(result, network = NULL) {
223233# ' @param network: Flow network with computed flows
224234print_flow_edges <- function (network ) {
225235 cat(" Flow on Edges:\n " )
226- cat(strrep(" -" , 60 ), " \n " )
236+ cat(strrep(" -" , LINE_WIDTH ), " \n " )
227237 cat(sprintf(" %-10s %-10s %-12s %-12s\n " , " From" , " To" , " Flow" , " Capacity" ))
228- cat(strrep(" -" , 60 ), " \n " )
238+ cat(strrep(" -" , LINE_WIDTH ), " \n " )
229239
230240 for (u in 1 : network $ n ) {
231241 for (v in network $ graph [[u ]]) {
@@ -235,7 +245,7 @@ print_flow_edges <- function(network) {
235245 }
236246 }
237247 }
238- cat(strrep(" -" , 60 ), " \n\n " )
248+ cat(strrep(" -" , LINE_WIDTH ), " \n\n " )
239249}
240250
241251# ========== Example 1: Basic 6-Vertex Network ==========
0 commit comments