From 553f433f9c6bf77462cbdcd852861eaca1a711f2 Mon Sep 17 00:00:00 2001 From: Ece Date: Wed, 2 Sep 2020 14:15:55 +0200 Subject: [PATCH 01/18] Added type functions, general heuristics and metagraph --- src/Heuristics.jl | 10 ++++ src/SyntheticNetworks.jl | 100 ++++++++++++++++++++++++++++++++------- 2 files changed, 94 insertions(+), 16 deletions(-) create mode 100644 src/Heuristics.jl diff --git a/src/Heuristics.jl b/src/Heuristics.jl new file mode 100644 index 0000000..11e2ef7 --- /dev/null +++ b/src/Heuristics.jl @@ -0,0 +1,10 @@ +export maximum_value_heuristics,cumulative_distribution_heuristics +function maximum_value_heuristics(f::Function, max_val) + h(g,i) = f(g)[i] < max_val + return h +end + +function cumulative_distribution_heuristics(f::Function; cdf::Function) + h(g,i) = f(g)[i] |> cdf |> x -> rand() > x + return h +end diff --git a/src/SyntheticNetworks.jl b/src/SyntheticNetworks.jl index 392782e..8c5560f 100755 --- a/src/SyntheticNetworks.jl +++ b/src/SyntheticNetworks.jl @@ -8,6 +8,9 @@ using LightGraphs # using SpatialIndexing using EmbeddedGraphs using Distances +using MetaGraphs +import MetaGraph +include("./Heuristics.jl") """ @@ -71,23 +74,61 @@ struct RandomPowerGrid r::Float32 s::Float32 u::Float32 + t_name # Array + t_prob::Array{Float32} + t_method::Array{Function} # (graph::EG, vertex::Int) -> candidate::Bool end -RandomPowerGrid(n, n0) = RandomPowerGrid(n, n0, rand(5)...) +RandomPowerGrid(n, n0) = RandomPowerGrid(n, n0, rand(5)..., " ", [1.], [x -> true]) function generate_graph(RPG) # (n, n0, p, q, r, s, u) = (RPG.n, RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.s) - eg = initialise(RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.u) - grow!(eg, RPG.n, RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.u) - eg + eg, t_list = initialise(RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.u, + RPG.t_name, RPG.t_prob, RPG.t_method) + grow!(eg, t_list, RPG.n, RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.u, + RPG.t_name, RPG.t_prob, RPG.t_method) + mg = MetaGraph(eg, t_list) + mg + # return eg end +# Step IG0 +""" From a list of probabilities of drawing a node type, determines one randomly and + returns the index of node type""" +function draw_type(type_prob::Array{Float32,1}) + t0 = copy(t_p) + pushfirst!(t0 , 0.) + type_interval = [sum(t0[1:i+1]) for i in 1:length(t0)-1] + typerand = rand() + t_n = findfirst(type_interval .>= rand()) + return t_n +end + +function MetaGraph(eg::EmbeddedGraph, default_weight = 1.) + mg = MetaGraph(eg.graph, default_weight) + for (i,j) in enumerate(eg.vertexpos) + set_prop!(mg,i,:pos,j) + end + return mg +end + + +function MetaGraph(eg::EmbeddedGraph, t_arr::Array{String}, default_weight = 1.) + mg = MetaGraph(eg.graph, default_weight) + for (i,j) in enumerate(eg.vertexpos) + set_props!(mg,i,Dict(:pos => j, :type => t_arr[i])) + end + return mg +end + -function initialise(n0::Int, p::Real, q::Real, r::Real, s::Real, u::Real; +function initialise(n0::Int, p::Real, q::Real, r::Real, s::Real, u::Real, + name, prob::Array{Float32}, methods::Array{Function}; vertex_density_prob::Function=rand_uniform_2D) # STEP I1 """If the locations x_1...x_N are not given, draw them independently at random from ρ.""" positions = [vertex_density_prob(i) for i=1:n0 ] + types = [draw_type(prob) for i = 1:n0] graph = EmbeddedGraph(SimpleGraph(n0), positions) # STEP I2 @@ -109,8 +150,13 @@ function initialise(n0::Int, p::Real, q::Real, r::Real, s::Real, u::Real; i = rand(1:nv(graph)) dist_spatial = map(j -> euclidean(graph.vertexpos[i], graph.vertexpos[j]), 1:nv(graph)) - l_edge = Step_G34(graph, i, dist_spatial, r) - add_edge!(graph, l_edge, i) + # + l_edge = Step_G34(graph, i, dist_spatial, r, methods[types]) + if l_edge == 0 + dummy -= 1 + else + add_edge!(graph, l_edge, i) + end end #"""In the new code the logic has changed and this step is equal to step G4. @@ -119,12 +165,16 @@ function initialise(n0::Int, p::Real, q::Real, r::Real, s::Real, u::Real; # for which f(i,j,G) [eqn. 1] is maximal, and add the link i–j to G.""" # Step_I3!(graph, r, m) # OLD LOGIC - graph + return graph, types end -function grow!(graph::EmbeddedGraph, n::Int, n0::Int, p, q, r, s, u; vertex_density_prob::Function=rand_uniform_2D) +function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, + name, prob::Array{Float32}, methods::Array{Function}; + vertex_density_prob::Function=rand_uniform_2D) for n_actual in n0+1:n # STEP G0 + t = draw_type(prob) + push!(types,t) """With probabilities 1−s and s, perform either steps G1–G4 or step G5, respectively.""" if rand() >= s @@ -145,8 +195,14 @@ function grow!(graph::EmbeddedGraph, n::Int, n0::Int, p, q, r, s, u; vertex_dens """ With probability p, find that node l ∈ {1,...,N} ⍀ {j} for which f(i,l,G) is maximal, and add the link i–l to G.""" if rand() <= p - l_edge = Step_G34(graph, nv(graph), dist_spatial, r) + l_edge = Step_G34(graph, nv(graph), dist_spatial, r, methods[types]) + if l_edge == 0 + n_actual -= 1 + continue + else add_edge!(graph, l_edge, nv(graph)) + end + end # STEP G4 """ With probability q, draw a node i' ∈ {1,...,N} uniformly at @@ -156,8 +212,14 @@ function grow!(graph::EmbeddedGraph, n::Int, n0::Int, p, q, r, s, u; vertex_dens if rand() <= q i = rand(1:nv(graph)) dist_spatial = map(j -> euclidean(graph.vertexpos[i], graph.vertexpos[j]), 1:nv(graph)) - l_edge = Step_G34(graph, i, dist_spatial, r) + l_edge = Step_G34(graph, i, dist_spatial, r, methods[types]) + if l_edge == 0 + n_actual -= 1 + continue + else add_edge!(graph, l_edge, i) + end + end else @@ -189,11 +251,17 @@ function Step_I3!(g::EmbeddedGraph, r::Real, m::Int) end -function Step_G34(g::EmbeddedGraph, i::Int, dist_spatial, r) - V = dijkstra_shortest_paths(g, i).dists - V = ((V .+ dist_spatial) .^ r) ./ dist_spatial - V[i] = 0 - argmax(V) +function Step_G34(g::EmbeddedGraph, i::Int, dist_spatial, r, method_arr::Array{Function,1}) + candidates = map(x -> method_arr(g, x), 1:nv(g)) + if sum(candidates) > 0 + V = dijkstra_shortest_paths(g, i).dists + V = ((V .+ dist_spatial) .^ r) ./ dist_spatial + V[i] = 0 + return argmax(V[candidates]) + else + print("no node found") + return 0 + end end rand_uniform_2D(i) = [rand_uniform(i),rand_uniform(i)] From c352160bf33f55a5806344f1430564a808339b51 Mon Sep 17 00:00:00 2001 From: Paul Schultz Date: Thu, 3 Sep 2020 11:44:03 +0200 Subject: [PATCH 02/18] some small fixes --- .gitignore | 3 +- Manifest.toml | 202 ++++++++++++++++++++++++++------------- Project.toml | 1 + src/SyntheticNetworks.jl | 147 ++++++++++++++++++---------- 4 files changed, 235 insertions(+), 118 deletions(-) diff --git a/.gitignore b/.gitignore index b926470..cb41608 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ docs/build/ docs/site/ -.vscode/ \ No newline at end of file +.vscode/ +Manifest.toml \ No newline at end of file diff --git a/Manifest.toml b/Manifest.toml index f834c07..db18cb3 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -9,35 +9,41 @@ version = "0.0.4" [[Base64]] uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +[[CodeTracking]] +deps = ["InteractiveUtils", "UUIDs"] +git-tree-sha1 = "ccc043a0df446cac279dca29d13e2827b40aceb5" +uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2" +version = "0.5.12" + +[[CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "ded953804d019afa9a3f98981d99b33e3db7b6da" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.0" + [[ColorTypes]] -deps = ["FixedPointNumbers", "Random", "Test"] -git-tree-sha1 = "f73b0e10f2a5756de7019818a41654686da06b09" +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "b9de8dc6106e09c79f3f776c27c62360d30e5eb8" uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" -version = "0.7.5" +version = "0.9.1" [[Colors]] -deps = ["ColorTypes", "FixedPointNumbers", "InteractiveUtils", "Printf", "Reexport", "Test"] -git-tree-sha1 = "9f0a0210450acb91c730b730a994f8eef1d3d543" +deps = ["ColorTypes", "FixedPointNumbers", "InteractiveUtils", "Printf", "Reexport"] +git-tree-sha1 = "177d8b959d3c103a6d57574c38ee79c81059c31b" uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" -version = "0.9.5" - -[[Compat]] -deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] -git-tree-sha1 = "195a3ffcb8b0762684b6821de18f83a16455c6ea" -uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "2.0.0" +version = "0.11.2" [[Compose]] -deps = ["Base64", "Colors", "DataStructures", "Dates", "IterTools", "JSON", "LinearAlgebra", "Measures", "Printf", "Random", "Requires", "Test", "UUIDs"] -git-tree-sha1 = "7d8fe0ad6f73c40ccc4e01f426a700c5a843a1d3" +deps = ["Base64", "Colors", "DataStructures", "Dates", "IterTools", "JSON", "LinearAlgebra", "Measures", "Printf", "Random", "Requires", "UUIDs"] +git-tree-sha1 = "034174e607d254b8ca0853a1a9029b265114bf6c" uuid = "a81c6b42-2e10-5240-aca2-a61377ecd94b" -version = "0.7.3" +version = "0.8.2" [[DataStructures]] -deps = ["InteractiveUtils", "OrderedCollections", "Random", "Serialization", "Test"] -git-tree-sha1 = "ca971f03e146cf144a9e2f2ce59674f5bf0e8038" +deps = ["InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "88d48e133e6d3dd68183309877eac74393daa7eb" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.15.0" +version = "0.17.20" [[Dates]] deps = ["Printf"] @@ -48,10 +54,10 @@ deps = ["Mmap"] uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" [[Distances]] -deps = ["LinearAlgebra", "Printf", "Random", "Statistics", "Test"] -git-tree-sha1 = "a135c7c062023051953141da8437ed74f89d767a" +deps = ["LinearAlgebra", "Statistics"] +git-tree-sha1 = "bed62cc5afcff16de797a9f38fb358b74071f785" uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" -version = "0.8.0" +version = "0.9.0" [[Distributed]] deps = ["Random", "Serialization", "Sockets"] @@ -59,69 +65,88 @@ uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" [[DocStringExtensions]] deps = ["LibGit2", "Markdown", "Pkg", "Test"] -git-tree-sha1 = "4d30e889c9f106a51ffa4791a88ffd4765bf20c3" +git-tree-sha1 = "50ddf44c53698f5e784bbebb3f4b21c5807401b1" uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.7.0" +version = "0.8.3" [[Documenter]] -deps = ["Base64", "DocStringExtensions", "InteractiveUtils", "LibGit2", "Logging", "Markdown", "Pkg", "REPL", "Random", "Test", "Unicode"] -git-tree-sha1 = "a8c41ba3d0861240dbec942ee1d0f86c57c37c1c" +deps = ["Base64", "Dates", "DocStringExtensions", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "REPL", "Test", "Unicode"] +git-tree-sha1 = "fb1ff838470573adc15c71ba79f8d31328f035da" uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "0.21.5" +version = "0.25.2" [[EmbeddedGraphs]] -deps = ["Compose", "Distances", "Documenter", "GraphPlot", "LightGraphs", "Parameters", "Random", "SparseArrays", "Test"] -git-tree-sha1 = "e8330f26683303d4cdc9532fb41d073f796338df" +deps = ["Distances", "GraphPlot", "LightGraphs", "Random", "Revise", "SparseArrays", "Test"] +git-tree-sha1 = "b98a7656987981644f69392db24df3401663bcc9" repo-rev = "master" -repo-url = "../EmbeddedGraphs.jl" +repo-url = "https://github.com/FHell/EmbeddedGraphs.jl.git" uuid = "9c1af47c-29f5-11e9-0b47-9f5334384f20" version = "0.1.0" +[[FileIO]] +deps = ["Pkg"] +git-tree-sha1 = "992b4aeb62f99b69fcf0cb2085094494cc05dfb3" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.4.3" + +[[FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" + [[FixedPointNumbers]] -deps = ["Test"] -git-tree-sha1 = "b8045033701c3b10bf2324d7203404be7aef88ba" +git-tree-sha1 = "4aaea64dd0c30ad79037084f8ca2b94348e65eaa" uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.5.3" +version = "0.7.1" [[GraphPlot]] -deps = ["ArnoldiMethod", "ColorTypes", "Colors", "Compose", "DelimitedFiles", "LightGraphs", "LinearAlgebra", "Random", "SparseArrays", "Test"] -git-tree-sha1 = "f4435ce0055d4da938f3bab0c0e523826735c96a" +deps = ["ArnoldiMethod", "ColorTypes", "Colors", "Compose", "DelimitedFiles", "LightGraphs", "LinearAlgebra", "Random", "SparseArrays"] +git-tree-sha1 = "32f72eb61d372429ce8fd2ee9b7079599dacb93b" uuid = "a2cc645c-3eea-5389-862e-a155d0052231" -version = "0.3.1" +version = "0.4.2" [[Inflate]] -deps = ["Pkg", "Printf", "Random", "Test"] -git-tree-sha1 = "b7ec91c153cf8bff9aff58b39497925d133ef7fd" +git-tree-sha1 = "f5fc07d4e706b84f72d54eedcc1c13d92fb0871c" uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" -version = "0.1.1" +version = "0.1.2" [[InteractiveUtils]] deps = ["Markdown"] uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" [[IterTools]] -deps = ["SparseArrays", "Test"] -git-tree-sha1 = "79246285c43602384e6f1943b3554042a3712056" +git-tree-sha1 = "05110a2ab1fc5f932622ffea2a003221f4782c18" uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" -version = "1.1.1" +version = "1.3.0" + +[[JLD2]] +deps = ["CodecZlib", "DataStructures", "FileIO", "Mmap", "Pkg", "Printf", "UUIDs"] +git-tree-sha1 = "9353b717ee4e27beab4e902c92a06bb5f160d2cf" +uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +version = "0.1.14" [[JSON]] -deps = ["Dates", "Distributed", "Mmap", "Sockets", "Test", "Unicode"] -git-tree-sha1 = "1f7a25b53ec67f5e9422f1f551ee216503f4a0fa" +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "b34d7cef7b337321e97d22242c3c2b91f476748e" uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" -version = "0.20.0" +version = "0.21.0" + +[[JuliaInterpreter]] +deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"] +git-tree-sha1 = "7b2a1b650cec61a7d8cd8ee9ee7a818b5764d502" +uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a" +version = "0.7.26" [[LibGit2]] +deps = ["Printf"] uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" [[Libdl]] uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" [[LightGraphs]] -deps = ["ArnoldiMethod", "Base64", "DataStructures", "DelimitedFiles", "Distributed", "Inflate", "LinearAlgebra", "Markdown", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics", "Test"] -git-tree-sha1 = "c7222c370d5cf6d4e08ae40bddd8c0db6852dfb1" +deps = ["ArnoldiMethod", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] +git-tree-sha1 = "6f85a35d2377cb2db1bc448ed0d6340d2bb1ea64" uuid = "093fc24a-ae57-5d10-9952-331d41423f4d" -version = "1.2.0" +version = "1.3.3" [[LinearAlgebra]] deps = ["Libdl"] @@ -130,39 +155,55 @@ uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" [[Logging]] uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" +[[LoweredCodeUtils]] +deps = ["JuliaInterpreter"] +git-tree-sha1 = "dbd9336b43c2d6fa492efa09ba3bb10fbdbeeb64" +uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b" +version = "0.4.9" + [[MacroTools]] -deps = ["Compat"] -git-tree-sha1 = "3fd1a3022952128935b449c33552eb65895380c1" +deps = ["Markdown", "Random"] +git-tree-sha1 = "f7d2e3f654af75f01ec49be82c231c382214223a" uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.4.5" +version = "0.5.5" [[Markdown]] deps = ["Base64"] uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" [[Measures]] -deps = ["Test"] -git-tree-sha1 = "ddfd6d13e330beacdde2c80de27c1c671945e7d9" +git-tree-sha1 = "e498ddeee6f9fdb4551ce855a46f54dbd900245f" uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e" -version = "0.3.0" +version = "0.3.1" + +[[MetaGraphs]] +deps = ["JLD2", "LightGraphs", "Random"] +git-tree-sha1 = "8900d368fa44bd61c7e598d6a0f577e347f3cf67" +uuid = "626554b9-1ddb-594c-aa3c-2596fe9399a5" +version = "0.6.5" [[Mmap]] uuid = "a63ad114-7e13-5084-954f-fe012c677804" [[OrderedCollections]] -deps = ["Random", "Serialization", "Test"] -git-tree-sha1 = "85619a3f3e17bb4761fe1b1fd47f0e979f964d5b" +git-tree-sha1 = "293b70ac1780f9584c89268a6e2a560d938a7065" uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.0.2" +version = "1.3.0" [[Parameters]] -deps = ["Markdown", "OrderedCollections", "REPL", "Test"] -git-tree-sha1 = "70bdbfb2bceabb15345c0b54be4544813b3444e4" +deps = ["OrderedCollections", "UnPack"] +git-tree-sha1 = "38b2e970043613c187bd56a995fe2e551821eb4a" uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" -version = "0.10.3" +version = "0.12.1" + +[[Parsers]] +deps = ["Dates", "Test"] +git-tree-sha1 = "8077624b3c450b15c087944363606a6ba12f925e" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "1.0.10" [[Pkg]] -deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] +deps = ["Dates", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" [[Printf]] @@ -184,10 +225,16 @@ uuid = "189a3867-3050-52da-a836-e630ba90ab69" version = "0.2.0" [[Requires]] -deps = ["Test"] -git-tree-sha1 = "f6fbf4ba64d295e146e49e021207993b6b48c7d1" +deps = ["UUIDs"] +git-tree-sha1 = "8c08d0c7812169e438a8478dae2a529377ad13f7" uuid = "ae029012-a4dd-5104-9daa-d747884805df" -version = "0.5.2" +version = "1.0.2" + +[[Revise]] +deps = ["CodeTracking", "Distributed", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "Pkg", "REPL", "UUIDs", "Unicode"] +git-tree-sha1 = "a860e786779be1ab6407d427470e1415711dd459" +uuid = "295af30f-e4ad-537b-8983-00126c2a3abe" +version = "2.7.5" [[SHA]] uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" @@ -200,10 +247,10 @@ deps = ["Distributed", "Mmap", "Random", "Serialization"] uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" [[SimpleTraits]] -deps = ["InteractiveUtils", "MacroTools", "Test"] -git-tree-sha1 = "c0a542b8d5e369b179ccd296b2ca987f6da5da0a" +deps = ["InteractiveUtils", "MacroTools"] +git-tree-sha1 = "daf7aec3fe3acb2131388f93a4c409b8c7f62226" uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" -version = "0.8.0" +version = "0.9.3" [[Sockets]] uuid = "6462fe0b-24de-5631-8697-dd941f90decc" @@ -219,10 +266,10 @@ uuid = "d4ead438-fe20-5cc5-a293-4fd39a41b74c" version = "0.1.2" [[StaticArrays]] -deps = ["InteractiveUtils", "LinearAlgebra", "Random", "Statistics", "Test"] -git-tree-sha1 = "3841b39ed5f047db1162627bf5f80a9cd3e39ae2" +deps = ["LinearAlgebra", "Random", "Statistics"] +git-tree-sha1 = "016d1e1a00fabc556473b07161da3d39726ded35" uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "0.10.3" +version = "0.12.4" [[Statistics]] deps = ["LinearAlgebra", "SparseArrays"] @@ -232,9 +279,26 @@ uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +[[TranscodingStreams]] +deps = ["Random", "Test"] +git-tree-sha1 = "7c53c35547de1c5b9d46a4797cf6d8253807108c" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.9.5" + [[UUIDs]] deps = ["Random", "SHA"] uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" +[[UnPack]] +git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" +uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" +version = "1.0.2" + [[Unicode]] uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[Zlib_jll]] +deps = ["Libdl", "Pkg"] +git-tree-sha1 = "fdd89e5ab270ea0f2a0174bd9093e557d06d4bfa" +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.2.11+16" diff --git a/Project.toml b/Project.toml index 35fa44b..2eba641 100644 --- a/Project.toml +++ b/Project.toml @@ -8,6 +8,7 @@ Distances = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" EmbeddedGraphs = "9c1af47c-29f5-11e9-0b47-9f5334384f20" LightGraphs = "093fc24a-ae57-5d10-9952-331d41423f4d" +MetaGraphs = "626554b9-1ddb-594c-aa3c-2596fe9399a5" Parameters = "d96e819e-fc66-5662-9728-84c9c7592b0a" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" SpatialIndexing = "d4ead438-fe20-5cc5-a293-4fd39a41b74c" diff --git a/src/SyntheticNetworks.jl b/src/SyntheticNetworks.jl index c2c1d26..39a23b2 100755 --- a/src/SyntheticNetworks.jl +++ b/src/SyntheticNetworks.jl @@ -1,5 +1,3 @@ -__precompile__(false) - module SyntheticNetworks using Random @@ -8,8 +6,8 @@ using LightGraphs # using SpatialIndexing using EmbeddedGraphs using Distances -using MetaGraphs -import MetaGraph +# using MetaGraphs +import MetaGraphs: MetaGraph include("./Heuristics.jl") @@ -74,66 +72,99 @@ struct RandomPowerGrid r::Float32 s::Float32 u::Float32 - t_name # Array + t_name::Any # Array t_prob::Array{Float32} t_method::Array{Function} # (graph::EG, vertex::Int) -> candidate::Bool end -RandomPowerGrid(n, n0) = RandomPowerGrid(n, n0, rand(5)..., " ", [1.], [x -> true]) +RandomPowerGrid(n, n0) = RandomPowerGrid(n, n0, rand(5)..., " ", [1.0], [x -> true]) function generate_graph(RPG) # (n, n0, p, q, r, s, u) = (RPG.n, RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.s) - eg, t_list = initialise(RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.u, - RPG.t_name, RPG.t_prob, RPG.t_method) - grow!(eg, t_list, RPG.n, RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.u, - RPG.t_name, RPG.t_prob, RPG.t_method) - mg = MetaGraph(eg, t_list) - mg + eg, t_list = initialise( + RPG.n0, + RPG.p, + RPG.q, + RPG.r, + RPG.s, + RPG.u, + RPG.t_name, + RPG.t_prob, + RPG.t_method, + ) + grow!( + eg, + t_list, + RPG.n, + RPG.n0, + RPG.p, + RPG.q, + RPG.r, + RPG.s, + RPG.u, + RPG.t_name, + RPG.t_prob, + RPG.t_method, + ) + mg = MetaGraph(eg, t_list) + return mg # return eg end + # Step IG0 """ From a list of probabilities of drawing a node type, determines one randomly and returns the index of node type""" function draw_type(type_prob::Array{Float32,1}) - t0 = copy(t_p) - pushfirst!(t0 , 0.) - type_interval = [sum(t0[1:i+1]) for i in 1:length(t0)-1] + t0 = copy(type_prob) + pushfirst!(t0, 0.0) + type_interval = [sum(t0[1:i+1]) for i = 1:length(t0)-1] typerand = rand() t_n = findfirst(type_interval .>= rand()) return t_n end -function MetaGraph(eg::EmbeddedGraph, default_weight = 1.) +function MetaGraph(eg::EmbeddedGraph, default_weight = 1.0) mg = MetaGraph(eg.graph, default_weight) - for (i,j) in enumerate(eg.vertexpos) - set_prop!(mg,i,:pos,j) + for (i, j) in enumerate(eg.vertexpos) + set_prop!(mg, i, :pos, j) end return mg end -function MetaGraph(eg::EmbeddedGraph, t_arr::Array{String}, default_weight = 1.) +function MetaGraph(eg::EmbeddedGraph, t_arr::Array{String}, default_weight = 1.0) mg = MetaGraph(eg.graph, default_weight) - for (i,j) in enumerate(eg.vertexpos) - set_props!(mg,i,Dict(:pos => j, :type => t_arr[i])) + for (i, j) in enumerate(eg.vertexpos) + set_props!(mg, i, Dict(:pos => j, :type => t_arr[i])) end return mg end -function initialise(n0::Int, p::Real, q::Real, r::Real, s::Real, u::Real, - name, prob::Array{Float32}, methods::Array{Function}; - vertex_density_prob::Function=rand_uniform_2D) +function initialise( + n0::Int, + p::Real, + q::Real, + r::Real, + s::Real, + u::Real, + name, + prob::Array{Float32}, + methods::Array{Function}; + vertex_density_prob::Function = rand_uniform_2D, +) # we can skip this when only a single node is given if n0 == 1 - graph = EmbeddedGraph(complete_graph(n0), vertex_density_prob(n0)) + positions = [vertex_density_prob(n0), ] + types = [draw_type(prob), ] + graph = EmbeddedGraph(SimpleGraph(n0), positions) else # STEP I1 """If the locations x_1...x_N are not given, draw them independently at random from ρ.""" - positions = [vertex_density_prob(i) for i=1:n0 ] + positions = [vertex_density_prob(i) for i = 1:n0] types = [draw_type(prob) for i = 1:n0] graph = EmbeddedGraph(SimpleGraph(n0), positions) @@ -143,7 +174,7 @@ function initialise(n0::Int, p::Real, q::Real, r::Real, s::Real, u::Real, Prim’s more efficient algorithm). """ mst_graph = EmbeddedGraph(complete_graph(n0), positions) - edges = prim_mst(mst_graph.graph, weights(mst_graph, dense=true)) + edges = prim_mst(mst_graph.graph, weights(mst_graph, dense = true)) for edge in edges add_edge!(graph, edge) end @@ -153,10 +184,11 @@ function initialise(n0::Int, p::Real, q::Real, r::Real, s::Real, u::Real, random, find that node l ∈ {1,...,N} which is not yet linked to i and for which f (i,l,G) is maximal, and add the link i–l to G.""" - m = Int(round(n0*(1-s)*(p+q), RoundDown)) - for dummy in 1:m + m = Int(round(n0 * (1 - s) * (p + q), RoundDown)) + for dummy = 1:m i = rand(1:nv(graph)) - dist_spatial = map(j -> euclidean(graph.vertexpos[i], graph.vertexpos[j]), 1:nv(graph)) + dist_spatial = + map(j -> euclidean(graph.vertexpos[i], graph.vertexpos[j]), 1:nv(graph)) # l_edge = Step_G34(graph, i, dist_spatial, r, methods[types]) if l_edge == 0 @@ -176,16 +208,28 @@ function initialise(n0::Int, p::Real, q::Real, r::Real, s::Real, u::Real, return graph, types end -function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, - name, prob::Array{Float32}, methods::Array{Function}; - vertex_density_prob::Function=rand_uniform_2D) - for n_actual in n0+1:n +function grow!( + graph::EmbeddedGraph, + types, + n::Int, + n0::Int, + p, + q, + r, + s, + u, + name, + prob::Array{Float32}, + methods::Array{Function}; + vertex_density_prob::Function = rand_uniform_2D, +) + for n_actual = n0+1:n # STEP G0 t = draw_type(prob) - push!(types,t) + push!(types, t) """With probabilities 1−s and s, perform either steps G1–G4 or step G5, respectively.""" - if rand() >= s + if (rand() >= s) | (ne(graph) == 0) # STEP G1 """If x i is not given, draw it at random from ρ.""" pos = vertex_density_prob(n_actual) @@ -194,8 +238,11 @@ function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, # STEP G2 """ Find that node j ∈ {1,...,N} for which dist_spatial(x_i,x_j) is minimal and add the link i–j to G.""" - dist_spatial = map(i -> euclidean(graph.vertexpos[nv(graph)], graph.vertexpos[i]), 1:nv(graph)) - dist_spatial[nv(graph)] = 100000. #Inf + dist_spatial = map( + i -> euclidean(graph.vertexpos[nv(graph)], graph.vertexpos[i]), + 1:nv(graph), + ) + dist_spatial[nv(graph)] = 100000.0 #Inf min_dist_vertex = argmin(dist_spatial) add_edge!(graph, min_dist_vertex, nv(graph)) @@ -208,7 +255,7 @@ function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, n_actual -= 1 continue else - add_edge!(graph, l_edge, nv(graph)) + add_edge!(graph, l_edge, nv(graph)) end end @@ -219,13 +266,14 @@ function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, to G.""" if rand() <= q i = rand(1:nv(graph)) - dist_spatial = map(j -> euclidean(graph.vertexpos[i], graph.vertexpos[j]), 1:nv(graph)) + dist_spatial = + map(j -> euclidean(graph.vertexpos[i], graph.vertexpos[j]), 1:nv(graph)) l_edge = Step_G34(graph, i, dist_spatial, r, methods[types]) if l_edge == 0 n_actual -= 1 continue else - add_edge!(graph, l_edge, i) + add_edge!(graph, l_edge, i) end end @@ -238,7 +286,10 @@ function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, New logic splits the nodes somewhere, not in the middle.""" edge = rand(edges(graph)) splitval = rand() - newpos = (graph.vertexpos[src(edge)] * splitval + graph.vertexpos[dst(edge)] * (1-splitval)) + newpos = ( + graph.vertexpos[src(edge)] * splitval + + graph.vertexpos[dst(edge)] * (1 - splitval) + ) add_vertex!(graph, newpos) add_edge!(graph, src(edge), nv(graph)) add_edge!(graph, dst(edge), nv(graph)) @@ -249,12 +300,12 @@ end function Step_I3!(g::EmbeddedGraph, r::Real, m::Int) - for dummy in 1:m - spatial = weights(g, dense=true) + for dummy = 1:m + spatial = weights(g, dense = true) A = floyd_warshall_shortest_paths(g, weights(g)).dists A = ((A .+ spatial) .^ r) ./ spatial - map(i -> A[i,i] = 0, 1:size(A)[1]) - add_edge!(g,Tuple(argmax(A))...) + map(i -> A[i, i] = 0, 1:size(A)[1]) + add_edge!(g, Tuple(argmax(A))...) end end @@ -272,8 +323,8 @@ function Step_G34(g::EmbeddedGraph, i::Int, dist_spatial, r, method_arr::Array{F end end -rand_uniform_2D(i) = [rand_uniform(i),rand_uniform(i)] -rand_uniform(i) = 2*(0.5-rand()) +rand_uniform_2D(i) = [rand_uniform(i), rand_uniform(i)] +rand_uniform(i) = 2 * (0.5 - rand()) end # module From edb0c1148598c8d0e40117ebab304858dac2552b Mon Sep 17 00:00:00 2001 From: Paul Schultz Date: Thu, 3 Sep 2020 13:14:41 +0200 Subject: [PATCH 03/18] resolve -> mainfest --- .gitignore | 2 +- Manifest.toml | 22 ++++++++++++++++++++++ Project.toml | 2 +- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index cb41608..e2c98f8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ docs/build/ docs/site/ .vscode/ -Manifest.toml \ No newline at end of file +Manifest.toml diff --git a/Manifest.toml b/Manifest.toml index e7514fc..db18cb3 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -15,6 +15,12 @@ git-tree-sha1 = "ccc043a0df446cac279dca29d13e2827b40aceb5" uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2" version = "0.5.12" +[[CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "ded953804d019afa9a3f98981d99b33e3db7b6da" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.0" + [[ColorTypes]] deps = ["FixedPointNumbers", "Random"] git-tree-sha1 = "b9de8dc6106e09c79f3f776c27c62360d30e5eb8" @@ -77,6 +83,11 @@ repo-url = "https://github.com/FHell/EmbeddedGraphs.jl.git" uuid = "9c1af47c-29f5-11e9-0b47-9f5334384f20" version = "0.1.0" +[[FileIO]] +deps = ["Pkg"] +git-tree-sha1 = "992b4aeb62f99b69fcf0cb2085094494cc05dfb3" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.4.3" [[FileWatching]] uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" @@ -106,6 +117,11 @@ git-tree-sha1 = "05110a2ab1fc5f932622ffea2a003221f4782c18" uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" version = "1.3.0" +[[JLD2]] +deps = ["CodecZlib", "DataStructures", "FileIO", "Mmap", "Pkg", "Printf", "UUIDs"] +git-tree-sha1 = "9353b717ee4e27beab4e902c92a06bb5f160d2cf" +uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +version = "0.1.14" [[JSON]] deps = ["Dates", "Mmap", "Parsers", "Unicode"] @@ -160,6 +176,12 @@ git-tree-sha1 = "e498ddeee6f9fdb4551ce855a46f54dbd900245f" uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e" version = "0.3.1" +[[MetaGraphs]] +deps = ["JLD2", "LightGraphs", "Random"] +git-tree-sha1 = "8900d368fa44bd61c7e598d6a0f577e347f3cf67" +uuid = "626554b9-1ddb-594c-aa3c-2596fe9399a5" +version = "0.6.5" + [[Mmap]] uuid = "a63ad114-7e13-5084-954f-fe012c677804" diff --git a/Project.toml b/Project.toml index 8053ee4..0a8a93f 100644 --- a/Project.toml +++ b/Project.toml @@ -15,5 +15,5 @@ SpatialIndexing = "d4ead438-fe20-5cc5-a293-4fd39a41b74c" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [compat] -julia = "1.0" Documenter = "0.25" +julia = "1.0" From 0bbed77ade0765241db3fe79fc2fcb2a66b70f4a Mon Sep 17 00:00:00 2001 From: Ece Date: Thu, 3 Sep 2020 18:57:03 +0200 Subject: [PATCH 04/18] Fixed heuristics functions. Added specific maximum value methods for degree and betweenness. Fixed some other bugs. Changed complete_graph to CompleteGraph because it used to be called this in LightGraphs version in the dependencies (1.2). It didn't otherwise work in the package environment. --- src/Heuristics.jl | 25 ++++- src/SyntheticNetworks.jl | 210 ++++++++++++++------------------------- 2 files changed, 99 insertions(+), 136 deletions(-) diff --git a/src/Heuristics.jl b/src/Heuristics.jl index 11e2ef7..65fc99f 100644 --- a/src/Heuristics.jl +++ b/src/Heuristics.jl @@ -1,10 +1,29 @@ -export maximum_value_heuristics,cumulative_distribution_heuristics +export maximum_value_heuristics,cumulative_distribution_heuristics, + maximum_degree, maximum_betweenness function maximum_value_heuristics(f::Function, max_val) - h(g,i) = f(g)[i] < max_val + # h(g,i) = f(g)[i] < max_val + h = (g,i) -> f(g)[i] < max_val ? 1 : 0 return h end function cumulative_distribution_heuristics(f::Function; cdf::Function) - h(g,i) = f(g)[i] |> cdf |> x -> rand() > x + h = (g,i) -> f(g)[i] |> cdf |> x -> rand() > x ? 1 : 0 return h end + +function maximum_degree(k_max) + max_degree = (g,i) -> maximum_value_heuristics( + x -> degree_centrality(x,normalize = false), + k_max + ) + return max_degree +end + +function maximum_betweenness(b_max) + max_betweenness = (g,i) -> maximum_value_heuristics( + x -> betweenness_centrality(x,normalize = false), + b_max + ) + return max_betweenness +end + diff --git a/src/SyntheticNetworks.jl b/src/SyntheticNetworks.jl index 4a5cd8a..0b988f2 100755 --- a/src/SyntheticNetworks.jl +++ b/src/SyntheticNetworks.jl @@ -1,3 +1,5 @@ +__precompile__(false) + module SyntheticNetworks using Random @@ -7,7 +9,7 @@ using LightGraphs using EmbeddedGraphs using Distances # using MetaGraphs -import MetaGraphs: MetaGraph +# import MetaGraph include("./Heuristics.jl") @@ -72,127 +74,88 @@ struct RandomPowerGrid r::Float32 s::Float32 u::Float32 - t_name::Any # Array + t_name # Array t_prob::Array{Float32} t_method::Array{Function} # (graph::EG, vertex::Int) -> candidate::Bool end - -RandomPowerGrid(n, n0) = RandomPowerGrid(n, n0, rand(5)..., " ", [1.0], [x -> true]) +default_method(g::EmbeddedGraph,i::Int32)::Bool = true +RandomPowerGrid(n, n0) = RandomPowerGrid(n, n0, rand(5)..., " ", [1.], [default_method]) function generate_graph(RPG) # (n, n0, p, q, r, s, u) = (RPG.n, RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.s) - eg, t_list = initialise( - RPG.n0, - RPG.p, - RPG.q, - RPG.r, - RPG.s, - RPG.u, - RPG.t_name, - RPG.t_prob, - RPG.t_method, - ) - grow!( - eg, - t_list, - RPG.n, - RPG.n0, - RPG.p, - RPG.q, - RPG.r, - RPG.s, - RPG.u, - RPG.t_name, - RPG.t_prob, - RPG.t_method, - ) - mg = MetaGraph(eg, t_list) - return mg - # return eg + eg, t_list = initialise(RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.u, + RPG.t_name, RPG.t_prob, RPG.t_method) + grow!(eg, t_list, RPG.n, RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.u, + RPG.t_name, RPG.t_prob, RPG.t_method) + # mg = MetaGraph(eg, t_list) + # mg + return eg, t_list end - # Step IG0 """ From a list of probabilities of drawing a node type, determines one randomly and returns the index of node type""" function draw_type(type_prob::Array{Float32,1}) t0 = copy(type_prob) - pushfirst!(t0, 0.0) - type_interval = [sum(t0[1:i+1]) for i = 1:length(t0)-1] + pushfirst!(t0 , 0.) + type_interval = [sum(t0[1:i+1]) for i in 1:length(t0)-1] typerand = rand() t_n = findfirst(type_interval .>= rand()) return t_n end -function MetaGraph(eg::EmbeddedGraph, default_weight = 1.0) +function MetaGraph(eg::EmbeddedGraph, default_weight = 1.) mg = MetaGraph(eg.graph, default_weight) - for (i, j) in enumerate(eg.vertexpos) - set_prop!(mg, i, :pos, j) + for (i,j) in enumerate(eg.vertexpos) + set_prop!(mg,i,:pos,j) end return mg end -function MetaGraph(eg::EmbeddedGraph, t_arr::Array{String}, default_weight = 1.0) + +function MetaGraph(eg::EmbeddedGraph, t_arr::Array{String}, default_weight = 1.) mg = MetaGraph(eg.graph, default_weight) - for (i, j) in enumerate(eg.vertexpos) - set_props!(mg, i, Dict(:pos => j, :type => t_arr[i])) + for (i,j) in enumerate(eg.vertexpos) + set_props!(mg,i,Dict(:pos => j, :type => t_arr[i])) end return mg end -function initialise( - n0::Int, - p::Real, - q::Real, - r::Real, - s::Real, - u::Real, - name, - prob::Array{Float32}, - methods::Array{Function}; - vertex_density_prob::Function = rand_uniform_2D, -) - # we can skip this when only a single node is given - if n0 == 1 - positions = [vertex_density_prob(n0), ] - types = [draw_type(prob), ] - graph = EmbeddedGraph(SimpleGraph(n0), positions) - else - # STEP I1 - """If the locations x_1...x_N are not given, draw them independently at +function initialise(n0::Int, p::Real, q::Real, r::Real, s::Real, u::Real, + name, prob::Array{Float32}, methods::Array{Function}; + vertex_density_prob::Function=rand_uniform_2D) + # STEP I1 + """If the locations x_1...x_N are not given, draw them independently at random from ρ.""" + positions = [vertex_density_prob(i) for i=1:n0 ] + types = [draw_type(prob) for i = 1:n0] + graph = EmbeddedGraph(SimpleGraph(n0), positions) + + # STEP I2 + """Initialize G to be a minimum spanning tree (MST) for x_1...x_N w.r.t. + the distance function dist_spatial(x, y) (using Kruskal’s simple or + Prim’s more efficient algorithm). """ + mst_graph = EmbeddedGraph(LightGraphs.CompleteGraph(n0), positions) + edges = prim_mst(mst_graph.graph, weights(mst_graph, dense=true)) + for edge in edges + add_edge!(graph, edge) + end - positions = [vertex_density_prob(i) for i = 1:n0] - types = [draw_type(prob) for i = 1:n0] - graph = EmbeddedGraph(SimpleGraph(n0), positions) - - # STEP I2 - """Initialize G to be a minimum spanning tree (MST) for x_1...x_N w.r.t. - the distance function dist_spatial(x, y) (using Kruskal’s simple or - Prim’s more efficient algorithm). """ - - mst_graph = EmbeddedGraph(complete_graph(n0), positions) - edges = prim_mst(mst_graph.graph, weights(mst_graph, dense = true)) - for edge in edges - add_edge!(graph, edge) - end - - # STEP I3 - """With probability q, draw a node i ∈ {1,...,N} uniformly at - random, find that node l ∈ {1,...,N} which is not yet linked to i and - for which f (i,l,G) is maximal, and add the link i–l to G.""" - m = Int(round(n0 * (1 - s) * (p + q), RoundDown)) - for dummy = 1:m - i = rand(1:nv(graph)) - dist_spatial = - map(j -> euclidean(graph.vertexpos[i], graph.vertexpos[j]), 1:nv(graph)) - # - l_edge = Step_G34(graph, i, dist_spatial, r, methods[types]) - if l_edge == 0 - dummy -= 1 - else - add_edge!(graph, l_edge, i) - end + # STEP I3 + """With probability q, draw a node i ∈ {1,...,N} uniformly at + random, find that node l ∈ {1,...,N} which is not yet linked to i and + for which f (i,l,G) is maximal, and add the link i–l to G.""" + m = Int(round(n0*(1-s)*(p+q), RoundDown)) + for dummy in 1:m + i = rand(1:nv(graph)) + dist_spatial = map(j -> euclidean(graph.vertexpos[i], + graph.vertexpos[j]), 1:nv(graph)) + # + l_edge = Step_G34(graph, i, dist_spatial, r, methods[types]) + if l_edge == 0 + dummy -= 1 + else + add_edge!(graph, l_edge, i) end end @@ -205,28 +168,16 @@ function initialise( return graph, types end -function grow!( - graph::EmbeddedGraph, - types, - n::Int, - n0::Int, - p, - q, - r, - s, - u, - name, - prob::Array{Float32}, - methods::Array{Function}; - vertex_density_prob::Function = rand_uniform_2D, -) - for n_actual = n0+1:n +function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, + name, prob::Array{Float32}, methods::Array{Function}; + vertex_density_prob::Function=rand_uniform_2D) + for n_actual in n0+1:n # STEP G0 t = draw_type(prob) - push!(types, t) + push!(types,t) """With probabilities 1−s and s, perform either steps G1–G4 or step G5, respectively.""" - if (rand() >= s) | isempty(edges(graph)) + if rand() >= s || ne(graph) > 0 # STEP G1 """If x i is not given, draw it at random from ρ.""" pos = vertex_density_prob(n_actual) @@ -235,11 +186,8 @@ function grow!( # STEP G2 """ Find that node j ∈ {1,...,N} for which dist_spatial(x_i,x_j) is minimal and add the link i–j to G.""" - dist_spatial = map( - i -> euclidean(graph.vertexpos[nv(graph)], graph.vertexpos[i]), - 1:nv(graph), - ) - dist_spatial[nv(graph)] = 100000.0 #Inf + dist_spatial = map(i -> euclidean(graph.vertexpos[nv(graph)], graph.vertexpos[i]), 1:nv(graph)) + dist_spatial[nv(graph)] = 100000. #Inf min_dist_vertex = argmin(dist_spatial) add_edge!(graph, min_dist_vertex, nv(graph)) @@ -252,7 +200,7 @@ function grow!( n_actual -= 1 continue else - add_edge!(graph, l_edge, nv(graph)) + add_edge!(graph, l_edge, nv(graph)) end end @@ -263,15 +211,15 @@ function grow!( to G.""" if rand() <= q i = rand(1:nv(graph)) - dist_spatial = - map(j -> euclidean(graph.vertexpos[i], graph.vertexpos[j]), 1:nv(graph)) + dist_spatial = map(j -> euclidean(graph.vertexpos[i], graph.vertexpos[j]), 1:nv(graph)) l_edge = Step_G34(graph, i, dist_spatial, r, methods[types]) if l_edge == 0 n_actual -= 1 continue else - add_edge!(graph, l_edge, i) + add_edge!(graph, l_edge, i) end + end else @@ -282,10 +230,7 @@ function grow!( New logic splits the nodes somewhere, not in the middle.""" edge = rand(edges(graph)) splitval = rand() - newpos = ( - graph.vertexpos[src(edge)] * splitval + - graph.vertexpos[dst(edge)] * (1 - splitval) - ) + newpos = (graph.vertexpos[src(edge)] * splitval + graph.vertexpos[dst(edge)] * (1-splitval)) add_vertex!(graph, newpos) add_edge!(graph, src(edge), nv(graph)) add_edge!(graph, dst(edge), nv(graph)) @@ -296,31 +241,30 @@ end function Step_I3!(g::EmbeddedGraph, r::Real, m::Int) - for dummy = 1:m - spatial = weights(g, dense = true) + for dummy in 1:m + spatial = weights(g, dense=true) A = floyd_warshall_shortest_paths(g, weights(g)).dists A = ((A .+ spatial) .^ r) ./ spatial - map(i -> A[i, i] = 0, 1:size(A)[1]) - add_edge!(g, Tuple(argmax(A))...) + map(i -> A[i,i] = 0, 1:size(A)[1]) + add_edge!(g,Tuple(argmax(A))...) end end function Step_G34(g::EmbeddedGraph, i::Int, dist_spatial, r, method_arr::Array{Function,1}) - candidates = map(x -> method_arr(g, x), 1:nv(g)) - if sum(candidates) > 0 + candidates = [method_arr[i](g, i) == 1 ? true : false for i in 1:nv(g)] + if true in candidates V = dijkstra_shortest_paths(g, i).dists V = ((V .+ dist_spatial) .^ r) ./ dist_spatial V[i] = 0 - return argmax(V[candidates]) + return argmax(V[findall(candidates)]) else - print("no node found") return 0 end end -rand_uniform_2D(i) = [rand_uniform(i), rand_uniform(i)] -rand_uniform(i) = 2 * (0.5 - rand()) +rand_uniform_2D(i) = [rand_uniform(i),rand_uniform(i)] +rand_uniform(i) = 2*(0.5-rand()) end # module From 558fa37492b77a03d82f226bc6267ac5dbdd5bac Mon Sep 17 00:00:00 2001 From: Paul Schultz Date: Thu, 3 Sep 2020 22:01:53 +0200 Subject: [PATCH 05/18] some comments --- src/SyntheticNetworks.jl | 16 +++++++++------- test/runtests.jl | 2 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/SyntheticNetworks.jl b/src/SyntheticNetworks.jl index 0b988f2..dc79347 100755 --- a/src/SyntheticNetworks.jl +++ b/src/SyntheticNetworks.jl @@ -1,5 +1,3 @@ -__precompile__(false) - module SyntheticNetworks using Random @@ -21,7 +19,8 @@ include("./Heuristics.jl") f(i,j,G) = (d_G(i,j) + 1) ^ r / (dist_spatial(x_i,x_j)) """ abstract type SyntheticNetwork end -export SyntheticNetwork, RandomPowerGrid, initialise, generate_graph, f + +export SyntheticNetwork, RandomPowerGrid, initialise, grow!, generate_graph """ RandomPowerGrid(num_layers, n, n0, p, q, r, s, u, sampling, α, β, γ, debug) @@ -78,7 +77,8 @@ struct RandomPowerGrid t_prob::Array{Float32} t_method::Array{Function} # (graph::EG, vertex::Int) -> candidate::Bool end -default_method(g::EmbeddedGraph,i::Int32)::Bool = true + +default_method(g::EmbeddedGraph,i::Int)::Bool = true RandomPowerGrid(n, n0) = RandomPowerGrid(n, n0, rand(5)..., " ", [1.], [default_method]) function generate_graph(RPG) @@ -177,7 +177,8 @@ function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, push!(types,t) """With probabilities 1−s and s, perform either steps G1–G4 or step G5, respectively.""" - if rand() >= s || ne(graph) > 0 + s_val = rand() + if (s_val <= s) || (ne(graph) == 0) # STEP G1 """If x i is not given, draw it at random from ρ.""" pos = vertex_density_prob(n_actual) @@ -200,7 +201,7 @@ function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, n_actual -= 1 continue else - add_edge!(graph, l_edge, nv(graph)) + add_edge!(graph, l_edge, nv(graph)) end end @@ -212,12 +213,13 @@ function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, if rand() <= q i = rand(1:nv(graph)) dist_spatial = map(j -> euclidean(graph.vertexpos[i], graph.vertexpos[j]), 1:nv(graph)) + dist_spatial[i] = 100000. #Inf l_edge = Step_G34(graph, i, dist_spatial, r, methods[types]) if l_edge == 0 n_actual -= 1 continue else - add_edge!(graph, l_edge, i) + add_edge!(graph, l_edge, i) end end diff --git a/test/runtests.jl b/test/runtests.jl index 68e38eb..ce85629 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -4,7 +4,7 @@ using Random Random.seed!(42); const RPG = RandomPowerGrid(100, 1) -const g = generate_graph(RPG) +const g, t_list = generate_graph(RPG) @testset "RPG" begin @test RPG isa RandomPowerGrid From 7b5e56a8b3d414b9becb53c6675c0e7ef4c6031e Mon Sep 17 00:00:00 2001 From: Paul Schultz Date: Fri, 4 Sep 2020 16:12:08 +0200 Subject: [PATCH 06/18] return boolean from method_arr --- src/Heuristics.jl | 28 +++++++++++++--------------- src/SyntheticNetworks.jl | 11 ++++++++--- test/runtests.jl | 17 +++++++++++++---- 3 files changed, 34 insertions(+), 22 deletions(-) diff --git a/src/Heuristics.jl b/src/Heuristics.jl index 65fc99f..1ac41ad 100644 --- a/src/Heuristics.jl +++ b/src/Heuristics.jl @@ -1,29 +1,27 @@ -export maximum_value_heuristics,cumulative_distribution_heuristics, - maximum_degree, maximum_betweenness +export maximum_value_heuristics, + cumulative_distribution_heuristics, maximum_degree, maximum_betweenness + function maximum_value_heuristics(f::Function, max_val) # h(g,i) = f(g)[i] < max_val - h = (g,i) -> f(g)[i] < max_val ? 1 : 0 - return h + return (g, i) -> f(g)[i] < max_val end function cumulative_distribution_heuristics(f::Function; cdf::Function) - h = (g,i) -> f(g)[i] |> cdf |> x -> rand() > x ? 1 : 0 - return h + return (g, i) -> f(g)[i] |> cdf |> x -> rand() > x end function maximum_degree(k_max) - max_degree = (g,i) -> maximum_value_heuristics( - x -> degree_centrality(x,normalize = false), - k_max - ) + max_degree = + (g, i) -> + maximum_value_heuristics(x -> degree_centrality(x, normalize = false), k_max) return max_degree end function maximum_betweenness(b_max) - max_betweenness = (g,i) -> maximum_value_heuristics( - x -> betweenness_centrality(x,normalize = false), - b_max - ) + max_betweenness = + (g, i) -> maximum_value_heuristics( + x -> betweenness_centrality(x, normalize = false), + b_max, + ) return max_betweenness end - diff --git a/src/SyntheticNetworks.jl b/src/SyntheticNetworks.jl index dc79347..a31399c 100755 --- a/src/SyntheticNetworks.jl +++ b/src/SyntheticNetworks.jl @@ -76,9 +76,13 @@ struct RandomPowerGrid t_name # Array t_prob::Array{Float32} t_method::Array{Function} # (graph::EG, vertex::Int) -> candidate::Bool + function RandomPowerGrid(n, n0, p, q, r, s, u, t_name, t_prob, t_method) + @warn "The parameter `u` is currently not implemented." + new(n, n0, p, q, r, s, u, t_name, t_prob, t_method) + end end -default_method(g::EmbeddedGraph,i::Int)::Bool = true +default_method(g::EmbeddedGraph, i::Int)::Bool = true RandomPowerGrid(n, n0) = RandomPowerGrid(n, n0, rand(5)..., " ", [1.], [default_method]) function generate_graph(RPG) @@ -91,6 +95,7 @@ function generate_graph(RPG) # mg return eg, t_list end + # Step IG0 """ From a list of probabilities of drawing a node type, determines one randomly and returns the index of node type""" @@ -135,7 +140,7 @@ function initialise(n0::Int, p::Real, q::Real, r::Real, s::Real, u::Real, """Initialize G to be a minimum spanning tree (MST) for x_1...x_N w.r.t. the distance function dist_spatial(x, y) (using Kruskal’s simple or Prim’s more efficient algorithm). """ - mst_graph = EmbeddedGraph(LightGraphs.CompleteGraph(n0), positions) + mst_graph = EmbeddedGraph(complete_graph(n0), positions) edges = prim_mst(mst_graph.graph, weights(mst_graph, dense=true)) for edge in edges add_edge!(graph, edge) @@ -254,7 +259,7 @@ end function Step_G34(g::EmbeddedGraph, i::Int, dist_spatial, r, method_arr::Array{Function,1}) - candidates = [method_arr[i](g, i) == 1 ? true : false for i in 1:nv(g)] + candidates = [method_arr[i](g, i) for i in 1:nv(g)] if true in candidates V = dijkstra_shortest_paths(g, i).dists V = ((V .+ dist_spatial) .^ r) ./ dist_spatial diff --git a/test/runtests.jl b/test/runtests.jl index ce85629..c9f2345 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -3,12 +3,21 @@ using EmbeddedGraphs: EmbeddedGraph, nv using Random Random.seed!(42); -const RPG = RandomPowerGrid(100, 1) -const g, t_list = generate_graph(RPG) +const p = 0.3 +const q = 0.2 +const r = 1//3 +const s = 0.1 +const u = 0. + +RPG = RandomPowerGrid(100, 1, p, q, r, s, u, " ", [1], [(g::EmbeddedGraph, i::Int) -> true]) +eg, t_list = initialise(RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.u, RPG.t_name, RPG.t_prob, RPG.t_method) +grow!(eg, t_list, RPG.n, RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.u, RPG.t_name, RPG.t_prob, RPG.t_method) @testset "RPG" begin @test RPG isa RandomPowerGrid - @test g isa EmbeddedGraph - @test nv(g) == RPG.n + @test eg isa EmbeddedGraph + @test t_list isa Array{Int} + @test nv(eg) == RPG.n end +# you can plot an EmbeddedGraph with `using EmbeddedGraphs: gplot`. From 95a908f9e4d30a0648f59b12faaf904a6b5586a0 Mon Sep 17 00:00:00 2001 From: Paul Schultz Date: Fri, 4 Sep 2020 16:15:28 +0200 Subject: [PATCH 07/18] apllied auto-formatting --- src/SyntheticNetworks.jl | 131 +++++++++++++++++++++++++++------------ 1 file changed, 90 insertions(+), 41 deletions(-) diff --git a/src/SyntheticNetworks.jl b/src/SyntheticNetworks.jl index a31399c..0cdee6d 100755 --- a/src/SyntheticNetworks.jl +++ b/src/SyntheticNetworks.jl @@ -83,16 +83,37 @@ struct RandomPowerGrid end default_method(g::EmbeddedGraph, i::Int)::Bool = true -RandomPowerGrid(n, n0) = RandomPowerGrid(n, n0, rand(5)..., " ", [1.], [default_method]) +RandomPowerGrid(n, n0) = RandomPowerGrid(n, n0, rand(5)..., " ", [1], [default_method]) function generate_graph(RPG) # (n, n0, p, q, r, s, u) = (RPG.n, RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.s) - eg, t_list = initialise(RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.u, - RPG.t_name, RPG.t_prob, RPG.t_method) - grow!(eg, t_list, RPG.n, RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.u, - RPG.t_name, RPG.t_prob, RPG.t_method) - # mg = MetaGraph(eg, t_list) - # mg + eg, t_list = initialise( + RPG.n0, + RPG.p, + RPG.q, + RPG.r, + RPG.s, + RPG.u, + RPG.t_name, + RPG.t_prob, + RPG.t_method, + ) + grow!( + eg, + t_list, + RPG.n, + RPG.n0, + RPG.p, + RPG.q, + RPG.r, + RPG.s, + RPG.u, + RPG.t_name, + RPG.t_prob, + RPG.t_method, + ) + # mg = MetaGraph(eg, t_list) + # mg return eg, t_list end @@ -101,38 +122,47 @@ end returns the index of node type""" function draw_type(type_prob::Array{Float32,1}) t0 = copy(type_prob) - pushfirst!(t0 , 0.) - type_interval = [sum(t0[1:i+1]) for i in 1:length(t0)-1] + pushfirst!(t0, 0.0) + type_interval = [sum(t0[1:i+1]) for i = 1:length(t0)-1] typerand = rand() t_n = findfirst(type_interval .>= rand()) return t_n end -function MetaGraph(eg::EmbeddedGraph, default_weight = 1.) +function MetaGraph(eg::EmbeddedGraph, default_weight = 1.0) mg = MetaGraph(eg.graph, default_weight) - for (i,j) in enumerate(eg.vertexpos) - set_prop!(mg,i,:pos,j) + for (i, j) in enumerate(eg.vertexpos) + set_prop!(mg, i, :pos, j) end return mg end -function MetaGraph(eg::EmbeddedGraph, t_arr::Array{String}, default_weight = 1.) +function MetaGraph(eg::EmbeddedGraph, t_arr::Array{String}, default_weight = 1.0) mg = MetaGraph(eg.graph, default_weight) - for (i,j) in enumerate(eg.vertexpos) - set_props!(mg,i,Dict(:pos => j, :type => t_arr[i])) + for (i, j) in enumerate(eg.vertexpos) + set_props!(mg, i, Dict(:pos => j, :type => t_arr[i])) end return mg end -function initialise(n0::Int, p::Real, q::Real, r::Real, s::Real, u::Real, - name, prob::Array{Float32}, methods::Array{Function}; - vertex_density_prob::Function=rand_uniform_2D) +function initialise( + n0::Int, + p::Real, + q::Real, + r::Real, + s::Real, + u::Real, + name, + prob::Array{Float32}, + methods::Array{Function}; + vertex_density_prob::Function = rand_uniform_2D, +) # STEP I1 """If the locations x_1...x_N are not given, draw them independently at random from ρ.""" - positions = [vertex_density_prob(i) for i=1:n0 ] + positions = [vertex_density_prob(i) for i = 1:n0] types = [draw_type(prob) for i = 1:n0] graph = EmbeddedGraph(SimpleGraph(n0), positions) @@ -141,7 +171,7 @@ function initialise(n0::Int, p::Real, q::Real, r::Real, s::Real, u::Real, the distance function dist_spatial(x, y) (using Kruskal’s simple or Prim’s more efficient algorithm). """ mst_graph = EmbeddedGraph(complete_graph(n0), positions) - edges = prim_mst(mst_graph.graph, weights(mst_graph, dense=true)) + edges = prim_mst(mst_graph.graph, weights(mst_graph, dense = true)) for edge in edges add_edge!(graph, edge) end @@ -150,11 +180,11 @@ function initialise(n0::Int, p::Real, q::Real, r::Real, s::Real, u::Real, """With probability q, draw a node i ∈ {1,...,N} uniformly at random, find that node l ∈ {1,...,N} which is not yet linked to i and for which f (i,l,G) is maximal, and add the link i–l to G.""" - m = Int(round(n0*(1-s)*(p+q), RoundDown)) - for dummy in 1:m + m = Int(round(n0 * (1 - s) * (p + q), RoundDown)) + for dummy = 1:m i = rand(1:nv(graph)) - dist_spatial = map(j -> euclidean(graph.vertexpos[i], - graph.vertexpos[j]), 1:nv(graph)) + dist_spatial = + map(j -> euclidean(graph.vertexpos[i], graph.vertexpos[j]), 1:nv(graph)) # l_edge = Step_G34(graph, i, dist_spatial, r, methods[types]) if l_edge == 0 @@ -173,13 +203,25 @@ function initialise(n0::Int, p::Real, q::Real, r::Real, s::Real, u::Real, return graph, types end -function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, - name, prob::Array{Float32}, methods::Array{Function}; - vertex_density_prob::Function=rand_uniform_2D) - for n_actual in n0+1:n +function grow!( + graph::EmbeddedGraph, + types, + n::Int, + n0::Int, + p, + q, + r, + s, + u, + name, + prob::Array{Float32}, + methods::Array{Function}; + vertex_density_prob::Function = rand_uniform_2D, +) + for n_actual = n0+1:n # STEP G0 t = draw_type(prob) - push!(types,t) + push!(types, t) """With probabilities 1−s and s, perform either steps G1–G4 or step G5, respectively.""" s_val = rand() @@ -192,8 +234,11 @@ function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, # STEP G2 """ Find that node j ∈ {1,...,N} for which dist_spatial(x_i,x_j) is minimal and add the link i–j to G.""" - dist_spatial = map(i -> euclidean(graph.vertexpos[nv(graph)], graph.vertexpos[i]), 1:nv(graph)) - dist_spatial[nv(graph)] = 100000. #Inf + dist_spatial = map( + i -> euclidean(graph.vertexpos[nv(graph)], graph.vertexpos[i]), + 1:nv(graph), + ) + dist_spatial[nv(graph)] = 100000.0 #Inf min_dist_vertex = argmin(dist_spatial) add_edge!(graph, min_dist_vertex, nv(graph)) @@ -217,8 +262,9 @@ function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, to G.""" if rand() <= q i = rand(1:nv(graph)) - dist_spatial = map(j -> euclidean(graph.vertexpos[i], graph.vertexpos[j]), 1:nv(graph)) - dist_spatial[i] = 100000. #Inf + dist_spatial = + map(j -> euclidean(graph.vertexpos[i], graph.vertexpos[j]), 1:nv(graph)) + dist_spatial[i] = 100000.0 #Inf l_edge = Step_G34(graph, i, dist_spatial, r, methods[types]) if l_edge == 0 n_actual -= 1 @@ -237,7 +283,10 @@ function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, New logic splits the nodes somewhere, not in the middle.""" edge = rand(edges(graph)) splitval = rand() - newpos = (graph.vertexpos[src(edge)] * splitval + graph.vertexpos[dst(edge)] * (1-splitval)) + newpos = ( + graph.vertexpos[src(edge)] * splitval + + graph.vertexpos[dst(edge)] * (1 - splitval) + ) add_vertex!(graph, newpos) add_edge!(graph, src(edge), nv(graph)) add_edge!(graph, dst(edge), nv(graph)) @@ -248,18 +297,18 @@ end function Step_I3!(g::EmbeddedGraph, r::Real, m::Int) - for dummy in 1:m - spatial = weights(g, dense=true) + for dummy = 1:m + spatial = weights(g, dense = true) A = floyd_warshall_shortest_paths(g, weights(g)).dists A = ((A .+ spatial) .^ r) ./ spatial - map(i -> A[i,i] = 0, 1:size(A)[1]) - add_edge!(g,Tuple(argmax(A))...) + map(i -> A[i, i] = 0, 1:size(A)[1]) + add_edge!(g, Tuple(argmax(A))...) end end function Step_G34(g::EmbeddedGraph, i::Int, dist_spatial, r, method_arr::Array{Function,1}) - candidates = [method_arr[i](g, i) for i in 1:nv(g)] + candidates = [method_arr[i](g, i) for i = 1:nv(g)] if true in candidates V = dijkstra_shortest_paths(g, i).dists V = ((V .+ dist_spatial) .^ r) ./ dist_spatial @@ -270,8 +319,8 @@ function Step_G34(g::EmbeddedGraph, i::Int, dist_spatial, r, method_arr::Array{F end end -rand_uniform_2D(i) = [rand_uniform(i),rand_uniform(i)] -rand_uniform(i) = 2*(0.5-rand()) +rand_uniform_2D(i) = [rand_uniform(i), rand_uniform(i)] +rand_uniform(i) = 2 * (0.5 - rand()) end # module From a1a908d4948febd7a3836b3369859c3c67a36ec7 Mon Sep 17 00:00:00 2001 From: Ece Date: Fri, 4 Sep 2020 17:12:03 +0200 Subject: [PATCH 08/18] Made changes to steps G3,G4. --- .gitignore | 1 + src/SyntheticNetworks.jl | 48 ++++++++++++++-------------------------- 2 files changed, 18 insertions(+), 31 deletions(-) diff --git a/.gitignore b/.gitignore index e2c98f8..0d6d9b5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ docs/build/ docs/site/ .vscode/ Manifest.toml +Examples.jl diff --git a/src/SyntheticNetworks.jl b/src/SyntheticNetworks.jl index 0b988f2..3e56983 100755 --- a/src/SyntheticNetworks.jl +++ b/src/SyntheticNetworks.jl @@ -8,10 +8,9 @@ using LightGraphs # using SpatialIndexing using EmbeddedGraphs using Distances -# using MetaGraphs -# import MetaGraph -include("./Heuristics.jl") - +using MetaGraphs +import MetaGraphs: MetaGraph +include("Heuristics.jl") """ SyntheticNetwork @@ -21,7 +20,7 @@ include("./Heuristics.jl") f(i,j,G) = (d_G(i,j) + 1) ^ r / (dist_spatial(x_i,x_j)) """ abstract type SyntheticNetwork end -export SyntheticNetwork, RandomPowerGrid, initialise, generate_graph, f +export SyntheticNetwork, RandomPowerGrid, initialise, generate_graph """ RandomPowerGrid(num_layers, n, n0, p, q, r, s, u, sampling, α, β, γ, debug) @@ -78,8 +77,9 @@ struct RandomPowerGrid t_prob::Array{Float32} t_method::Array{Function} # (graph::EG, vertex::Int) -> candidate::Bool end -default_method(g::EmbeddedGraph,i::Int32)::Bool = true +default_method(g::EmbeddedGraph,i::Int64)::Bool = true RandomPowerGrid(n, n0) = RandomPowerGrid(n, n0, rand(5)..., " ", [1.], [default_method]) +RandomPowerGrid(n,n0,p,q,r,s,u) = RandomPowerGrid(n,n0,p,q,r,s,u, " ", [1.], [default_method]) function generate_graph(RPG) # (n, n0, p, q, r, s, u) = (RPG.n, RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.s) @@ -87,9 +87,9 @@ function generate_graph(RPG) RPG.t_name, RPG.t_prob, RPG.t_method) grow!(eg, t_list, RPG.n, RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.u, RPG.t_name, RPG.t_prob, RPG.t_method) - # mg = MetaGraph(eg, t_list) - # mg - return eg, t_list + mg = Embedded_to_MetaGraph(eg, RPG.t_name[t_list]) + mg + return mg end # Step IG0 """ From a list of probabilities of drawing a node type, determines one randomly and @@ -103,17 +103,9 @@ function draw_type(type_prob::Array{Float32,1}) return t_n end -function MetaGraph(eg::EmbeddedGraph, default_weight = 1.) - mg = MetaGraph(eg.graph, default_weight) - for (i,j) in enumerate(eg.vertexpos) - set_prop!(mg,i,:pos,j) - end - return mg -end - -function MetaGraph(eg::EmbeddedGraph, t_arr::Array{String}, default_weight = 1.) - mg = MetaGraph(eg.graph, default_weight) +function Embedded_to_MetaGraph(eg::EmbeddedGraph, t_arr) + mg = MetaGraph(eg.graph,1.) for (i,j) in enumerate(eg.vertexpos) set_props!(mg,i,Dict(:pos => j, :type => t_arr[i])) end @@ -135,7 +127,7 @@ function initialise(n0::Int, p::Real, q::Real, r::Real, s::Real, u::Real, """Initialize G to be a minimum spanning tree (MST) for x_1...x_N w.r.t. the distance function dist_spatial(x, y) (using Kruskal’s simple or Prim’s more efficient algorithm). """ - mst_graph = EmbeddedGraph(LightGraphs.CompleteGraph(n0), positions) + mst_graph = EmbeddedGraph(complete_graph(n0), positions) edges = prim_mst(mst_graph.graph, weights(mst_graph, dense=true)) for edge in edges add_edge!(graph, edge) @@ -177,7 +169,7 @@ function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, push!(types,t) """With probabilities 1−s and s, perform either steps G1–G4 or step G5, respectively.""" - if rand() >= s || ne(graph) > 0 + if rand() >= s || ne(graph) == 0 # STEP G1 """If x i is not given, draw it at random from ρ.""" pos = vertex_density_prob(n_actual) @@ -196,11 +188,8 @@ function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, which f(i,l,G) is maximal, and add the link i–l to G.""" if rand() <= p l_edge = Step_G34(graph, nv(graph), dist_spatial, r, methods[types]) - if l_edge == 0 - n_actual -= 1 - continue - else - add_edge!(graph, l_edge, nv(graph)) + if l_edge !== 0 + add_edge!(graph, l_edge, nv(graph)) end end @@ -213,11 +202,8 @@ function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, i = rand(1:nv(graph)) dist_spatial = map(j -> euclidean(graph.vertexpos[i], graph.vertexpos[j]), 1:nv(graph)) l_edge = Step_G34(graph, i, dist_spatial, r, methods[types]) - if l_edge == 0 - n_actual -= 1 - continue - else - add_edge!(graph, l_edge, i) + if l_edge !== 0 + add_edge!(graph, l_edge, i) end end From c6945842db6836996b163fa980c2d3b7daa36f94 Mon Sep 17 00:00:00 2001 From: Paul Schultz Date: Sun, 6 Sep 2020 22:35:40 +0200 Subject: [PATCH 09/18] test --- Manifest.toml | 304 -------------------------------------------------- 1 file changed, 304 deletions(-) delete mode 100644 Manifest.toml diff --git a/Manifest.toml b/Manifest.toml deleted file mode 100644 index db18cb3..0000000 --- a/Manifest.toml +++ /dev/null @@ -1,304 +0,0 @@ -# This file is machine-generated - editing it directly is not advised - -[[ArnoldiMethod]] -deps = ["DelimitedFiles", "LinearAlgebra", "Random", "SparseArrays", "StaticArrays", "Test"] -git-tree-sha1 = "2b6845cea546604fb4dca4e31414a6a59d39ddcd" -uuid = "ec485272-7323-5ecc-a04f-4719b315124d" -version = "0.0.4" - -[[Base64]] -uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" - -[[CodeTracking]] -deps = ["InteractiveUtils", "UUIDs"] -git-tree-sha1 = "ccc043a0df446cac279dca29d13e2827b40aceb5" -uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2" -version = "0.5.12" - -[[CodecZlib]] -deps = ["TranscodingStreams", "Zlib_jll"] -git-tree-sha1 = "ded953804d019afa9a3f98981d99b33e3db7b6da" -uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.7.0" - -[[ColorTypes]] -deps = ["FixedPointNumbers", "Random"] -git-tree-sha1 = "b9de8dc6106e09c79f3f776c27c62360d30e5eb8" -uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" -version = "0.9.1" - -[[Colors]] -deps = ["ColorTypes", "FixedPointNumbers", "InteractiveUtils", "Printf", "Reexport"] -git-tree-sha1 = "177d8b959d3c103a6d57574c38ee79c81059c31b" -uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" -version = "0.11.2" - -[[Compose]] -deps = ["Base64", "Colors", "DataStructures", "Dates", "IterTools", "JSON", "LinearAlgebra", "Measures", "Printf", "Random", "Requires", "UUIDs"] -git-tree-sha1 = "034174e607d254b8ca0853a1a9029b265114bf6c" -uuid = "a81c6b42-2e10-5240-aca2-a61377ecd94b" -version = "0.8.2" - -[[DataStructures]] -deps = ["InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "88d48e133e6d3dd68183309877eac74393daa7eb" -uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.17.20" - -[[Dates]] -deps = ["Printf"] -uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" - -[[DelimitedFiles]] -deps = ["Mmap"] -uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" - -[[Distances]] -deps = ["LinearAlgebra", "Statistics"] -git-tree-sha1 = "bed62cc5afcff16de797a9f38fb358b74071f785" -uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" -version = "0.9.0" - -[[Distributed]] -deps = ["Random", "Serialization", "Sockets"] -uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" - -[[DocStringExtensions]] -deps = ["LibGit2", "Markdown", "Pkg", "Test"] -git-tree-sha1 = "50ddf44c53698f5e784bbebb3f4b21c5807401b1" -uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.8.3" - -[[Documenter]] -deps = ["Base64", "Dates", "DocStringExtensions", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "REPL", "Test", "Unicode"] -git-tree-sha1 = "fb1ff838470573adc15c71ba79f8d31328f035da" -uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "0.25.2" - -[[EmbeddedGraphs]] -deps = ["Distances", "GraphPlot", "LightGraphs", "Random", "Revise", "SparseArrays", "Test"] -git-tree-sha1 = "b98a7656987981644f69392db24df3401663bcc9" -repo-rev = "master" -repo-url = "https://github.com/FHell/EmbeddedGraphs.jl.git" -uuid = "9c1af47c-29f5-11e9-0b47-9f5334384f20" -version = "0.1.0" - -[[FileIO]] -deps = ["Pkg"] -git-tree-sha1 = "992b4aeb62f99b69fcf0cb2085094494cc05dfb3" -uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -version = "1.4.3" - -[[FileWatching]] -uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" - -[[FixedPointNumbers]] -git-tree-sha1 = "4aaea64dd0c30ad79037084f8ca2b94348e65eaa" -uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.7.1" - -[[GraphPlot]] -deps = ["ArnoldiMethod", "ColorTypes", "Colors", "Compose", "DelimitedFiles", "LightGraphs", "LinearAlgebra", "Random", "SparseArrays"] -git-tree-sha1 = "32f72eb61d372429ce8fd2ee9b7079599dacb93b" -uuid = "a2cc645c-3eea-5389-862e-a155d0052231" -version = "0.4.2" - -[[Inflate]] -git-tree-sha1 = "f5fc07d4e706b84f72d54eedcc1c13d92fb0871c" -uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" -version = "0.1.2" - -[[InteractiveUtils]] -deps = ["Markdown"] -uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" - -[[IterTools]] -git-tree-sha1 = "05110a2ab1fc5f932622ffea2a003221f4782c18" -uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" -version = "1.3.0" - -[[JLD2]] -deps = ["CodecZlib", "DataStructures", "FileIO", "Mmap", "Pkg", "Printf", "UUIDs"] -git-tree-sha1 = "9353b717ee4e27beab4e902c92a06bb5f160d2cf" -uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.1.14" - -[[JSON]] -deps = ["Dates", "Mmap", "Parsers", "Unicode"] -git-tree-sha1 = "b34d7cef7b337321e97d22242c3c2b91f476748e" -uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" -version = "0.21.0" - -[[JuliaInterpreter]] -deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"] -git-tree-sha1 = "7b2a1b650cec61a7d8cd8ee9ee7a818b5764d502" -uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a" -version = "0.7.26" - -[[LibGit2]] -deps = ["Printf"] -uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" - -[[Libdl]] -uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" - -[[LightGraphs]] -deps = ["ArnoldiMethod", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] -git-tree-sha1 = "6f85a35d2377cb2db1bc448ed0d6340d2bb1ea64" -uuid = "093fc24a-ae57-5d10-9952-331d41423f4d" -version = "1.3.3" - -[[LinearAlgebra]] -deps = ["Libdl"] -uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - -[[Logging]] -uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" - -[[LoweredCodeUtils]] -deps = ["JuliaInterpreter"] -git-tree-sha1 = "dbd9336b43c2d6fa492efa09ba3bb10fbdbeeb64" -uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b" -version = "0.4.9" - -[[MacroTools]] -deps = ["Markdown", "Random"] -git-tree-sha1 = "f7d2e3f654af75f01ec49be82c231c382214223a" -uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.5.5" - -[[Markdown]] -deps = ["Base64"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" - -[[Measures]] -git-tree-sha1 = "e498ddeee6f9fdb4551ce855a46f54dbd900245f" -uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e" -version = "0.3.1" - -[[MetaGraphs]] -deps = ["JLD2", "LightGraphs", "Random"] -git-tree-sha1 = "8900d368fa44bd61c7e598d6a0f577e347f3cf67" -uuid = "626554b9-1ddb-594c-aa3c-2596fe9399a5" -version = "0.6.5" - -[[Mmap]] -uuid = "a63ad114-7e13-5084-954f-fe012c677804" - -[[OrderedCollections]] -git-tree-sha1 = "293b70ac1780f9584c89268a6e2a560d938a7065" -uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.3.0" - -[[Parameters]] -deps = ["OrderedCollections", "UnPack"] -git-tree-sha1 = "38b2e970043613c187bd56a995fe2e551821eb4a" -uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" -version = "0.12.1" - -[[Parsers]] -deps = ["Dates", "Test"] -git-tree-sha1 = "8077624b3c450b15c087944363606a6ba12f925e" -uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "1.0.10" - -[[Pkg]] -deps = ["Dates", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] -uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" - -[[Printf]] -deps = ["Unicode"] -uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" - -[[REPL]] -deps = ["InteractiveUtils", "Markdown", "Sockets"] -uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" - -[[Random]] -deps = ["Serialization"] -uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" - -[[Reexport]] -deps = ["Pkg"] -git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" -uuid = "189a3867-3050-52da-a836-e630ba90ab69" -version = "0.2.0" - -[[Requires]] -deps = ["UUIDs"] -git-tree-sha1 = "8c08d0c7812169e438a8478dae2a529377ad13f7" -uuid = "ae029012-a4dd-5104-9daa-d747884805df" -version = "1.0.2" - -[[Revise]] -deps = ["CodeTracking", "Distributed", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "Pkg", "REPL", "UUIDs", "Unicode"] -git-tree-sha1 = "a860e786779be1ab6407d427470e1415711dd459" -uuid = "295af30f-e4ad-537b-8983-00126c2a3abe" -version = "2.7.5" - -[[SHA]] -uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" - -[[Serialization]] -uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" - -[[SharedArrays]] -deps = ["Distributed", "Mmap", "Random", "Serialization"] -uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" - -[[SimpleTraits]] -deps = ["InteractiveUtils", "MacroTools"] -git-tree-sha1 = "daf7aec3fe3acb2131388f93a4c409b8c7f62226" -uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" -version = "0.9.3" - -[[Sockets]] -uuid = "6462fe0b-24de-5631-8697-dd941f90decc" - -[[SparseArrays]] -deps = ["LinearAlgebra", "Random"] -uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - -[[SpatialIndexing]] -deps = ["Printf", "Random", "Test"] -git-tree-sha1 = "7bc6fc5c363aae476ec2c8bc527aef104b90c779" -uuid = "d4ead438-fe20-5cc5-a293-4fd39a41b74c" -version = "0.1.2" - -[[StaticArrays]] -deps = ["LinearAlgebra", "Random", "Statistics"] -git-tree-sha1 = "016d1e1a00fabc556473b07161da3d39726ded35" -uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "0.12.4" - -[[Statistics]] -deps = ["LinearAlgebra", "SparseArrays"] -uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" - -[[Test]] -deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] -uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[[TranscodingStreams]] -deps = ["Random", "Test"] -git-tree-sha1 = "7c53c35547de1c5b9d46a4797cf6d8253807108c" -uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.9.5" - -[[UUIDs]] -deps = ["Random", "SHA"] -uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" - -[[UnPack]] -git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" -uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" -version = "1.0.2" - -[[Unicode]] -uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" - -[[Zlib_jll]] -deps = ["Libdl", "Pkg"] -git-tree-sha1 = "fdd89e5ab270ea0f2a0174bd9093e557d06d4bfa" -uuid = "83775a58-1f1d-513f-b197-d71354ab007a" -version = "1.2.11+16" From 049f1540c5fc3291b8c5c8e177378739be4fbd96 Mon Sep 17 00:00:00 2001 From: Ece Date: Fri, 18 Sep 2020 11:39:19 +0200 Subject: [PATCH 10/18] Minor changes --- src/SyntheticNetworks.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/SyntheticNetworks.jl b/src/SyntheticNetworks.jl index 70bf9e2..2e3292d 100755 --- a/src/SyntheticNetworks.jl +++ b/src/SyntheticNetworks.jl @@ -9,7 +9,6 @@ using LightGraphs using EmbeddedGraphs using Distances using MetaGraphs -import MetaGraphs: MetaGraph include("Heuristics.jl") """ @@ -89,6 +88,7 @@ function generate_graph(RPG) grow!(eg, t_list, RPG.n, RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.u, RPG.t_name, RPG.t_prob, RPG.t_method) mg = Embedded_to_MetaGraph(eg, RPG.t_name[t_list]) + set_prop!(mg,:name,string(RPG.p)*";"*string(RPG.q)*";"*string(RPG.r)*";"*string(RPG.s)) mg return mg end @@ -99,7 +99,6 @@ function draw_type(type_prob::Array{Float32,1}) t0 = copy(type_prob) pushfirst!(t0 , 0.) type_interval = [sum(t0[1:i+1]) for i in 1:length(t0)-1] - typerand = rand() t_n = findfirst(type_interval .>= rand()) return t_n end From 2558f8bbcdf577abec8d6ba344d42ba3f1ba90b5 Mon Sep 17 00:00:00 2001 From: Ece Kuru Date: Mon, 28 Sep 2020 19:14:58 +0200 Subject: [PATCH 11/18] New struct NodeType added. Has properties name, probability and method. Changed the rest to work with NodeType structs. --- src/SyntheticNetworks.jl | 52 ++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/src/SyntheticNetworks.jl b/src/SyntheticNetworks.jl index 2e3292d..7f8976c 100755 --- a/src/SyntheticNetworks.jl +++ b/src/SyntheticNetworks.jl @@ -11,6 +11,7 @@ using Distances using MetaGraphs include("Heuristics.jl") +import Base: getproperty """ SyntheticNetwork """ @@ -64,6 +65,14 @@ export SyntheticNetwork, RandomPowerGrid, initialise, generate_graph, grow! # export RandomPowerGrid # +# abstract type NodeType end + +struct NodeType + name + probability + neighbor_probability + method# (graph::EG, vertex::Int) -> candidate::Bool +end struct RandomPowerGrid n::Int @@ -73,34 +82,35 @@ struct RandomPowerGrid r::Float32 s::Float32 u::Float32 - t_name # Array - t_prob::Array{Float32} - t_method::Array{Function} # (graph::EG, vertex::Int) -> candidate::Bool + types::Array{NodeType} end + +getproperty(arr::Array{NodeType},attr::Symbol) = map(x -> getproperty(x,attr), arr) +NodeType() = NodeType("Node", 1., 1., default_method) default_method(g::EmbeddedGraph,i::Int64)::Bool = true -RandomPowerGrid(n, n0) = RandomPowerGrid(n, n0, rand(5)..., " ", [1.], [default_method]) -RandomPowerGrid(n,n0,p,q,r,s,u) = RandomPowerGrid(n,n0,p,q,r,s,u, " ", [1.], [default_method]) +RandomPowerGrid(n, n0) = RandomPowerGrid(n, n0, rand(5)...,[NodeType()]) +RandomPowerGrid(n,n0,p,q,r,s,u) = RandomPowerGrid(n,n0,p,q,r,s,u,[NodeType()]) function generate_graph(RPG) # (n, n0, p, q, r, s, u) = (RPG.n, RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.s) eg, t_list = initialise(RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.u, - RPG.t_name, RPG.t_prob, RPG.t_method) + RPG.types) grow!(eg, t_list, RPG.n, RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.u, - RPG.t_name, RPG.t_prob, RPG.t_method) - mg = Embedded_to_MetaGraph(eg, RPG.t_name[t_list]) - set_prop!(mg,:name,string(RPG.p)*";"*string(RPG.q)*";"*string(RPG.r)*";"*string(RPG.s)) + RPG.types) + mg = Embedded_to_MetaGraph(eg, t_list) + set_prop!(mg,:pqrs,[RPG.p, RPG.q, RPG.r, RPG.s]) mg return mg end # Step IG0 """ From a list of probabilities of drawing a node type, determines one randomly and returns the index of node type""" -function draw_type(type_prob::Array{Float32,1}) - t0 = copy(type_prob) +function draw_type(node_types::Array{NodeType,1}) + t0 = copy(node_types.probability) pushfirst!(t0 , 0.) type_interval = [sum(t0[1:i+1]) for i in 1:length(t0)-1] t_n = findfirst(type_interval .>= rand()) - return t_n + return node_types[t_n] end @@ -114,13 +124,13 @@ end function initialise(n0::Int, p::Real, q::Real, r::Real, s::Real, u::Real, - name, prob::Array{Float32}, methods::Array{Function}; + node_types::Array{NodeTypes}; vertex_density_prob::Function=rand_uniform_2D) # STEP I1 """If the locations x_1...x_N are not given, draw them independently at random from ρ.""" positions = [vertex_density_prob(i) for i=1:n0 ] - types = [draw_type(prob) for i = 1:n0] + types = [draw_type(node_types) for i = 1:n0] graph = EmbeddedGraph(SimpleGraph(n0), positions) # STEP I2 @@ -143,7 +153,7 @@ function initialise(n0::Int, p::Real, q::Real, r::Real, s::Real, u::Real, dist_spatial = map(j -> euclidean(graph.vertexpos[i], graph.vertexpos[j]), 1:nv(graph)) # - l_edge = Step_G34(graph, i, dist_spatial, r, methods[types]) + l_edge = Step_G34(graph, i, dist_spatial, r, types) if l_edge == 0 dummy -= 1 else @@ -161,11 +171,11 @@ function initialise(n0::Int, p::Real, q::Real, r::Real, s::Real, u::Real, end function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, - name, prob::Array{Float32}, methods::Array{Function}; + node_types::Array{NodeType}; vertex_density_prob::Function=rand_uniform_2D) for n_actual in n0+1:n # STEP G0 - t = draw_type(prob) + t = draw_type(node_types) push!(types,t) """With probabilities 1−s and s, perform either steps G1–G4 or step G5, respectively.""" @@ -187,7 +197,7 @@ function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, """ With probability p, find that node l ∈ {1,...,N} ⍀ {j} for which f(i,l,G) is maximal, and add the link i–l to G.""" if rand() <= p - l_edge = Step_G34(graph, nv(graph), dist_spatial, r, methods[types]) + l_edge = Step_G34(graph, nv(graph), dist_spatial, r, types) if l_edge !== 0 add_edge!(graph, l_edge, nv(graph)) end @@ -201,7 +211,7 @@ function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, if rand() <= q i = rand(1:nv(graph)) dist_spatial = map(j -> euclidean(graph.vertexpos[i], graph.vertexpos[j]), 1:nv(graph)) - l_edge = Step_G34(graph, i, dist_spatial, r, methods[types]) + l_edge = Step_G34(graph, i, dist_spatial, r, types) if l_edge !== 0 add_edge!(graph, l_edge, i) end @@ -237,8 +247,8 @@ function Step_I3!(g::EmbeddedGraph, r::Real, m::Int) end -function Step_G34(g::EmbeddedGraph, i::Int, dist_spatial, r, method_arr::Array{Function,1}) - candidates = [method_arr[i](g, i) == 1 ? true : false for i in 1:nv(g)] +function Step_G34(g::EmbeddedGraph, i::Int, dist_spatial, r, types::Array{NodeType}) + candidates = [types[i].method(g, i) == 1 ? true : false for i in 1:nv(g)] if true in candidates V = dijkstra_shortest_paths(g, i).dists V = ((V .+ dist_spatial) .^ r) ./ dist_spatial From 9bf1f01340b89732919d82937d1df6b8869ddab7 Mon Sep 17 00:00:00 2001 From: Ece Kuru Date: Tue, 29 Sep 2020 12:46:29 +0200 Subject: [PATCH 12/18] Implemented different probabilities for connections between different node types --- src/Heuristics.jl | 22 ++++++++++++---------- src/SyntheticNetworks.jl | 22 ++++++++++++---------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/Heuristics.jl b/src/Heuristics.jl index 1ac41ad..b888555 100644 --- a/src/Heuristics.jl +++ b/src/Heuristics.jl @@ -1,13 +1,13 @@ export maximum_value_heuristics, - cumulative_distribution_heuristics, maximum_degree, maximum_betweenness + cumulative_distribution_heuristics, maximum_degree function maximum_value_heuristics(f::Function, max_val) # h(g,i) = f(g)[i] < max_val - return (g, i) -> f(g)[i] < max_val + return (g, i) -> f(g)[i] < max_val end function cumulative_distribution_heuristics(f::Function; cdf::Function) - return (g, i) -> f(g)[i] |> cdf |> x -> rand() > x + return (g, i) -> f(g)[i] |> cdf |> x -> rand() > x end function maximum_degree(k_max) @@ -17,11 +17,13 @@ function maximum_degree(k_max) return max_degree end -function maximum_betweenness(b_max) - max_betweenness = - (g, i) -> maximum_value_heuristics( - x -> betweenness_centrality(x, normalize = false), - b_max, - ) - return max_betweenness +# With probability p1 + threshold, allows the connection of nodes. +# The idea is to find where V is maximal, and use this function for chosen node +# If false is returned, set V[j] = 0 and find j' where V is maximal +# Repeat this for given number of times. If none is found take the first one +# or draw new position +function accept_neighbor(neighbor_prob, type, threshold = 0) + return rand() <= neighbor_prob[type] + threshold end + + diff --git a/src/SyntheticNetworks.jl b/src/SyntheticNetworks.jl index 7f8976c..5bac0a7 100755 --- a/src/SyntheticNetworks.jl +++ b/src/SyntheticNetworks.jl @@ -20,7 +20,7 @@ import Base: getproperty f(i,j,G) = (d_G(i,j) + 1) ^ r / (dist_spatial(x_i,x_j)) """ abstract type SyntheticNetwork end -export SyntheticNetwork, RandomPowerGrid, initialise, generate_graph, grow! +export SyntheticNetwork, NodeType, RandomPowerGrid, initialise, generate_graph, grow! """ @@ -68,10 +68,10 @@ export SyntheticNetwork, RandomPowerGrid, initialise, generate_graph, grow! # abstract type NodeType end struct NodeType - name - probability - neighbor_probability - method# (graph::EG, vertex::Int) -> candidate::Bool + name::String + probability::Float32 + neighbor_probability::Dict(Symbol,Float32) # Dict(Symbol(NodeType_i.name) => prob) + method::Function # (graph::EG, vertex::Int) -> candidate::Bool end struct RandomPowerGrid @@ -82,11 +82,11 @@ struct RandomPowerGrid r::Float32 s::Float32 u::Float32 - types::Array{NodeType} + types::Array{NodeType,1} end getproperty(arr::Array{NodeType},attr::Symbol) = map(x -> getproperty(x,attr), arr) -NodeType() = NodeType("Node", 1., 1., default_method) +NodeType() = NodeType("Node", 1., Dict(:Node => 1.), default_method) default_method(g::EmbeddedGraph,i::Int64)::Bool = true RandomPowerGrid(n, n0) = RandomPowerGrid(n, n0, rand(5)...,[NodeType()]) RandomPowerGrid(n,n0,p,q,r,s,u) = RandomPowerGrid(n,n0,p,q,r,s,u,[NodeType()]) @@ -124,7 +124,7 @@ end function initialise(n0::Int, p::Real, q::Real, r::Real, s::Real, u::Real, - node_types::Array{NodeTypes}; + node_types::Array{NodeType,1}; vertex_density_prob::Function=rand_uniform_2D) # STEP I1 """If the locations x_1...x_N are not given, draw them independently at @@ -190,7 +190,8 @@ function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, minimal and add the link i–j to G.""" dist_spatial = map(i -> euclidean(graph.vertexpos[nv(graph)], graph.vertexpos[i]), 1:nv(graph)) dist_spatial[nv(graph)] = 100000. #Inf - min_dist_vertex = argmin(dist_spatial) + neigbor_prob = map(x -> x[Symbol(types[i].name)] , types.neighbor_probability) + min_dist_vertex = argmin(dist_spatial ./ neighbor_prob) add_edge!(graph, min_dist_vertex, nv(graph)) # STEP G3 @@ -253,7 +254,8 @@ function Step_G34(g::EmbeddedGraph, i::Int, dist_spatial, r, types::Array{NodeTy V = dijkstra_shortest_paths(g, i).dists V = ((V .+ dist_spatial) .^ r) ./ dist_spatial V[i] = 0 - return argmax(V[findall(candidates)]) + p = map(x -> x[Symbol(types[i].name)] , types.neighbor_probability) + return argmax(V[findall(candidates)] .* p) else return 0 end From 713e1bebe39873fdad51466f9762104efcc120fd Mon Sep 17 00:00:00 2001 From: Ece Kuru Date: Mon, 5 Oct 2020 20:05:21 +0200 Subject: [PATCH 13/18] Implemented node type connection probabilities --- Project.toml | 1 + src/.#Heuristics.jl | 1 + src/Heuristics.jl | 10 ---------- src/NodeTypes.jl | 37 +++++++++++++++++++++++++++++++++++++ src/SyntheticNetworks.jl | 35 +++++++---------------------------- 5 files changed, 46 insertions(+), 38 deletions(-) create mode 120000 src/.#Heuristics.jl create mode 100644 src/NodeTypes.jl diff --git a/Project.toml b/Project.toml index 0a8a93f..9d9f607 100644 --- a/Project.toml +++ b/Project.toml @@ -12,6 +12,7 @@ MetaGraphs = "626554b9-1ddb-594c-aa3c-2596fe9399a5" Parameters = "d96e819e-fc66-5662-9728-84c9c7592b0a" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" SpatialIndexing = "d4ead438-fe20-5cc5-a293-4fd39a41b74c" +StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [compat] diff --git a/src/.#Heuristics.jl b/src/.#Heuristics.jl new file mode 120000 index 0000000..c567db8 --- /dev/null +++ b/src/.#Heuristics.jl @@ -0,0 +1 @@ +ecek@ece-ThinkPad.2654:1601892162 \ No newline at end of file diff --git a/src/Heuristics.jl b/src/Heuristics.jl index b888555..4be3307 100644 --- a/src/Heuristics.jl +++ b/src/Heuristics.jl @@ -17,13 +17,3 @@ function maximum_degree(k_max) return max_degree end -# With probability p1 + threshold, allows the connection of nodes. -# The idea is to find where V is maximal, and use this function for chosen node -# If false is returned, set V[j] = 0 and find j' where V is maximal -# Repeat this for given number of times. If none is found take the first one -# or draw new position -function accept_neighbor(neighbor_prob, type, threshold = 0) - return rand() <= neighbor_prob[type] + threshold -end - - diff --git a/src/NodeTypes.jl b/src/NodeTypes.jl new file mode 100644 index 0000000..7b1a472 --- /dev/null +++ b/src/NodeTypes.jl @@ -0,0 +1,37 @@ +"""For the incorporation of different node types to SyntheticNetworks package.""" +using StatsBase + +struct NodeType + name::String + probability::Float32 + neighbor_probability::Dict # Dict(Symbol(NodeType_i.name) => prob) + method::Function # (graph::EG, vertex::Int) -> candidate::Bool +end + +getproperty(arr::Array{NodeType},attr::Symbol) = map(x -> getproperty(x,attr), arr) +NodeType() = NodeType("Node", 1., Dict(:Node => 1.), default_method) +default_method(g::EmbeddedGraph,i::Int64)::Bool = true + +# Step IG0 +""" From a list of probabilities of drawing a node type, determines one randomly and + returns the index of node type""" +function draw_type(node_types::Array{NodeType,1}) + t0 = copy(node_types.probability) + pushfirst!(t0 , 0.) + type_interval = [sum(t0[1:i+1]) for i in 1:length(t0)-1] + t_n = findfirst(type_interval .>= rand()) + return node_types[t_n] +end + +function connect_types(g::EmbeddedGraph, n_types::Array{NodeType,1}, i, n) + nodetype_frequency = countmap(n_types) + weights = n_types.neighbor_probability[Symbol(n_types[i].name)] .* + nodetype_frequency[Symbol(n_types[i].name)] + candidates = sample([1:i-1;i+1:nv(g)], deleteat!(weights,i), n) + return [i in candidates for i in 1:nv(g)] +end + +function connectable_nodes(g::EmbeddedGraph, n_types::Array{NodeType,1}, i) + return n_types.neighbor_probability[Symbol(n_types[i].name)] .> 0. +end + diff --git a/src/SyntheticNetworks.jl b/src/SyntheticNetworks.jl index 5bac0a7..1f6fb89 100755 --- a/src/SyntheticNetworks.jl +++ b/src/SyntheticNetworks.jl @@ -10,6 +10,7 @@ using EmbeddedGraphs using Distances using MetaGraphs include("Heuristics.jl") +include("NodeTypes.jl") import Base: getproperty """ @@ -20,7 +21,8 @@ import Base: getproperty f(i,j,G) = (d_G(i,j) + 1) ^ r / (dist_spatial(x_i,x_j)) """ abstract type SyntheticNetwork end -export SyntheticNetwork, NodeType, RandomPowerGrid, initialise, generate_graph, grow! +export SyntheticNetwork, NodeType, RandomPowerGrid, initialise, generate_graph, grow!, maximum_value_heuristics, cumulative_distribution_heuristics, maximum_degree + """ @@ -65,15 +67,6 @@ export SyntheticNetwork, NodeType, RandomPowerGrid, initialise, generate_graph, # export RandomPowerGrid # -# abstract type NodeType end - -struct NodeType - name::String - probability::Float32 - neighbor_probability::Dict(Symbol,Float32) # Dict(Symbol(NodeType_i.name) => prob) - method::Function # (graph::EG, vertex::Int) -> candidate::Bool -end - struct RandomPowerGrid n::Int n0::Int @@ -85,9 +78,6 @@ struct RandomPowerGrid types::Array{NodeType,1} end -getproperty(arr::Array{NodeType},attr::Symbol) = map(x -> getproperty(x,attr), arr) -NodeType() = NodeType("Node", 1., Dict(:Node => 1.), default_method) -default_method(g::EmbeddedGraph,i::Int64)::Bool = true RandomPowerGrid(n, n0) = RandomPowerGrid(n, n0, rand(5)...,[NodeType()]) RandomPowerGrid(n,n0,p,q,r,s,u) = RandomPowerGrid(n,n0,p,q,r,s,u,[NodeType()]) @@ -102,16 +92,6 @@ function generate_graph(RPG) mg return mg end -# Step IG0 -""" From a list of probabilities of drawing a node type, determines one randomly and - returns the index of node type""" -function draw_type(node_types::Array{NodeType,1}) - t0 = copy(node_types.probability) - pushfirst!(t0 , 0.) - type_interval = [sum(t0[1:i+1]) for i in 1:length(t0)-1] - t_n = findfirst(type_interval .>= rand()) - return node_types[t_n] -end function Embedded_to_MetaGraph(eg::EmbeddedGraph, t_arr) @@ -190,8 +170,7 @@ function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, minimal and add the link i–j to G.""" dist_spatial = map(i -> euclidean(graph.vertexpos[nv(graph)], graph.vertexpos[i]), 1:nv(graph)) dist_spatial[nv(graph)] = 100000. #Inf - neigbor_prob = map(x -> x[Symbol(types[i].name)] , types.neighbor_probability) - min_dist_vertex = argmin(dist_spatial ./ neighbor_prob) + min_dist_vertex = argmin(dist_spatial[connectable_nodes(graph, types,nv(graph))]) add_edge!(graph, min_dist_vertex, nv(graph)) # STEP G3 @@ -249,13 +228,13 @@ end function Step_G34(g::EmbeddedGraph, i::Int, dist_spatial, r, types::Array{NodeType}) - candidates = [types[i].method(g, i) == 1 ? true : false for i in 1:nv(g)] + candidates = connectable_nodes(g, types, i) .& + [types[i].method(g, i) == 1 ? true : false for i in 1:nv(g)] if true in candidates V = dijkstra_shortest_paths(g, i).dists V = ((V .+ dist_spatial) .^ r) ./ dist_spatial V[i] = 0 - p = map(x -> x[Symbol(types[i].name)] , types.neighbor_probability) - return argmax(V[findall(candidates)] .* p) + return argmax(V[findall(candidates)]) else return 0 end From 83010a326c35f6a98a1c1ef1345f398bdc570144 Mon Sep 17 00:00:00 2001 From: Ece Kuru Date: Thu, 29 Oct 2020 17:57:21 +0100 Subject: [PATCH 14/18] Minor changes --- src/.#Heuristics.jl | 1 - src/Heuristics.jl | 3 --- src/NodeTypes.jl | 13 ++++++++----- src/SyntheticNetworks.jl | 9 +++++---- 4 files changed, 13 insertions(+), 13 deletions(-) delete mode 120000 src/.#Heuristics.jl diff --git a/src/.#Heuristics.jl b/src/.#Heuristics.jl deleted file mode 120000 index c567db8..0000000 --- a/src/.#Heuristics.jl +++ /dev/null @@ -1 +0,0 @@ -ecek@ece-ThinkPad.2654:1601892162 \ No newline at end of file diff --git a/src/Heuristics.jl b/src/Heuristics.jl index 4be3307..9a49a60 100644 --- a/src/Heuristics.jl +++ b/src/Heuristics.jl @@ -1,6 +1,3 @@ -export maximum_value_heuristics, - cumulative_distribution_heuristics, maximum_degree - function maximum_value_heuristics(f::Function, max_val) # h(g,i) = f(g)[i] < max_val return (g, i) -> f(g)[i] < max_val diff --git a/src/NodeTypes.jl b/src/NodeTypes.jl index 7b1a472..b29775c 100644 --- a/src/NodeTypes.jl +++ b/src/NodeTypes.jl @@ -1,5 +1,4 @@ """For the incorporation of different node types to SyntheticNetworks package.""" -using StatsBase struct NodeType name::String @@ -8,15 +7,17 @@ struct NodeType method::Function # (graph::EG, vertex::Int) -> candidate::Bool end -getproperty(arr::Array{NodeType},attr::Symbol) = map(x -> getproperty(x,attr), arr) NodeType() = NodeType("Node", 1., Dict(:Node => 1.), default_method) +NodeType(name::String, probability::Float32, n_prob::Dict) = NodeType(name, probability, n_prob, default_method) +NodeType(name::String, probability::Float32, method::Function; n_types) = NodeType(name, probability, fill(1., n_types), default_method) default_method(g::EmbeddedGraph,i::Int64)::Bool = true # Step IG0 """ From a list of probabilities of drawing a node type, determines one randomly and returns the index of node type""" function draw_type(node_types::Array{NodeType,1}) - t0 = copy(node_types.probability) + prob = map(x -> x.probability, node_types) + t0 = copy(prob) pushfirst!(t0 , 0.) type_interval = [sum(t0[1:i+1]) for i in 1:length(t0)-1] t_n = findfirst(type_interval .>= rand()) @@ -25,13 +26,15 @@ end function connect_types(g::EmbeddedGraph, n_types::Array{NodeType,1}, i, n) nodetype_frequency = countmap(n_types) - weights = n_types.neighbor_probability[Symbol(n_types[i].name)] .* + n_prob = map(x -> x.neighbor_probability, n_types) + weights = n_prob[Symbol(n_types[i].name)] .* nodetype_frequency[Symbol(n_types[i].name)] candidates = sample([1:i-1;i+1:nv(g)], deleteat!(weights,i), n) return [i in candidates for i in 1:nv(g)] end function connectable_nodes(g::EmbeddedGraph, n_types::Array{NodeType,1}, i) - return n_types.neighbor_probability[Symbol(n_types[i].name)] .> 0. + n_prob = map(x -> x.neighbor_probability[Symbol(n_types[i].name)], n_types) + return n_prob .> 0. end diff --git a/src/SyntheticNetworks.jl b/src/SyntheticNetworks.jl index 1f6fb89..279b19b 100755 --- a/src/SyntheticNetworks.jl +++ b/src/SyntheticNetworks.jl @@ -2,6 +2,7 @@ __precompile__(false) module SyntheticNetworks +import StatsBase: countmap, sample using Random using Parameters using LightGraphs @@ -12,7 +13,6 @@ using MetaGraphs include("Heuristics.jl") include("NodeTypes.jl") -import Base: getproperty """ SyntheticNetwork """ @@ -21,7 +21,8 @@ import Base: getproperty f(i,j,G) = (d_G(i,j) + 1) ^ r / (dist_spatial(x_i,x_j)) """ abstract type SyntheticNetwork end -export SyntheticNetwork, NodeType, RandomPowerGrid, initialise, generate_graph, grow!, maximum_value_heuristics, cumulative_distribution_heuristics, maximum_degree +export SyntheticNetwork, NodeType, RandomPowerGrid, initialise, generate_graph, grow!, maximum_value_heuristics, cumulative_distribution_heuristics, maximum_degree, + default_method @@ -97,7 +98,7 @@ end function Embedded_to_MetaGraph(eg::EmbeddedGraph, t_arr) mg = MetaGraph(eg.graph,1.) for (i,j) in enumerate(eg.vertexpos) - set_props!(mg,i,Dict(:pos => j, :type => t_arr[i])) + set_props!(mg,i,Dict(:pos => j, :type => t_arr[i].name)) end return mg end @@ -229,7 +230,7 @@ end function Step_G34(g::EmbeddedGraph, i::Int, dist_spatial, r, types::Array{NodeType}) candidates = connectable_nodes(g, types, i) .& - [types[i].method(g, i) == 1 ? true : false for i in 1:nv(g)] + [types[i].method(g, i) for i in 1:nv(g)] if true in candidates V = dijkstra_shortest_paths(g, i).dists V = ((V .+ dist_spatial) .^ r) ./ dist_spatial From 2a1b97f52dfd60f2e5ad2bb21959a6d0569f3217 Mon Sep 17 00:00:00 2001 From: Ece Kuru Date: Fri, 30 Oct 2020 16:02:22 +0100 Subject: [PATCH 15/18] Changed heurstics implementation. --- src/Heuristics.jl | 30 +++++++++---------- src/NodeTypes.jl | 37 +++++++++++------------ src/SyntheticNetworks.jl | 64 ++++++++++++++++++++++++++++++---------- 3 files changed, 81 insertions(+), 50 deletions(-) diff --git a/src/Heuristics.jl b/src/Heuristics.jl index 9a49a60..e74705c 100644 --- a/src/Heuristics.jl +++ b/src/Heuristics.jl @@ -1,16 +1,16 @@ -function maximum_value_heuristics(f::Function, max_val) - # h(g,i) = f(g)[i] < max_val - return (g, i) -> f(g)[i] < max_val -end - -function cumulative_distribution_heuristics(f::Function; cdf::Function) - return (g, i) -> f(g)[i] |> cdf |> x -> rand() > x -end - -function maximum_degree(k_max) - max_degree = - (g, i) -> - maximum_value_heuristics(x -> degree_centrality(x, normalize = false), k_max) - return max_degree -end +# function maximum_value_heuristics(f::Function, max_val) +# # h(g,i) = f(g)[i] < max_val +# return (g, i) -> f(g)[i] < max_val +# end +# +# function cumulative_distribution_heuristics(f::Function; cdf::Function) +# return (g, i) -> f(g)[i] |> cdf |> x -> rand() > x +# end +# +# function maximum_degree(k_max) +# max_degree = +# (g, i) -> +# maximum_value_heuristics(x -> degree_centrality(x, normalize = false), k_max) +# return max_degree +# end diff --git a/src/NodeTypes.jl b/src/NodeTypes.jl index b29775c..2c50ecd 100644 --- a/src/NodeTypes.jl +++ b/src/NodeTypes.jl @@ -4,15 +4,11 @@ struct NodeType name::String probability::Float32 neighbor_probability::Dict # Dict(Symbol(NodeType_i.name) => prob) - method::Function # (graph::EG, vertex::Int) -> candidate::Bool + method_parameter end -NodeType() = NodeType("Node", 1., Dict(:Node => 1.), default_method) -NodeType(name::String, probability::Float32, n_prob::Dict) = NodeType(name, probability, n_prob, default_method) -NodeType(name::String, probability::Float32, method::Function; n_types) = NodeType(name, probability, fill(1., n_types), default_method) -default_method(g::EmbeddedGraph,i::Int64)::Bool = true +NodeType() = NodeType("Node", 1., Dict(:Node => 1.), 0) -# Step IG0 """ From a list of probabilities of drawing a node type, determines one randomly and returns the index of node type""" function draw_type(node_types::Array{NodeType,1}) @@ -23,18 +19,21 @@ function draw_type(node_types::Array{NodeType,1}) t_n = findfirst(type_interval .>= rand()) return node_types[t_n] end +# NodeType(name::String, probability::Float32, n_prob::Dict) = NodeType(name, probability, n_prob, default_method) +# NodeType(name::String, probability::Float32, method::Function; n_types) = NodeType(name, probability, fill(1., n_types), default_method) +# default_method(g::EmbeddedGraph,i::Int64)::Bool = true -function connect_types(g::EmbeddedGraph, n_types::Array{NodeType,1}, i, n) - nodetype_frequency = countmap(n_types) - n_prob = map(x -> x.neighbor_probability, n_types) - weights = n_prob[Symbol(n_types[i].name)] .* - nodetype_frequency[Symbol(n_types[i].name)] - candidates = sample([1:i-1;i+1:nv(g)], deleteat!(weights,i), n) - return [i in candidates for i in 1:nv(g)] -end - -function connectable_nodes(g::EmbeddedGraph, n_types::Array{NodeType,1}, i) - n_prob = map(x -> x.neighbor_probability[Symbol(n_types[i].name)], n_types) - return n_prob .> 0. -end +# Step IG0 +# function connectable_nodes(g::EmbeddedGraph, n_types::Array{NodeType,1}, i) +# n_prob = map(x -> x.neighbor_probability[Symbol(n_types[i].name)], n_types) +# return n_prob .> 0. +# end +# function connect_types(g::EmbeddedGraph, n_types::Array{NodeType,1}, i, n) +# nodetype_frequency = countmap(n_types) +# n_prob = map(x -> x.neighbor_probability, n_types) +# weights = n_prob[Symbol(n_types[i].name)] .* +# nodetype_frequency[Symbol(n_types[i].name)] +# candidates = sample([1:i-1;i+1:nv(g)], deleteat!(weights,i), n) +# return [i in candidates for i in 1:nv(g)] +# end diff --git a/src/SyntheticNetworks.jl b/src/SyntheticNetworks.jl index 279b19b..cf78338 100755 --- a/src/SyntheticNetworks.jl +++ b/src/SyntheticNetworks.jl @@ -21,8 +21,7 @@ include("NodeTypes.jl") f(i,j,G) = (d_G(i,j) + 1) ^ r / (dist_spatial(x_i,x_j)) """ abstract type SyntheticNetwork end -export SyntheticNetwork, NodeType, RandomPowerGrid, initialise, generate_graph, grow!, maximum_value_heuristics, cumulative_distribution_heuristics, maximum_degree, - default_method +export SyntheticNetwork, NodeType, RandomPowerGrid, initialise, generate_graph, grow!#, maximum_value_heuristics, cumulative_distribution_heuristics, maximum_degree, default_method @@ -77,19 +76,21 @@ struct RandomPowerGrid s::Float32 u::Float32 types::Array{NodeType,1} + heuristic::Symbol end -RandomPowerGrid(n, n0) = RandomPowerGrid(n, n0, rand(5)...,[NodeType()]) -RandomPowerGrid(n,n0,p,q,r,s,u) = RandomPowerGrid(n,n0,p,q,r,s,u,[NodeType()]) +RandomPowerGrid(n, n0) = RandomPowerGrid(n, n0, rand(5)...,[NodeType()], :standard) +RandomPowerGrid(n,n0,p,q,r,s,u) = RandomPowerGrid(n,n0,p,q,r,s,u,[NodeType()], :standard) function generate_graph(RPG) + @assert RPG.heuristic in [:standard, :maxdegree, :neighbor_probability] # (n, n0, p, q, r, s, u) = (RPG.n, RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.s) eg, t_list = initialise(RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.u, - RPG.types) + RPG.types, RPG.heuristic) grow!(eg, t_list, RPG.n, RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.u, - RPG.types) + RPG.types, RPG.heuristic) mg = Embedded_to_MetaGraph(eg, t_list) - set_prop!(mg,:pqrs,[RPG.p, RPG.q, RPG.r, RPG.s]) + set_props!(mg, Dict(:pqrs => [RPG.p, RPG.q, RPG.r, RPG.s], :heuristic => RPG.heuristic)) mg return mg end @@ -105,7 +106,7 @@ end function initialise(n0::Int, p::Real, q::Real, r::Real, s::Real, u::Real, - node_types::Array{NodeType,1}; + node_types::Array{NodeType,1}, heuristic::Symbol; vertex_density_prob::Function=rand_uniform_2D) # STEP I1 """If the locations x_1...x_N are not given, draw them independently at @@ -134,7 +135,7 @@ function initialise(n0::Int, p::Real, q::Real, r::Real, s::Real, u::Real, dist_spatial = map(j -> euclidean(graph.vertexpos[i], graph.vertexpos[j]), 1:nv(graph)) # - l_edge = Step_G34(graph, i, dist_spatial, r, types) + l_edge = Step_G34(graph, i, dist_spatial, r, types, heuristic) if l_edge == 0 dummy -= 1 else @@ -152,7 +153,7 @@ function initialise(n0::Int, p::Real, q::Real, r::Real, s::Real, u::Real, end function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, - node_types::Array{NodeType}; + node_types::Array{NodeType}, heuristic::Symbol; vertex_density_prob::Function=rand_uniform_2D) for n_actual in n0+1:n # STEP G0 @@ -171,14 +172,14 @@ function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, minimal and add the link i–j to G.""" dist_spatial = map(i -> euclidean(graph.vertexpos[nv(graph)], graph.vertexpos[i]), 1:nv(graph)) dist_spatial[nv(graph)] = 100000. #Inf - min_dist_vertex = argmin(dist_spatial[connectable_nodes(graph, types,nv(graph))]) + min_dist_vertex = argmin(dist_spatial) add_edge!(graph, min_dist_vertex, nv(graph)) # STEP G3 """ With probability p, find that node l ∈ {1,...,N} ⍀ {j} for which f(i,l,G) is maximal, and add the link i–l to G.""" if rand() <= p - l_edge = Step_G34(graph, nv(graph), dist_spatial, r, types) + l_edge = Step_G34(graph, nv(graph), dist_spatial, r, types, heuristic) if l_edge !== 0 add_edge!(graph, l_edge, nv(graph)) end @@ -192,7 +193,7 @@ function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, if rand() <= q i = rand(1:nv(graph)) dist_spatial = map(j -> euclidean(graph.vertexpos[i], graph.vertexpos[j]), 1:nv(graph)) - l_edge = Step_G34(graph, i, dist_spatial, r, types) + l_edge = Step_G34(graph, i, dist_spatial, r, types, heuristic) if l_edge !== 0 add_edge!(graph, l_edge, i) end @@ -227,10 +228,41 @@ function Step_I3!(g::EmbeddedGraph, r::Real, m::Int) end end +function Step_G34(g::EmbeddedGraph, i::Int, dist_spatial, r, types::Array{NodeType}, heuristic::Symbol) + if heuristic == :standard + return Step_G34_standard(g, i, dist_spatial, r, types) + elseif heuristic == :maxdegree + return Step_G34_maxdegree(g, i, dist_spatial, r, types) + elseif heuristic == :neighbor_probability + return Step_G34_neighbours(g, i, dist_spatial, r, types) + end +end + + +function Step_G34_standard(g::EmbeddedGraph, i::Int, dist_spatial, r, types::Array{NodeType}) + V = dijkstra_shortest_paths(g, i).dists + V = ((V .+ dist_spatial) .^ r) ./ dist_spatial + V[i] = 0 + return argmax(V) +end + + +function Step_G34_maxdegree(g::EmbeddedGraph, i::Int, dist_spatial, r, types::Array{NodeType}) + d = degree_centrality(g, normalize = false) + candidates = [d[i] .<= types[i].method_parameter for i in 1:nv(g)] + if true in candidates + V = dijkstra_shortest_paths(g, i).dists + V = ((V .+ dist_spatial) .^ r) ./ dist_spatial + V[i] = 0 + return argmax(V[findall(candidates)]) + else + return 0 + end +end -function Step_G34(g::EmbeddedGraph, i::Int, dist_spatial, r, types::Array{NodeType}) - candidates = connectable_nodes(g, types, i) .& - [types[i].method(g, i) for i in 1:nv(g)] +function Step_G34_neighbours(g::EmbeddedGraph, i::Int, dist_spatial, r, types::Array{NodeType}) + n_prob = map(x -> x.neighbor_probability[Symbol(types[i].name)], types) + candidates = n_prob .> 0. if true in candidates V = dijkstra_shortest_paths(g, i).dists V = ((V .+ dist_spatial) .^ r) ./ dist_spatial From c52dc761769d953dce4906ed3e309712de60ccdf Mon Sep 17 00:00:00 2001 From: Ece Kuru Date: Fri, 11 Dec 2020 17:59:56 +0100 Subject: [PATCH 16/18] Added degree distribution and a simplified version of neighbour probability heuristics. --- src/NodeTypes.jl | 18 ----------- src/SyntheticNetworks.jl | 66 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 21 deletions(-) diff --git a/src/NodeTypes.jl b/src/NodeTypes.jl index 2c50ecd..6e90b25 100644 --- a/src/NodeTypes.jl +++ b/src/NodeTypes.jl @@ -19,21 +19,3 @@ function draw_type(node_types::Array{NodeType,1}) t_n = findfirst(type_interval .>= rand()) return node_types[t_n] end -# NodeType(name::String, probability::Float32, n_prob::Dict) = NodeType(name, probability, n_prob, default_method) -# NodeType(name::String, probability::Float32, method::Function; n_types) = NodeType(name, probability, fill(1., n_types), default_method) -# default_method(g::EmbeddedGraph,i::Int64)::Bool = true - -# Step IG0 - -# function connectable_nodes(g::EmbeddedGraph, n_types::Array{NodeType,1}, i) -# n_prob = map(x -> x.neighbor_probability[Symbol(n_types[i].name)], n_types) -# return n_prob .> 0. -# end -# function connect_types(g::EmbeddedGraph, n_types::Array{NodeType,1}, i, n) -# nodetype_frequency = countmap(n_types) -# n_prob = map(x -> x.neighbor_probability, n_types) -# weights = n_prob[Symbol(n_types[i].name)] .* -# nodetype_frequency[Symbol(n_types[i].name)] -# candidates = sample([1:i-1;i+1:nv(g)], deleteat!(weights,i), n) -# return [i in candidates for i in 1:nv(g)] -# end diff --git a/src/SyntheticNetworks.jl b/src/SyntheticNetworks.jl index cf78338..0506314 100755 --- a/src/SyntheticNetworks.jl +++ b/src/SyntheticNetworks.jl @@ -21,7 +21,7 @@ include("NodeTypes.jl") f(i,j,G) = (d_G(i,j) + 1) ^ r / (dist_spatial(x_i,x_j)) """ abstract type SyntheticNetwork end -export SyntheticNetwork, NodeType, RandomPowerGrid, initialise, generate_graph, grow!#, maximum_value_heuristics, cumulative_distribution_heuristics, maximum_degree, default_method +export SyntheticNetwork, NodeType, RandomPowerGrid, initialise, generate_graph, grow! @@ -83,7 +83,7 @@ RandomPowerGrid(n, n0) = RandomPowerGrid(n, n0, rand(5)...,[NodeType()], :standa RandomPowerGrid(n,n0,p,q,r,s,u) = RandomPowerGrid(n,n0,p,q,r,s,u,[NodeType()], :standard) function generate_graph(RPG) - @assert RPG.heuristic in [:standard, :maxdegree, :neighbor_probability] + @assert RPG.heuristic in [:standard, :maxdegree, :neighbor_probability, :degree_cdf, :neighbor_probability_simple] # (n, n0, p, q, r, s, u) = (RPG.n, RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.s) eg, t_list = initialise(RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.u, RPG.types, RPG.heuristic) @@ -173,7 +173,21 @@ function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, dist_spatial = map(i -> euclidean(graph.vertexpos[nv(graph)], graph.vertexpos[i]), 1:nv(graph)) dist_spatial[nv(graph)] = 100000. #Inf min_dist_vertex = argmin(dist_spatial) + if heuristic == :neighbor_probability_simple + found = types[min_dist_vertex] !== types[nv(graph)] + while !found + if rand() < 1/2 + dist_spatial[min_dist_vertex] = 100000. + min_dist_vertex = argmin(dist_spatial) + found = types[min_dist_vertex] !== types[nv(graph)] + else + found = true + end + end + else add_edge!(graph, min_dist_vertex, nv(graph)) + end + # STEP G3 """ With probability p, find that node l ∈ {1,...,N} ⍀ {j} for @@ -191,7 +205,16 @@ function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, i' and for which f(i',l',G) is maximal, and add the link i'–l' to G.""" if rand() <= q - i = rand(1:nv(graph)) + if heuristic == :degree_cdf + found = false + while !found + i = rand(1:nv(graph)) + d = degree(graph, i) + found = rand() <= probs(d+1,types[i].method_parameter) + end + else + i = rand(1:nv(graph)) + end dist_spatial = map(j -> euclidean(graph.vertexpos[i], graph.vertexpos[j]), 1:nv(graph)) l_edge = Step_G34(graph, i, dist_spatial, r, types, heuristic) if l_edge !== 0 @@ -235,6 +258,10 @@ function Step_G34(g::EmbeddedGraph, i::Int, dist_spatial, r, types::Array{NodeTy return Step_G34_maxdegree(g, i, dist_spatial, r, types) elseif heuristic == :neighbor_probability return Step_G34_neighbours(g, i, dist_spatial, r, types) + elseif heuristic == :degree_cdf + return Step_G34_degree_cdf(g, i, dist_spatial, r, types) + elseif heuristic == :neighbor_probability_simple + return Step_G34_neighbours_simple(g, i, dist_spatial, r, types) end end @@ -273,6 +300,39 @@ function Step_G34_neighbours(g::EmbeddedGraph, i::Int, dist_spatial, r, types::A end end +function Step_G34_neighbours_simple(g::EmbeddedGraph, i::Int, dist_spatial, r, types::Array{NodeType}) + V = dijkstra_shortest_paths(g, i).dists + V = ((V .+ dist_spatial) .^ r) ./ dist_spatial + V[i] = 0 + j = argmax(V) + same = types[i] == types[j] + while same + if rand() < 1/2 + V[j] = 0 + j = argmax(V) + same = types[i] == types[j] + else + same = false + end + end + return j +end + + +probs(k,p) = exp(p[1] + p[2] * k) +function Step_G34_degree_cdf(g::EmbeddedGraph, i::Int, dist_spatial, r, types::Array{NodeType}) + d = degree(g) + candidates = [rand() <= probs(d[j]+1,types[j].method_parameter) for j in 1:nv(g)] + if true in candidates + V = dijkstra_shortest_paths(g, i).dists + V = ((V .+ dist_spatial) .^ r) ./ dist_spatial + V[i] = 0 + return argmax(V[findall(candidates)]) + else + return 0 + end +end + rand_uniform_2D(i) = [rand_uniform(i),rand_uniform(i)] rand_uniform(i) = 2*(0.5-rand()) From eb0ce50f0b642d679f018fc76f3f4179c55e1ccd Mon Sep 17 00:00:00 2001 From: Ece Kuru Date: Wed, 16 Dec 2020 20:43:41 +0100 Subject: [PATCH 17/18] Added a check for already connected nodes in G34. Removed the step checking the node types in step G2. --- src/SyntheticNetworks.jl | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/SyntheticNetworks.jl b/src/SyntheticNetworks.jl index 0506314..3a8e5bd 100755 --- a/src/SyntheticNetworks.jl +++ b/src/SyntheticNetworks.jl @@ -173,20 +173,19 @@ function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, dist_spatial = map(i -> euclidean(graph.vertexpos[nv(graph)], graph.vertexpos[i]), 1:nv(graph)) dist_spatial[nv(graph)] = 100000. #Inf min_dist_vertex = argmin(dist_spatial) - if heuristic == :neighbor_probability_simple - found = types[min_dist_vertex] !== types[nv(graph)] - while !found - if rand() < 1/2 - dist_spatial[min_dist_vertex] = 100000. - min_dist_vertex = argmin(dist_spatial) - found = types[min_dist_vertex] !== types[nv(graph)] - else - found = true - end - end - else + # if heuristic == :neighbor_probability_simple + # found = types[min_dist_vertex] !== types[nv(graph)] + # while !found + # if rand() < 1/2 + # dist_spatial[min_dist_vertex] = 100000. + # min_dist_vertex = argmin(dist_spatial) + # found = types[min_dist_vertex] !== types[nv(graph)] + # else + # found = true + # end + # end + # end add_edge!(graph, min_dist_vertex, nv(graph)) - end # STEP G3 @@ -270,17 +269,19 @@ function Step_G34_standard(g::EmbeddedGraph, i::Int, dist_spatial, r, types::Arr V = dijkstra_shortest_paths(g, i).dists V = ((V .+ dist_spatial) .^ r) ./ dist_spatial V[i] = 0 + V[neighbors(g, i)] .= 0 return argmax(V) end function Step_G34_maxdegree(g::EmbeddedGraph, i::Int, dist_spatial, r, types::Array{NodeType}) d = degree_centrality(g, normalize = false) - candidates = [d[i] .<= types[i].method_parameter for i in 1:nv(g)] + candidates = [d[i] .< types[i].method_parameter for i in 1:nv(g)] if true in candidates V = dijkstra_shortest_paths(g, i).dists V = ((V .+ dist_spatial) .^ r) ./ dist_spatial V[i] = 0 + V[neighbors(g, i)] .= 0 return argmax(V[findall(candidates)]) else return 0 @@ -294,6 +295,7 @@ function Step_G34_neighbours(g::EmbeddedGraph, i::Int, dist_spatial, r, types::A V = dijkstra_shortest_paths(g, i).dists V = ((V .+ dist_spatial) .^ r) ./ dist_spatial V[i] = 0 + V[neighbors(g, i)] .= 0 return argmax(V[findall(candidates)]) else return 0 @@ -304,6 +306,7 @@ function Step_G34_neighbours_simple(g::EmbeddedGraph, i::Int, dist_spatial, r, t V = dijkstra_shortest_paths(g, i).dists V = ((V .+ dist_spatial) .^ r) ./ dist_spatial V[i] = 0 + V[neighbors(g, i)] .= 0 j = argmax(V) same = types[i] == types[j] while same @@ -322,11 +325,12 @@ end probs(k,p) = exp(p[1] + p[2] * k) function Step_G34_degree_cdf(g::EmbeddedGraph, i::Int, dist_spatial, r, types::Array{NodeType}) d = degree(g) - candidates = [rand() <= probs(d[j]+1,types[j].method_parameter) for j in 1:nv(g)] + candidates = [rand() <= probs(d[j],types[j].method_parameter) for j in 1:nv(g)] if true in candidates V = dijkstra_shortest_paths(g, i).dists V = ((V .+ dist_spatial) .^ r) ./ dist_spatial V[i] = 0 + V[neighbors(g, i)] .= 0 return argmax(V[findall(candidates)]) else return 0 From 20cd5cf238708a0ebafcee8d30f82d9d4d6a85bd Mon Sep 17 00:00:00 2001 From: Ece Kuru Date: Tue, 26 Jan 2021 11:13:04 +0100 Subject: [PATCH 18/18] Fixed some bugs: 1) added checks to avoid self-edges and multi-edges from G34, 2) fixed how a node is chosen from candidates. Changes in heuristics, which are now in conditionals instead of defining functions in NodeTypes. Final (?) version for BA-Ece :) --- src/Heuristics.jl | 16 ------ src/SyntheticNetworks.jl | 108 +++++++++++++++++++++++++-------------- 2 files changed, 70 insertions(+), 54 deletions(-) delete mode 100644 src/Heuristics.jl diff --git a/src/Heuristics.jl b/src/Heuristics.jl deleted file mode 100644 index e74705c..0000000 --- a/src/Heuristics.jl +++ /dev/null @@ -1,16 +0,0 @@ -# function maximum_value_heuristics(f::Function, max_val) -# # h(g,i) = f(g)[i] < max_val -# return (g, i) -> f(g)[i] < max_val -# end -# -# function cumulative_distribution_heuristics(f::Function; cdf::Function) -# return (g, i) -> f(g)[i] |> cdf |> x -> rand() > x -# end -# -# function maximum_degree(k_max) -# max_degree = -# (g, i) -> -# maximum_value_heuristics(x -> degree_centrality(x, normalize = false), k_max) -# return max_degree -# end - diff --git a/src/SyntheticNetworks.jl b/src/SyntheticNetworks.jl index 7017484..28994ba 100755 --- a/src/SyntheticNetworks.jl +++ b/src/SyntheticNetworks.jl @@ -26,7 +26,7 @@ end abstract type SyntheticNetwork end export SyntheticNetwork, NodeType, RandomPowerGrid, initialise, generate_graph, grow! - +max_iter = 200 """ RandomPowerGrid(num_layers, n, n0, p, q, r, s, u, sampling, α, β, γ, debug) @@ -94,7 +94,7 @@ function generate_graph(RPG) eg, t_list = initialise(RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.u, RPG.types, RPG.heuristic) grow!(eg, t_list, RPG.n, RPG.n0, RPG.p, RPG.q, RPG.r, RPG.s, RPG.u, - RPG.types, RPG.heuristic) + RPG.types, RPG.heuristic) mg = Embedded_to_MetaGraph(eg, t_list) set_props!(mg, Dict(:pqrs => [RPG.p, RPG.q, RPG.r, RPG.s], :heuristic => RPG.heuristic)) mg @@ -142,9 +142,7 @@ function initialise(n0::Int, p::Real, q::Real, r::Real, s::Real, u::Real, graph.vertexpos[j]), 1:nv(graph)) # l_edge = Step_G34(graph, i, dist_spatial, r, types, heuristic) - if l_edge == 0 - dummy -= 1 - else + if l_edge != 0 add_edge!(graph, l_edge, i) end end @@ -178,22 +176,37 @@ function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, minimal and add the link i–j to G.""" dist_spatial = map(i -> euclidean(graph.vertexpos[nv(graph)], graph.vertexpos[i]), 1:nv(graph)) dist_spatial[nv(graph)] = 100000. #Inf - min_dist_vertex = argmin(dist_spatial) - # if heuristic == :neighbor_probability_simple - # found = types[min_dist_vertex] !== types[nv(graph)] - # while !found - # if rand() < 1/2 - # dist_spatial[min_dist_vertex] = 100000. - # min_dist_vertex = argmin(dist_spatial) - # found = types[min_dist_vertex] !== types[nv(graph)] - # else - # found = true - # end - # end - # end + if heuristic == :standard + min_dist_vertex = argmin(dist_spatial) + elseif heuristic == :neighbor_probability_simple + min_dist_vertex = argmin(dist_spatial) + found = types[min_dist_vertex] !== types[nv(graph)] + iter1 = 0 + while !found && iter1 <= max_iter + if rand() < 1/2 + dist_spatial[min_dist_vertex] = 100000. + min_dist_vertex = argmin(dist_spatial) + found = types[min_dist_vertex] !== types[nv(graph)] + else + found = true + end + iter1 += 1 + end + elseif heuristic == :maxdegree + d = degree(graph) + candidates = [d[i] < types[i].method_parameter for i in 1:nv(graph)] + dist_spatial[.!candidates] .= 100000. + min_dist_vertex = argmin(dist_spatial) + elseif heuristic == :degree_cdf + d = degree(graph) + candidates = [rand() <= probs(d[j],types[j].method_parameter) for j in 1:nv(graph)] + dist_spatial[.!candidates] .= 100000. + min_dist_vertex = argmin(dist_spatial) + end add_edge!(graph, min_dist_vertex, nv(graph)) + # STEP G3 """ With probability p, find that node l ∈ {1,...,N} ⍀ {j} for which f(i,l,G) is maximal, and add the link i–l to G.""" @@ -211,12 +224,18 @@ function grow!(graph::EmbeddedGraph, types, n::Int, n0::Int, p, q, r, s, u, to G.""" if rand() <= q if heuristic == :degree_cdf - found = false - while !found - i = rand(1:nv(graph)) - d = degree(graph, i) - found = rand() <= probs(d+1,types[i].method_parameter) + d = degree(graph) + candidates = [rand() <= probs(d[j],types[j].method_parameter) for j in 1:nv(graph)] + iter2 = 0 + while isempty(findall(candidates)) && iter2 <= max_iter + candidates = [rand() <= probs(d[j],types[j].method_parameter) for j in 1:nv(graph)] + iter2 += 1 end + i = rand(findall(candidates)) + elseif heuristic == :maxdegree + d = degree(graph) + candidates = [d[i] < types[i].method_parameter for i in 1:nv(graph)] + i = rand(findall(candidates)) else i = rand(1:nv(graph)) end @@ -276,19 +295,22 @@ function Step_G34_standard(g::EmbeddedGraph, i::Int, dist_spatial, r, types::Arr V = ((V .+ dist_spatial) .^ r) ./ dist_spatial V[i] = 0 V[neighbors(g, i)] .= 0 - return argmax(V) + m = argmax(V) + return maximum(V) > 0. ? m : 0 end function Step_G34_maxdegree(g::EmbeddedGraph, i::Int, dist_spatial, r, types::Array{NodeType}) d = degree_centrality(g, normalize = false) - candidates = [d[i] .< types[i].method_parameter for i in 1:nv(g)] + candidates = [d[i] < types[i].method_parameter for i in 1:nv(g)] if true in candidates V = dijkstra_shortest_paths(g, i).dists V = ((V .+ dist_spatial) .^ r) ./ dist_spatial V[i] = 0 V[neighbors(g, i)] .= 0 - return argmax(V[findall(candidates)]) + V[.!candidates] .= 0 + m = argmax(V) + return maximum(V) > 0 ? m : 0 else return 0 end @@ -302,7 +324,9 @@ function Step_G34_neighbours(g::EmbeddedGraph, i::Int, dist_spatial, r, types::A V = ((V .+ dist_spatial) .^ r) ./ dist_spatial V[i] = 0 V[neighbors(g, i)] .= 0 - return argmax(V[findall(candidates)]) + V[.!candidates] .= 0 + m = argmax(V) + return maximum(V) > 0 ? m : 0 else return 0 end @@ -313,18 +337,24 @@ function Step_G34_neighbours_simple(g::EmbeddedGraph, i::Int, dist_spatial, r, t V = ((V .+ dist_spatial) .^ r) ./ dist_spatial V[i] = 0 V[neighbors(g, i)] .= 0 - j = argmax(V) - same = types[i] == types[j] - while same - if rand() < 1/2 - V[j] = 0 - j = argmax(V) - same = types[i] == types[j] - else - same = false + if maximum(V) > 0 + j = argmax(V) + same = types[i] == types[j] + iter3 = 0 + while same && iter3 <= max_iter + if rand() < 1/2 + V[j] = 0 + j = argmax(V) + same = types[i] == types[j] + else + same = false + end + iter3 += 1 end + return j + else + return 0 end - return j end @@ -337,7 +367,9 @@ function Step_G34_degree_cdf(g::EmbeddedGraph, i::Int, dist_spatial, r, types::A V = ((V .+ dist_spatial) .^ r) ./ dist_spatial V[i] = 0 V[neighbors(g, i)] .= 0 - return argmax(V[findall(candidates)]) + V[.!candidates] .= 0. + m = argmax(V) + return maximum(V) > 0 ? m : 0 else return 0 end