11
22"""
3- add_node(param, graph, x, y, neighbors) -> Dict, Dict
3+ add_node(graph, x, y, neighbors) -> Dict
44
5- Add a node in position (x,y) and list of neighbors. The new node is given an index J+1.
5+ Add a node in position (x,y) and list of neighbors. The new node is given an index J+1. Returns an updated `graph` object.
66
77# Arguments
8- - `param::Dict`: Dict that contains the model's parameters, or `nothing` to only update graph
98- `graph::Dict`: Dict that contains the underlying graph (created by create_graph())
109- `x::Float64`: x coordinate of the new node (any real number)
1110- `y::Float64`: y coordinate of the new node (any real number)
1211- `neighbors::Vector{Int64}`: Vector of nodes to which it is connected (1 x n list of node indices between 1 and J, where n is an arbitrary # of neighbors)
1312
14- The cost matrices `delta_tau` and `delta_i` are parametrized as a function of Euclidean distance between nodes.
15-
16- Returns the updated `graph` and `param` objects (`param` is affected too because the variable `Zjn`, `Lj`, `Hj` and others are reset to a uniform dist.)
13+ # Notes
14+ The cost matrices `delta_tau` and `delta_i` are parametrized as a function of Euclidean distance between nodes.
15+ The new node is given population 1e-6 and productivity equal to the minimum productivity in the graph.
1716"""
18- function add_node (param, graph, x, y, neighbors)
17+ function add_node (graph, x, y, neighbors)
1918
20- graph = dict_to_namedtuple (graph)
19+ if graph isa Dict
20+ graph_new = copy (dict)
21+ else
22+ graph_new = Dict (pairs (namedtuple))
23+ end
2124
2225 # Check validity of neighbors list
23- if any (neighbors .!= floor .(neighbors)) || any (neighbors .< 1 ) || any (neighbors .> graph. J )
24- error (" neighbors should be a list of integers between 1 and $(graph. J ) ." )
26+ if any (neighbors .!= floor .(neighbors)) || any (neighbors .< 1 ) || any (neighbors .> graph[ :J ] )
27+ error (" neighbors should be a list of integers between 1 and $(graph[ :J ] ) ." )
2528 end
26- Jnew = graph. J + 1
29+ Jnew = graph[ :J ] + 1
2730
2831 # Add node
29- nodes = [graph. nodes; [neighbors]]
30- new_x = [graph. x ; x]
31- new_y = [graph. y ; y]
32+ nodes = [graph[ : nodes] ; [neighbors]]
33+ new_x = [graph[ :x ] ; x]
34+ new_y = [graph[ :y ] ; y]
3235
3336 # Add new node to neighbors' neighbors
3437 # And update adjacency and cost matrices
3538 adjacency = zeros (Jnew, Jnew)
36- adjacency[1 : graph. J , 1 : graph. J] = graph. adjacency
39+ adjacency[1 : graph[ :J ] , 1 : graph[ :J ]] = graph[ : adjacency]
3740
3841 delta_tau = zeros (Jnew, Jnew)
39- delta_tau[1 : graph. J , 1 : graph. J] = graph. delta_tau
42+ delta_tau[1 : graph[ :J ] , 1 : graph[ :J ]] = graph[ : delta_tau]
4043
4144 delta_i = zeros (Jnew, Jnew)
42- delta_i[1 : graph. J , 1 : graph. J] = graph. delta_i
45+ delta_i[1 : graph[ :J ] , 1 : graph[ :J ]] = graph[ : delta_i]
4346
4447 for i in neighbors
4548 nodes[i] = [nodes[i]; Jnew]
4649 distance = sqrt ((new_x[i] - x)^ 2 + (new_y[i] - y)^ 2 )
4750
4851 # Adjacency
49- adjacency[i, Jnew] = 1
50- adjacency[Jnew, i] = 1
52+ adjacency[i, Jnew] = adjacency[Jnew, i] = 1
5153
5254 # Travel cost: delta_tau
53- delta_tau[i, Jnew] = distance
54- delta_tau[Jnew, i] = distance
55+ delta_tau[i, Jnew] = delta_tau[Jnew, i] = distance
5556
5657 # Building cost: delta_i
57- delta_i[i, Jnew] = distance
58- delta_i[Jnew, i] = distance
58+ delta_i[i, Jnew] = delta_i[Jnew, i] = distance
5959 end
6060
6161 # Update number of degrees of liberty for Ijk
6262 ndeg = sum (tril (adjacency)) # nb of degrees of liberty in adjacency matrix
6363
64- # Return new graph structure
65- graph_new = Dict (
66- :J => Jnew,
67- :x => new_x,
68- :y => new_y,
69- :nodes => nodes,
70- :adjacency => adjacency,
71- :delta_i => delta_i,
72- :delta_tau => delta_tau,
73- :ndeg => ndeg
74- )
75-
76- if param != = nothing
77- # Now, update the param structure
78- if param isa Dict
79- param_new = copy (param)
80- else
81- param_new = Dict (pairs (param))
82- end
83- if haskey (param, :J )
84- param_new[:J ] = Jnew
85- end
86- if haskey (param, :Lj )
87- param_new[:Lj ] = ones (Jnew) / Jnew
88- end
89- if haskey (param, :Hj )
90- param_new[:Hj ] = ones (Jnew)
91- end
92- if haskey (param, :hj )
93- param_new[:hj ] = param[:Hj ] ./ param[:Lj ]
94- end
95- if haskey (param, :omegaj )
96- param_new[:omegaj ] = ones (Jnew)
97- end
98- if haskey (param, :Zjn )
99- param_new[:Zjn ] = ones (Jnew, param[:N ])
100- end
101-
102- return param_new, graph_new
64+ # Update graph structure
65+ graph_new[:J ] = Jnew
66+ graph_new[:x ] = new_x
67+ graph_new[:y ] = new_y
68+ graph_new[:nodes ] = nodes
69+ graph_new[:adjacency ] = adjacency
70+ graph_new[:delta_i ] = delta_i
71+ graph_new[:delta_tau ] = delta_tau
72+ graph_new[:ndeg ] = ndeg
73+
74+ # Update other parameters if they exist
75+ if haskey (graph, :Lj )
76+ graph_new[:Lj ] = [graph[:Lj ]; 1e-6 ] # ones(Jnew) / Jnew
77+ end
78+ if haskey (graph, :Hj )
79+ graph_new[:Hj ] = [graph[:Hj ]; 1e-6 ] # ones(Jnew)
80+ end
81+ if haskey (graph, :hj )
82+ graph_new[:hj ] = graph_new[:Hj ] ./ graph_new[:Lj ]
83+ end
84+ if haskey (graph, :omegaj )
85+ graph_new[:omegaj ] = [graph_new[:omegaj ]; 1e-6 ] # ones(Jnew)
86+ end
87+ if haskey (graph, :Zjn )
88+ Zjn = fill (minimum (graph[:Zjn ]), Jnew, size (graph[:Zjn ], 2 ))
89+ Zjn[1 : graph[:J ], :] = graph[:Zjn ]
90+ graph_new[:Zjn ] = Zjn # ones(Jnew, size(graph[:Zjn], 2))
91+ end
92+ if haskey (graph, :region )
93+ closest_node = find_node (graph, x, y)
94+ closest_region = graph[:region ][closest_node]
95+ graph_new[:region ] = [graph[:region ]; closest_region]
10396 end
10497
10598 return graph_new
10699end
107100
108-
109- # Please note that in Julia, we use `Dict` to represent structures as in Matlab. The keys of the `Dict` are strings that correspond to the field names in the Matlab structure. Also, the `tril` function is not built-in in Julia, you may need to use a package like `LinearAlgebra` to use it.
110-
111101"""
112102 find_node(graph, x, y) -> Int64
113103
@@ -124,97 +114,79 @@ function find_node(graph, x, y)
124114 return id
125115end
126116
127-
128-
129117"""
130- remove_node(param, graph, i) -> updated_param, updated_graph
118+ remove_node(graph, i) -> Dict
131119
132- Removes node i from the graph.
120+ Removes node i from the graph, returning an updated `graph` object .
133121
134122# Arguments
135- - `param::Dict`: Dict that contains the model's parameters, or `nothing` to only update graph
136123- `graph::Dict`: Dict that contains the underlying graph (created by create_graph())
137- - `i::Int64`: index of the mode to be removed (integer between 1 and graph.J)
138-
139- Returns the updated graph and param objects (param is affected too because the variable Zjn, Lj, Hj and others are changed).
124+ - `i::Int64`: index of the mode to be removed (integer between 1 and graph[:J])
140125"""
141- function remove_node (param, graph, i)
126+ function remove_node (graph, i)
142127
143128 if graph isa Dict
144129 graph_new = copy (dict)
145130 else
146131 graph_new = Dict (pairs (namedtuple))
147132 end
148- graph = dict_to_namedtuple (graph)
149133
150- if i < 1 || i > graph. J || i != floor (i)
151- error (" remove_node: node i should be an integer between 1 and $(graph. J ) ." )
134+ if i < 1 || i > graph[ :J ] || i != floor (i)
135+ error (" remove_node: node i should be an integer between 1 and $(graph[ :J ] ) ." )
152136 end
153137
154- Jnew = graph. J - 1
138+ Jnew = graph[ :J ] - 1
155139
156140 graph_new[:J ] = Jnew
157- graph_new[:x ] = deleteat! (copy (graph. x), i)
158- graph_new[:y ] = deleteat! (copy (graph. y), i)
159- graph_new[:nodes ] = deleteat! (copy (graph. nodes), i)
160-
161- nodes = graph_new[:nodes ]
141+ graph_new[:x ] = deleteat! (copy (graph[:x ]), i)
142+ graph_new[:y ] = deleteat! (copy (graph[:y ]), i)
143+ nodes = deleteat! (copy (graph[:nodes ]), i)
162144 for k in 1 : Jnew
163- node_k = filter (x -> x != i, nodes[k]) # nodes[k][nodes[k] .!= i]
145+ node_k = filter (x -> x != i, nodes[k])
164146 nodes[k] = ifelse .(node_k .> i, node_k .- 1 , node_k) # reindex nodes k > i to k-1
165147 end
148+ graph_new[:nodes ] = nodes # Assign the modified nodes to graph_new
166149
167150 # Rebuild adjacency matrix, delta_i and delta_tau
168- graph_new[:adjacency ] = [graph. adjacency[1 : i- 1 , 1 : i- 1 ] graph. adjacency[1 : i- 1 , i+ 1 : end ];
169- graph. adjacency[i+ 1 : end , 1 : i- 1 ] graph. adjacency[i+ 1 : end , i+ 1 : end ]]
151+ graph_new[:adjacency ] = [graph[ : adjacency] [1 : i- 1 , 1 : i- 1 ] graph[ : adjacency] [1 : i- 1 , i+ 1 : end ];
152+ graph[ : adjacency] [i+ 1 : end , 1 : i- 1 ] graph[ : adjacency] [i+ 1 : end , i+ 1 : end ]]
170153
171- graph_new[:delta_i ] = [graph. delta_i[1 : i- 1 , 1 : i- 1 ] graph. delta_i[1 : i- 1 , i+ 1 : end ];
172- graph. delta_i[i+ 1 : end , 1 : i- 1 ] graph. delta_i[i+ 1 : end , i+ 1 : end ]]
154+ graph_new[:delta_i ] = [graph[ : delta_i] [1 : i- 1 , 1 : i- 1 ] graph[ : delta_i] [1 : i- 1 , i+ 1 : end ];
155+ graph[ : delta_i] [i+ 1 : end , 1 : i- 1 ] graph[ : delta_i] [i+ 1 : end , i+ 1 : end ]]
173156
174- graph_new[:delta_tau ] = [graph. delta_tau[1 : i- 1 , 1 : i- 1 ] graph. delta_tau[1 : i- 1 , i+ 1 : end ];
175- graph. delta_tau[i+ 1 : end , 1 : i- 1 ] graph. delta_tau[i+ 1 : end , i+ 1 : end ]]
157+ graph_new[:delta_tau ] = [graph[ : delta_tau] [1 : i- 1 , 1 : i- 1 ] graph[ : delta_tau] [1 : i- 1 , i+ 1 : end ];
158+ graph[ : delta_tau] [i+ 1 : end , 1 : i- 1 ] graph[ : delta_tau] [i+ 1 : end , i+ 1 : end ]]
176159
177160 if haskey (graph, :across_obstacle )
178- graph_new[:across_obstacle ] = [graph. across_obstacle[1 : i- 1 , 1 : i- 1 ] graph. across_obstacle[1 : i- 1 , i+ 1 : end ];
179- graph. across_obstacle[i+ 1 : end , 1 : i- 1 ] graph. across_obstacle[i+ 1 : end , i+ 1 : end ]]
161+ graph_new[:across_obstacle ] = [graph[ : across_obstacle] [1 : i- 1 , 1 : i- 1 ] graph[ : across_obstacle] [1 : i- 1 , i+ 1 : end ];
162+ graph[ : across_obstacle] [i+ 1 : end , 1 : i- 1 ] graph[ : across_obstacle] [i+ 1 : end , i+ 1 : end ]]
180163 end
181164
182165 if haskey (graph, :along_obstacle )
183- graph_new[:along_obstacle ] = [graph. along_obstacle[1 : i- 1 , 1 : i- 1 ] graph. along_obstacle[1 : i- 1 , i+ 1 : end ];
184- graph. along_obstacle[i+ 1 : end , 1 : i- 1 ] graph. along_obstacle[i+ 1 : end , i+ 1 : end ]]
166+ graph_new[:along_obstacle ] = [graph[ : along_obstacle] [1 : i- 1 , 1 : i- 1 ] graph[ : along_obstacle] [1 : i- 1 , i+ 1 : end ];
167+ graph[ : along_obstacle] [i+ 1 : end , 1 : i- 1 ] graph[ : along_obstacle] [i+ 1 : end , i+ 1 : end ]]
185168 end
186169
187170 graph_new[:ndeg ] = sum (tril (graph_new[:adjacency ]))
188171
189- if graph. region != = nothing
190- graph_new[:region ] = deleteat! (copy (graph. region), i)
191- end
192-
193- if param != = nothing
194- # Now, update the param structure
195- if param isa Dict
196- param_new = copy (param)
197- else
198- param_new = Dict (pairs (param))
199- end
200- param_new[:J ] = Jnew
201- if haskey (param, :Lj )
202- param_new[:Lj ] = deleteat! (copy (param[:Lj ]), i)
203- end
204- if haskey (param, :Hj )
205- param_new[:Hj ] = deleteat! (copy (param[:Hj ]), i)
206- end
207- if haskey (param, :hj )
208- param_new[:hj ] = deleteat! (copy (param[:hj ]), i)
209- end
210- if haskey (param, :omegaj )
211- param_new[:omegaj ] = deleteat! (copy (param[:omegaj ]), i)
212- end
213- if haskey (param, :Zjn )
214- param_new[:Zjn ] = vcat (param[:Zjn ][1 : i- 1 , :], param[:Zjn ][i+ 1 : end , :])
215- end
216-
217- return param_new, graph_new
172+ # Update other parameters if they exist
173+ if haskey (graph, :Lj )
174+ graph_new[:Lj ] = deleteat! (copy (graph[:Lj ]), i)
175+ end
176+ if haskey (graph, :Hj )
177+ graph_new[:Hj ] = deleteat! (copy (graph[:Hj ]), i)
178+ end
179+ if haskey (graph, :hj )
180+ graph_new[:hj ] = deleteat! (copy (graph[:hj ]), i)
181+ end
182+ if haskey (graph, :omegaj )
183+ graph_new[:omegaj ] = deleteat! (copy (graph[:omegaj ]), i)
184+ end
185+ if haskey (graph, :Zjn )
186+ graph_new[:Zjn ] = vcat (graph[:Zjn ][1 : i- 1 , :], graph[:Zjn ][i+ 1 : end , :])
187+ end
188+ if haskey (graph, :region )
189+ graph_new[:region ] = deleteat! (copy (graph[:region ]), i)
218190 end
219191
220192 return graph_new
0 commit comments