|
187 | 187 | struct ConnectionSet |
188 | 188 | set::Vector{ConnectionElement} # namespace.sys, var, isouter |
189 | 189 | end |
| 190 | +ConnectionSet() = ConnectionSet(ConnectionElement[]) |
190 | 191 | Base.copy(c::ConnectionSet) = ConnectionSet(copy(c.set)) |
191 | 192 |
|
192 | 193 | function Base.show(io::IO, c::ConnectionSet) |
@@ -373,51 +374,38 @@ function generate_connection_set!(connectionsets, domain_csets, |
373 | 374 | end |
374 | 375 |
|
375 | 376 | function Base.merge(csets::AbstractVector{<:ConnectionSet}, allouter = false) |
376 | | - csets, merged = partial_merge(csets, allouter) |
377 | | - while merged |
378 | | - csets, merged = partial_merge(csets) |
379 | | - end |
380 | | - csets |
381 | | -end |
382 | | - |
383 | | -function partial_merge(csets::AbstractVector{<:ConnectionSet}, allouter = false) |
384 | | - mcsets = ConnectionSet[] |
385 | 377 | ele2idx = Dict{ConnectionElement, Int}() |
386 | | - cacheset = Set{ConnectionElement}() |
387 | | - merged = false |
388 | | - for (j, cset) in enumerate(csets) |
389 | | - if allouter |
390 | | - cset = ConnectionSet(map(withtrueouter, cset.set)) |
391 | | - end |
392 | | - idx = nothing |
393 | | - for e in cset.set |
394 | | - idx = get(ele2idx, e, nothing) |
395 | | - if idx !== nothing |
396 | | - merged = true |
397 | | - break |
| 378 | + idx2ele = ConnectionElement[] |
| 379 | + union_find = IntDisjointSets(0) |
| 380 | + prev_id = Ref(-1) |
| 381 | + for cset in csets, (j, s) in enumerate(cset.set) |
| 382 | + v = allouter ? withtrueouter(s) : s |
| 383 | + id = let ele2idx = ele2idx, idx2ele = idx2ele |
| 384 | + get!(ele2idx, v) do |
| 385 | + push!(idx2ele, v) |
| 386 | + id = length(idx2ele) |
| 387 | + id′ = push!(union_find) |
| 388 | + @assert id == id′ |
| 389 | + id |
398 | 390 | end |
399 | 391 | end |
400 | | - if idx === nothing |
401 | | - push!(mcsets, copy(cset)) |
402 | | - for e in cset.set |
403 | | - ele2idx[e] = length(mcsets) |
404 | | - end |
405 | | - else |
406 | | - for e in mcsets[idx].set |
407 | | - push!(cacheset, e) |
408 | | - end |
409 | | - for e in cset.set |
410 | | - push!(cacheset, e) |
411 | | - end |
412 | | - empty!(mcsets[idx].set) |
413 | | - for e in cacheset |
414 | | - ele2idx[e] = idx |
415 | | - push!(mcsets[idx].set, e) |
416 | | - end |
417 | | - empty!(cacheset) |
| 392 | + if j > 1 |
| 393 | + union!(union_find, prev_id[], id) |
| 394 | + end |
| 395 | + prev_id[] = id |
| 396 | + end |
| 397 | + id2set = Dict{Int, ConnectionSet}() |
| 398 | + merged_set = ConnectionSet[] |
| 399 | + for (id, ele) in enumerate(idx2ele) |
| 400 | + rid = find_root(union_find, id) |
| 401 | + set = get!(id2set, rid) do |
| 402 | + set = ConnectionSet() |
| 403 | + push!(merged_set, set) |
| 404 | + set |
418 | 405 | end |
| 406 | + push!(set.set, ele) |
419 | 407 | end |
420 | | - mcsets, merged |
| 408 | + merged_set |
421 | 409 | end |
422 | 410 |
|
423 | 411 | function generate_connection_equations_and_stream_connections(csets::AbstractVector{ |
|
0 commit comments