|
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