diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 4976979..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,4 +0,0 @@ -include requirements.txt -include test-requirements.txt -include README.rst -graft soil \ No newline at end of file diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 2fc6b44..af3dadb --- a/README.md +++ b/README.md @@ -1,34 +1,12 @@ -# [SOIL](https://github.com/gsi-upm/soil) +#[Soil](https://github.com/gsi-upm/soil) -Soil is an extensible and user-friendly Agent-based Social Simulator for Social Networks. -Learn how to run your own simulations with our [documentation](http://soilsim.readthedocs.io). +The purpose of Soil (SOcial network sImuLator) is provding an Agent-based Social Simulator written in Python for Social Networks. + + +In order to see quickly how to use Soil, you can follow the following [tutorial](https://github.com/gsi-upm/soil/blob/master/soil_tutorial.ipynb). -Follow our [tutorial](notebooks/soil_tutorial.ipynb) to develop your own agent models. -If you use Soil in your research, don't forget to cite this paper: -```bibtex -@inbook{soil-gsi-conference-2017, - author = "S{\'a}nchez, Jes{\'u}s M. and Iglesias, Carlos A. and S{\'a}nchez-Rada, J. Fernando", - booktitle = "Advances in Practical Applications of Cyber-Physical Multi-Agent Systems: The PAAMS Collection", - doi = "10.1007/978-3-319-59930-4_19", - editor = "Demazeau Y., Davidsson P., Bajo J., Vale Z.", - isbn = "978-3-319-59929-8", - keywords = "soil;social networks;agent based social simulation;python", - month = "June", - organization = "PAAMS 2017", - pages = "234-245", - publisher = "Springer Verlag", - series = "LNAI", - title = "{S}oil: {A}n {A}gent-{B}ased {S}ocial {S}imulator in {P}ython for {M}odelling and {S}imulation of {S}ocial {N}etworks", - url = "https://link.springer.com/chapter/10.1007/978-3-319-59930-4_19", - volume = "10349", - year = "2017", -} -``` @Copyright GSI - Universidad Politécnica de Madrid 2017 - -[![SOIL](logo_gsi.png)](https://www.gsi.dit.upm.es) - diff --git a/TerroristModel.png b/TerroristModel.png new file mode 100644 index 0000000..e59ff27 Binary files /dev/null and b/TerroristModel.png differ diff --git a/TerroristModel_tipo.png b/TerroristModel_tipo.png new file mode 100644 index 0000000..dba3c6e Binary files /dev/null and b/TerroristModel_tipo.png differ diff --git a/TerroristModel_type.png b/TerroristModel_type.png new file mode 100644 index 0000000..68198c0 Binary files /dev/null and b/TerroristModel_type.png differ diff --git a/clase_base.pyc b/clase_base.pyc new file mode 100755 index 0000000..2cb8ded Binary files /dev/null and b/clase_base.pyc differ diff --git a/data.txt b/data.txt new file mode 100755 index 0000000..e1e4337 --- /dev/null +++ b/data.txt @@ -0,0 +1,8802 @@ +{ + "agent_0": { + "fstatus": { + "0": 0, + "2": 0, + "4": 0, + "6": 1, + "8": 1, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.08880030965403382, + "2": 0.12880030965403383, + "4": 0.20880030965403384, + "6": 0.4288003096540339, + "8": 0.5188003096540339, + "10": 0.648800309654034, + "12": 0.648800309654034, + "14": 0.648800309654034, + "16": 0.648800309654034, + "18": 0.648800309654034, + "20": 0.648800309654034, + "22": 0.648800309654034, + "24": 0.648800309654034, + "26": 0.648800309654034, + "28": 0.648800309654034, + "30": 0.648800309654034, + "32": 0.648800309654034, + "34": 0.648800309654034, + "36": 0.648800309654034, + "38": 0.648800309654034, + "40": 0.648800309654034, + "42": 0.648800309654034, + "44": 0.648800309654034, + "46": 0.648800309654034, + "48": 0.648800309654034 + }, + "status": { + "0": 0, + "2": 0, + "4": 0, + "6": 1, + "8": 1, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_1": { + "fstatus": { + "0": 0, + "2": 0, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.15809591017204133, + "2": 0.2780959101720414, + "4": 0.5580959101720416, + "6": 0.6480959101720417, + "8": 0.6480959101720417, + "10": 0.6480959101720417, + "12": 0.6480959101720417, + "14": 0.6480959101720417, + "16": 0.6480959101720417, + "18": 0.6480959101720417, + "20": 0.6480959101720417, + "22": 0.6480959101720417, + "24": 0.6480959101720417, + "26": 0.6480959101720417, + "28": 0.6480959101720417, + "30": 0.6480959101720417, + "32": 0.6480959101720417, + "34": 0.6480959101720417, + "36": 0.6480959101720417, + "38": 0.6480959101720417, + "40": 0.6480959101720417, + "42": 0.6480959101720417, + "44": 0.6480959101720417, + "46": 0.6480959101720417, + "48": 0.6480959101720417 + }, + "status": { + "0": 0, + "2": 0, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_10": { + "fstatus": { + "0": 2, + "2": 6, + "4": 6, + "6": 6, + "8": 6, + "10": 6, + "12": 6, + "14": 6, + "16": 6, + "18": 6, + "20": 6, + "22": 6, + "24": 6, + "26": 6, + "28": 6, + "30": 6, + "32": 6, + "34": 6, + "36": 6, + "38": 6, + "40": 6, + "42": 6, + "44": 6, + "46": 6, + "48": 6 + }, + "radicalism": { + "0": 0.8035297540281455, + "2": 0.8535297540281456, + "4": 0.9035297540281456, + "6": 0.9535297540281457, + "8": 1.0035297540281456, + "10": 1.0535297540281456, + "12": 1.1035297540281457, + "14": 1.1535297540281457, + "16": 1.2035297540281458, + "18": 1.2535297540281458, + "20": 1.3035297540281459, + "22": 1.353529754028146, + "24": 1.403529754028146, + "26": 1.453529754028146, + "28": 1.503529754028146, + "30": 1.553529754028146, + "32": 1.6035297540281461, + "34": 1.6535297540281462, + "36": 1.7035297540281462, + "38": 1.7535297540281463, + "40": 1.8035297540281463, + "42": 1.8535297540281463, + "44": 1.9035297540281464, + "46": 1.9535297540281464, + "48": 2.0035297540281465 + }, + "status": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 1, + "16": 1, + "18": 1, + "20": 1, + "22": 1, + "24": 1, + "26": 1, + "28": 1, + "30": 1, + "32": 1, + "34": 1, + "36": 1, + "38": 1, + "40": 1, + "42": 1, + "44": 1, + "46": 1, + "48": 1 + } + }, + "agent_11": { + "fstatus": { + "0": 1, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.6009401979934893, + "2": 0.6509401979934893, + "4": 0.7009401979934894, + "6": 0.7509401979934894, + "8": 0.8009401979934895, + "10": 0.8509401979934895, + "12": 0.9009401979934896, + "14": 0.9509401979934896, + "16": 1.0009401979934895, + "18": 1.0509401979934896, + "20": 1.1009401979934896, + "22": 1.1509401979934897, + "24": 1.2009401979934897, + "26": 1.2509401979934898, + "28": 1.3009401979934898, + "30": 1.3509401979934899, + "32": 1.40094019799349, + "34": 1.45094019799349, + "36": 1.50094019799349, + "38": 1.55094019799349, + "40": 1.60094019799349, + "42": 1.6509401979934901, + "44": 1.7009401979934902, + "46": 1.7509401979934902, + "48": 1.8009401979934903 + }, + "status": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_12": { + "fstatus": { + "0": 0, + "2": 0, + "4": 1, + "6": 1, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.07120438914023139, + "2": 0.1512043891402314, + "4": 0.4312043891402315, + "6": 0.5212043891402315, + "8": 0.6912043891402316, + "10": 0.6912043891402316, + "12": 0.6912043891402316, + "14": 0.6912043891402316, + "16": 0.6912043891402316, + "18": 0.6912043891402316, + "20": 0.6912043891402316, + "22": 0.6912043891402316, + "24": 0.6912043891402316, + "26": 0.6912043891402316, + "28": 0.6912043891402316, + "30": 0.6912043891402316, + "32": 0.6912043891402316, + "34": 0.6912043891402316, + "36": 0.6912043891402316, + "38": 0.6912043891402316, + "40": 0.6912043891402316, + "42": 0.6912043891402316, + "44": 0.6912043891402316, + "46": 0.6912043891402316, + "48": 0.6912043891402316 + }, + "status": { + "0": 0, + "2": 0, + "4": 1, + "6": 1, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_13": { + "fstatus": { + "0": 1, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.5854833303883875, + "2": 0.7554833303883877, + "4": 0.7554833303883877, + "6": 0.7554833303883877, + "8": 0.7554833303883877, + "10": 0.7554833303883877, + "12": 0.7554833303883877, + "14": 0.7554833303883877, + "16": 0.7554833303883877, + "18": 0.7554833303883877, + "20": 0.7554833303883877, + "22": 0.7554833303883877, + "24": 0.7554833303883877, + "26": 0.7554833303883877, + "28": 0.7554833303883877, + "30": 0.7554833303883877, + "32": 0.7554833303883877, + "34": 0.7554833303883877, + "36": 0.7554833303883877, + "38": 0.7554833303883877, + "40": 0.7554833303883877, + "42": 0.7554833303883877, + "44": 0.7554833303883877, + "46": 0.7554833303883877, + "48": 0.7554833303883877 + }, + "status": { + "0": 1, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_14": { + "fstatus": { + "0": 1, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 1, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.42252345656789614, + "2": 0.42252345656789614, + "4": 0.42252345656789614, + "6": 0.42252345656789614, + "8": 0.42252345656789614, + "10": 0.42252345656789614, + "12": 0.4625234565678962, + "14": 0.5925234565678963, + "16": 0.6425234565678963, + "18": 0.6425234565678963, + "20": 0.6425234565678963, + "22": 0.6425234565678963, + "24": 0.6425234565678963, + "26": 0.6425234565678963, + "28": 0.6425234565678963, + "30": 0.6425234565678963, + "32": 0.6425234565678963, + "34": 0.6425234565678963, + "36": 0.6425234565678963, + "38": 0.6425234565678963, + "40": 0.6425234565678963, + "42": 0.6425234565678963, + "44": 0.6425234565678963, + "46": 0.6425234565678963, + "48": 0.6425234565678963 + }, + "status": { + "0": 1, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 1, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_15": { + "fstatus": { + "0": 0, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.2126113364252416, + "2": 0.3726113364252417, + "4": 0.3726113364252417, + "6": 0.3726113364252417, + "8": 0.45261133642524176, + "10": 0.692611336425242, + "12": 0.692611336425242, + "14": 0.692611336425242, + "16": 0.692611336425242, + "18": 0.692611336425242, + "20": 0.692611336425242, + "22": 0.692611336425242, + "24": 0.692611336425242, + "26": 0.692611336425242, + "28": 0.692611336425242, + "30": 0.692611336425242, + "32": 0.692611336425242, + "34": 0.692611336425242, + "36": 0.692611336425242, + "38": 0.692611336425242, + "40": 0.692611336425242, + "42": 0.692611336425242, + "44": 0.692611336425242, + "46": 0.692611336425242, + "48": 0.692611336425242 + }, + "status": { + "0": 0, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_16": { + "fstatus": { + "0": 0, + "2": 0, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.1743730559361031, + "2": 0.2943730559361032, + "4": 0.59, + "6": 0.68, + "8": 0.68, + "10": 0.68, + "12": 0.68, + "14": 0.68, + "16": 0.68, + "18": 0.68, + "20": 0.68, + "22": 0.68, + "24": 0.68, + "26": 0.68, + "28": 0.68, + "30": 0.68, + "32": 0.68, + "34": 0.68, + "36": 0.68, + "38": 0.68, + "40": 0.68, + "42": 0.68, + "44": 0.68, + "46": 0.68, + "48": 0.68 + }, + "status": { + "0": 0, + "2": 0, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_17": { + "fstatus": { + "0": 1, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.49396896059319867, + "2": 0.49396896059319867, + "4": 0.49396896059319867, + "6": 0.49396896059319867, + "8": 0.49396896059319867, + "10": 0.6539689605931988, + "12": 0.6539689605931988, + "14": 0.6539689605931988, + "16": 0.6539689605931988, + "18": 0.6539689605931988, + "20": 0.6539689605931988, + "22": 0.6539689605931988, + "24": 0.6539689605931988, + "26": 0.6539689605931988, + "28": 0.6539689605931988, + "30": 0.6539689605931988, + "32": 0.6539689605931988, + "34": 0.6539689605931988, + "36": 0.6539689605931988, + "38": 0.6539689605931988, + "40": 0.6539689605931988, + "42": 0.6539689605931988, + "44": 0.6539689605931988, + "46": 0.6539689605931988, + "48": 0.6539689605931988 + }, + "status": { + "0": 1, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_18": { + "fstatus": { + "0": 0, + "2": 0, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.09014238039585168, + "2": 0.2501423803958517, + "4": 0.59, + "6": 0.7200000000000001, + "8": 0.7200000000000001, + "10": 0.7200000000000001, + "12": 0.7200000000000001, + "14": 0.7200000000000001, + "16": 0.7200000000000001, + "18": 0.7200000000000001, + "20": 0.7200000000000001, + "22": 0.7200000000000001, + "24": 0.7200000000000001, + "26": 0.7200000000000001, + "28": 0.7200000000000001, + "30": 0.7200000000000001, + "32": 0.7200000000000001, + "34": 0.7200000000000001, + "36": 0.7200000000000001, + "38": 0.7200000000000001, + "40": 0.7200000000000001, + "42": 0.7200000000000001, + "44": 0.7200000000000001, + "46": 0.7200000000000001, + "48": 0.7200000000000001 + }, + "status": { + "0": 0, + "2": 0, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_19": { + "fstatus": { + "0": 1, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 1, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.4731752191572189, + "2": 0.4731752191572189, + "4": 0.4731752191572189, + "6": 0.4731752191572189, + "8": 0.5131752191572189, + "10": 0.5931752191572189, + "12": 0.713175219157219, + "14": 0.713175219157219, + "16": 0.713175219157219, + "18": 0.713175219157219, + "20": 0.713175219157219, + "22": 0.713175219157219, + "24": 0.713175219157219, + "26": 0.713175219157219, + "28": 0.713175219157219, + "30": 0.713175219157219, + "32": 0.713175219157219, + "34": 0.713175219157219, + "36": 0.713175219157219, + "38": 0.713175219157219, + "40": 0.713175219157219, + "42": 0.713175219157219, + "44": 0.713175219157219, + "46": 0.713175219157219, + "48": 0.713175219157219 + }, + "status": { + "0": 1, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 1, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_2": { + "fstatus": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.8271650258338952, + "2": 0.8271650258338952, + "4": 0.8271650258338952, + "6": 0.8271650258338952, + "8": 0.8271650258338952, + "10": 0.8271650258338952, + "12": 0.8271650258338952, + "14": 0.8271650258338952, + "16": 0.8271650258338952, + "18": 0.8271650258338952, + "20": 0.8271650258338952, + "22": 0.8271650258338952, + "24": 0.8271650258338952, + "26": 0.8271650258338952, + "28": 0.8271650258338952, + "30": 0.8271650258338952, + "32": 0.8271650258338952, + "34": 0.8271650258338952, + "36": 0.8271650258338952, + "38": 0.8271650258338952, + "40": 0.8271650258338952, + "42": 0.8271650258338952, + "44": 0.8271650258338952, + "46": 0.8271650258338952, + "48": 0.8271650258338952 + }, + "status": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_20": { + "fstatus": { + "0": 0, + "2": 0, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.13553780592089704, + "2": 0.21553780592089705, + "4": 0.6555378059208974, + "6": 0.6555378059208974, + "8": 0.6555378059208974, + "10": 0.6555378059208974, + "12": 0.6555378059208974, + "14": 0.6555378059208974, + "16": 0.6555378059208974, + "18": 0.6555378059208974, + "20": 0.6555378059208974, + "22": 0.6555378059208974, + "24": 0.6555378059208974, + "26": 0.6555378059208974, + "28": 0.6555378059208974, + "30": 0.6555378059208974, + "32": 0.6555378059208974, + "34": 0.6555378059208974, + "36": 0.6555378059208974, + "38": 0.6555378059208974, + "40": 0.6555378059208974, + "42": 0.6555378059208974, + "44": 0.6555378059208974, + "46": 0.6555378059208974, + "48": 0.6555378059208974 + }, + "status": { + "0": 0, + "2": 0, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_21": { + "fstatus": { + "0": 0, + "2": 1, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.13966398522048593, + "2": 0.4696639852204859, + "4": 0.619663985220486, + "6": 0.7196639852204861, + "8": 0.8196639852204862, + "10": 0.9196639852204863, + "12": 1.0196639852204863, + "14": 1.1196639852204864, + "16": 1.2196639852204865, + "18": 1.3196639852204866, + "20": 1.4196639852204866, + "22": 1.5196639852204867, + "24": 1.6196639852204868, + "26": 1.719663985220487, + "28": 1.819663985220487, + "30": 1.919663985220487, + "32": 2.019663985220487, + "34": 2.1196639852204866, + "36": 2.2196639852204862, + "38": 2.319663985220486, + "40": 2.4196639852204855, + "42": 2.519663985220485, + "44": 2.619663985220485, + "46": 2.7196639852204845, + "48": 2.819663985220484 + }, + "status": { + "0": 0, + "2": 1, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_22": { + "fstatus": { + "0": 1, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 1, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.470841683280595, + "2": 0.470841683280595, + "4": 0.470841683280595, + "6": 0.470841683280595, + "8": 0.470841683280595, + "10": 0.590841683280595, + "12": 0.7108416832805952, + "14": 0.7108416832805952, + "16": 0.7108416832805952, + "18": 0.7108416832805952, + "20": 0.7108416832805952, + "22": 0.7108416832805952, + "24": 0.7108416832805952, + "26": 0.7108416832805952, + "28": 0.7108416832805952, + "30": 0.7108416832805952, + "32": 0.7108416832805952, + "34": 0.7108416832805952, + "36": 0.7108416832805952, + "38": 0.7108416832805952, + "40": 0.7108416832805952, + "42": 0.7108416832805952, + "44": 0.7108416832805952, + "46": 0.7108416832805952, + "48": 0.7108416832805952 + }, + "status": { + "0": 1, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 1, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_23": { + "fstatus": { + "0": 0, + "2": 1, + "4": 1, + "6": 1, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.14790005774497247, + "2": 0.34790005774497257, + "4": 0.3879000577449726, + "6": 0.5579000577449726, + "8": 0.7679000577449728, + "10": 0.7679000577449728, + "12": 0.7679000577449728, + "14": 0.7679000577449728, + "16": 0.7679000577449728, + "18": 0.7679000577449728, + "20": 0.7679000577449728, + "22": 0.7679000577449728, + "24": 0.7679000577449728, + "26": 0.7679000577449728, + "28": 0.7679000577449728, + "30": 0.7679000577449728, + "32": 0.7679000577449728, + "34": 0.7679000577449728, + "36": 0.7679000577449728, + "38": 0.7679000577449728, + "40": 0.7679000577449728, + "42": 0.7679000577449728, + "44": 0.7679000577449728, + "46": 0.7679000577449728, + "48": 0.7679000577449728 + }, + "status": { + "0": 0, + "2": 1, + "4": 1, + "6": 1, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_24": { + "fstatus": { + "0": 0, + "2": 0, + "4": 0, + "6": 1, + "8": 1, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.09745274067666362, + "2": 0.17745274067666364, + "4": 0.2974527406766637, + "6": 0.4274527406766637, + "8": 0.5474527406766638, + "10": 0.747452740676664, + "12": 0.747452740676664, + "14": 0.747452740676664, + "16": 0.747452740676664, + "18": 0.747452740676664, + "20": 0.747452740676664, + "22": 0.747452740676664, + "24": 0.747452740676664, + "26": 0.747452740676664, + "28": 0.747452740676664, + "30": 0.747452740676664, + "32": 0.747452740676664, + "34": 0.747452740676664, + "36": 0.747452740676664, + "38": 0.747452740676664, + "40": 0.747452740676664, + "42": 0.747452740676664, + "44": 0.747452740676664, + "46": 0.747452740676664, + "48": 0.747452740676664 + }, + "status": { + "0": 0, + "2": 0, + "4": 0, + "6": 1, + "8": 1, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_25": { + "fstatus": { + "0": 0, + "2": 0, + "4": 0, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 1, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.10542251799583074, + "2": 0.18542251799583076, + "4": 0.2654225179958308, + "6": 0.3454225179958308, + "8": 0.3454225179958308, + "10": 0.3854225179958308, + "12": 0.4654225179958309, + "14": 0.545422517995831, + "16": 0.625422517995831, + "18": 0.625422517995831, + "20": 0.625422517995831, + "22": 0.625422517995831, + "24": 0.625422517995831, + "26": 0.625422517995831, + "28": 0.625422517995831, + "30": 0.625422517995831, + "32": 0.625422517995831, + "34": 0.625422517995831, + "36": 0.625422517995831, + "38": 0.625422517995831, + "40": 0.625422517995831, + "42": 0.625422517995831, + "44": 0.625422517995831, + "46": 0.625422517995831, + "48": 0.625422517995831 + }, + "status": { + "0": 0, + "2": 0, + "4": 0, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 1, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_26": { + "fstatus": { + "0": 0, + "2": 1, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.2335518690523134, + "2": 0.5035518690523134, + "4": 0.6035518690523135, + "6": 0.6535518690523135, + "8": 0.7035518690523136, + "10": 0.7535518690523136, + "12": 0.8035518690523137, + "14": 0.8535518690523137, + "16": 0.9035518690523138, + "18": 0.9535518690523138, + "20": 1.0035518690523137, + "22": 1.0535518690523138, + "24": 1.1035518690523138, + "26": 1.1535518690523139, + "28": 1.203551869052314, + "30": 1.253551869052314, + "32": 1.303551869052314, + "34": 1.353551869052314, + "36": 1.403551869052314, + "38": 1.4535518690523141, + "40": 1.5035518690523142, + "42": 1.5535518690523142, + "44": 1.6035518690523143, + "46": 1.6535518690523143, + "48": 1.7035518690523144 + }, + "status": { + "0": 0, + "2": 1, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_27": { + "fstatus": { + "0": 1, + "2": 1, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.505345212696026, + "2": 0.555345212696026, + "4": 0.6753452126960261, + "6": 0.6753452126960261, + "8": 0.6753452126960261, + "10": 0.6753452126960261, + "12": 0.6753452126960261, + "14": 0.6753452126960261, + "16": 0.6753452126960261, + "18": 0.6753452126960261, + "20": 0.6753452126960261, + "22": 0.6753452126960261, + "24": 0.6753452126960261, + "26": 0.6753452126960261, + "28": 0.6753452126960261, + "30": 0.6753452126960261, + "32": 0.6753452126960261, + "34": 0.6753452126960261, + "36": 0.6753452126960261, + "38": 0.6753452126960261, + "40": 0.6753452126960261, + "42": 0.6753452126960261, + "44": 0.6753452126960261, + "46": 0.6753452126960261, + "48": 0.6753452126960261 + }, + "status": { + "0": 1, + "2": 1, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_28": { + "fstatus": { + "0": 0, + "2": 1, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.06103253863394516, + "2": 0.40103253863394517, + "4": 0.6310325386339453, + "6": 0.7310325386339454, + "8": 0.8310325386339454, + "10": 0.9310325386339455, + "12": 1.0310325386339456, + "14": 1.1310325386339457, + "16": 1.2310325386339458, + "18": 1.3310325386339459, + "20": 1.431032538633946, + "22": 1.531032538633946, + "24": 1.6310325386339461, + "26": 1.7310325386339462, + "28": 1.8310325386339463, + "30": 1.9310325386339464, + "32": 2.0310325386339465, + "34": 2.131032538633946, + "36": 2.231032538633946, + "38": 2.3310325386339454, + "40": 2.431032538633945, + "42": 2.5310325386339447, + "44": 2.6310325386339444, + "46": 2.731032538633944, + "48": 2.8310325386339437 + }, + "status": { + "0": 0, + "2": 1, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_29": { + "fstatus": { + "0": 0, + "2": 0, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.1073306046107562, + "2": 0.23733060461075622, + "4": 0.6373306046107565, + "6": 0.6373306046107565, + "8": 0.6373306046107565, + "10": 0.6373306046107565, + "12": 0.6373306046107565, + "14": 0.6373306046107565, + "16": 0.6373306046107565, + "18": 0.6373306046107565, + "20": 0.6373306046107565, + "22": 0.6373306046107565, + "24": 0.6373306046107565, + "26": 0.6373306046107565, + "28": 0.6373306046107565, + "30": 0.6373306046107565, + "32": 0.6373306046107565, + "34": 0.6373306046107565, + "36": 0.6373306046107565, + "38": 0.6373306046107565, + "40": 0.6373306046107565, + "42": 0.6373306046107565, + "44": 0.6373306046107565, + "46": 0.6373306046107565, + "48": 0.6373306046107565 + }, + "status": { + "0": 0, + "2": 0, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_3": { + "fstatus": { + "0": 0, + "2": 0, + "4": 1, + "6": 1, + "8": 1, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.047285269729742986, + "2": 0.187285269729743, + "4": 0.36728526972974307, + "6": 0.46728526972974305, + "8": 0.6072852697297432, + "10": 0.6572852697297432, + "12": 0.7072852697297433, + "14": 0.7572852697297433, + "16": 0.8072852697297433, + "18": 0.8572852697297434, + "20": 0.9072852697297434, + "22": 0.9572852697297435, + "24": 1.0072852697297434, + "26": 1.0572852697297435, + "28": 1.1072852697297435, + "30": 1.1572852697297435, + "32": 1.2072852697297436, + "34": 1.2572852697297436, + "36": 1.3072852697297437, + "38": 1.3572852697297437, + "40": 1.4072852697297438, + "42": 1.4572852697297438, + "44": 1.5072852697297439, + "46": 1.557285269729744, + "48": 1.607285269729744 + }, + "status": { + "0": 0, + "2": 0, + "4": 1, + "6": 1, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_30": { + "fstatus": { + "0": 1, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 1, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.4273553059276942, + "2": 0.4273553059276942, + "4": 0.4273553059276942, + "6": 0.4273553059276942, + "8": 0.4273553059276942, + "10": 0.4273553059276942, + "12": 0.46735530592769425, + "14": 0.5973553059276944, + "16": 0.6473553059276944, + "18": 0.6473553059276944, + "20": 0.6473553059276944, + "22": 0.6473553059276944, + "24": 0.6473553059276944, + "26": 0.6473553059276944, + "28": 0.6473553059276944, + "30": 0.6473553059276944, + "32": 0.6473553059276944, + "34": 0.6473553059276944, + "36": 0.6473553059276944, + "38": 0.6473553059276944, + "40": 0.6473553059276944, + "42": 0.6473553059276944, + "44": 0.6473553059276944, + "46": 0.6473553059276944, + "48": 0.6473553059276944 + }, + "status": { + "0": 1, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 1, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_31": { + "fstatus": { + "0": 1, + "2": 1, + "4": 1, + "6": 1, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.44001544543070764, + "2": 0.44001544543070764, + "4": 0.44001544543070764, + "6": 0.5200154454307077, + "8": 0.6800154454307078, + "10": 0.6800154454307078, + "12": 0.6800154454307078, + "14": 0.6800154454307078, + "16": 0.6800154454307078, + "18": 0.6800154454307078, + "20": 0.6800154454307078, + "22": 0.6800154454307078, + "24": 0.6800154454307078, + "26": 0.6800154454307078, + "28": 0.6800154454307078, + "30": 0.6800154454307078, + "32": 0.6800154454307078, + "34": 0.6800154454307078, + "36": 0.6800154454307078, + "38": 0.6800154454307078, + "40": 0.6800154454307078, + "42": 0.6800154454307078, + "44": 0.6800154454307078, + "46": 0.6800154454307078, + "48": 0.6800154454307078 + }, + "status": { + "0": 1, + "2": 1, + "4": 1, + "6": 1, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_32": { + "fstatus": { + "0": 1, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 1, + "16": 1, + "18": 1, + "20": 1, + "22": 1, + "24": 1, + "26": 1, + "28": 1, + "30": 1, + "32": 1, + "34": 1, + "36": 1, + "38": 1, + "40": 1, + "42": 1, + "44": 1, + "46": 1, + "48": 1 + }, + "radicalism": { + "0": 0.6037830407953667, + "2": 0.6037830407953667, + "4": 0.6037830407953667, + "6": 0.6037830407953667, + "8": 0.6037830407953667, + "10": 0.6037830407953667, + "12": 0.6037830407953667, + "14": 0.6037830407953667, + "16": 0.6037830407953667, + "18": 0.6037830407953667, + "20": 0.6037830407953667, + "22": 0.6037830407953667, + "24": 0.6037830407953667, + "26": 0.6037830407953667, + "28": 0.6037830407953667, + "30": 0.6037830407953667, + "32": 0.6037830407953667, + "34": 0.6037830407953667, + "36": 0.6037830407953667, + "38": 0.6037830407953667, + "40": 0.6037830407953667, + "42": 0.6037830407953667, + "44": 0.6037830407953667, + "46": 0.6037830407953667, + "48": 0.6037830407953667 + }, + "status": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_33": { + "fstatus": { + "0": 0, + "2": 1, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.1459504193482717, + "2": 0.5859504193482719, + "4": 0.685950419348272, + "6": 0.735950419348272, + "8": 0.785950419348272, + "10": 0.8359504193482721, + "12": 0.8859504193482721, + "14": 0.9359504193482722, + "16": 0.9859504193482722, + "18": 1.0359504193482723, + "20": 1.0859504193482723, + "22": 1.1359504193482723, + "24": 1.1859504193482724, + "26": 1.2359504193482724, + "28": 1.2859504193482725, + "30": 1.3359504193482725, + "32": 1.3859504193482726, + "34": 1.4359504193482726, + "36": 1.4859504193482727, + "38": 1.5359504193482727, + "40": 1.5859504193482727, + "42": 1.6359504193482728, + "44": 1.6859504193482728, + "46": 1.7359504193482729, + "48": 1.785950419348273 + }, + "status": { + "0": 0, + "2": 1, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_34": { + "fstatus": { + "0": 0, + "2": 0, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.14116155796065988, + "2": 0.2611615579606599, + "4": 0.4311615579606599, + "6": 0.64116155796066, + "8": 0.64116155796066, + "10": 0.64116155796066, + "12": 0.64116155796066, + "14": 0.64116155796066, + "16": 0.64116155796066, + "18": 0.64116155796066, + "20": 0.64116155796066, + "22": 0.64116155796066, + "24": 0.64116155796066, + "26": 0.64116155796066, + "28": 0.64116155796066, + "30": 0.64116155796066, + "32": 0.64116155796066, + "34": 0.64116155796066, + "36": 0.64116155796066, + "38": 0.64116155796066, + "40": 0.64116155796066, + "42": 0.64116155796066, + "44": 0.64116155796066, + "46": 0.64116155796066, + "48": 0.64116155796066 + }, + "status": { + "0": 0, + "2": 0, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_35": { + "fstatus": { + "0": 2, + "2": 6, + "4": 6, + "6": 6, + "8": 6, + "10": 6, + "12": 6, + "14": 6, + "16": 6, + "18": 6, + "20": 6, + "22": 6, + "24": 6, + "26": 6, + "28": 6, + "30": 6, + "32": 6, + "34": 6, + "36": 6, + "38": 6, + "40": 6, + "42": 6, + "44": 6, + "46": 6, + "48": 6 + }, + "radicalism": { + "0": 0.8381303094857427, + "2": 0.8881303094857428, + "4": 0.9381303094857428, + "6": 0.9881303094857429, + "8": 1.0381303094857428, + "10": 1.0881303094857429, + "12": 1.138130309485743, + "14": 1.188130309485743, + "16": 1.238130309485743, + "18": 1.288130309485743, + "20": 1.338130309485743, + "22": 1.3881303094857431, + "24": 1.4381303094857432, + "26": 1.4881303094857432, + "28": 1.5381303094857433, + "30": 1.5881303094857433, + "32": 1.6381303094857433, + "34": 1.6881303094857434, + "36": 1.7381303094857434, + "38": 1.7881303094857435, + "40": 1.8381303094857435, + "42": 1.8881303094857436, + "44": 1.9381303094857436, + "46": 1.9881303094857437, + "48": 2.0381303094857435 + }, + "status": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 1, + "16": 1, + "18": 1, + "20": 1, + "22": 1, + "24": 1, + "26": 1, + "28": 1, + "30": 1, + "32": 1, + "34": 1, + "36": 1, + "38": 1, + "40": 1, + "42": 1, + "44": 1, + "46": 1, + "48": 1 + } + }, + "agent_36": { + "fstatus": { + "0": 0, + "2": 0, + "4": 0, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.08025539747254315, + "2": 0.16025539747254317, + "4": 0.2802553974725432, + "6": 0.40025539747254324, + "8": 0.40025539747254324, + "10": 0.4402553974725433, + "12": 0.5602553974725434, + "14": 0.6802553974725435, + "16": 0.6802553974725435, + "18": 0.6802553974725435, + "20": 0.6802553974725435, + "22": 0.6802553974725435, + "24": 0.6802553974725435, + "26": 0.6802553974725435, + "28": 0.6802553974725435, + "30": 0.6802553974725435, + "32": 0.6802553974725435, + "34": 0.6802553974725435, + "36": 0.6802553974725435, + "38": 0.6802553974725435, + "40": 0.6802553974725435, + "42": 0.6802553974725435, + "44": 0.6802553974725435, + "46": 0.6802553974725435, + "48": 0.6802553974725435 + }, + "status": { + "0": 0, + "2": 0, + "4": 0, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_37": { + "fstatus": { + "0": 0, + "2": 0, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.10593058181753726, + "2": 0.25593058181753725, + "4": 0.48593058181753723, + "6": 0.6659305818175374, + "8": 0.7159305818175374, + "10": 0.7659305818175375, + "12": 0.8159305818175375, + "14": 0.8659305818175376, + "16": 0.9159305818175376, + "18": 0.9659305818175377, + "20": 1.0159305818175377, + "22": 1.0659305818175377, + "24": 1.1159305818175378, + "26": 1.1659305818175378, + "28": 1.2159305818175379, + "30": 1.265930581817538, + "32": 1.315930581817538, + "34": 1.365930581817538, + "36": 1.415930581817538, + "38": 1.465930581817538, + "40": 1.5159305818175381, + "42": 1.5659305818175382, + "44": 1.6159305818175382, + "46": 1.6659305818175383, + "48": 1.7159305818175383 + }, + "status": { + "0": 0, + "2": 0, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_38": { + "fstatus": { + "0": 1, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 6, + "16": 6, + "18": 6, + "20": 6, + "22": 6, + "24": 6, + "26": 6, + "28": 6, + "30": 6, + "32": 6, + "34": 6, + "36": 6, + "38": 6, + "40": 6, + "42": 6, + "44": 6, + "46": 6, + "48": 6 + }, + "radicalism": { + "0": 0.46738699576326936, + "2": 0.46738699576326936, + "4": 0.46738699576326936, + "6": 0.46738699576326936, + "8": 0.46738699576326936, + "10": 0.46738699576326936, + "12": 0.5473869957632694, + "14": 0.6273869957632695, + "16": 0.6273869957632695, + "18": 0.6273869957632695, + "20": 0.6273869957632695, + "22": 0.6273869957632695, + "24": 0.6273869957632695, + "26": 0.6273869957632695, + "28": 0.6273869957632695, + "30": 0.6273869957632695, + "32": 0.6273869957632695, + "34": 0.6273869957632695, + "36": 0.6273869957632695, + "38": 0.6273869957632695, + "40": 0.6273869957632695, + "42": 0.6273869957632695, + "44": 0.6273869957632695, + "46": 0.6273869957632695, + "48": 0.6273869957632695 + }, + "status": { + "0": 1, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 1, + "16": 1, + "18": 1, + "20": 1, + "22": 1, + "24": 1, + "26": 1, + "28": 1, + "30": 1, + "32": 1, + "34": 1, + "36": 1, + "38": 1, + "40": 1, + "42": 1, + "44": 1, + "46": 1, + "48": 1 + } + }, + "agent_39": { + "fstatus": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.9099735008069635, + "2": 0.9599735008069635, + "4": 1.0099735008069635, + "6": 1.0599735008069635, + "8": 1.1099735008069636, + "10": 1.1599735008069636, + "12": 1.2099735008069636, + "14": 1.2599735008069637, + "16": 1.3099735008069637, + "18": 1.3599735008069638, + "20": 1.4099735008069638, + "22": 1.4599735008069639, + "24": 1.509973500806964, + "26": 1.559973500806964, + "28": 1.609973500806964, + "30": 1.659973500806964, + "32": 1.709973500806964, + "34": 1.7599735008069641, + "36": 1.8099735008069642, + "38": 1.8599735008069642, + "40": 1.9099735008069643, + "42": 1.9599735008069643, + "44": 2.0099735008069644, + "46": 2.059973500806964, + "48": 2.109973500806964 + }, + "status": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_4": { + "fstatus": { + "0": 2, + "2": 6, + "4": 6, + "6": 6, + "8": 6, + "10": 6, + "12": 6, + "14": 6, + "16": 6, + "18": 6, + "20": 6, + "22": 6, + "24": 6, + "26": 6, + "28": 6, + "30": 6, + "32": 6, + "34": 6, + "36": 6, + "38": 6, + "40": 6, + "42": 6, + "44": 6, + "46": 6, + "48": 6 + }, + "radicalism": { + "0": 0.9144186686474172, + "2": 0.9644186686474172, + "4": 1.0144186686474173, + "6": 1.0644186686474173, + "8": 1.1144186686474173, + "10": 1.1644186686474174, + "12": 1.2144186686474174, + "14": 1.2644186686474175, + "16": 1.3144186686474175, + "18": 1.3644186686474176, + "20": 1.4144186686474176, + "22": 1.4644186686474177, + "24": 1.5144186686474177, + "26": 1.5644186686474177, + "28": 1.6144186686474178, + "30": 1.6644186686474178, + "32": 1.7144186686474179, + "34": 1.764418668647418, + "36": 1.814418668647418, + "38": 1.864418668647418, + "40": 1.914418668647418, + "42": 1.964418668647418, + "44": 2.014418668647418, + "46": 2.0644186686474177, + "48": 2.1144186686474176 + }, + "status": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 1, + "16": 1, + "18": 1, + "20": 1, + "22": 1, + "24": 1, + "26": 1, + "28": 1, + "30": 1, + "32": 1, + "34": 1, + "36": 1, + "38": 1, + "40": 1, + "42": 1, + "44": 1, + "46": 1, + "48": 1 + } + }, + "agent_40": { + "fstatus": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.9071008191179996, + "2": 0.9071008191179996, + "4": 0.9071008191179996, + "6": 0.9071008191179996, + "8": 0.9071008191179996, + "10": 0.9071008191179996, + "12": 0.9071008191179996, + "14": 0.9071008191179996, + "16": 0.9071008191179996, + "18": 0.9071008191179996, + "20": 0.9071008191179996, + "22": 0.9071008191179996, + "24": 0.9071008191179996, + "26": 0.9071008191179996, + "28": 0.9071008191179996, + "30": 0.9071008191179996, + "32": 0.9071008191179996, + "34": 0.9071008191179996, + "36": 0.9071008191179996, + "38": 0.9071008191179996, + "40": 0.9071008191179996, + "42": 0.9071008191179996, + "44": 0.9071008191179996, + "46": 0.9071008191179996, + "48": 0.9071008191179996 + }, + "status": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_41": { + "fstatus": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 1, + "14": 1, + "16": 1, + "18": 1, + "20": 1, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.07208782098570736, + "2": 0.11208782098570737, + "4": 0.1520878209857074, + "6": 0.1920878209857074, + "8": 0.2320878209857074, + "10": 0.2720878209857074, + "12": 0.4320878209857075, + "14": 0.47208782098570756, + "16": 0.5120878209857076, + "18": 0.5520878209857076, + "20": 0.5920878209857077, + "22": 0.6320878209857077, + "24": 0.6320878209857077, + "26": 0.6320878209857077, + "28": 0.6320878209857077, + "30": 0.6320878209857077, + "32": 0.6320878209857077, + "34": 0.6320878209857077, + "36": 0.6320878209857077, + "38": 0.6320878209857077, + "40": 0.6320878209857077, + "42": 0.6320878209857077, + "44": 0.6320878209857077, + "46": 0.6320878209857077, + "48": 0.6320878209857077 + }, + "status": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 1, + "14": 1, + "16": 1, + "18": 1, + "20": 1, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_42": { + "fstatus": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.8012677533614061, + "2": 0.8012677533614061, + "4": 0.8012677533614061, + "6": 0.8012677533614061, + "8": 0.8012677533614061, + "10": 0.8012677533614061, + "12": 0.8012677533614061, + "14": 0.8012677533614061, + "16": 0.8012677533614061, + "18": 0.8012677533614061, + "20": 0.8012677533614061, + "22": 0.8012677533614061, + "24": 0.8012677533614061, + "26": 0.8012677533614061, + "28": 0.8012677533614061, + "30": 0.8012677533614061, + "32": 0.8012677533614061, + "34": 0.8012677533614061, + "36": 0.8012677533614061, + "38": 0.8012677533614061, + "40": 0.8012677533614061, + "42": 0.8012677533614061, + "44": 0.8012677533614061, + "46": 0.8012677533614061, + "48": 0.8012677533614061 + }, + "status": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_43": { + "fstatus": { + "0": 0, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.2135570742174386, + "2": 0.37355707421743867, + "4": 0.37355707421743867, + "6": 0.45355707421743874, + "8": 0.5735570742174388, + "10": 0.773557074217439, + "12": 0.773557074217439, + "14": 0.773557074217439, + "16": 0.773557074217439, + "18": 0.773557074217439, + "20": 0.773557074217439, + "22": 0.773557074217439, + "24": 0.773557074217439, + "26": 0.773557074217439, + "28": 0.773557074217439, + "30": 0.773557074217439, + "32": 0.773557074217439, + "34": 0.773557074217439, + "36": 0.773557074217439, + "38": 0.773557074217439, + "40": 0.773557074217439, + "42": 0.773557074217439, + "44": 0.773557074217439, + "46": 0.773557074217439, + "48": 0.773557074217439 + }, + "status": { + "0": 0, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_44": { + "fstatus": { + "0": 1, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.47419476080421896, + "2": 0.47419476080421896, + "4": 0.47419476080421896, + "6": 0.514194760804219, + "8": 0.5941947608042191, + "10": 0.7541947608042192, + "12": 0.7541947608042192, + "14": 0.7541947608042192, + "16": 0.7541947608042192, + "18": 0.7541947608042192, + "20": 0.7541947608042192, + "22": 0.7541947608042192, + "24": 0.7541947608042192, + "26": 0.7541947608042192, + "28": 0.7541947608042192, + "30": 0.7541947608042192, + "32": 0.7541947608042192, + "34": 0.7541947608042192, + "36": 0.7541947608042192, + "38": 0.7541947608042192, + "40": 0.7541947608042192, + "42": 0.7541947608042192, + "44": 0.7541947608042192, + "46": 0.7541947608042192, + "48": 0.7541947608042192 + }, + "status": { + "0": 1, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_45": { + "fstatus": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.9115481906248958, + "2": 0.9115481906248958, + "4": 0.9115481906248958, + "6": 0.9115481906248958, + "8": 0.9115481906248958, + "10": 0.9115481906248958, + "12": 0.9115481906248958, + "14": 0.9115481906248958, + "16": 0.9115481906248958, + "18": 0.9115481906248958, + "20": 0.9115481906248958, + "22": 0.9115481906248958, + "24": 0.9115481906248958, + "26": 0.9115481906248958, + "28": 0.9115481906248958, + "30": 0.9115481906248958, + "32": 0.9115481906248958, + "34": 0.9115481906248958, + "36": 0.9115481906248958, + "38": 0.9115481906248958, + "40": 0.9115481906248958, + "42": 0.9115481906248958, + "44": 0.9115481906248958, + "46": 0.9115481906248958, + "48": 0.9115481906248958 + }, + "status": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_46": { + "fstatus": { + "0": 0, + "2": 1, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.1870712881496192, + "2": 0.4470712881496193, + "4": 0.49707128814961926, + "6": 0.6770712881496194, + "8": 0.7270712881496194, + "10": 0.7770712881496195, + "12": 0.8270712881496195, + "14": 0.8770712881496195, + "16": 0.9270712881496196, + "18": 0.9770712881496196, + "20": 1.0270712881496196, + "22": 1.0770712881496196, + "24": 1.1270712881496197, + "26": 1.1770712881496197, + "28": 1.2270712881496197, + "30": 1.2770712881496198, + "32": 1.3270712881496198, + "34": 1.3770712881496199, + "36": 1.42707128814962, + "38": 1.47707128814962, + "40": 1.52707128814962, + "42": 1.57707128814962, + "44": 1.62707128814962, + "46": 1.6770712881496201, + "48": 1.7270712881496202 + }, + "status": { + "0": 0, + "2": 1, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_47": { + "fstatus": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 1, + "12": 1, + "14": 1, + "16": 1, + "18": 1, + "20": 1, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.10203104630475306, + "2": 0.14203104630475305, + "4": 0.18203104630475306, + "6": 0.22203104630475307, + "8": 0.26203104630475305, + "10": 0.3420310463047531, + "12": 0.38203104630475315, + "14": 0.4220310463047532, + "16": 0.4620310463047532, + "18": 0.5020310463047533, + "20": 0.5420310463047533, + "22": 0.6220310463047534, + "24": 0.6220310463047534, + "26": 0.6220310463047534, + "28": 0.6220310463047534, + "30": 0.6220310463047534, + "32": 0.6220310463047534, + "34": 0.6220310463047534, + "36": 0.6220310463047534, + "38": 0.6220310463047534, + "40": 0.6220310463047534, + "42": 0.6220310463047534, + "44": 0.6220310463047534, + "46": 0.6220310463047534, + "48": 0.6220310463047534 + }, + "status": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 1, + "12": 1, + "14": 1, + "16": 1, + "18": 1, + "20": 1, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_48": { + "fstatus": { + "0": 1, + "2": 1, + "4": 1, + "6": 1, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.4550316561417992, + "2": 0.5050316561417992, + "4": 0.5550316561417993, + "6": 0.6050316561417993, + "8": 0.6550316561417994, + "10": 0.7050316561417994, + "12": 0.7550316561417995, + "14": 0.8050316561417995, + "16": 0.8550316561417995, + "18": 0.9050316561417996, + "20": 0.9550316561417996, + "22": 1.0050316561417996, + "24": 1.0550316561417996, + "26": 1.1050316561417997, + "28": 1.1550316561417997, + "30": 1.2050316561417997, + "32": 1.2550316561417998, + "34": 1.3050316561417998, + "36": 1.3550316561417999, + "38": 1.4050316561418, + "40": 1.4550316561418, + "42": 1.5050316561418, + "44": 1.5550316561418, + "46": 1.6050316561418, + "48": 1.6550316561418001 + }, + "status": { + "0": 1, + "2": 1, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_49": { + "fstatus": { + "0": 0, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 1, + "16": 1, + "18": 1, + "20": 1, + "22": 1, + "24": 1, + "26": 1, + "28": 1, + "30": 1, + "32": 1, + "34": 1, + "36": 1, + "38": 1, + "40": 1, + "42": 1, + "44": 1, + "46": 1, + "48": 1 + }, + "radicalism": { + "0": 0.1418817100709423, + "2": 0.30188171007094233, + "4": 0.30188171007094233, + "6": 0.47188171007094243, + "8": 0.6418817100709425, + "10": 0.6418817100709425, + "12": 0.6418817100709425, + "14": 0.6418817100709425, + "16": 0.6418817100709425, + "18": 0.6418817100709425, + "20": 0.6418817100709425, + "22": 0.6418817100709425, + "24": 0.6418817100709425, + "26": 0.6418817100709425, + "28": 0.6418817100709425, + "30": 0.6418817100709425, + "32": 0.6418817100709425, + "34": 0.6418817100709425, + "36": 0.6418817100709425, + "38": 0.6418817100709425, + "40": 0.6418817100709425, + "42": 0.6418817100709425, + "44": 0.6418817100709425, + "46": 0.6418817100709425, + "48": 0.6418817100709425 + }, + "status": { + "0": 0, + "2": 1, + "4": 1, + "6": 1, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_5": { + "fstatus": { + "0": 0, + "2": 1, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.17076584445991447, + "2": 0.47076584445991443, + "4": 0.6907658444599146, + "6": 0.7407658444599147, + "8": 0.7907658444599147, + "10": 0.8407658444599148, + "12": 0.8907658444599148, + "14": 0.9407658444599148, + "16": 0.9907658444599149, + "18": 1.0407658444599148, + "20": 1.0907658444599149, + "22": 1.140765844459915, + "24": 1.190765844459915, + "26": 1.240765844459915, + "28": 1.290765844459915, + "30": 1.340765844459915, + "32": 1.3907658444599151, + "34": 1.4407658444599152, + "36": 1.4907658444599152, + "38": 1.5407658444599153, + "40": 1.5907658444599153, + "42": 1.6407658444599154, + "44": 1.6907658444599154, + "46": 1.7407658444599154, + "48": 1.7907658444599155 + }, + "status": { + "0": 0, + "2": 1, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_50": { + "fstatus": { + "0": 1, + "2": 1, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.48426647620251495, + "2": 0.534266476202515, + "4": 0.584266476202515, + "6": 0.6342664762025151, + "8": 0.6842664762025151, + "10": 0.7342664762025152, + "12": 0.7842664762025152, + "14": 0.8342664762025153, + "16": 0.8842664762025153, + "18": 0.9342664762025154, + "20": 0.9842664762025154, + "22": 1.0342664762025153, + "24": 1.0842664762025154, + "26": 1.1342664762025154, + "28": 1.1842664762025155, + "30": 1.2342664762025155, + "32": 1.2842664762025156, + "34": 1.3342664762025156, + "36": 1.3842664762025156, + "38": 1.4342664762025157, + "40": 1.4842664762025157, + "42": 1.5342664762025158, + "44": 1.5842664762025158, + "46": 1.6342664762025159, + "48": 1.684266476202516 + }, + "status": { + "0": 1, + "2": 1, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_51": { + "fstatus": { + "0": 0, + "2": 0, + "4": 1, + "6": 1, + "8": 6, + "10": 6, + "12": 6, + "14": 6, + "16": 6, + "18": 6, + "20": 6, + "22": 6, + "24": 6, + "26": 6, + "28": 6, + "30": 6, + "32": 6, + "34": 6, + "36": 6, + "38": 6, + "40": 6, + "42": 6, + "44": 6, + "46": 6, + "48": 6 + }, + "radicalism": { + "0": 0.09841082606620145, + "2": 0.2784108260662015, + "4": 0.4184108260662015, + "6": 0.5884108260662015, + "8": 0.6384108260662016, + "10": 0.6884108260662016, + "12": 0.7384108260662017, + "14": 0.7884108260662017, + "16": 0.8384108260662018, + "18": 0.8884108260662018, + "20": 0.9384108260662019, + "22": 0.9884108260662019, + "24": 1.038410826066202, + "26": 1.088410826066202, + "28": 1.138410826066202, + "30": 1.188410826066202, + "32": 1.2384108260662021, + "34": 1.2884108260662022, + "36": 1.3384108260662022, + "38": 1.3884108260662023, + "40": 1.4384108260662023, + "42": 1.4884108260662023, + "44": 1.5384108260662024, + "46": 1.5884108260662024, + "48": 1.6384108260662025 + }, + "status": { + "0": 0, + "2": 0, + "4": 1, + "6": 1, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 1, + "10": 1, + "12": 1, + "14": 1, + "16": 1, + "18": 1, + "20": 1, + "22": 1, + "24": 1, + "26": 1, + "28": 1, + "30": 1, + "32": 1, + "34": 1, + "36": 1, + "38": 1, + "40": 1, + "42": 1, + "44": 1, + "46": 1, + "48": 1 + } + }, + "agent_52": { + "fstatus": { + "0": 0, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 1, + "16": 1, + "18": 1, + "20": 1, + "22": 1, + "24": 1, + "26": 1, + "28": 1, + "30": 1, + "32": 1, + "34": 1, + "36": 1, + "38": 1, + "40": 1, + "42": 1, + "44": 1, + "46": 1, + "48": 1 + }, + "radicalism": { + "0": 0.2045787959553396, + "2": 0.3645787959553397, + "4": 0.3645787959553397, + "6": 0.3645787959553397, + "8": 0.3645787959553397, + "10": 0.4845787959553398, + "12": 0.6045787959553399, + "14": 0.6045787959553399, + "16": 0.6045787959553399, + "18": 0.6045787959553399, + "20": 0.6045787959553399, + "22": 0.6045787959553399, + "24": 0.6045787959553399, + "26": 0.6045787959553399, + "28": 0.6045787959553399, + "30": 0.6045787959553399, + "32": 0.6045787959553399, + "34": 0.6045787959553399, + "36": 0.6045787959553399, + "38": 0.6045787959553399, + "40": 0.6045787959553399, + "42": 0.6045787959553399, + "44": 0.6045787959553399, + "46": 0.6045787959553399, + "48": 0.6045787959553399 + }, + "status": { + "0": 0, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 1, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_53": { + "fstatus": { + "0": 0, + "2": 0, + "4": 1, + "6": 1, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.14924101157973158, + "2": 0.26924101157973157, + "4": 0.46924101157973175, + "6": 0.5992410115797319, + "8": 0.729241011579732, + "10": 0.729241011579732, + "12": 0.729241011579732, + "14": 0.729241011579732, + "16": 0.729241011579732, + "18": 0.729241011579732, + "20": 0.729241011579732, + "22": 0.729241011579732, + "24": 0.729241011579732, + "26": 0.729241011579732, + "28": 0.729241011579732, + "30": 0.729241011579732, + "32": 0.729241011579732, + "34": 0.729241011579732, + "36": 0.729241011579732, + "38": 0.729241011579732, + "40": 0.729241011579732, + "42": 0.729241011579732, + "44": 0.729241011579732, + "46": 0.729241011579732, + "48": 0.729241011579732 + }, + "status": { + "0": 0, + "2": 0, + "4": 1, + "6": 1, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_54": { + "fstatus": { + "0": 0, + "2": 1, + "4": 1, + "6": 1, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.210222866132391, + "2": 0.4102228661323911, + "4": 0.4102228661323911, + "6": 0.5402228661323912, + "8": 0.7102228661323914, + "10": 0.7102228661323914, + "12": 0.7102228661323914, + "14": 0.7102228661323914, + "16": 0.7102228661323914, + "18": 0.7102228661323914, + "20": 0.7102228661323914, + "22": 0.7102228661323914, + "24": 0.7102228661323914, + "26": 0.7102228661323914, + "28": 0.7102228661323914, + "30": 0.7102228661323914, + "32": 0.7102228661323914, + "34": 0.7102228661323914, + "36": 0.7102228661323914, + "38": 0.7102228661323914, + "40": 0.7102228661323914, + "42": 0.7102228661323914, + "44": 0.7102228661323914, + "46": 0.7102228661323914, + "48": 0.7102228661323914 + }, + "status": { + "0": 0, + "2": 1, + "4": 1, + "6": 1, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_55": { + "fstatus": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 1, + "12": 1, + "14": 1, + "16": 1, + "18": 1, + "20": 1, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.07876429836418261, + "2": 0.11876429836418262, + "4": 0.15876429836418263, + "6": 0.19876429836418263, + "8": 0.23876429836418264, + "10": 0.35876429836418267, + "12": 0.3987642983641827, + "14": 0.43876429836418274, + "16": 0.47876429836418277, + "18": 0.5187642983641828, + "20": 0.5587642983641828, + "22": 0.678764298364183, + "24": 0.678764298364183, + "26": 0.678764298364183, + "28": 0.678764298364183, + "30": 0.678764298364183, + "32": 0.678764298364183, + "34": 0.678764298364183, + "36": 0.678764298364183, + "38": 0.678764298364183, + "40": 0.678764298364183, + "42": 0.678764298364183, + "44": 0.678764298364183, + "46": 0.678764298364183, + "48": 0.678764298364183 + }, + "status": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 1, + "12": 1, + "14": 1, + "16": 1, + "18": 1, + "20": 1, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_56": { + "fstatus": { + "0": 0, + "2": 1, + "4": 1, + "6": 1, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.10868148079493808, + "2": 0.3086814807949382, + "4": 0.3086814807949382, + "6": 0.4786814807949383, + "8": 0.7286814807949384, + "10": 0.7286814807949384, + "12": 0.7286814807949384, + "14": 0.7286814807949384, + "16": 0.7286814807949384, + "18": 0.7286814807949384, + "20": 0.7286814807949384, + "22": 0.7286814807949384, + "24": 0.7286814807949384, + "26": 0.7286814807949384, + "28": 0.7286814807949384, + "30": 0.7286814807949384, + "32": 0.7286814807949384, + "34": 0.7286814807949384, + "36": 0.7286814807949384, + "38": 0.7286814807949384, + "40": 0.7286814807949384, + "42": 0.7286814807949384, + "44": 0.7286814807949384, + "46": 0.7286814807949384, + "48": 0.7286814807949384 + }, + "status": { + "0": 0, + "2": 1, + "4": 1, + "6": 1, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_57": { + "fstatus": { + "0": 0, + "2": 1, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.12374461206401023, + "2": 0.38374461206401034, + "4": 0.5937446120640104, + "6": 0.6437446120640105, + "8": 0.6937446120640105, + "10": 0.7437446120640105, + "12": 0.7937446120640106, + "14": 0.8437446120640106, + "16": 0.8937446120640107, + "18": 0.9437446120640107, + "20": 0.9937446120640108, + "22": 1.0437446120640108, + "24": 1.0937446120640109, + "26": 1.143744612064011, + "28": 1.193744612064011, + "30": 1.243744612064011, + "32": 1.293744612064011, + "34": 1.343744612064011, + "36": 1.3937446120640111, + "38": 1.4437446120640112, + "40": 1.4937446120640112, + "42": 1.5437446120640113, + "44": 1.5937446120640113, + "46": 1.6437446120640113, + "48": 1.6937446120640114 + }, + "status": { + "0": 0, + "2": 1, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_58": { + "fstatus": { + "0": 0, + "2": 1, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.19972453589217024, + "2": 0.5997245358921705, + "4": 0.6497245358921705, + "6": 0.6997245358921705, + "8": 0.7497245358921706, + "10": 0.7997245358921706, + "12": 0.8497245358921707, + "14": 0.8997245358921707, + "16": 0.9497245358921708, + "18": 0.9997245358921708, + "20": 1.0497245358921707, + "22": 1.0997245358921708, + "24": 1.1497245358921708, + "26": 1.1997245358921709, + "28": 1.249724535892171, + "30": 1.299724535892171, + "32": 1.349724535892171, + "34": 1.399724535892171, + "36": 1.449724535892171, + "38": 1.4997245358921711, + "40": 1.5497245358921712, + "42": 1.5997245358921712, + "44": 1.6497245358921713, + "46": 1.6997245358921713, + "48": 1.7497245358921714 + }, + "status": { + "0": 0, + "2": 1, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_59": { + "fstatus": { + "0": 0, + "2": 1, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.13149999666239542, + "2": 0.5714999966623956, + "4": 0.6214999966623956, + "6": 0.6714999966623957, + "8": 0.7214999966623957, + "10": 0.7714999966623958, + "12": 0.8214999966623958, + "14": 0.8714999966623959, + "16": 0.9214999966623959, + "18": 0.971499996662396, + "20": 1.0214999966623959, + "22": 1.071499996662396, + "24": 1.121499996662396, + "26": 1.171499996662396, + "28": 1.221499996662396, + "30": 1.271499996662396, + "32": 1.3214999966623961, + "34": 1.3714999966623962, + "36": 1.4214999966623962, + "38": 1.4714999966623963, + "40": 1.5214999966623963, + "42": 1.5714999966623964, + "44": 1.6214999966623964, + "46": 1.6714999966623965, + "48": 1.7214999966623965 + }, + "status": { + "0": 0, + "2": 1, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_6": { + "fstatus": { + "0": 0, + "2": 1, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.20277444106244377, + "2": 0.4427744410624439, + "4": 0.562774441062444, + "6": 0.6827744410624441, + "8": 0.6827744410624441, + "10": 0.6827744410624441, + "12": 0.6827744410624441, + "14": 0.6827744410624441, + "16": 0.6827744410624441, + "18": 0.6827744410624441, + "20": 0.6827744410624441, + "22": 0.6827744410624441, + "24": 0.6827744410624441, + "26": 0.6827744410624441, + "28": 0.6827744410624441, + "30": 0.6827744410624441, + "32": 0.6827744410624441, + "34": 0.6827744410624441, + "36": 0.6827744410624441, + "38": 0.6827744410624441, + "40": 0.6827744410624441, + "42": 0.6827744410624441, + "44": 0.6827744410624441, + "46": 0.6827744410624441, + "48": 0.6827744410624441 + }, + "status": { + "0": 0, + "2": 1, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 1, + "16": 1, + "18": 1, + "20": 1, + "22": 1, + "24": 1, + "26": 1, + "28": 1, + "30": 1, + "32": 1, + "34": 1, + "36": 1, + "38": 1, + "40": 1, + "42": 1, + "44": 1, + "46": 1, + "48": 1 + } + }, + "agent_60": { + "fstatus": { + "0": 0, + "2": 0, + "4": 0, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 1, + "16": 1, + "18": 1, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.0723130801985715, + "2": 0.1523130801985715, + "4": 0.23231308019857153, + "6": 0.3123130801985715, + "8": 0.3123130801985715, + "10": 0.3123130801985715, + "12": 0.35231308019857155, + "14": 0.3923130801985716, + "16": 0.47231308019857166, + "18": 0.5523130801985717, + "20": 0.6723130801985718, + "22": 0.6723130801985718, + "24": 0.6723130801985718, + "26": 0.6723130801985718, + "28": 0.6723130801985718, + "30": 0.6723130801985718, + "32": 0.6723130801985718, + "34": 0.6723130801985718, + "36": 0.6723130801985718, + "38": 0.6723130801985718, + "40": 0.6723130801985718, + "42": 0.6723130801985718, + "44": 0.6723130801985718, + "46": 0.6723130801985718, + "48": 0.6723130801985718 + }, + "status": { + "0": 0, + "2": 0, + "4": 0, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 1, + "16": 1, + "18": 1, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_61": { + "fstatus": { + "0": 0, + "2": 0, + "4": 0, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 1, + "16": 1, + "18": 1, + "20": 1, + "22": 1, + "24": 1, + "26": 1, + "28": 1, + "30": 1, + "32": 1, + "34": 1, + "36": 1, + "38": 1, + "40": 1, + "42": 1, + "44": 1, + "46": 1, + "48": 1 + }, + "radicalism": { + "0": 0.1158717620741975, + "2": 0.19587176207419751, + "4": 0.2758717620741975, + "6": 0.3958717620741976, + "8": 0.3958717620741976, + "10": 0.3958717620741976, + "12": 0.3958717620741976, + "14": 0.4458717620741976, + "16": 0.5358717620741976, + "18": 0.6258717620741977, + "20": 0.6258717620741977, + "22": 0.6258717620741977, + "24": 0.6258717620741977, + "26": 0.6258717620741977, + "28": 0.6258717620741977, + "30": 0.6258717620741977, + "32": 0.6258717620741977, + "34": 0.6258717620741977, + "36": 0.6258717620741977, + "38": 0.6258717620741977, + "40": 0.6258717620741977, + "42": 0.6258717620741977, + "44": 0.6258717620741977, + "46": 0.6258717620741977, + "48": 0.6258717620741977 + }, + "status": { + "0": 0, + "2": 0, + "4": 0, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 1, + "16": 1, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_62": { + "fstatus": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.8761471650735113, + "2": 0.8761471650735113, + "4": 0.8761471650735113, + "6": 0.8761471650735113, + "8": 0.8761471650735113, + "10": 0.8761471650735113, + "12": 0.8761471650735113, + "14": 0.8761471650735113, + "16": 0.8761471650735113, + "18": 0.8761471650735113, + "20": 0.8761471650735113, + "22": 0.8761471650735113, + "24": 0.8761471650735113, + "26": 0.8761471650735113, + "28": 0.8761471650735113, + "30": 0.8761471650735113, + "32": 0.8761471650735113, + "34": 0.8761471650735113, + "36": 0.8761471650735113, + "38": 0.8761471650735113, + "40": 0.8761471650735113, + "42": 0.8761471650735113, + "44": 0.8761471650735113, + "46": 0.8761471650735113, + "48": 0.8761471650735113 + }, + "status": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_63": { + "fstatus": { + "0": 0, + "2": 1, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.08870479044734575, + "2": 0.5887047904473458, + "4": 0.6887047904473459, + "6": 0.788704790447346, + "8": 0.8887047904473461, + "10": 0.9887047904473462, + "12": 1.0887047904473461, + "14": 1.1887047904473462, + "16": 1.2887047904473463, + "18": 1.3887047904473464, + "20": 1.4887047904473465, + "22": 1.5887047904473466, + "24": 1.6887047904473467, + "26": 1.7887047904473468, + "28": 1.8887047904473468, + "30": 1.988704790447347, + "32": 2.0887047904473466, + "34": 2.1887047904473462, + "36": 2.288704790447346, + "38": 2.3887047904473455, + "40": 2.488704790447345, + "42": 2.588704790447345, + "44": 2.6887047904473445, + "46": 2.788704790447344, + "48": 2.8887047904473437 + }, + "status": { + "0": 0, + "2": 1, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_64": { + "fstatus": { + "0": 0, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 1, + "16": 1, + "18": 1, + "20": 1, + "22": 1, + "24": 1, + "26": 1, + "28": 1, + "30": 1, + "32": 1, + "34": 1, + "36": 1, + "38": 1, + "40": 1, + "42": 1, + "44": 1, + "46": 1, + "48": 1 + }, + "radicalism": { + "0": 0.23881783978080057, + "2": 0.6188178397808007, + "4": 0.6188178397808007, + "6": 0.6188178397808007, + "8": 0.6188178397808007, + "10": 0.6188178397808007, + "12": 0.6188178397808007, + "14": 0.6188178397808007, + "16": 0.6188178397808007, + "18": 0.6188178397808007, + "20": 0.6188178397808007, + "22": 0.6188178397808007, + "24": 0.6188178397808007, + "26": 0.6188178397808007, + "28": 0.6188178397808007, + "30": 0.6188178397808007, + "32": 0.6188178397808007, + "34": 0.6188178397808007, + "36": 0.6188178397808007, + "38": 0.6188178397808007, + "40": 0.6188178397808007, + "42": 0.6188178397808007, + "44": 0.6188178397808007, + "46": 0.6188178397808007, + "48": 0.6188178397808007 + }, + "status": { + "0": 0, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_65": { + "fstatus": { + "0": 1, + "2": 1, + "4": 1, + "6": 6, + "8": 6, + "10": 6, + "12": 6, + "14": 6, + "16": 6, + "18": 6, + "20": 6, + "22": 6, + "24": 6, + "26": 6, + "28": 6, + "30": 6, + "32": 6, + "34": 6, + "36": 6, + "38": 6, + "40": 6, + "42": 6, + "44": 6, + "46": 6, + "48": 6 + }, + "radicalism": { + "0": 0.49191295321098594, + "2": 0.541912953210986, + "4": 0.591912953210986, + "6": 0.6419129532109861, + "8": 0.6919129532109861, + "10": 0.7419129532109862, + "12": 0.7919129532109862, + "14": 0.8419129532109862, + "16": 0.8919129532109863, + "18": 0.9419129532109863, + "20": 0.9919129532109864, + "22": 1.0419129532109863, + "24": 1.0919129532109864, + "26": 1.1419129532109864, + "28": 1.1919129532109864, + "30": 1.2419129532109865, + "32": 1.2919129532109865, + "34": 1.3419129532109866, + "36": 1.3919129532109866, + "38": 1.4419129532109867, + "40": 1.4919129532109867, + "42": 1.5419129532109868, + "44": 1.5919129532109868, + "46": 1.6419129532109868, + "48": 1.691912953210987 + }, + "status": { + "0": 1, + "2": 1, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 1, + "16": 1, + "18": 1, + "20": 1, + "22": 1, + "24": 1, + "26": 1, + "28": 1, + "30": 1, + "32": 1, + "34": 1, + "36": 1, + "38": 1, + "40": 1, + "42": 1, + "44": 1, + "46": 1, + "48": 1 + } + }, + "agent_66": { + "fstatus": { + "0": 0, + "2": 0, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.17466451403307784, + "2": 0.2946645140330779, + "4": 0.5346645140330781, + "6": 0.6546645140330782, + "8": 0.6546645140330782, + "10": 0.6546645140330782, + "12": 0.6546645140330782, + "14": 0.6546645140330782, + "16": 0.6546645140330782, + "18": 0.6546645140330782, + "20": 0.6546645140330782, + "22": 0.6546645140330782, + "24": 0.6546645140330782, + "26": 0.6546645140330782, + "28": 0.6546645140330782, + "30": 0.6546645140330782, + "32": 0.6546645140330782, + "34": 0.6546645140330782, + "36": 0.6546645140330782, + "38": 0.6546645140330782, + "40": 0.6546645140330782, + "42": 0.6546645140330782, + "44": 0.6546645140330782, + "46": 0.6546645140330782, + "48": 0.6546645140330782 + }, + "status": { + "0": 0, + "2": 0, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_67": { + "fstatus": { + "0": 0, + "2": 1, + "4": 1, + "6": 1, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.12985201337204827, + "2": 0.40985201337204835, + "4": 0.40985201337204835, + "6": 0.5398520133720484, + "8": 0.7898520133720486, + "10": 0.7898520133720486, + "12": 0.7898520133720486, + "14": 0.7898520133720486, + "16": 0.7898520133720486, + "18": 0.7898520133720486, + "20": 0.7898520133720486, + "22": 0.7898520133720486, + "24": 0.7898520133720486, + "26": 0.7898520133720486, + "28": 0.7898520133720486, + "30": 0.7898520133720486, + "32": 0.7898520133720486, + "34": 0.7898520133720486, + "36": 0.7898520133720486, + "38": 0.7898520133720486, + "40": 0.7898520133720486, + "42": 0.7898520133720486, + "44": 0.7898520133720486, + "46": 0.7898520133720486, + "48": 0.7898520133720486 + }, + "status": { + "0": 0, + "2": 1, + "4": 1, + "6": 1, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_68": { + "fstatus": { + "0": 3, + "2": 3, + "4": 3, + "6": 3, + "8": 3, + "10": 3, + "12": 3, + "14": 3, + "16": 3, + "18": 3, + "20": 3, + "22": 3, + "24": 3, + "26": 3, + "28": 3, + "30": 3, + "32": 3, + "34": 3, + "36": 3, + "38": 3, + "40": 3, + "42": 3, + "44": 3, + "46": 3, + "48": 3 + }, + "radicalism": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + }, + "status": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + }, + "type": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + } + }, + "agent_69": { + "fstatus": { + "0": 3, + "2": 3, + "4": 3, + "6": 3, + "8": 3, + "10": 3, + "12": 3, + "14": 3, + "16": 3, + "18": 3, + "20": 3, + "22": 3, + "24": 3, + "26": 3, + "28": 3, + "30": 3, + "32": 3, + "34": 3, + "36": 3, + "38": 3, + "40": 3, + "42": 3, + "44": 3, + "46": 3, + "48": 3 + }, + "radicalism": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + }, + "status": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + }, + "type": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + } + }, + "agent_7": { + "fstatus": { + "0": 1, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.47987486574034277, + "2": 0.47987486574034277, + "4": 0.47987486574034277, + "6": 0.47987486574034277, + "8": 0.5598748657403428, + "10": 0.759874865740343, + "12": 0.759874865740343, + "14": 0.759874865740343, + "16": 0.759874865740343, + "18": 0.759874865740343, + "20": 0.759874865740343, + "22": 0.759874865740343, + "24": 0.759874865740343, + "26": 0.759874865740343, + "28": 0.759874865740343, + "30": 0.759874865740343, + "32": 0.759874865740343, + "34": 0.759874865740343, + "36": 0.759874865740343, + "38": 0.759874865740343, + "40": 0.759874865740343, + "42": 0.759874865740343, + "44": 0.759874865740343, + "46": 0.759874865740343, + "48": 0.759874865740343 + }, + "status": { + "0": 1, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_70": { + "fstatus": { + "0": 3, + "2": 3, + "4": 3, + "6": 3, + "8": 3, + "10": 3, + "12": 3, + "14": 3, + "16": 3, + "18": 3, + "20": 3, + "22": 3, + "24": 3, + "26": 3, + "28": 3, + "30": 3, + "32": 3, + "34": 3, + "36": 3, + "38": 3, + "40": 3, + "42": 3, + "44": 3, + "46": 3, + "48": 3 + }, + "radicalism": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + }, + "status": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + }, + "type": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + } + }, + "agent_71": { + "fstatus": { + "0": 3, + "2": 3, + "4": 3, + "6": 3, + "8": 3, + "10": 3, + "12": 3, + "14": 3, + "16": 3, + "18": 3, + "20": 3, + "22": 3, + "24": 3, + "26": 3, + "28": 3, + "30": 3, + "32": 3, + "34": 3, + "36": 3, + "38": 3, + "40": 3, + "42": 3, + "44": 3, + "46": 3, + "48": 3 + }, + "radicalism": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + }, + "status": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + }, + "type": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + } + }, + "agent_72": { + "fstatus": { + "0": 3, + "2": 3, + "4": 3, + "6": 3, + "8": 3, + "10": 3, + "12": 3, + "14": 3, + "16": 3, + "18": 3, + "20": 3, + "22": 3, + "24": 3, + "26": 3, + "28": 3, + "30": 3, + "32": 3, + "34": 3, + "36": 3, + "38": 3, + "40": 3, + "42": 3, + "44": 3, + "46": 3, + "48": 3 + }, + "radicalism": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + }, + "status": { + "0": 0, + "2": 0, + "4": 1, + "6": 1, + "8": 1, + "10": 1, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + } + }, + "agent_73": { + "fstatus": { + "0": 3, + "2": 3, + "4": 3, + "6": 3, + "8": 3, + "10": 3, + "12": 3, + "14": 3, + "16": 3, + "18": 3, + "20": 3, + "22": 3, + "24": 3, + "26": 3, + "28": 3, + "30": 3, + "32": 3, + "34": 3, + "36": 3, + "38": 3, + "40": 3, + "42": 3, + "44": 3, + "46": 3, + "48": 3 + }, + "radicalism": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + }, + "status": { + "0": 0, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + } + }, + "agent_74": { + "fstatus": { + "0": 3, + "2": 3, + "4": 3, + "6": 3, + "8": 4, + "10": 4, + "12": 4, + "14": 4, + "16": 4, + "18": 4, + "20": 5, + "22": 5, + "24": 5, + "26": 5, + "28": 5, + "30": 5, + "32": 5, + "34": 5, + "36": 5, + "38": 5, + "40": 5, + "42": 5, + "44": 5, + "46": 5, + "48": 5 + }, + "radicalism": { + "0": 0, + "2": 0.1, + "4": 0.2, + "6": 0.25, + "8": 0.3, + "10": 0.35, + "12": 0.39999999999999997, + "14": 0.44999999999999996, + "16": 0.49999999999999994, + "18": 0.5499999999999999, + "20": 0.6, + "22": 0.65, + "24": 0.7000000000000001, + "26": 0.7500000000000001, + "28": 0.8000000000000002, + "30": 0.8500000000000002, + "32": 0.9000000000000002, + "34": 0.9500000000000003, + "36": 1.0000000000000002, + "38": 1.0500000000000003, + "40": 1.1000000000000003, + "42": 1.1500000000000004, + "44": 1.2000000000000004, + "46": 1.2500000000000004, + "48": 1.3000000000000005 + }, + "status": { + "0": 0, + "2": 0, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + } + }, + "agent_75": { + "fstatus": { + "0": 3, + "2": 3, + "4": 3, + "6": 3, + "8": 3, + "10": 3, + "12": 3, + "14": 3, + "16": 3, + "18": 3, + "20": 3, + "22": 3, + "24": 3, + "26": 3, + "28": 3, + "30": 3, + "32": 3, + "34": 3, + "36": 3, + "38": 3, + "40": 3, + "42": 3, + "44": 3, + "46": 3, + "48": 3 + }, + "radicalism": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + }, + "status": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + }, + "type": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + } + }, + "agent_76": { + "fstatus": { + "0": 7, + "2": 7, + "4": 7, + "6": 7, + "8": 7, + "10": 7, + "12": 7, + "14": 7, + "16": 7, + "18": 7, + "20": 7, + "22": 7, + "24": 7, + "26": 7, + "28": 7, + "30": 7, + "32": 7, + "34": 7, + "36": 7, + "38": 7, + "40": 7, + "42": 7, + "44": 7, + "46": 7, + "48": 7 + }, + "radicalism": { + "0": 1, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 1, + "16": 1, + "18": 1, + "20": 1, + "22": 1, + "24": 1, + "26": 1, + "28": 1, + "30": 1, + "32": 1, + "34": 1, + "36": 1, + "38": 1, + "40": 1, + "42": 1, + "44": 1, + "46": 1, + "48": 1 + }, + "status": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 3, + "2": 3, + "4": 3, + "6": 3, + "8": 3, + "10": 3, + "12": 3, + "14": 3, + "16": 3, + "18": 3, + "20": 3, + "22": 3, + "24": 3, + "26": 3, + "28": 3, + "30": 3, + "32": 3, + "34": 3, + "36": 3, + "38": 3, + "40": 3, + "42": 3, + "44": 3, + "46": 3, + "48": 3 + } + }, + "agent_77": { + "fstatus": { + "0": 7, + "2": 7, + "4": 7, + "6": 7, + "8": 7, + "10": 7, + "12": 7, + "14": 7, + "16": 7, + "18": 7, + "20": 7, + "22": 7, + "24": 7, + "26": 7, + "28": 7, + "30": 7, + "32": 7, + "34": 7, + "36": 7, + "38": 7, + "40": 7, + "42": 7, + "44": 7, + "46": 7, + "48": 7 + }, + "radicalism": { + "0": 1, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 1, + "16": 1, + "18": 1, + "20": 1, + "22": 1, + "24": 1, + "26": 1, + "28": 1, + "30": 1, + "32": 1, + "34": 1, + "36": 1, + "38": 1, + "40": 1, + "42": 1, + "44": 1, + "46": 1, + "48": 1 + }, + "status": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 3, + "2": 3, + "4": 3, + "6": 3, + "8": 3, + "10": 3, + "12": 3, + "14": 3, + "16": 3, + "18": 3, + "20": 3, + "22": 3, + "24": 3, + "26": 3, + "28": 3, + "30": 3, + "32": 3, + "34": 3, + "36": 3, + "38": 3, + "40": 3, + "42": 3, + "44": 3, + "46": 3, + "48": 3 + } + }, + "agent_78": { + "fstatus": { + "0": 7, + "2": 7, + "4": 7, + "6": 7, + "8": 7, + "10": 7, + "12": 7, + "14": 7, + "16": 7, + "18": 7, + "20": 7, + "22": 7, + "24": 7, + "26": 7, + "28": 7, + "30": 7, + "32": 7, + "34": 7, + "36": 7, + "38": 7, + "40": 7, + "42": 7, + "44": 7, + "46": 7, + "48": 7 + }, + "radicalism": { + "0": 1, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 1, + "16": 1, + "18": 1, + "20": 1, + "22": 1, + "24": 1, + "26": 1, + "28": 1, + "30": 1, + "32": 1, + "34": 1, + "36": 1, + "38": 1, + "40": 1, + "42": 1, + "44": 1, + "46": 1, + "48": 1 + }, + "status": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 3, + "2": 3, + "4": 3, + "6": 3, + "8": 3, + "10": 3, + "12": 3, + "14": 3, + "16": 3, + "18": 3, + "20": 3, + "22": 3, + "24": 3, + "26": 3, + "28": 3, + "30": 3, + "32": 3, + "34": 3, + "36": 3, + "38": 3, + "40": 3, + "42": 3, + "44": 3, + "46": 3, + "48": 3 + } + }, + "agent_79": { + "fstatus": { + "0": 7, + "2": 7, + "4": 7, + "6": 7, + "8": 7, + "10": 7, + "12": 7, + "14": 7, + "16": 7, + "18": 7, + "20": 7, + "22": 7, + "24": 7, + "26": 7, + "28": 7, + "30": 7, + "32": 7, + "34": 7, + "36": 7, + "38": 7, + "40": 7, + "42": 7, + "44": 7, + "46": 7, + "48": 7 + }, + "radicalism": { + "0": 1, + "2": 1, + "4": 1, + "6": 1, + "8": 1, + "10": 1, + "12": 1, + "14": 1, + "16": 1, + "18": 1, + "20": 1, + "22": 1, + "24": 1, + "26": 1, + "28": 1, + "30": 1, + "32": 1, + "34": 1, + "36": 1, + "38": 1, + "40": 1, + "42": 1, + "44": 1, + "46": 1, + "48": 1 + }, + "status": { + "0": 2, + "2": 2, + "4": 2, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 3, + "2": 3, + "4": 3, + "6": 3, + "8": 3, + "10": 3, + "12": 3, + "14": 3, + "16": 3, + "18": 3, + "20": 3, + "22": 3, + "24": 3, + "26": 3, + "28": 3, + "30": 3, + "32": 3, + "34": 3, + "36": 3, + "38": 3, + "40": 3, + "42": 3, + "44": 3, + "46": 3, + "48": 3 + } + }, + "agent_8": { + "fstatus": { + "0": 0, + "2": 0, + "4": 1, + "6": 1, + "8": 1, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.1029605352882617, + "2": 0.1829605352882617, + "4": 0.3029605352882617, + "6": 0.3029605352882617, + "8": 0.42296053528826183, + "10": 0.622960535288262, + "12": 0.622960535288262, + "14": 0.622960535288262, + "16": 0.622960535288262, + "18": 0.622960535288262, + "20": 0.622960535288262, + "22": 0.622960535288262, + "24": 0.622960535288262, + "26": 0.622960535288262, + "28": 0.622960535288262, + "30": 0.622960535288262, + "32": 0.622960535288262, + "34": 0.622960535288262, + "36": 0.622960535288262, + "38": 0.622960535288262, + "40": 0.622960535288262, + "42": 0.622960535288262, + "44": 0.622960535288262, + "46": 0.622960535288262, + "48": 0.622960535288262 + }, + "status": { + "0": 0, + "2": 0, + "4": 1, + "6": 1, + "8": 1, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + }, + "agent_9": { + "fstatus": { + "0": 0, + "2": 0, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "radicalism": { + "0": 0.10244406243340591, + "2": 0.22244406243340592, + "4": 0.5024440624334061, + "6": 0.6324440624334062, + "8": 0.6324440624334062, + "10": 0.6324440624334062, + "12": 0.6324440624334062, + "14": 0.6324440624334062, + "16": 0.6324440624334062, + "18": 0.6324440624334062, + "20": 0.6324440624334062, + "22": 0.6324440624334062, + "24": 0.6324440624334062, + "26": 0.6324440624334062, + "28": 0.6324440624334062, + "30": 0.6324440624334062, + "32": 0.6324440624334062, + "34": 0.6324440624334062, + "36": 0.6324440624334062, + "38": 0.6324440624334062, + "40": 0.6324440624334062, + "42": 0.6324440624334062, + "44": 0.6324440624334062, + "46": 0.6324440624334062, + "48": 0.6324440624334062 + }, + "status": { + "0": 0, + "2": 0, + "4": 1, + "6": 2, + "8": 2, + "10": 2, + "12": 2, + "14": 2, + "16": 2, + "18": 2, + "20": 2, + "22": 2, + "24": 2, + "26": 2, + "28": 2, + "30": 2, + "32": 2, + "34": 2, + "36": 2, + "38": 2, + "40": 2, + "42": 2, + "44": 2, + "46": 2, + "48": 2 + }, + "type": { + "0": 0, + "2": 0, + "4": 0, + "6": 0, + "8": 0, + "10": 0, + "12": 0, + "14": 0, + "16": 0, + "18": 0, + "20": 0, + "22": 0, + "24": 0, + "26": 0, + "28": 0, + "30": 0, + "32": 0, + "34": 0, + "36": 0, + "38": 0, + "40": 0, + "42": 0, + "44": 0, + "46": 0, + "48": 0 + } + } +} \ No newline at end of file diff --git a/debug.py b/debug.py deleted file mode 100644 index c1edbcb..0000000 --- a/debug.py +++ /dev/null @@ -1,3 +0,0 @@ -import soil -soil.main() -import pdb diff --git a/docs/Makefile b/docs/Makefile old mode 100644 new mode 100755 diff --git a/docs/Tutorial - Spreading news.rst b/docs/Tutorial - Spreading news.rst deleted file mode 100644 index 8eaf7cd..0000000 --- a/docs/Tutorial - Spreading news.rst +++ /dev/null @@ -1,1284 +0,0 @@ -Developing new models ---------------------- - -Introduction -============ - -This notebook is an introduction to the soil agent-based social network -simulation framework. In particular, we will focus on a specific use -case: studying the propagation of news in a social network. - -The steps we will follow are: - -- Modelling the behavior of agents -- Running the simulation using different configurations -- Analysing the results of each simulation - -But before that, let's import the soil module and networkx. - -.. code:: ipython3 - - import soil - import networkx as nx - -.. code:: ipython3 - - %pylab inline - # To display plots in the notebook - - -.. parsed-literal:: - - Populating the interactive namespace from numpy and matplotlib - - -Basic concepts -============== - -There are three main elements in a soil simulation: - -- The network topology. A simulation may use an existing NetworkX - topology, or generate one on the fly -- Agents. There are two types: 1) network agents, which are linked to a - node in the topology, and 2) environment agents, which are freely - assigned to the environment. -- The environment. It assigns agents to nodes in the network, and - stores the environment parameters (shared state for all agents). - -Soil is based on ``simpy``, which is an event-based network simulation -library. Soil provides several abstractions over events to make -developing agents easier. This means you can use events (timeouts, -delays) in soil, but for the most part we will assume your models will -be step-based. - -Modeling behaviour -================== - -Our first step will be to model how every person in the social network -reacts when it comes to news. We will follow a very simple model (a -finite state machine). - -There are two types of people, those who have heard about a newsworthy -event (infected) or those who have not (neutral). A neutral person may -heard about the news either on the TV (with probability -**prob\_tv\_spread**) or through their friends. Once a person has heard -the news, they will spread it to their friends (with a probability -**prob\_neighbor\_spread**). Some users do not have a TV, so they only -rely on their friends. - -The spreading probabilities will change over time due to different -factors. We will represent this variance using an environment agent. - -Network Agents -++++++++++++++ - -A basic network agent in Soil should inherit from -``soil.agents.BaseAgent``, and define its behaviour in every step of the -simulation by implementing a ``run(self)`` method. The most important -attributes of the agent are: - -- ``agent.state``, a dictionary with the state of the agent. - ``agent.state['id']`` reflects the state id of the agent. That state - id can be used to look for other networks in that specific state. The - state can be access via the agent as well. For instance: - - .. code:: py - - a = soil.agents.BaseAgent(env=env) - a['hours_of_sleep'] = 10 - print(a['hours_of_sleep']) - - The state of the agent is stored in every step of the simulation: - ``py print(a['hours_of_sleep', 10]) # hours of sleep before step #10 print(a[None, 0]) # whole state of the agent before step #0`` - -- ``agent.env``, a reference to the environment. Most commonly used to - get access to the environment parameters and the topology: - - .. code:: py - - a.env.G.nodes() # Get all nodes ids in the topology - a.env['minimum_hours_of_sleep'] - -Since our model is a finite state machine, we will be basing it on -``soil.agents.FSM``. - -With ``soil.agents.FSM``, we do not need to specify a ``step`` method. -Instead, we describe every step as a function. To change to another -state, a function may return the new state. If no state is returned, the -state remains unchanged.[ It will consist of two states, ``neutral`` -(default) and ``infected``. - -Here's the code: - -.. code:: ipython3 - - import random - - class NewsSpread(soil.agents.FSM): - @soil.agents.default_state - @soil.agents.state - def neutral(self): - r = random.random() - if self['has_tv'] and r < self.env['prob_tv_spread']: - return self.infected - return - - @soil.agents.state - def infected(self): - prob_infect = self.env['prob_neighbor_spread'] - for neighbor in self.get_neighboring_agents(state_id=self.neutral.id): - r = random.random() - if r < prob_infect: - neighbor.state['id'] = self.infected.id - return - - -Environment agents -++++++++++++++++++ - -Environment agents allow us to control the state of the environment. In -this case, we will use an environment agent to simulate a very viral -event. - -When the event happens, the agent will modify the probability of -spreading the rumor. - -.. code:: ipython3 - - NEIGHBOR_FACTOR = 0.9 - TV_FACTOR = 0.5 - class NewsEnvironmentAgent(soil.agents.BaseAgent): - def step(self): - if self.now == self['event_time']: - self.env['prob_tv_spread'] = 1 - self.env['prob_neighbor_spread'] = 1 - elif self.now > self['event_time']: - self.env['prob_tv_spread'] = self.env['prob_tv_spread'] * TV_FACTOR - self.env['prob_neighbor_spread'] = self.env['prob_neighbor_spread'] * NEIGHBOR_FACTOR - -Testing the agents -++++++++++++++++++ - -Feel free to skip this section if this is your first time with soil. - -Testing agents is not easy, and this is not a thorough testing process -for agents. Rather, this section is aimed to show you how to access -internal pats of soil so you can test your agents. - -First of all, let's check if our network agent has the states we would -expect: - -.. code:: ipython3 - - NewsSpread.states - - - - -.. parsed-literal:: - - {'infected': , - 'neutral': } - - - -Now, let's run a simulation on a simple network. It is comprised of -three nodes: - -.. code:: ipython3 - - G = nx.Graph() - G.add_edge(0, 1) - G.add_edge(0, 2) - G.add_edge(2, 3) - G.add_node(4) - pos = nx.spring_layout(G) - nx.draw_networkx(G, pos, node_color='red') - nx.draw_networkx(G, pos, nodelist=[0], node_color='blue') - - - -.. image:: output_21_0.png - - -Let's run a simple simulation that assigns a NewsSpread agent to all the -nodes in that network. Notice how node 0 is the only one with a TV. - -.. code:: ipython3 - - env_params = {'prob_tv_spread': 0, - 'prob_neighbor_spread': 0} - - MAX_TIME = 100 - EVENT_TIME = 10 - - sim = soil.simulation.SoilSimulation(topology=G, - num_trials=1, - max_time=MAX_TIME, - environment_agents=[{'agent_type': NewsEnvironmentAgent, - 'state': { - 'event_time': EVENT_TIME - }}], - network_agents=[{'agent_type': NewsSpread, - 'weight': 1}], - states={0: {'has_tv': True}}, - default_state={'has_tv': False}, - environment_params=env_params) - env = sim.run_simulation()[0] - - -.. parsed-literal:: - - Trial: 0 - Running - Finished trial in 0.014928102493286133 seconds - Finished simulation in 0.015764951705932617 seconds - - -Now we can access the results of the simulation and compare them to our -expected results - -.. code:: ipython3 - - agents = list(env.network_agents) - - # Until the event, all agents are neutral - for t in range(10): - for a in agents: - assert a['id', t] == a.neutral.id - - # After the event, the node with a TV is infected, the rest are not - assert agents[0]['id', 11] == NewsSpread.infected.id - - for a in agents[1:4]: - assert a['id', 11] == NewsSpread.neutral.id - - # At the end, the agents connected to the infected one will probably be infected, too. - assert agents[1]['id', MAX_TIME] == NewsSpread.infected.id - assert agents[2]['id', MAX_TIME] == NewsSpread.infected.id - - # But the node with no friends should not be affected - assert agents[4]['id', MAX_TIME] == NewsSpread.neutral.id - - -Lastly, let's see if the probabilities have decreased as expected: - -.. code:: ipython3 - - assert abs(env.environment_params['prob_neighbor_spread'] - (NEIGHBOR_FACTOR**(MAX_TIME-1-10))) < 10e-4 - assert abs(env.environment_params['prob_tv_spread'] - (TV_FACTOR**(MAX_TIME-1-10))) < 10e-6 - -Running the simulation -====================== - -To run a simulation, we need a configuration. Soil can load -configurations from python dictionaries as well as JSON and YAML files. -For this demo, we will use a python dictionary: - -.. code:: ipython3 - - config = { - 'name': 'ExampleSimulation', - 'max_time': 20, - 'interval': 1, - 'num_trials': 1, - 'network_params': { - 'generator': 'complete_graph', - 'n': 500, - }, - 'network_agents': [ - { - 'agent_type': NewsSpread, - 'weight': 1, - 'state': { - 'has_tv': False - } - }, - { - 'agent_type': NewsSpread, - 'weight': 2, - 'state': { - 'has_tv': True - } - } - ], - 'states': [ {'has_tv': True} ], - 'environment_params':{ - 'prob_tv_spread': 0.01, - 'prob_neighbor_spread': 0.5 - } - } - -Let's run our simulation: - -.. code:: ipython3 - - soil.simulation.run_from_config(config, dump=False) - - -.. parsed-literal:: - - Using config(s): ExampleSimulation - Trial: 0 - Running - Finished trial in 1.4140360355377197 seconds - Finished simulation in 2.4056642055511475 seconds - - -In real life, you probably want to run several simulations, varying some -of the parameters so that you can compare and answer your research -questions. - -For instance: - -- Does the outcome depend on the structure of our network? We will use - different generation algorithms to compare them (Barabasi-Albert and - Erdos-Renyi) -- How does neighbor spreading probability affect my simulation? We will - try probability values in the range of [0, 0.4], in intervals of 0.1. - -.. code:: ipython3 - - network_1 = { - 'generator': 'erdos_renyi_graph', - 'n': 500, - 'p': 0.1 - } - network_2 = { - 'generator': 'barabasi_albert_graph', - 'n': 500, - 'm': 2 - } - - - for net in [network_1, network_2]: - for i in range(5): - prob = i / 10 - config['environment_params']['prob_neighbor_spread'] = prob - config['network_params'] = net - config['name'] = 'Spread_{}_prob_{}'.format(net['generator'], prob) - s = soil.simulation.run_from_config(config) - - -.. parsed-literal:: - - Using config(s): Spread_erdos_renyi_graph_prob_0.0 - Trial: 0 - Running - Finished trial in 0.2691483497619629 seconds - Finished simulation in 0.3650345802307129 seconds - Using config(s): Spread_erdos_renyi_graph_prob_0.1 - Trial: 0 - Running - Finished trial in 0.34261059761047363 seconds - Finished simulation in 0.44017767906188965 seconds - Using config(s): Spread_erdos_renyi_graph_prob_0.2 - Trial: 0 - Running - Finished trial in 0.34417223930358887 seconds - Finished simulation in 0.4550771713256836 seconds - Using config(s): Spread_erdos_renyi_graph_prob_0.3 - Trial: 0 - Running - Finished trial in 0.3237779140472412 seconds - Finished simulation in 0.42307496070861816 seconds - Using config(s): Spread_erdos_renyi_graph_prob_0.4 - Trial: 0 - Running - Finished trial in 0.3507683277130127 seconds - Finished simulation in 0.45061564445495605 seconds - Using config(s): Spread_barabasi_albert_graph_prob_0.0 - Trial: 0 - Running - Finished trial in 0.19115304946899414 seconds - Finished simulation in 0.20927715301513672 seconds - Using config(s): Spread_barabasi_albert_graph_prob_0.1 - Trial: 0 - Running - Finished trial in 0.22086191177368164 seconds - Finished simulation in 0.2390913963317871 seconds - Using config(s): Spread_barabasi_albert_graph_prob_0.2 - Trial: 0 - Running - Finished trial in 0.21225976943969727 seconds - Finished simulation in 0.23252630233764648 seconds - Using config(s): Spread_barabasi_albert_graph_prob_0.3 - Trial: 0 - Running - Finished trial in 0.2853121757507324 seconds - Finished simulation in 0.30568504333496094 seconds - Using config(s): Spread_barabasi_albert_graph_prob_0.4 - Trial: 0 - Running - Finished trial in 0.21434736251831055 seconds - Finished simulation in 0.23370599746704102 seconds - - -The results are conveniently stored in pickle (simulation), csv (history -of agent and environment state) and gexf format. - -.. code:: ipython3 - - !tree soil_output - !du -xh soil_output/* - - -.. parsed-literal:: - - soil_output - ├── Sim_prob_0 - │   ├── Sim_prob_0.dumped.yml - │   ├── Sim_prob_0.simulation.pickle - │   ├── Sim_prob_0_trial_0.environment.csv - │   └── Sim_prob_0_trial_0.gexf - ├── Spread_barabasi_albert_graph_prob_0.0 - │   ├── Spread_barabasi_albert_graph_prob_0.0.dumped.yml - │   ├── Spread_barabasi_albert_graph_prob_0.0.simulation.pickle - │   ├── Spread_barabasi_albert_graph_prob_0.0_trial_0.environment.csv - │   └── Spread_barabasi_albert_graph_prob_0.0_trial_0.gexf - ├── Spread_barabasi_albert_graph_prob_0.1 - │   ├── Spread_barabasi_albert_graph_prob_0.1.dumped.yml - │   ├── Spread_barabasi_albert_graph_prob_0.1.simulation.pickle - │   ├── Spread_barabasi_albert_graph_prob_0.1_trial_0.environment.csv - │   └── Spread_barabasi_albert_graph_prob_0.1_trial_0.gexf - ├── Spread_barabasi_albert_graph_prob_0.2 - │   ├── Spread_barabasi_albert_graph_prob_0.2.dumped.yml - │   ├── Spread_barabasi_albert_graph_prob_0.2.simulation.pickle - │   ├── Spread_barabasi_albert_graph_prob_0.2_trial_0.environment.csv - │   └── Spread_barabasi_albert_graph_prob_0.2_trial_0.gexf - ├── Spread_barabasi_albert_graph_prob_0.3 - │   ├── Spread_barabasi_albert_graph_prob_0.3.dumped.yml - │   ├── Spread_barabasi_albert_graph_prob_0.3.simulation.pickle - │   ├── Spread_barabasi_albert_graph_prob_0.3_trial_0.environment.csv - │   └── Spread_barabasi_albert_graph_prob_0.3_trial_0.gexf - ├── Spread_barabasi_albert_graph_prob_0.4 - │   ├── Spread_barabasi_albert_graph_prob_0.4.dumped.yml - │   ├── Spread_barabasi_albert_graph_prob_0.4.simulation.pickle - │   ├── Spread_barabasi_albert_graph_prob_0.4_trial_0.environment.csv - │   └── Spread_barabasi_albert_graph_prob_0.4_trial_0.gexf - ├── Spread_erdos_renyi_graph_prob_0.0 - │   ├── Spread_erdos_renyi_graph_prob_0.0.dumped.yml - │   ├── Spread_erdos_renyi_graph_prob_0.0.simulation.pickle - │   ├── Spread_erdos_renyi_graph_prob_0.0_trial_0.environment.csv - │   └── Spread_erdos_renyi_graph_prob_0.0_trial_0.gexf - ├── Spread_erdos_renyi_graph_prob_0.1 - │   ├── Spread_erdos_renyi_graph_prob_0.1.dumped.yml - │   ├── Spread_erdos_renyi_graph_prob_0.1.simulation.pickle - │   ├── Spread_erdos_renyi_graph_prob_0.1_trial_0.environment.csv - │   └── Spread_erdos_renyi_graph_prob_0.1_trial_0.gexf - ├── Spread_erdos_renyi_graph_prob_0.2 - │   ├── Spread_erdos_renyi_graph_prob_0.2.dumped.yml - │   ├── Spread_erdos_renyi_graph_prob_0.2.simulation.pickle - │   ├── Spread_erdos_renyi_graph_prob_0.2_trial_0.environment.csv - │   └── Spread_erdos_renyi_graph_prob_0.2_trial_0.gexf - ├── Spread_erdos_renyi_graph_prob_0.3 - │   ├── Spread_erdos_renyi_graph_prob_0.3.dumped.yml - │   ├── Spread_erdos_renyi_graph_prob_0.3.simulation.pickle - │   ├── Spread_erdos_renyi_graph_prob_0.3_trial_0.environment.csv - │   └── Spread_erdos_renyi_graph_prob_0.3_trial_0.gexf - └── Spread_erdos_renyi_graph_prob_0.4 - ├── Spread_erdos_renyi_graph_prob_0.4.dumped.yml - ├── Spread_erdos_renyi_graph_prob_0.4.simulation.pickle - ├── Spread_erdos_renyi_graph_prob_0.4_trial_0.environment.csv - └── Spread_erdos_renyi_graph_prob_0.4_trial_0.gexf - - 11 directories, 44 files - 1.8M soil_output/Sim_prob_0 - 652K soil_output/Spread_barabasi_albert_graph_prob_0.0 - 684K soil_output/Spread_barabasi_albert_graph_prob_0.1 - 692K soil_output/Spread_barabasi_albert_graph_prob_0.2 - 692K soil_output/Spread_barabasi_albert_graph_prob_0.3 - 688K soil_output/Spread_barabasi_albert_graph_prob_0.4 - 1.8M soil_output/Spread_erdos_renyi_graph_prob_0.0 - 1.9M soil_output/Spread_erdos_renyi_graph_prob_0.1 - 1.9M soil_output/Spread_erdos_renyi_graph_prob_0.2 - 1.9M soil_output/Spread_erdos_renyi_graph_prob_0.3 - 1.9M soil_output/Spread_erdos_renyi_graph_prob_0.4 - - -Analysing the results -===================== - -Once the simulations are over, we can use soil to analyse the results. - -First, let's load the stored results into a pandas dataframe. - -.. code:: ipython3 - - %pylab inline - from soil import analysis - - -.. parsed-literal:: - - Populating the interactive namespace from numpy and matplotlib - - -.. parsed-literal:: - - /usr/lib/python3.6/site-packages/IPython/core/magics/pylab.py:160: UserWarning: pylab import has clobbered these variables: ['random'] - `%matplotlib` prevents importing * from pylab and numpy - "\n`%matplotlib` prevents importing * from pylab and numpy" - - -.. code:: ipython3 - - config_file, df, config = list(analysis.get_data('soil_output/Spread_barabasi*prob_0.1*', process=False))[0] - df - - - - -.. raw:: html - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
agent_idtstepattributevalue
0env0prob_tv_spread0.01
1env0prob_neighbor_spread0.1
2env1prob_tv_spread0.01
3env1prob_neighbor_spread0.1
4env2prob_tv_spread0.01
5env2prob_neighbor_spread0.1
6env3prob_tv_spread0.01
7env3prob_neighbor_spread0.1
8env4prob_tv_spread0.01
9env4prob_neighbor_spread0.1
10env5prob_tv_spread0.01
11env5prob_neighbor_spread0.1
12env6prob_tv_spread0.01
13env6prob_neighbor_spread0.1
14env7prob_tv_spread0.01
15env7prob_neighbor_spread0.1
16env8prob_tv_spread0.01
17env8prob_neighbor_spread0.1
18env9prob_tv_spread0.01
19env9prob_neighbor_spread0.1
20env10prob_tv_spread0.01
21env10prob_neighbor_spread0.1
22env11prob_tv_spread0.01
23env11prob_neighbor_spread0.1
24env12prob_tv_spread0.01
25env12prob_neighbor_spread0.1
26env13prob_tv_spread0.01
27env13prob_neighbor_spread0.1
28env14prob_tv_spread0.01
29env14prob_neighbor_spread0.1
...............
210124996has_tvTrue
210134996idneutral
210144997has_tvTrue
210154997idneutral
210164998has_tvTrue
210174998idneutral
210184999has_tvTrue
210194999idneutral
2102049910has_tvTrue
2102149910idneutral
2102249911has_tvTrue
2102349911idneutral
2102449912has_tvTrue
2102549912idneutral
2102649913has_tvTrue
2102749913idneutral
2102849914has_tvTrue
2102949914idneutral
2103049915has_tvTrue
2103149915idneutral
2103249916has_tvTrue
2103349916idneutral
2103449917has_tvTrue
2103549917idneutral
2103649918has_tvTrue
2103749918idneutral
2103849919has_tvTrue
2103949919idneutral
2104049920has_tvTrue
2104149920idinfected
-

21042 rows × 4 columns

-
- - - -.. code:: ipython3 - - list(analysis.get_data('soil_output/Spread_barabasi*prob_0.1*', process=True))[0][1] - - - - -.. raw:: html - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
value0.010.1FalseTrueinfectedneutral
tstep
01.01.0163.0337.00.0500.0
11.01.0163.0337.03.0497.0
21.01.0163.0337.06.0494.0
31.01.0163.0337.012.0488.0
41.01.0163.0337.023.0477.0
51.01.0163.0337.036.0464.0
61.01.0163.0337.053.0447.0
71.01.0163.0337.079.0421.0
81.01.0163.0337.0119.0381.0
91.01.0163.0337.0164.0336.0
101.01.0163.0337.0204.0296.0
111.01.0163.0337.0254.0246.0
121.01.0163.0337.0293.0207.0
131.01.0163.0337.0336.0164.0
141.01.0163.0337.0365.0135.0
151.01.0163.0337.0391.0109.0
161.01.0163.0337.0407.093.0
171.01.0163.0337.0424.076.0
181.01.0163.0337.0442.058.0
191.01.0163.0337.0452.048.0
201.01.0163.0337.0464.036.0
-
- - - -If you don't want to work with pandas, you can also use some pre-defined -functions from soil to conveniently plot the results: - -.. code:: ipython3 - - analysis.plot_all('soil_output/Spread_barabasi*', attributes=['id']) - - - -.. image:: output_44_0.png - - - -.. image:: output_44_1.png - - - -.. image:: output_44_2.png - - - -.. image:: output_44_3.png - - - -.. image:: output_44_4.png - - -.. code:: ipython3 - - analysis.plot_all('soil_output/Spread_erdos*', attributes=['id']) - - - -.. image:: output_45_0.png - - - -.. image:: output_45_1.png - - - -.. image:: output_45_2.png - - - -.. image:: output_45_3.png - - - -.. image:: output_45_4.png - diff --git a/docs/conf.py b/docs/conf.py old mode 100644 new mode 100755 diff --git a/docs/index.rst b/docs/index.rst old mode 100644 new mode 100755 index 24fbf0b..6d96db2 --- a/docs/index.rst +++ b/docs/index.rst @@ -8,38 +8,13 @@ Welcome to Soil's documentation! Soil is an Agent-based Social Simulator in Python for modelling and simulation of Social Networks. -If you use Soil in your research, do not forget to cite this paper: - -.. code:: bibtex - - @inbook{soil-gsi-conference-2017, - author = "S{\'a}nchez, Jes{\'u}s M. and Iglesias, Carlos A. and S{\'a}nchez-Rada, J. Fernando", - booktitle = "Advances in Practical Applications of Cyber-Physical Multi-Agent Systems: The PAAMS Collection", - doi = "10.1007/978-3-319-59930-4_19", - editor = "Demazeau Y., Davidsson P., Bajo J., Vale Z.", - isbn = "978-3-319-59929-8", - keywords = "soil;social networks;agent based social simulation;python", - month = "June", - organization = "PAAMS 2017", - pages = "234-245", - publisher = "Springer Verlag", - series = "LNAI", - title = "{S}oil: {A}n {A}gent-{B}ased {S}ocial {S}imulator in {P}ython for {M}odelling and {S}imulation of {S}ocial {N}etworks", - url = "https://link.springer.com/chapter/10.1007/978-3-319-59930-4_19", - volume = "10349", - year = "2017", - } - - - - .. toctree:: :maxdepth: 2 :caption: Learn more about soil: installation - quickstart - Tutorial - Spreading news + usage + models diff --git a/docs/installation.rst b/docs/installation.rst old mode 100644 new mode 100755 index a1fddd4..f4fa73c --- a/docs/installation.rst +++ b/docs/installation.rst @@ -1,24 +1,7 @@ Installation ------------ - -The easiest way to install Soil is through pip: +The latest version can be installed through GitLab. .. code:: bash - pip install soil - - -Now test that it worked by running the command line tool - -.. code:: bash - - soil --help - -Or using soil programmatically: - -.. code:: python - - import soil - print(soil.__version__) - -The latest version can be installed through `GitLab `_. + git clone https://lab.cluster.gsi.dit.upm.es/soil/soil.git \ No newline at end of file diff --git a/docs/make.bat b/docs/make.bat old mode 100644 new mode 100755 diff --git a/docs/models.rst b/docs/models.rst new file mode 100755 index 0000000..d179d7b --- /dev/null +++ b/docs/models.rst @@ -0,0 +1,112 @@ +Developing new models +--------------------- +This document describes how to develop a new analysis model. + +What is a model? +================ + +A model defines the behaviour of the agents with a view to assessing their effects on the system as a whole. +In practice, a model consists of at least two parts: + +* Python module: the actual code that describes the behaviour. +* Setting up the variables in the Settings JSON file. + +This separation allows us to run the simulation with different agents. + +Models Code +=========== + +All the models are imported to the main file. The initialization look like this: + +.. code:: python + + import settings + + networkStatus = {} # Dict that will contain the status of every agent in the network + + sentimentCorrelationNodeArray = [] + for x in range(0, settings.network_params["number_of_nodes"]): + sentimentCorrelationNodeArray.append({'id': x}) + # Initialize agent states. Let's assume everyone is normal. + init_states = [{'id': 0, } for _ in range(settings.network_params["number_of_nodes"])] + # add keys as as necessary, but "id" must always refer to that state category + +A new model have to inherit the BaseBehaviour class which is in the same module. +There are two basics methods: + +* __init__ +* step: used to define the behaviour over time. + +Variable Initialization +======================= + +The different parameters of the model have to be initialize in the Simulation Settings JSON file which will be +passed as a parameter to the simulation. + +.. code:: json + + { + "agent": ["SISaModel","ControlModelM2"], + + "neutral_discontent_spon_prob": 0.04, + "neutral_discontent_infected_prob": 0.04, + "neutral_content_spon_prob": 0.18, + "neutral_content_infected_prob": 0.02, + + "discontent_neutral": 0.13, + "discontent_content": 0.07, + "variance_d_c": 0.02, + + "content_discontent": 0.009, + "variance_c_d": 0.003, + "content_neutral": 0.088, + + "standard_variance": 0.055, + + + "prob_neutral_making_denier": 0.035, + + "prob_infect": 0.075, + + "prob_cured_healing_infected": 0.035, + "prob_cured_vaccinate_neutral": 0.035, + + "prob_vaccinated_healing_infected": 0.035, + "prob_vaccinated_vaccinate_neutral": 0.035, + "prob_generate_anti_rumor": 0.035 + } + +In this file you will also define the models you are going to simulate. You can simulate as many models as you want. +The simulation returns one result for each model, executing each model separately. For the usage, see :doc:`usage`. + +Example Model +============= + +In this section, we will implement a Sentiment Correlation Model. + +The class would look like this: + +.. code:: python + + from ..BaseBehaviour import * + from .. import sentimentCorrelationNodeArray + + class SentimentCorrelationModel(BaseBehaviour): + + def __init__(self, environment=None, agent_id=0, state=()): + super().__init__(environment=environment, agent_id=agent_id, state=state) + self.outside_effects_prob = environment.environment_params['outside_effects_prob'] + self.anger_prob = environment.environment_params['anger_prob'] + self.joy_prob = environment.environment_params['joy_prob'] + self.sadness_prob = environment.environment_params['sadness_prob'] + self.disgust_prob = environment.environment_params['disgust_prob'] + self.time_awareness = [] + for i in range(4): # In this model we have 4 sentiments + self.time_awareness.append(0) # 0-> Anger, 1-> joy, 2->sadness, 3 -> disgust + sentimentCorrelationNodeArray[self.id][self.env.now] = 0 + + def step(self, now): + self.behaviour() # Method which define the behaviour + super().step(now) + +The variables will be modified by the user, so you have to include them in the Simulation Settings JSON file. \ No newline at end of file diff --git a/docs/output_21_0.png b/docs/output_21_0.png deleted file mode 100644 index df25782..0000000 Binary files a/docs/output_21_0.png and /dev/null differ diff --git a/docs/output_44_0.png b/docs/output_44_0.png deleted file mode 100644 index 101c22a..0000000 Binary files a/docs/output_44_0.png and /dev/null differ diff --git a/docs/output_44_1.png b/docs/output_44_1.png deleted file mode 100644 index 5973ac6..0000000 Binary files a/docs/output_44_1.png and /dev/null differ diff --git a/docs/output_44_2.png b/docs/output_44_2.png deleted file mode 100644 index 3e55aba..0000000 Binary files a/docs/output_44_2.png and /dev/null differ diff --git a/docs/output_44_3.png b/docs/output_44_3.png deleted file mode 100644 index db7d651..0000000 Binary files a/docs/output_44_3.png and /dev/null differ diff --git a/docs/output_44_4.png b/docs/output_44_4.png deleted file mode 100644 index 226fa72..0000000 Binary files a/docs/output_44_4.png and /dev/null differ diff --git a/docs/output_45_0.png b/docs/output_45_0.png deleted file mode 100644 index 4b3a22b..0000000 Binary files a/docs/output_45_0.png and /dev/null differ diff --git a/docs/output_45_1.png b/docs/output_45_1.png deleted file mode 100644 index bf1b9d2..0000000 Binary files a/docs/output_45_1.png and /dev/null differ diff --git a/docs/output_45_2.png b/docs/output_45_2.png deleted file mode 100644 index db31580..0000000 Binary files a/docs/output_45_2.png and /dev/null differ diff --git a/docs/output_45_3.png b/docs/output_45_3.png deleted file mode 100644 index b3980d6..0000000 Binary files a/docs/output_45_3.png and /dev/null differ diff --git a/docs/output_45_4.png b/docs/output_45_4.png deleted file mode 100644 index 6dffdb5..0000000 Binary files a/docs/output_45_4.png and /dev/null differ diff --git a/docs/quickstart.rst b/docs/quickstart.rst deleted file mode 100644 index acb2b85..0000000 --- a/docs/quickstart.rst +++ /dev/null @@ -1,194 +0,0 @@ -Quickstart ----------- - -This section shows how to run simulations from simulation configuration files. -First of all, you need to install the package (See :doc:`installation`) - -Simulation configuration files are ``json`` or ``yaml`` files that define all the parameters of a simulation. -Here's an example (``example.yml``). - -.. code:: yaml - - --- - name: MyExampleSimulation - max_time: 50 - num_trials: 3 - timeout: 2 - network_params: - network_type: barabasi_albert_graph - n: 100 - m: 2 - agent_distribution: - - agent_type: SISaModel - weight: 1 - state: - id: content - - agent_type: SISaModel - weight: 1 - state: - id: discontent - - agent_type: SISaModel - weight: 8 - state: - id: neutral - environment_params: - prob_infect: 0.075 - -Now run the simulation with the command line tool: - -.. code:: bash - - soil example.yml - -Once the simulation finishes, its results will be stored in a folder named ``MyExampleSimulation``. -Four types of objects are saved by default: a pickle of the simulation, a ``YAML`` representation of the simulation (to re-launch it), for every trial, a csv file with the content of the state of every network node and the environment parameters at every step of the simulation as well as the network in gephi format (``gexf``). - - -.. code:: - - soil_output - ├── Sim_prob_0 - │   ├── Sim_prob_0.dumped.yml - │   ├── Sim_prob_0.simulation.pickle - │   ├── Sim_prob_0_trial_0.environment.csv - │   └── Sim_prob_0_trial_0.gexf - - -This example configuration will run three trials of a simulation containing a randomly generated network. -The 100 nodes in the network will be SISaModel agents, 10% of them will start in the content state, 10% in the discontent state, and the remaining 80% in the neutral state. -All agents will have access to the environment, which only contains one variable, ``prob_infected``. -The state of the agents will be updated every 2 seconds (``timeout``). - - -Network -======= - -The network topology for the simulation can be loaded from an existing network file or generated with one of the random network generation methods from networkx. - -Loading a network -################# - -To load an existing network, specify its path in the configuration: - -.. code:: yaml - - --- - network_params: - path: /tmp/mynetwork.gexf - -Soil will try to guess what networkx method to use to read the file based on its extension. -However, we only test using ``gexf`` files. - -Generating a random network -########################### - -To generate a random network using one of networkx's built-in methods, specify the `graph generation algorithm `_ and other parameters. -For example, the following configuration is equivalent to :code:`nx.complete_graph(100)`: - -.. code:: yaml - - network_params: - network_type: complete_graph - n: 100 - -Environment -============ -The environment is the place where the shared state of the simulation is stored. -For instance, the probability of certain events. -The configuration file may specify the initial value of the environment parameters: - -.. code:: yaml - - environment_params: - daily_probability_of_earthquake: 0.001 - number_of_earthquakes: 0 - -Agents -====== -Agents are a way of modelling behavior. -Agents can be characterized with two variables: an agent type (``agent_type``) and its state. -Only one agent is executed at a time (generally, every ``timeout`` seconds), and it has access to its state and the environment parameters. -Through the environment, it can access the network topology and the state of other agents. - -There are three three types of agents according to how they are added to the simulation: network agents, environment agent, and other agents. - -Network Agents -############## -Network agents are attached to a node in the topology. -The configuration file allows you to specify how agents will be mapped to topology nodes. - -The simplest way is to specify a single type of agent. -Hence, every node in the network will have an associated agent of that type. - -.. code:: yaml - - agent_type: SISaModel - -It is also possible to add more than one type of agent to the simulation, and to control the ratio of each type (``weight``). -For instance, with following configuration, it is five times more likely for a node to be assigned a CounterModel type than a SISaModel type. - -.. code:: yaml - - agent_distribution: - - agent_type: SISaModel - weight: 1 - - agent_type: CounterModel - weight: 5 - -In addition to agent type, you may also add a custom initial state to the distribution. -This is very useful to add the same agent type with different states. -e.g., to populate the network with SISaModel, roughly 10% of them with a discontent state: - -.. code:: yaml - - agent_distribution: - - agent_type: SISaModel - weight: 9 - state: - id: neutral - - agent_type: SISaModel - weight: 1 - state: - id: discontent - -Lastly, the configuration may include initial state for one or more nodes. -For instance, to add a state for the two nodes in this configuration: - -.. code:: yaml - - agent_type: SISaModel - network: - network_type: complete_graph - n: 2 - states: - - id: content - - id: discontent - - -Or to add state only to specific nodes (by ``id``). -For example, to apply special skills to Linux Torvalds in a simulation: - -.. literalinclude:: ../examples/torvalds.yml - :language: yaml - - -Environment Agents -################## -In addition to network agents, more agents can be added to the simulation. -These agens are programmed in much the same way as network agents, the only difference is that they will not be assigned to network nodes. - - -.. code:: - - environment_agents: - - agent_type: MyAgent - state: - mood: happy - - agent_type: DummyAgent - - -Visualizing the results -======================= - -The simulation will return a dynamic graph .gexf file which could be visualized with -`Gephi `__. diff --git a/docs/usage.rst b/docs/usage.rst new file mode 100755 index 0000000..17b3291 --- /dev/null +++ b/docs/usage.rst @@ -0,0 +1,99 @@ +Usage +----- + +First of all, you need to install the package. See :doc:`installation` for installation instructions. + +Simulation Settings +=================== + +Once installed, before running a simulation, you need to configure it. + +* In the Settings JSON file you will find the configuration of the network. + + .. code:: python + + { + "network_type": 1, + "number_of_nodes": 1000, + "max_time": 50, + "num_trials": 1, + "timeout": 2 + } + +* In the Settings JSON file, you will also find the configuration of the models. + +Network Types +============= + +There are three types of network implemented, but you could add more. + +.. code:: python + + if settings.network_type == 0: + G = nx.complete_graph(settings.number_of_nodes) + if settings.network_type == 1: + G = nx.barabasi_albert_graph(settings.number_of_nodes, 10) + if settings.network_type == 2: + G = nx.margulis_gabber_galil_graph(settings.number_of_nodes, None) + # More types of networks can be added here + +Models Settings +=============== + +After having configured the simulation, the next step is setting up the variables of the models. +For this, you will need to modify the Settings JSON file again. + +.. code:: json + + { + "agent": ["SISaModel","ControlModelM2"], + + "neutral_discontent_spon_prob": 0.04, + "neutral_discontent_infected_prob": 0.04, + "neutral_content_spon_prob": 0.18, + "neutral_content_infected_prob": 0.02, + + "discontent_neutral": 0.13, + "discontent_content": 0.07, + "variance_d_c": 0.02, + + "content_discontent": 0.009, + "variance_c_d": 0.003, + "content_neutral": 0.088, + + "standard_variance": 0.055, + + + "prob_neutral_making_denier": 0.035, + + "prob_infect": 0.075, + + "prob_cured_healing_infected": 0.035, + "prob_cured_vaccinate_neutral": 0.035, + + "prob_vaccinated_healing_infected": 0.035, + "prob_vaccinated_vaccinate_neutral": 0.035, + "prob_generate_anti_rumor": 0.035 + } + +In this file you will define the different models you are going to simulate. You can simulate as many models +as you want. Each model will be simulated separately. + +After setting up the models, you have to initialize the parameters of each one. You will find the parameters needed +in the documentation of each model. + +Parameter validation will fail if a required parameter without a default has not been provided. + +Running the Simulation +====================== + +After setting all the configuration, you will be able to run the simulation. All you need to do is execute: + +.. code:: bash + + python3 soil.py + +The simulation will return a dynamic graph .gexf file which could be visualized with +`Gephi `__. + +It will also return one .png picture for each model simulated. diff --git a/examples/complete.yml b/examples/complete.yml deleted file mode 100644 index 7b52842..0000000 --- a/examples/complete.yml +++ /dev/null @@ -1,24 +0,0 @@ ---- -name: simple -dir_path: "/tmp/" -num_trials: 3 -max_time: 100 -interval: 1 -network_params: - generator: complete_graph - n: 10 -network_agents: - - agent_type: CounterModel - weight: 1 - state: - id: 0 - - agent_type: AggregatedCounter - weight: 0.2 -environment_agents: [] -environment_params: - am_i_complete: true -default_state: - incidents: 0 -states: - - name: 'The first node' - - name: 'The second node' \ No newline at end of file diff --git a/examples/custom-agents/UnnamedSimulation.dumped.yml b/examples/custom-agents/UnnamedSimulation.dumped.yml deleted file mode 100644 index 34c5534..0000000 --- a/examples/custom-agents/UnnamedSimulation.dumped.yml +++ /dev/null @@ -1,17 +0,0 @@ -default_state: {} -environment_agents: [] -environment_params: {prob_neighbor_spread: 0.0, prob_tv_spread: 0.01} -interval: 1 -max_time: 20 -name: Sim_prob_0 -network_agents: -- agent_type: NewsSpread - state: {has_tv: false} - weight: 1 -- agent_type: NewsSpread - state: {has_tv: true} - weight: 2 -network_params: {generator: erdos_renyi_graph, n: 500, p: 0.1} -num_trials: 1 -states: -- {has_tv: true} diff --git a/examples/custom-agents/agent.py b/examples/custom-agents/agent.py deleted file mode 100644 index 0f4d8a4..0000000 --- a/examples/custom-agents/agent.py +++ /dev/null @@ -1,20 +0,0 @@ -import soil -import random - -class NewsSpread(soil.agents.FSM): - @soil.agents.default_state - @soil.agents.state - def neutral(self): - r = random.random() - if self['has_tv'] and r < self.env['prob_tv_spread']: - return self.infected - return - - @soil.agents.state - def infected(self): - prob_infect = self.env['prob_neighbor_spread'] - for neighbor in self.get_neighboring_agents(state_id=self.neutral.id): - r = random.random() - if r < prob_infect: - neighbor.state['id'] = self.infected.id - return diff --git a/examples/torvalds.edgelist b/examples/torvalds.edgelist deleted file mode 100644 index 3947fe2..0000000 --- a/examples/torvalds.edgelist +++ /dev/null @@ -1,2 +0,0 @@ -balkian Torvalds {} -anonymous Torvalds {} diff --git a/examples/torvalds.yml b/examples/torvalds.yml deleted file mode 100644 index d346c99..0000000 --- a/examples/torvalds.yml +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: torvalds_example -max_time: 1 -interval: 2 -agent_type: CounterModel -default_state: - skill_level: 'beginner' -network_params: - path: 'torvalds.edgelist' -states: - Torvalds: - skill_level: 'God' - balkian: - skill_level: 'developer' \ No newline at end of file diff --git a/logo_gsi.png b/logo_gsi.png old mode 100644 new mode 100755 diff --git a/logo_gsi.svg b/logo_gsi.svg old mode 100644 new mode 100755 diff --git a/models/BaseBehaviour/BaseBehaviour.py b/models/BaseBehaviour/BaseBehaviour.py new file mode 100755 index 0000000..aef94b1 --- /dev/null +++ b/models/BaseBehaviour/BaseBehaviour.py @@ -0,0 +1,38 @@ +import settings +from nxsim import BaseNetworkAgent +from .. import networkStatus + + +class BaseBehaviour(BaseNetworkAgent): + + def __init__(self, environment=None, agent_id=0, state=()): + super().__init__(environment=environment, agent_id=agent_id, state=state) + self._attrs = {} + + @property + def attrs(self): + now = self.env.now + if now not in self._attrs: + self._attrs[now] = {} + return self._attrs[now] + + @attrs.setter + def attrs(self, value): + self._attrs[self.env.now] = value + + def run(self): + while True: + self.step(self.env.now) + yield self.env.timeout(settings.network_params["timeout"]) + + def step(self, now): + networkStatus['agent_%s'% self.id] = self.to_json() + + def to_json(self): + final = {} + for stamp, attrs in self._attrs.items(): + for a in attrs: + if a not in final: + final[a] = {} + final[a][stamp] = attrs[a] + return final diff --git a/models/BaseBehaviour/__init__.py b/models/BaseBehaviour/__init__.py new file mode 100755 index 0000000..7494c75 --- /dev/null +++ b/models/BaseBehaviour/__init__.py @@ -0,0 +1 @@ +from .BaseBehaviour import BaseBehaviour diff --git a/models/TerroristModel/TerroristModel.py b/models/TerroristModel/TerroristModel.py new file mode 100644 index 0000000..42bb3ad --- /dev/null +++ b/models/TerroristModel/TerroristModel.py @@ -0,0 +1,367 @@ +import random +import numpy as np +from ..BaseBehaviour import * +import settings +import networkx as nx + + + +POPULATION = 0 +LEADERS = 1 +HAVEN = 2 +TRAININGENV = 3 + +NON_RADICAL = 0 +NEUTRAL = 1 +RADICAL = 2 + +POPNON =0 +POPNE=1 +POPRAD=2 + +HAVNON=3 +HAVNE=4 +HAVRAD=5 + +LEADER=6 + +TRAINING = 7 + + +class TerroristModel(BaseBehaviour): + num_agents = 0 + + def __init__(self, environment=None, agent_id=0, state=()): + + super().__init__(environment=environment, agent_id=agent_id, state=state) + + self.population = settings.network_params["number_of_nodes"] * settings.environment_params['initial_population'] + self.havens = settings.network_params["number_of_nodes"] * settings.environment_params['initial_havens'] + self.training_enviroments = settings.network_params["number_of_nodes"] * settings.environment_params['initial_training_enviroments'] + + self.initial_radicalism = settings.environment_params['initial_radicalism'] + self.information_spread_intensity = settings.environment_params['information_spread_intensity'] + self.influence = settings.environment_params['influence'] + self.relative_inequality = settings.environment_params['relative_inequality'] + self.additional_influence = settings.environment_params['additional_influence'] + + if TerroristModel.num_agents < self.population: + self.state['type'] = POPULATION + TerroristModel.num_agents = TerroristModel.num_agents + 1 + random1 = random.random() + if random1 < 0.7: + self.state['id'] = NON_RADICAL + self.state['fstatus'] = POPNON + elif random1 >= 0.7 and random1 < 0.9: + self.state['id'] = NEUTRAL + self.state['fstatus'] = POPNE + elif random1 >= 0.9: + self.state['id'] = RADICAL + self.state['fstatus'] = POPRAD + + elif TerroristModel.num_agents < self.havens + self.population: + self.state['type'] = HAVEN + TerroristModel.num_agents = TerroristModel.num_agents + 1 + random2 = random.random() + random1 = random2 + self.initial_radicalism + if random1 < 1.2: + self.state['id'] = NON_RADICAL + self.state['fstatus'] = HAVNON + elif random1 >= 1.2 and random1 < 1.6: + self.state['id'] = NEUTRAL + self.state['fstatus'] = HAVNE + elif random1 >= 1.6: + self.state['id'] = RADICAL + self.state['fstatus'] = HAVRAD + + elif TerroristModel.num_agents < self.training_enviroments + self.havens + self.population: + self.state['type'] = TRAININGENV + self.state['fstatus'] = TRAINING + TerroristModel.num_agents = TerroristModel.num_agents + 1 + + def step(self, now): + if self.state['type'] == POPULATION: + self.population_and_leader_conduct() + if self.state['type'] == LEADERS: + self.population_and_leader_conduct() + if self.state['type'] == HAVEN: + self.haven_conduct() + if self.state['type'] == TRAININGENV: + self.training_enviroment_conduct() + + self.attrs['status'] = self.state['id'] + self.attrs['type'] = self.state['type'] + self.attrs['radicalism'] = self.state['rad'] + self.attrs['fstatus'] = self.state['fstatus'] + super().step(now) + + def population_and_leader_conduct(self): + if self.state['id'] == NON_RADICAL: + if self.state['rad'] == 0.000: + self.state['rad'] = self.set_radicalism() + self.non_radical_behaviour() + if self.state['id'] == NEUTRAL: + if self.state['rad'] == 0.000: + self.state['rad'] = self.set_radicalism() + while self.state['id'] == RADICAL: + self.radical_behaviour() + break + self.neutral_behaviour() + if self.state['id'] == RADICAL: + if self.state['rad'] == 0.000: + self.state['rad'] = self.set_radicalism() + self.radical_behaviour() + + def haven_conduct(self): + non_radical_neighbors = self.get_neighboring_agents(state_id=NON_RADICAL) + neutral_neighbors = self.get_neighboring_agents(state_id=NEUTRAL) + radical_neighbors = self.get_neighboring_agents(state_id=RADICAL) + + neighbors_of_non_radical = len(neutral_neighbors) + len(radical_neighbors) + neighbors_of_neutral = len(non_radical_neighbors) + len(radical_neighbors) + neighbors_of_radical = len(non_radical_neighbors) + len(neutral_neighbors) + threshold = 8 + if (len(non_radical_neighbors) > neighbors_of_non_radical) and len(non_radical_neighbors) >= threshold: + self.state['id'] = NON_RADICAL + elif (len(neutral_neighbors) > neighbors_of_neutral) and len(neutral_neighbors) >= threshold: + self.state['id'] = NEUTRAL + elif (len(radical_neighbors) > neighbors_of_radical) and len(radical_neighbors) >= threshold: + self.state['id'] = RADICAL + + if self.state['id'] == NEUTRAL: + for neighbor in non_radical_neighbors: + neighbor.state['rad'] = neighbor.state['rad'] + (self.influence + self.additional_influence) * self.information_spread_intensity + if neighbor.state['rad'] >= 0.3 and neighbor.state['rad'] <= 0.59: + neighbor.state['id'] = NEUTRAL + if neighbor.state['type'] == POPULATION: + neighbor.state['fstatus'] = POPNE + elif neighbor.state['type'] == HAVEN: + neighbor.state['fstatus'] = HAVNE + elif neighbor.state['rad'] > 0.59: + neighbor.state['rad'] = 0.59 + neighbor.state['id'] = NEUTRAL + if neighbor.state['type'] == POPULATION: + neighbor.state['fstatus'] = POPNE + elif neighbor.state['type'] == HAVEN: + neighbor.state['fstatus'] = HAVNE + + if self.state['id'] == RADICAL: + + for neighbor in non_radical_neighbors: + neighbor.state['rad'] = neighbor.state['rad'] + (self.influence + self.additional_influence) * self.information_spread_intensity + if neighbor.state['rad'] >= 0.3 and neighbor.state['rad'] <= 0.59: + neighbor.state['id'] = NEUTRAL + if neighbor.state['type'] == POPULATION: + neighbor.state['fstatus'] = POPNE + elif neighbor.state['type'] == HAVEN: + neighbor.state['fstatus'] = HAVNE + elif neighbor.state['rad'] > 0.59: + neighbor.state['rad'] = 0.59 + neighbor.state['id'] = NEUTRAL + if neighbor.state['type'] == POPULATION: + neighbor.state['fstatus'] = POPNE + elif neighbor.state['type'] == HAVEN: + neighbor.state['fstatus'] = HAVNE + + for neighbor in neutral_neighbors: + neighbor.state['rad'] = neighbor.state['rad'] + (self.influence + self.additional_influence) * self.information_spread_intensity + if neighbor.state['rad'] >= 0.6: + neighbor.state['id'] = RADICAL + if neighbor.state['type'] != HAVEN and neighbor.state['type']!=TRAININGENV: + if neighbor.state['rad'] >= 0.62: + if create_leader(neighbor): + neighbor.state['type'] = LEADERS + neighbor.state['fstatus'] = LEADER + # elif neighbor.state['type'] == LEADERS: + # neighbor.state['type'] = POPULATION + # neighbor.state['fstatus'] = POPRAD + elif neighbor.state['type'] == POPULATION: + neighbor.state['fstatus'] = POPRAD + elif neighbor.state['type'] == HAVEN: + neighbor.state['fstatus'] = HAVRAD + + def training_enviroment_conduct(self): + self.state['id'] = RADICAL + self.state['rad'] = 1 + neighbors = self.get_neighboring_agents() + for neighbor in neighbors: + if neighbor.state['id'] == NON_RADICAL: + neighbor.state['rad'] = neighbor.state['rad'] + (self.influence + self.additional_influence) * self.information_spread_intensity + if neighbor.state['rad'] >= 0.3 and self.state['rad'] <= 0.59: + neighbor.state['id'] = NEUTRAL + if neighbor.state['type'] == POPULATION: + neighbor.state['fstatus'] = POPNE + elif neighbor.state['type'] == HAVEN: + neighbor.state['fstatus'] = HAVNE + elif neighbor.state['rad'] > 0.59: + neighbor.state['rad'] = 0.59 + neighbor.state['id'] = NEUTRAL + if neighbor.state['type'] == POPULATION: + neighbor.state['fstatus'] = POPNE + elif neighbor.state['type'] == HAVEN: + neighbor.state['fstatus'] = HAVNE + + + neighbor.state['rad'] = neighbor.state['rad'] + (neighbor.influence + neighbor.additional_influence) * neighbor.information_spread_intensity + if neighbor.state['rad'] >= 0.3 and neighbor.state['rad'] <= 0.59: + neighbor.state['id'] = NEUTRAL + if neighbor.state['type'] == POPULATION: + neighbor.state['fstatus'] = POPNE + elif neighbor.state['type'] == HAVEN: + neighbor.state['fstatus'] = HAVNE + elif neighbor.state['rad'] >= 0.6: + neighbor.state['id'] = RADICAL + if neighbor.state['type'] != HAVEN and neighbor.state['type'] != TRAININGENV: + if neighbor.state['rad'] >= 0.62: + if create_leader(neighbor): + neighbor.state['type'] = LEADERS + neighbor.state['fstatus'] = LEADER + # elif neighbor.state['type'] == LEADERS: + # neighbor.state['type'] = POPULATION + # neighbor.state['fstatus'] = POPRAD + elif neighbor.state['type'] == POPULATION: + neighbor.state['fstatus'] = POPRAD + elif neighbor.state['type'] == HAVEN: + neighbor.state['fstatus'] = HAVRAD + + def non_radical_behaviour(self): + neighbors = self.get_neighboring_agents() + + for neighbor in neighbors: + if neighbor.state['type'] == POPULATION: + if neighbor.state['id'] == NEUTRAL or neighbor.state['id'] == RADICAL: + self.state['rad'] = self.state['rad'] + self.influence * self.information_spread_intensity + if self.state['rad'] >= 0.3 and self.state['rad'] <= 0.59: + self.state['id'] = NEUTRAL + + if self.state['type']==POPULATION: + self.state['fstatus'] = POPNE + elif self.state['type'] == HAVEN: + self.state['fstatus'] = HAVNE + elif self.state['rad'] > 0.59: + self.state['rad'] = 0.59 + self.state['id'] = NEUTRAL + if self.state['type']==POPULATION: + self.state['fstatus'] = POPNE + elif self.state['type'] == HAVEN: + self.state['fstatus'] = HAVNE + + elif neighbor.state['type'] == LEADERS: + + if neighbor.state['id'] == NEUTRAL or neighbor.state['id'] == RADICAL: + self.state['rad'] = self.state['rad'] + (self.influence + self.additional_influence) * self.information_spread_intensity + if self.state['rad'] >= 0.3 and self.state['rad'] <= 0.59: + self.state['id'] = NEUTRAL + if self.state['type']==POPULATION: + self.state['fstatus'] = POPNE + elif self.state['type'] == HAVEN: + self.state['fstatus'] = HAVNE + elif self.state['rad'] > 0.59: + self.state['rad'] = 0.59 + self.state['id'] = NEUTRAL + if self.state['type']==POPULATION: + self.state['fstatus'] = POPNE + elif self.state['type'] == HAVEN: + self.state['fstatus'] = HAVNE + + + def neutral_behaviour(self): + neighbors = self.get_neighboring_agents() + for neighbor in neighbors: + if neighbor.state['type'] == POPULATION: + if neighbor.state['id'] == RADICAL: + self.state['rad'] = self.state['rad'] + self.influence * self.information_spread_intensity + if self.state['rad'] >= 0.6: + self.state['id'] = RADICAL + if self.state['type'] != HAVEN: + if self.state['rad'] >= 0.62: + if create_leader(self): + self.state['type'] = LEADERS + + self.state['fstatus'] = LEADER + # elif self.state['type'] == LEADERS: + # self.state['type'] = POPULATION + # self.state['fstatus'] = POPRAD + elif neighbor.state['type'] == POPULATION: + self.state['fstatus'] = POPRAD + elif self.state['type'] == HAVEN: + self.state['fstatus'] = HAVRAD + + + elif neighbor.state['type'] == LEADERS: + if neighbor.state['id'] == RADICAL: + self.state['rad'] = self.state['rad'] + (self.influence + self.additional_influence) * self.information_spread_intensity + if self.state['rad'] >= 0.6: + self.state['id'] = RADICAL + if self.state['type'] != HAVEN: + if self.state['rad'] >= 0.62: + if create_leader(self): + self.state['type'] = LEADERS + self.state['fstatus'] = LEADER + # elif self.state['type'] == LEADERS: + # self.state['type'] = POPULATION + # self.state['fstatus'] = POPRAD + elif neighbor.state['type'] == POPULATION: + self.state['fstatus'] = POPRAD + elif self.state['type'] == HAVEN: + self.state['fstatus'] = HAVRAD + + + + + + def radical_behaviour(self): + neighbors = self.get_neighboring_agents(state_id=RADICAL) + + for neighbor in neighbors: + if self.state['rad']< neighbor.state['rad'] and self.state['type']== LEADERS and neighbor.state['type']==LEADERS: + self.state['type'] = POPULATION + self.state['fstatus'] = POPRAD + + + def set_radicalism(self): + if self.state['id'] == NON_RADICAL: + radicalism = random.uniform(0.0, 0.29) * self.relative_inequality + return radicalism + elif self.state['id'] == NEUTRAL: + radicalism = 0.3 + random.uniform(0.3, 0.59) * self.relative_inequality + if radicalism >= 0.6: + self.state['id'] = RADICAL + return radicalism + elif self.state['id'] == RADICAL: + radicalism = 0.6 + random.uniform(0.6, 1.0) * self.relative_inequality + return radicalism + +def get_partition(agent): + return settings.partition_param[agent.id] + +def get_centrality(agent): + return settings.centrality_param[agent.id] +def get_centrality_given_id(id): + return settings.centrality_param[id] + +def get_leader(partition): + if not bool(settings.leaders) or partition not in settings.leaders.keys(): + return None + return settings.leaders[partition] + +def set_leader(partition, agent): + settings.leaders[partition] = agent.id + +def create_leader(agent): + my_partition = get_partition(agent) + old_leader = get_leader(my_partition) + + if old_leader == None: + set_leader(my_partition, agent) + return True + else: + my_centrality = get_centrality(agent) + old_leader_centrality = get_centrality_given_id(old_leader) + if my_centrality > old_leader_centrality: + set_leader(my_partition, agent) + return True + return False + + + diff --git a/models/TerroristModel/__init__.py b/models/TerroristModel/__init__.py new file mode 100644 index 0000000..8a1d874 --- /dev/null +++ b/models/TerroristModel/__init__.py @@ -0,0 +1 @@ +from .TerroristModel import TerroristModel \ No newline at end of file diff --git a/models/__init__.py b/models/__init__.py new file mode 100755 index 0000000..1e45794 --- /dev/null +++ b/models/__init__.py @@ -0,0 +1,3 @@ +from .models import * +from .BaseBehaviour import * +from .TerroristModel import * diff --git a/models/models.py b/models/models.py new file mode 100755 index 0000000..3ff0403 --- /dev/null +++ b/models/models.py @@ -0,0 +1,7 @@ +import settings + +networkStatus = {} # Dict that will contain the status of every agent in the network + +# Initialize agent states. Let's assume everyone is normal and all types are population. +init_states = [{'id': 0, 'type': 0, 'rad': 0, 'fstatus':0, } for _ in range(settings.network_params["number_of_nodes"])] + diff --git a/models_org.py b/models_org.py deleted file mode 100644 index fb776cc..0000000 --- a/models_org.py +++ /dev/null @@ -1,596 +0,0 @@ -from nxsim import BaseNetworkAgent -import numpy as np -import random -import settings - -settings.init() - -############################## -# Variables initialization # -############################## -def init(): - global networkStatus - networkStatus = {} # Dict that will contain the status of every agent in the network - -sentimentCorrelationNodeArray=[] -for x in range(0, settings.number_of_nodes): - sentimentCorrelationNodeArray.append({'id':x}) -# Initialize agent states. Let's assume everyone is normal. -init_states = [{'id': 0, } for _ in range(settings.number_of_nodes)] # add keys as as necessary, but "id" must always refer to that state category - - -#################### -# Available models # -#################### - -class BaseBehaviour(BaseNetworkAgent): - def __init__(self, environment=None, agent_id=0, state=()): - super().__init__(environment=environment, agent_id=agent_id, state=state) - self._attrs = {} - - @property - def attrs(self): - now = self.env.now - if now not in self._attrs: - self._attrs[now] = {} - return self._attrs[now] - - @attrs.setter - def attrs(self, value): - self._attrs[self.env.now] = value - - def run(self): - while True: - self.step(self.env.now) - yield self.env.timeout(settings.timeout) - - def step(self, now): - networkStatus['agent_%s'% self.id] = self.to_json() - - def to_json(self): - final = {} - for stamp, attrs in self._attrs.items(): - for a in attrs: - if a not in final: - final[a] = {} - final[a][stamp] = attrs[a] - return final - -class ControlModelM2(BaseBehaviour): - #Init infected - init_states[random.randint(0,settings.number_of_nodes-1)] = {'id':1} - init_states[random.randint(0,settings.number_of_nodes-1)] = {'id':1} - - # Init beacons - init_states[random.randint(0, settings.number_of_nodes-1)] = {'id': 4} - init_states[random.randint(0, settings.number_of_nodes-1)] = {'id': 4} - def __init__(self, environment=None, agent_id=0, state=()): - super().__init__(environment=environment, agent_id=agent_id, state=state) - - self.prob_neutral_making_denier = np.random.normal(settings.prob_neutral_making_denier, settings.standard_variance) - - self.prob_infect = np.random.normal(settings.prob_infect, settings.standard_variance) - - self.prob_cured_healing_infected = np.random.normal(settings.prob_cured_healing_infected, settings.standard_variance) - self.prob_cured_vaccinate_neutral = np.random.normal(settings.prob_cured_vaccinate_neutral, settings.standard_variance) - - self.prob_vaccinated_healing_infected = np.random.normal(settings.prob_vaccinated_healing_infected, settings.standard_variance) - self.prob_vaccinated_vaccinate_neutral = np.random.normal(settings.prob_vaccinated_vaccinate_neutral, settings.standard_variance) - self.prob_generate_anti_rumor = np.random.normal(settings.prob_generate_anti_rumor, settings.standard_variance) - - def step(self, now): - - if self.state['id'] == 0: #Neutral - self.neutral_behaviour() - elif self.state['id'] == 1: #Infected - self.infected_behaviour() - elif self.state['id'] == 2: #Cured - self.cured_behaviour() - elif self.state['id'] == 3: #Vaccinated - self.vaccinated_behaviour() - elif self.state['id'] == 4: #Beacon-off - self.beacon_off_behaviour() - elif self.state['id'] == 5: #Beacon-on - self.beacon_on_behaviour() - - self.attrs['status'] = self.state['id'] - super().step(now) - - - def neutral_behaviour(self): - - # Infected - infected_neighbors = self.get_neighboring_agents(state_id=1) - if len(infected_neighbors)>0: - if random.random() < self.prob_neutral_making_denier: - self.state['id'] = 3 # Vaccinated making denier - - def infected_behaviour(self): - - # Neutral - neutral_neighbors = self.get_neighboring_agents(state_id=0) - for neighbor in neutral_neighbors: - if random.random() < self.prob_infect: - neighbor.state['id'] = 1 # Infected - - def cured_behaviour(self): - - # Vaccinate - neutral_neighbors = self.get_neighboring_agents(state_id=0) - for neighbor in neutral_neighbors: - if random.random() < self.prob_cured_vaccinate_neutral: - neighbor.state['id'] = 3 # Vaccinated - - # Cure - infected_neighbors = self.get_neighboring_agents(state_id=1) - for neighbor in infected_neighbors: - if random.random() < self.prob_cured_healing_infected: - neighbor.state['id'] = 2 # Cured - - - def vaccinated_behaviour(self): - - # Cure - infected_neighbors = self.get_neighboring_agents(state_id=1) - for neighbor in infected_neighbors: - if random.random() < self.prob_cured_healing_infected: - neighbor.state['id'] = 2 # Cured - - - # Vaccinate - neutral_neighbors = self.get_neighboring_agents(state_id=0) - for neighbor in neutral_neighbors: - if random.random() < self.prob_cured_vaccinate_neutral: - neighbor.state['id'] = 3 # Vaccinated - - # Generate anti-rumor - infected_neighbors_2 = self.get_neighboring_agents(state_id=1) - for neighbor in infected_neighbors_2: - if random.random() < self.prob_generate_anti_rumor: - neighbor.state['id'] = 2 # Cured - - def beacon_off_behaviour(self): - infected_neighbors = self.get_neighboring_agents(state_id=1) - if len(infected_neighbors) > 0: - self.state['id'] == 5 #Beacon on - - def beacon_on_behaviour(self): - - # Cure (M2 feature added) - infected_neighbors = self.get_neighboring_agents(state_id=1) - for neighbor in infected_neighbors: - if random.random() < self.prob_generate_anti_rumor: - neighbor.state['id'] = 2 # Cured - neutral_neighbors_infected = neighbor.get_neighboring_agents(state_id=0) - for neighbor in neutral_neighbors_infected: - if random.random() < self.prob_generate_anti_rumor: - neighbor.state['id'] = 3 # Vaccinated - infected_neighbors_infected = neighbor.get_neighboring_agents(state_id=1) - for neighbor in infected_neighbors_infected: - if random.random() < self.prob_generate_anti_rumor: - neighbor.state['id'] = 2 # Cured - - - # Vaccinate - neutral_neighbors = self.get_neighboring_agents(state_id=0) - for neighbor in neutral_neighbors: - if random.random() < self.prob_cured_vaccinate_neutral: - neighbor.state['id'] = 3 # Vaccinated - - -class SpreadModelM2(BaseBehaviour): - init_states[random.randint(0,settings.number_of_nodes)] = {'id':1} - init_states[random.randint(0,settings.number_of_nodes)] = {'id':1} - def __init__(self, environment=None, agent_id=0, state=()): - super().__init__(environment=environment, agent_id=agent_id, state=state) - - self.prob_neutral_making_denier = np.random.normal(settings.prob_neutral_making_denier, settings.standard_variance) - - self.prob_infect = np.random.normal(settings.prob_infect, settings.standard_variance) - - self.prob_cured_healing_infected = np.random.normal(settings.prob_cured_healing_infected, settings.standard_variance) - self.prob_cured_vaccinate_neutral = np.random.normal(settings.prob_cured_vaccinate_neutral, settings.standard_variance) - - self.prob_vaccinated_healing_infected = np.random.normal(settings.prob_vaccinated_healing_infected, settings.standard_variance) - self.prob_vaccinated_vaccinate_neutral = np.random.normal(settings.prob_vaccinated_vaccinate_neutral, settings.standard_variance) - self.prob_generate_anti_rumor = np.random.normal(settings.prob_generate_anti_rumor, settings.standard_variance) - - def step(self, now): - - if self.state['id'] == 0: #Neutral - self.neutral_behaviour() - elif self.state['id'] == 1: #Infected - self.infected_behaviour() - elif self.state['id'] == 2: #Cured - self.cured_behaviour() - elif self.state['id'] == 3: #Vaccinated - self.vaccinated_behaviour() - - self.attrs['status'] = self.state['id'] - super().step(now) - - - def neutral_behaviour(self): - - # Infected - infected_neighbors = self.get_neighboring_agents(state_id=1) - if len(infected_neighbors)>0: - if random.random() < self.prob_neutral_making_denier: - self.state['id'] = 3 # Vaccinated making denier - - def infected_behaviour(self): - - # Neutral - neutral_neighbors = self.get_neighboring_agents(state_id=0) - for neighbor in neutral_neighbors: - if random.random() < self.prob_infect: - neighbor.state['id'] = 1 # Infected - - def cured_behaviour(self): - - # Vaccinate - neutral_neighbors = self.get_neighboring_agents(state_id=0) - for neighbor in neutral_neighbors: - if random.random() < self.prob_cured_vaccinate_neutral: - neighbor.state['id'] = 3 # Vaccinated - - # Cure - infected_neighbors = self.get_neighboring_agents(state_id=1) - for neighbor in infected_neighbors: - if random.random() < self.prob_cured_healing_infected: - neighbor.state['id'] = 2 # Cured - - - def vaccinated_behaviour(self): - - # Cure - infected_neighbors = self.get_neighboring_agents(state_id=1) - for neighbor in infected_neighbors: - if random.random() < self.prob_cured_healing_infected: - neighbor.state['id'] = 2 # Cured - - - # Vaccinate - neutral_neighbors = self.get_neighboring_agents(state_id=0) - for neighbor in neutral_neighbors: - if random.random() < self.prob_cured_vaccinate_neutral: - neighbor.state['id'] = 3 # Vaccinated - - # Generate anti-rumor - infected_neighbors_2 = self.get_neighboring_agents(state_id=1) - for neighbor in infected_neighbors_2: - if random.random() < self.prob_generate_anti_rumor: - neighbor.state['id'] = 2 # Cured - - -class SISaModel(BaseBehaviour): - def __init__(self, environment=None, agent_id=0, state=()): - super().__init__(environment=environment, agent_id=agent_id, state=state) - - self.neutral_discontent_spon_prob = np.random.normal(settings.neutral_discontent_spon_prob, settings.standard_variance) - self.neutral_discontent_infected_prob = np.random.normal(settings.neutral_discontent_infected_prob,settings.standard_variance) - self.neutral_content_spon_prob = np.random.normal(settings.neutral_content_spon_prob,settings.standard_variance) - self.neutral_content_infected_prob = np.random.normal(settings.neutral_content_infected_prob,settings.standard_variance) - - self.discontent_neutral = np.random.normal(settings.discontent_neutral,settings.standard_variance) - self.discontent_content = np.random.normal(settings.discontent_content,settings.variance_d_c) - - self.content_discontent = np.random.normal(settings.content_discontent,settings.variance_c_d) - self.content_neutral = np.random.normal(settings.content_neutral,settings.standard_variance) - - def step(self, now): - - if self.state['id'] == 0: - self.neutral_behaviour() - if self.state['id'] == 1: - self.discontent_behaviour() - if self.state['id'] == 2: - self.content_behaviour() - - self.attrs['status'] = self.state['id'] - super().step(now) - - - def neutral_behaviour(self): - - #Spontaneus effects - if random.random() < self.neutral_discontent_spon_prob: - self.state['id'] = 1 - if random.random() < self.neutral_content_spon_prob: - self.state['id'] = 2 - - #Infected - discontent_neighbors = self.get_neighboring_agents(state_id=1) - if random.random() < len(discontent_neighbors)*self.neutral_discontent_infected_prob: - self.state['id'] = 1 - content_neighbors = self.get_neighboring_agents(state_id=2) - if random.random() < len(content_neighbors)*self.neutral_content_infected_prob: - self.state['id'] = 2 - - def discontent_behaviour(self): - - #Healing - if random.random() < self.discontent_neutral: - self.state['id'] = 0 - - #Superinfected - content_neighbors = self.get_neighboring_agents(state_id=2) - if random.random() < len(content_neighbors)*self.discontent_content: - self.state['id'] = 2 - - def content_behaviour(self): - - #Healing - if random.random() < self.content_neutral: - self.state['id'] = 0 - - #Superinfected - discontent_neighbors = self.get_neighboring_agents(state_id=1) - if random.random() < len(discontent_neighbors)*self.content_discontent: - self.state['id'] = 1 - - -class BigMarketModel(BaseBehaviour): - - def __init__(self, environment=None, agent_id=0, state=()): - super().__init__(environment=environment, agent_id=agent_id, state=state) - self.enterprises = settings.enterprises - self.type = "" - self.number_of_enterprises = len(settings.enterprises) - - if self.id < self.number_of_enterprises: #Enterprises - self.state['id']=self.id - self.type="Enterprise" - self.tweet_probability = settings.tweet_probability_enterprises[self.id] - else: #normal users - self.state['id']=self.number_of_enterprises - self.type="User" - self.tweet_probability = settings.tweet_probability_users - self.tweet_relevant_probability = settings.tweet_relevant_probability - self.tweet_probability_about = settings.tweet_probability_about #List - self.sentiment_about = settings.sentiment_about #List - - def step(self, now): - - if(self.id < self.number_of_enterprises): # Ennterprise - self.enterpriseBehaviour() - else: # Usuario - self.userBehaviour() - for i in range(self.number_of_enterprises): # So that it never is set to 0 if there are not changes (logs) - self.attrs['sentiment_enterprise_%s'% self.enterprises[i]] = self.sentiment_about[i] - - super().step(now) - - def enterpriseBehaviour(self): - - if random.random()< self.tweet_probability: #Tweets - aware_neighbors = self.get_neighboring_agents(state_id=self.number_of_enterprises) #Nodes neighbour users - for x in aware_neighbors: - if random.uniform(0,10) < 5: - x.sentiment_about[self.id] += 0.1 #Increments for enterprise - else: - x.sentiment_about[self.id] -= 0.1 #Decrements for enterprise - - # Establecemos limites - if x.sentiment_about[self.id] > 1: - x.sentiment_about[self.id] = 1 - if x.sentiment_about[self.id]< -1: - x.sentiment_about[self.id] = -1 - - x.attrs['sentiment_enterprise_%s'% self.enterprises[self.id]] = x.sentiment_about[self.id] - - - def userBehaviour(self): - - if random.random() < self.tweet_probability: #Tweets - if random.random() < self.tweet_relevant_probability: #Tweets something relevant - #Tweet probability per enterprise - for i in range(self.number_of_enterprises): - random_num = random.random() - if random_num < self.tweet_probability_about[i]: - #The condition is fulfilled, sentiments are evaluated towards that enterprise - if self.sentiment_about[i] < 0: - #NEGATIVO - self.userTweets("negative",i) - elif self.sentiment_about[i] == 0: - #NEUTRO - pass - else: - #POSITIVO - self.userTweets("positive",i) - - def userTweets(self,sentiment,enterprise): - aware_neighbors = self.get_neighboring_agents(state_id=self.number_of_enterprises) #Nodes neighbours users - for x in aware_neighbors: - if sentiment == "positive": - x.sentiment_about[enterprise] +=0.003 - elif sentiment == "negative": - x.sentiment_about[enterprise] -=0.003 - else: - pass - - # Establecemos limites - if x.sentiment_about[enterprise] > 1: - x.sentiment_about[enterprise] = 1 - if x.sentiment_about[enterprise] < -1: - x.sentiment_about[enterprise] = -1 - - x.attrs['sentiment_enterprise_%s'% self.enterprises[enterprise]] = x.sentiment_about[enterprise] - -class SentimentCorrelationModel(BaseBehaviour): - - def __init__(self, environment=None, agent_id=0, state=()): - super().__init__(environment=environment, agent_id=agent_id, state=state) - self.outside_effects_prob = settings.outside_effects_prob - self.anger_prob = settings.anger_prob - self.joy_prob = settings.joy_prob - self.sadness_prob = settings.sadness_prob - self.disgust_prob = settings.disgust_prob - self.time_awareness=[] - for i in range(4): #In this model we have 4 sentiments - self.time_awareness.append(0) #0-> Anger, 1-> joy, 2->sadness, 3 -> disgust - sentimentCorrelationNodeArray[self.id][self.env.now]=0 - - - def step(self, now): - self.behaviour() - super().step(now) - - def behaviour(self): - - angry_neighbors_1_time_step=[] - joyful_neighbors_1_time_step=[] - sad_neighbors_1_time_step=[] - disgusted_neighbors_1_time_step=[] - - - angry_neighbors = self.get_neighboring_agents(state_id=1) - for x in angry_neighbors: - if x.time_awareness[0] > (self.env.now-500): - angry_neighbors_1_time_step.append(x) - num_neighbors_angry = len(angry_neighbors_1_time_step) - - - joyful_neighbors = self.get_neighboring_agents(state_id=2) - for x in joyful_neighbors: - if x.time_awareness[1] > (self.env.now-500): - joyful_neighbors_1_time_step.append(x) - num_neighbors_joyful = len(joyful_neighbors_1_time_step) - - - sad_neighbors = self.get_neighboring_agents(state_id=3) - for x in sad_neighbors: - if x.time_awareness[2] > (self.env.now-500): - sad_neighbors_1_time_step.append(x) - num_neighbors_sad = len(sad_neighbors_1_time_step) - - - disgusted_neighbors = self.get_neighboring_agents(state_id=4) - for x in disgusted_neighbors: - if x.time_awareness[3] > (self.env.now-500): - disgusted_neighbors_1_time_step.append(x) - num_neighbors_disgusted = len(disgusted_neighbors_1_time_step) - - - anger_prob= settings.anger_prob+(len(angry_neighbors_1_time_step)*settings.anger_prob) - joy_prob= settings.joy_prob+(len(joyful_neighbors_1_time_step)*settings.joy_prob) - sadness_prob = settings.sadness_prob+(len(sad_neighbors_1_time_step)*settings.sadness_prob) - disgust_prob = settings.disgust_prob+(len(disgusted_neighbors_1_time_step)*settings.disgust_prob) - outside_effects_prob= settings.outside_effects_prob - - - num = random.random() - - - if(numanger_prob): - - self.state['id'] = 2 - sentimentCorrelationNodeArray[self.id][self.env.now]=2 - self.time_awareness[self.state['id']-1] = self.env.now - elif (numjoy_prob+anger_prob): - - - self.state['id'] = 3 - sentimentCorrelationNodeArray[self.id][self.env.now]=3 - self.time_awareness[self.state['id']-1] = self.env.now - elif (numsadness_prob+anger_prob+joy_prob): - - - self.state['id'] = 4 - sentimentCorrelationNodeArray[self.id][self.env.now]=4 - self.time_awareness[self.state['id']-1] = self.env.now - - self.attrs['sentiment'] = self.state['id'] - - -class BassModel(BaseBehaviour): - def __init__(self, environment=None, agent_id=0, state=()): - super().__init__(environment=environment, agent_id=agent_id, state=state) - self.innovation_prob = settings.innovation_prob - self.imitation_prob = settings.imitation_prob - sentimentCorrelationNodeArray[self.id][self.env.now]=0 - - def step(self, now): - self.behaviour() - super().step(now) - - def behaviour(self): - #Outside effects - if random.random() < settings.innovation_prob: - if self.state['id'] == 0: - self.state['id'] = 1 - sentimentCorrelationNodeArray[self.id][self.env.now]=1 - else: - pass - - self.attrs['status'] = self.state['id'] - return - - #Imitation effects - if self.state['id'] == 0: - aware_neighbors = self.get_neighboring_agents(state_id=1) - num_neighbors_aware = len(aware_neighbors) - if random.random() < (settings.imitation_prob*num_neighbors_aware): - self.state['id'] = 1 - sentimentCorrelationNodeArray[self.id][self.env.now]=1 - - else: - pass - self.attrs['status'] = self.state['id'] - - -class IndependentCascadeModel(BaseBehaviour): - def __init__(self, environment=None, agent_id=0, state=()): - super().__init__(environment=environment, agent_id=agent_id, state=state) - self.innovation_prob = settings.innovation_prob - self.imitation_prob = settings.imitation_prob - self.time_awareness = 0 - sentimentCorrelationNodeArray[self.id][self.env.now]=0 - - def step(self,now): - self.behaviour() - super().step(now) - - def behaviour(self): - aware_neighbors_1_time_step=[] - #Outside effects - if random.random() < settings.innovation_prob: - if self.state['id'] == 0: - self.state['id'] = 1 - sentimentCorrelationNodeArray[self.id][self.env.now]=1 - self.time_awareness = self.env.now #To know when they have been infected - else: - pass - - self.attrs['status'] = self.state['id'] - return - - #Imitation effects - if self.state['id'] == 0: - aware_neighbors = self.get_neighboring_agents(state_id=1) - for x in aware_neighbors: - if x.time_awareness == (self.env.now-1): - aware_neighbors_1_time_step.append(x) - num_neighbors_aware = len(aware_neighbors_1_time_step) - if random.random() < (settings.imitation_prob*num_neighbors_aware): - self.state['id'] = 1 - sentimentCorrelationNodeArray[self.id][self.env.now]=1 - else: - pass - - self.attrs['status'] = self.state['id'] - return diff --git a/notebooks/soil_tutorial.ipynb b/notebooks/soil_tutorial.ipynb deleted file mode 100644 index d19424e..0000000 --- a/notebooks/soil_tutorial.ipynb +++ /dev/null @@ -1,1912 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-02T16:44:14.120953Z", - "start_time": "2017-07-02T18:44:14.117152+02:00" - } - }, - "source": [ - "# Introduction" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "cell_style": "center", - "collapsed": true - }, - "source": [ - "This notebook is an introduction to the soil agent-based social network simulation framework.\n", - "In particular, we will focus on a specific use case: studying the propagation of news in a social network.\n", - "\n", - "The steps we will follow are:\n", - "\n", - "* Modelling the behavior of agents\n", - "* Running the simulation using different configurations\n", - "* Analysing the results of each simulation" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T13:38:48.052876Z", - "start_time": "2017-07-03T15:38:48.044762+02:00" - } - }, - "source": [ - "But before that, let's import the soil module and networkx." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T14:42:51.679937Z", - "start_time": "2017-07-03T16:42:51.185463+02:00" - }, - "collapsed": true - }, - "outputs": [], - "source": [ - "import soil\n", - "import networkx as nx" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T14:42:51.690373Z", - "start_time": "2017-07-03T16:42:51.682644+02:00" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Populating the interactive namespace from numpy and matplotlib\n" - ] - } - ], - "source": [ - "%pylab inline\n", - "# To display plots in the notebook" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T13:41:19.788717Z", - "start_time": "2017-07-03T15:41:19.785448+02:00" - } - }, - "source": [ - "# Basic concepts" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "There are three main elements in a soil simulation:\n", - " \n", - "* The network topology. A simulation may use an existing NetworkX topology, or generate one on the fly\n", - "* Agents. There are two types: 1) network agents, which are linked to a node in the topology, and 2) environment agents, which are freely assigned to the environment.\n", - "* The environment. It assigns agents to nodes in the network, and stores the environment parameters (shared state for all agents).\n", - "\n", - "Soil is based on ``simpy``, which is an event-based network simulation library.\n", - "Soil provides several abstractions over events to make developing agents easier.\n", - "This means you can use events (timeouts, delays) in soil, but for the most part we will assume your models will be step-based.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-02T15:55:12.933978Z", - "start_time": "2017-07-02T17:55:12.930860+02:00" - } - }, - "source": [ - "# Modeling behaviour" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T13:49:31.269687Z", - "start_time": "2017-07-03T15:49:31.257850+02:00" - } - }, - "source": [ - "Our first step will be to model how every person in the social network reacts when it comes to news.\n", - "We will follow a very simple model (a finite state machine).\n", - "\n", - "There are two types of people, those who have heard about a newsworthy event (infected) or those who have not (neutral).\n", - "A neutral person may heard about the news either on the TV (with probability **prob_tv_spread**) or through their friends.\n", - "Once a person has heard the news, they will spread it to their friends (with a probability **prob_neighbor_spread**).\n", - "Some users do not have a TV, so they only rely on their friends.\n", - "\n", - "The spreading probabilities will change over time due to different factors.\n", - "We will represent this variance using an environment agent." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Network Agents" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T14:03:07.171127Z", - "start_time": "2017-07-03T16:03:07.165779+02:00" - } - }, - "source": [ - "A basic network agent in Soil should inherit from ``soil.agents.BaseAgent``, and define its behaviour in every step of the simulation by implementing a ``run(self)`` method.\n", - "The most important attributes of the agent are:\n", - "\n", - "* ``agent.state``, a dictionary with the state of the agent. ``agent.state['id']`` reflects the state id of the agent. That state id can be used to look for other networks in that specific state. The state can be access via the agent as well. For instance:\n", - "```py\n", - "a = soil.agents.BaseAgent(env=env)\n", - "a['hours_of_sleep'] = 10\n", - "print(a['hours_of_sleep'])\n", - "```\n", - " The state of the agent is stored in every step of the simulation:\n", - " ```py\n", - " print(a['hours_of_sleep', 10]) # hours of sleep before step #10\n", - " print(a[None, 0]) # whole state of the agent before step #0\n", - " ```\n", - "\n", - "* ``agent.env``, a reference to the environment. Most commonly used to get access to the environment parameters and the topology:\n", - " ```py\n", - " a.env.G.nodes() # Get all nodes ids in the topology\n", - " a.env['minimum_hours_of_sleep']\n", - "\n", - " ```\n", - "\n", - "Since our model is a finite state machine, we will be basing it on ``soil.agents.FSM``.\n", - "\n", - "With ``soil.agents.FSM``, we do not need to specify a ``step`` method.\n", - "Instead, we describe every step as a function.\n", - "To change to another state, a function may return the new state.\n", - "If no state is returned, the state remains unchanged.[\n", - "It will consist of two states, ``neutral`` (default) and ``infected``.\n", - "\n", - "Here's the code:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T14:42:51.715535Z", - "start_time": "2017-07-03T16:42:51.692301+02:00" - }, - "collapsed": true - }, - "outputs": [], - "source": [ - "import random\n", - "\n", - "class NewsSpread(soil.agents.FSM):\n", - " @soil.agents.default_state\n", - " @soil.agents.state\n", - " def neutral(self):\n", - " r = random.random()\n", - " if self['has_tv'] and r < self.env['prob_tv_spread']:\n", - " return self.infected\n", - " return\n", - " \n", - " @soil.agents.state\n", - " def infected(self):\n", - " prob_infect = self.env['prob_neighbor_spread']\n", - " for neighbor in self.get_neighboring_agents(state_id=self.neutral.id):\n", - " r = random.random()\n", - " if r < prob_infect:\n", - " neighbor.state['id'] = self.infected.id\n", - " return\n", - " " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-02T12:22:53.931963Z", - "start_time": "2017-07-02T14:22:53.928340+02:00" - } - }, - "source": [ - "## Environment agents" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Environment agents allow us to control the state of the environment.\n", - "In this case, we will use an environment agent to simulate a very viral event.\n", - "\n", - "When the event happens, the agent will modify the probability of spreading the rumor." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T14:42:51.727938Z", - "start_time": "2017-07-03T16:42:51.717828+02:00" - }, - "collapsed": true - }, - "outputs": [], - "source": [ - "NEIGHBOR_FACTOR = 0.9\n", - "TV_FACTOR = 0.5\n", - "class NewsEnvironmentAgent(soil.agents.BaseAgent):\n", - " def step(self):\n", - " if self.now == self['event_time']:\n", - " self.env['prob_tv_spread'] = 1\n", - " self.env['prob_neighbor_spread'] = 1\n", - " elif self.now > self['event_time']:\n", - " self.env['prob_tv_spread'] = self.env['prob_tv_spread'] * TV_FACTOR\n", - " self.env['prob_neighbor_spread'] = self.env['prob_neighbor_spread'] * NEIGHBOR_FACTOR" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-02T11:23:18.052235Z", - "start_time": "2017-07-02T13:23:18.047452+02:00" - } - }, - "source": [ - "## Testing the agents" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-02T16:14:54.572431Z", - "start_time": "2017-07-02T18:14:54.564095+02:00" - } - }, - "source": [ - "Feel free to skip this section if this is your first time with soil." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Testing agents is not easy, and this is not a thorough testing process for agents.\n", - "Rather, this section is aimed to show you how to access internal pats of soil so you can test your agents." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "cell_style": "split" - }, - "source": [ - "First of all, let's check if our network agent has the states we would expect:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T14:42:51.816465Z", - "start_time": "2017-07-03T16:42:51.811222+02:00" - }, - "cell_style": "split" - }, - "outputs": [ - { - "data": { - "text/plain": [ - "{'infected': ,\n", - " 'neutral': }" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "NewsSpread.states" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "cell_style": "split" - }, - "source": [ - "Now, let's run a simulation on a simple network. It is comprised of three nodes:\n" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T14:42:52.106636Z", - "start_time": "2017-07-03T16:42:51.904738+02:00" - }, - "cell_style": "split", - "scrolled": false - }, - "outputs": [ - { - "data": { - "image/png": "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\n/X8ieN7dQkZLXwAAAABJRU5ErkJggg==\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "G = nx.Graph()\n", - "G.add_edge(0, 1)\n", - "G.add_edge(0, 2)\n", - "G.add_edge(2, 3)\n", - "G.add_node(4)\n", - "pos = nx.spring_layout(G)\n", - "nx.draw_networkx(G, pos, node_color='red')\n", - "nx.draw_networkx(G, pos, nodelist=[0], node_color='blue')" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T11:53:30.997756Z", - "start_time": "2017-07-03T13:53:30.989609+02:00" - }, - "cell_style": "split" - }, - "source": [ - "Let's run a simple simulation that assigns a NewsSpread agent to all the nodes in that network.\n", - "Notice how node 0 is the only one with a TV." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T14:42:52.136477Z", - "start_time": "2017-07-03T16:42:52.108729+02:00" - }, - "cell_style": "split" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Trial: 0\n", - "\tRunning\n", - "Finished trial in 0.014928102493286133 seconds\n", - "Finished simulation in 0.015764951705932617 seconds\n" - ] - } - ], - "source": [ - "env_params = {'prob_tv_spread': 0,\n", - " 'prob_neighbor_spread': 0}\n", - "\n", - "MAX_TIME = 100\n", - "EVENT_TIME = 10\n", - "\n", - "sim = soil.simulation.SoilSimulation(topology=G,\n", - " num_trials=1,\n", - " max_time=MAX_TIME,\n", - " environment_agents=[{'agent_type': NewsEnvironmentAgent,\n", - " 'state': {\n", - " 'event_time': EVENT_TIME\n", - " }}],\n", - " network_agents=[{'agent_type': NewsSpread,\n", - " 'weight': 1}],\n", - " states={0: {'has_tv': True}},\n", - " default_state={'has_tv': False},\n", - " environment_params=env_params)\n", - "env = sim.run_simulation()[0]" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "cell_style": "split" - }, - "source": [ - "Now we can access the results of the simulation and compare them to our expected results" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T14:42:52.160856Z", - "start_time": "2017-07-03T16:42:52.138976+02:00" - }, - "cell_style": "split", - "collapsed": true, - "scrolled": false - }, - "outputs": [], - "source": [ - "agents = list(env.network_agents)\n", - "\n", - "# Until the event, all agents are neutral\n", - "for t in range(10):\n", - " for a in agents:\n", - " assert a['id', t] == a.neutral.id\n", - "\n", - "# After the event, the node with a TV is infected, the rest are not\n", - "assert agents[0]['id', 11] == NewsSpread.infected.id\n", - "\n", - "for a in agents[1:4]:\n", - " assert a['id', 11] == NewsSpread.neutral.id\n", - "\n", - "# At the end, the agents connected to the infected one will probably be infected, too.\n", - "assert agents[1]['id', MAX_TIME] == NewsSpread.infected.id\n", - "assert agents[2]['id', MAX_TIME] == NewsSpread.infected.id\n", - "\n", - "# But the node with no friends should not be affected\n", - "assert agents[4]['id', MAX_TIME] == NewsSpread.neutral.id\n", - " " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-02T16:41:09.110652Z", - "start_time": "2017-07-02T18:41:09.106966+02:00" - }, - "cell_style": "split" - }, - "source": [ - "Lastly, let's see if the probabilities have decreased as expected:" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T14:42:52.193918Z", - "start_time": "2017-07-03T16:42:52.163476+02:00" - }, - "cell_style": "split", - "collapsed": true - }, - "outputs": [], - "source": [ - "assert abs(env.environment_params['prob_neighbor_spread'] - (NEIGHBOR_FACTOR**(MAX_TIME-1-10))) < 10e-4\n", - "assert abs(env.environment_params['prob_tv_spread'] - (TV_FACTOR**(MAX_TIME-1-10))) < 10e-6" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Running the simulation" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T11:20:28.566944Z", - "start_time": "2017-07-03T13:20:28.561052+02:00" - }, - "cell_style": "split" - }, - "source": [ - "To run a simulation, we need a configuration.\n", - "Soil can load configurations from python dictionaries as well as JSON and YAML files.\n", - "For this demo, we will use a python dictionary:" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T14:42:52.219072Z", - "start_time": "2017-07-03T16:42:52.196203+02:00" - }, - "cell_style": "split", - "collapsed": true - }, - "outputs": [], - "source": [ - "config = {\n", - " 'name': 'ExampleSimulation',\n", - " 'max_time': 20,\n", - " 'interval': 1,\n", - " 'num_trials': 1,\n", - " 'network_params': {\n", - " 'generator': 'complete_graph',\n", - " 'n': 500,\n", - " },\n", - " 'network_agents': [\n", - " {\n", - " 'agent_type': NewsSpread,\n", - " 'weight': 1,\n", - " 'state': {\n", - " 'has_tv': False\n", - " }\n", - " },\n", - " {\n", - " 'agent_type': NewsSpread,\n", - " 'weight': 2,\n", - " 'state': {\n", - " 'has_tv': True\n", - " }\n", - " }\n", - " ],\n", - " 'states': [ {'has_tv': True} ],\n", - " 'environment_params':{\n", - " 'prob_tv_spread': 0.01,\n", - " 'prob_neighbor_spread': 0.5\n", - " }\n", - "}" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T11:57:34.219618Z", - "start_time": "2017-07-03T13:57:34.213817+02:00" - }, - "cell_style": "split" - }, - "source": [ - "Let's run our simulation:" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T14:42:55.366288Z", - "start_time": "2017-07-03T16:42:52.295584+02:00" - }, - "cell_style": "split" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Using config(s): ExampleSimulation\n", - "Trial: 0\n", - "\tRunning\n", - "Finished trial in 1.4140360355377197 seconds\n", - "Finished simulation in 2.4056642055511475 seconds\n" - ] - } - ], - "source": [ - "soil.simulation.run_from_config(config, dump=False)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T12:03:32.183588Z", - "start_time": "2017-07-03T14:03:32.167797+02:00" - }, - "cell_style": "split", - "collapsed": true - }, - "source": [ - "In real life, you probably want to run several simulations, varying some of the parameters so that you can compare and answer your research questions.\n", - "\n", - "For instance:\n", - " \n", - "* Does the outcome depend on the structure of our network? We will use different generation algorithms to compare them (Barabasi-Albert and Erdos-Renyi)\n", - "* How does neighbor spreading probability affect my simulation? We will try probability values in the range of [0, 0.4], in intervals of 0.1." - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T14:43:15.488799Z", - "start_time": "2017-07-03T16:42:55.368021+02:00" - }, - "cell_style": "split", - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Using config(s): Spread_erdos_renyi_graph_prob_0.0\n", - "Trial: 0\n", - "\tRunning\n", - "Finished trial in 0.2691483497619629 seconds\n", - "Finished simulation in 0.3650345802307129 seconds\n", - "Using config(s): Spread_erdos_renyi_graph_prob_0.1\n", - "Trial: 0\n", - "\tRunning\n", - "Finished trial in 0.34261059761047363 seconds\n", - "Finished simulation in 0.44017767906188965 seconds\n", - "Using config(s): Spread_erdos_renyi_graph_prob_0.2\n", - "Trial: 0\n", - "\tRunning\n", - "Finished trial in 0.34417223930358887 seconds\n", - "Finished simulation in 0.4550771713256836 seconds\n", - "Using config(s): Spread_erdos_renyi_graph_prob_0.3\n", - "Trial: 0\n", - "\tRunning\n", - "Finished trial in 0.3237779140472412 seconds\n", - "Finished simulation in 0.42307496070861816 seconds\n", - "Using config(s): Spread_erdos_renyi_graph_prob_0.4\n", - "Trial: 0\n", - "\tRunning\n", - "Finished trial in 0.3507683277130127 seconds\n", - "Finished simulation in 0.45061564445495605 seconds\n", - "Using config(s): Spread_barabasi_albert_graph_prob_0.0\n", - "Trial: 0\n", - "\tRunning\n", - "Finished trial in 0.19115304946899414 seconds\n", - "Finished simulation in 0.20927715301513672 seconds\n", - "Using config(s): Spread_barabasi_albert_graph_prob_0.1\n", - "Trial: 0\n", - "\tRunning\n", - "Finished trial in 0.22086191177368164 seconds\n", - "Finished simulation in 0.2390913963317871 seconds\n", - "Using config(s): Spread_barabasi_albert_graph_prob_0.2\n", - "Trial: 0\n", - "\tRunning\n", - "Finished trial in 0.21225976943969727 seconds\n", - "Finished simulation in 0.23252630233764648 seconds\n", - "Using config(s): Spread_barabasi_albert_graph_prob_0.3\n", - "Trial: 0\n", - "\tRunning\n", - "Finished trial in 0.2853121757507324 seconds\n", - "Finished simulation in 0.30568504333496094 seconds\n", - "Using config(s): Spread_barabasi_albert_graph_prob_0.4\n", - "Trial: 0\n", - "\tRunning\n", - "Finished trial in 0.21434736251831055 seconds\n", - "Finished simulation in 0.23370599746704102 seconds\n" - ] - } - ], - "source": [ - "network_1 = {\n", - " 'generator': 'erdos_renyi_graph',\n", - " 'n': 500,\n", - " 'p': 0.1\n", - "}\n", - "network_2 = {\n", - " 'generator': 'barabasi_albert_graph',\n", - " 'n': 500,\n", - " 'm': 2\n", - "}\n", - "\n", - "\n", - "for net in [network_1, network_2]:\n", - " for i in range(5):\n", - " prob = i / 10\n", - " config['environment_params']['prob_neighbor_spread'] = prob\n", - " config['network_params'] = net\n", - " config['name'] = 'Spread_{}_prob_{}'.format(net['generator'], prob)\n", - " s = soil.simulation.run_from_config(config)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T11:05:18.043194Z", - "start_time": "2017-07-03T13:05:18.034699+02:00" - }, - "cell_style": "split" - }, - "source": [ - "The results are conveniently stored in pickle (simulation), csv (history of agent and environment state) and gexf format." - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T14:43:15.721720Z", - "start_time": "2017-07-03T16:43:15.490854+02:00" - }, - "cell_style": "split", - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[01;34msoil_output\u001b[00m\n", - "├── \u001b[01;34mSim_prob_0\u001b[00m\n", - "│   ├── Sim_prob_0.dumped.yml\n", - "│   ├── Sim_prob_0.simulation.pickle\n", - "│   ├── Sim_prob_0_trial_0.environment.csv\n", - "│   └── Sim_prob_0_trial_0.gexf\n", - "├── \u001b[01;34mSpread_barabasi_albert_graph_prob_0.0\u001b[00m\n", - "│   ├── Spread_barabasi_albert_graph_prob_0.0.dumped.yml\n", - "│   ├── Spread_barabasi_albert_graph_prob_0.0.simulation.pickle\n", - "│   ├── Spread_barabasi_albert_graph_prob_0.0_trial_0.environment.csv\n", - "│   └── Spread_barabasi_albert_graph_prob_0.0_trial_0.gexf\n", - "├── \u001b[01;34mSpread_barabasi_albert_graph_prob_0.1\u001b[00m\n", - "│   ├── Spread_barabasi_albert_graph_prob_0.1.dumped.yml\n", - "│   ├── Spread_barabasi_albert_graph_prob_0.1.simulation.pickle\n", - "│   ├── Spread_barabasi_albert_graph_prob_0.1_trial_0.environment.csv\n", - "│   └── Spread_barabasi_albert_graph_prob_0.1_trial_0.gexf\n", - "├── \u001b[01;34mSpread_barabasi_albert_graph_prob_0.2\u001b[00m\n", - "│   ├── Spread_barabasi_albert_graph_prob_0.2.dumped.yml\n", - "│   ├── Spread_barabasi_albert_graph_prob_0.2.simulation.pickle\n", - "│   ├── Spread_barabasi_albert_graph_prob_0.2_trial_0.environment.csv\n", - "│   └── Spread_barabasi_albert_graph_prob_0.2_trial_0.gexf\n", - "├── \u001b[01;34mSpread_barabasi_albert_graph_prob_0.3\u001b[00m\n", - "│   ├── Spread_barabasi_albert_graph_prob_0.3.dumped.yml\n", - "│   ├── Spread_barabasi_albert_graph_prob_0.3.simulation.pickle\n", - "│   ├── Spread_barabasi_albert_graph_prob_0.3_trial_0.environment.csv\n", - "│   └── Spread_barabasi_albert_graph_prob_0.3_trial_0.gexf\n", - "├── \u001b[01;34mSpread_barabasi_albert_graph_prob_0.4\u001b[00m\n", - "│   ├── Spread_barabasi_albert_graph_prob_0.4.dumped.yml\n", - "│   ├── Spread_barabasi_albert_graph_prob_0.4.simulation.pickle\n", - "│   ├── Spread_barabasi_albert_graph_prob_0.4_trial_0.environment.csv\n", - "│   └── Spread_barabasi_albert_graph_prob_0.4_trial_0.gexf\n", - "├── \u001b[01;34mSpread_erdos_renyi_graph_prob_0.0\u001b[00m\n", - "│   ├── Spread_erdos_renyi_graph_prob_0.0.dumped.yml\n", - "│   ├── Spread_erdos_renyi_graph_prob_0.0.simulation.pickle\n", - "│   ├── Spread_erdos_renyi_graph_prob_0.0_trial_0.environment.csv\n", - "│   └── Spread_erdos_renyi_graph_prob_0.0_trial_0.gexf\n", - "├── \u001b[01;34mSpread_erdos_renyi_graph_prob_0.1\u001b[00m\n", - "│   ├── Spread_erdos_renyi_graph_prob_0.1.dumped.yml\n", - "│   ├── Spread_erdos_renyi_graph_prob_0.1.simulation.pickle\n", - "│   ├── Spread_erdos_renyi_graph_prob_0.1_trial_0.environment.csv\n", - "│   └── Spread_erdos_renyi_graph_prob_0.1_trial_0.gexf\n", - "├── \u001b[01;34mSpread_erdos_renyi_graph_prob_0.2\u001b[00m\n", - "│   ├── Spread_erdos_renyi_graph_prob_0.2.dumped.yml\n", - "│   ├── Spread_erdos_renyi_graph_prob_0.2.simulation.pickle\n", - "│   ├── Spread_erdos_renyi_graph_prob_0.2_trial_0.environment.csv\n", - "│   └── Spread_erdos_renyi_graph_prob_0.2_trial_0.gexf\n", - "├── \u001b[01;34mSpread_erdos_renyi_graph_prob_0.3\u001b[00m\n", - "│   ├── Spread_erdos_renyi_graph_prob_0.3.dumped.yml\n", - "│   ├── Spread_erdos_renyi_graph_prob_0.3.simulation.pickle\n", - "│   ├── Spread_erdos_renyi_graph_prob_0.3_trial_0.environment.csv\n", - "│   └── Spread_erdos_renyi_graph_prob_0.3_trial_0.gexf\n", - "└── \u001b[01;34mSpread_erdos_renyi_graph_prob_0.4\u001b[00m\n", - " ├── Spread_erdos_renyi_graph_prob_0.4.dumped.yml\n", - " ├── Spread_erdos_renyi_graph_prob_0.4.simulation.pickle\n", - " ├── Spread_erdos_renyi_graph_prob_0.4_trial_0.environment.csv\n", - " └── Spread_erdos_renyi_graph_prob_0.4_trial_0.gexf\n", - "\n", - "11 directories, 44 files\n", - "1.8M\tsoil_output/Sim_prob_0\n", - "652K\tsoil_output/Spread_barabasi_albert_graph_prob_0.0\n", - "684K\tsoil_output/Spread_barabasi_albert_graph_prob_0.1\n", - "692K\tsoil_output/Spread_barabasi_albert_graph_prob_0.2\n", - "692K\tsoil_output/Spread_barabasi_albert_graph_prob_0.3\n", - "688K\tsoil_output/Spread_barabasi_albert_graph_prob_0.4\n", - "1.8M\tsoil_output/Spread_erdos_renyi_graph_prob_0.0\n", - "1.9M\tsoil_output/Spread_erdos_renyi_graph_prob_0.1\n", - "1.9M\tsoil_output/Spread_erdos_renyi_graph_prob_0.2\n", - "1.9M\tsoil_output/Spread_erdos_renyi_graph_prob_0.3\n", - "1.9M\tsoil_output/Spread_erdos_renyi_graph_prob_0.4\n" - ] - } - ], - "source": [ - "!tree soil_output\n", - "!du -xh soil_output/*" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-02T10:40:14.384177Z", - "start_time": "2017-07-02T12:40:14.381885+02:00" - } - }, - "source": [ - "# Analysing the results" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Once the simulations are over, we can use soil to analyse the results." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T14:44:30.978223Z", - "start_time": "2017-07-03T16:44:30.971952+02:00" - } - }, - "source": [ - "First, let's load the stored results into a pandas dataframe." - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T14:43:15.987794Z", - "start_time": "2017-07-03T16:43:15.724519+02:00" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Populating the interactive namespace from numpy and matplotlib\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/usr/lib/python3.6/site-packages/IPython/core/magics/pylab.py:160: UserWarning: pylab import has clobbered these variables: ['random']\n", - "`%matplotlib` prevents importing * from pylab and numpy\n", - " \"\\n`%matplotlib` prevents importing * from pylab and numpy\"\n" - ] - } - ], - "source": [ - "%pylab inline\n", - "from soil import analysis" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T14:43:16.590910Z", - "start_time": "2017-07-03T16:43:15.990320+02:00" - }, - "scrolled": true - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
agent_idtstepattributevalue
0env0prob_tv_spread0.01
1env0prob_neighbor_spread0.1
2env1prob_tv_spread0.01
3env1prob_neighbor_spread0.1
4env2prob_tv_spread0.01
5env2prob_neighbor_spread0.1
6env3prob_tv_spread0.01
7env3prob_neighbor_spread0.1
8env4prob_tv_spread0.01
9env4prob_neighbor_spread0.1
10env5prob_tv_spread0.01
11env5prob_neighbor_spread0.1
12env6prob_tv_spread0.01
13env6prob_neighbor_spread0.1
14env7prob_tv_spread0.01
15env7prob_neighbor_spread0.1
16env8prob_tv_spread0.01
17env8prob_neighbor_spread0.1
18env9prob_tv_spread0.01
19env9prob_neighbor_spread0.1
20env10prob_tv_spread0.01
21env10prob_neighbor_spread0.1
22env11prob_tv_spread0.01
23env11prob_neighbor_spread0.1
24env12prob_tv_spread0.01
25env12prob_neighbor_spread0.1
26env13prob_tv_spread0.01
27env13prob_neighbor_spread0.1
28env14prob_tv_spread0.01
29env14prob_neighbor_spread0.1
...............
210124996has_tvTrue
210134996idneutral
210144997has_tvTrue
210154997idneutral
210164998has_tvTrue
210174998idneutral
210184999has_tvTrue
210194999idneutral
2102049910has_tvTrue
2102149910idneutral
2102249911has_tvTrue
2102349911idneutral
2102449912has_tvTrue
2102549912idneutral
2102649913has_tvTrue
2102749913idneutral
2102849914has_tvTrue
2102949914idneutral
2103049915has_tvTrue
2103149915idneutral
2103249916has_tvTrue
2103349916idneutral
2103449917has_tvTrue
2103549917idneutral
2103649918has_tvTrue
2103749918idneutral
2103849919has_tvTrue
2103949919idneutral
2104049920has_tvTrue
2104149920idinfected
\n", - "

21042 rows × 4 columns

\n", - "
" - ], - "text/plain": [ - " agent_id tstep attribute value\n", - "0 env 0 prob_tv_spread 0.01\n", - "1 env 0 prob_neighbor_spread 0.1\n", - "2 env 1 prob_tv_spread 0.01\n", - "3 env 1 prob_neighbor_spread 0.1\n", - "4 env 2 prob_tv_spread 0.01\n", - "5 env 2 prob_neighbor_spread 0.1\n", - "6 env 3 prob_tv_spread 0.01\n", - "7 env 3 prob_neighbor_spread 0.1\n", - "8 env 4 prob_tv_spread 0.01\n", - "9 env 4 prob_neighbor_spread 0.1\n", - "10 env 5 prob_tv_spread 0.01\n", - "11 env 5 prob_neighbor_spread 0.1\n", - "12 env 6 prob_tv_spread 0.01\n", - "13 env 6 prob_neighbor_spread 0.1\n", - "14 env 7 prob_tv_spread 0.01\n", - "15 env 7 prob_neighbor_spread 0.1\n", - "16 env 8 prob_tv_spread 0.01\n", - "17 env 8 prob_neighbor_spread 0.1\n", - "18 env 9 prob_tv_spread 0.01\n", - "19 env 9 prob_neighbor_spread 0.1\n", - "20 env 10 prob_tv_spread 0.01\n", - "21 env 10 prob_neighbor_spread 0.1\n", - "22 env 11 prob_tv_spread 0.01\n", - "23 env 11 prob_neighbor_spread 0.1\n", - "24 env 12 prob_tv_spread 0.01\n", - "25 env 12 prob_neighbor_spread 0.1\n", - "26 env 13 prob_tv_spread 0.01\n", - "27 env 13 prob_neighbor_spread 0.1\n", - "28 env 14 prob_tv_spread 0.01\n", - "29 env 14 prob_neighbor_spread 0.1\n", - "... ... ... ... ...\n", - "21012 499 6 has_tv True\n", - "21013 499 6 id neutral\n", - "21014 499 7 has_tv True\n", - "21015 499 7 id neutral\n", - "21016 499 8 has_tv True\n", - "21017 499 8 id neutral\n", - "21018 499 9 has_tv True\n", - "21019 499 9 id neutral\n", - "21020 499 10 has_tv True\n", - "21021 499 10 id neutral\n", - "21022 499 11 has_tv True\n", - "21023 499 11 id neutral\n", - "21024 499 12 has_tv True\n", - "21025 499 12 id neutral\n", - "21026 499 13 has_tv True\n", - "21027 499 13 id neutral\n", - "21028 499 14 has_tv True\n", - "21029 499 14 id neutral\n", - "21030 499 15 has_tv True\n", - "21031 499 15 id neutral\n", - "21032 499 16 has_tv True\n", - "21033 499 16 id neutral\n", - "21034 499 17 has_tv True\n", - "21035 499 17 id neutral\n", - "21036 499 18 has_tv True\n", - "21037 499 18 id neutral\n", - "21038 499 19 has_tv True\n", - "21039 499 19 id neutral\n", - "21040 499 20 has_tv True\n", - "21041 499 20 id infected\n", - "\n", - "[21042 rows x 4 columns]" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "config_file, df, config = list(analysis.get_data('soil_output/Spread_barabasi*prob_0.1*', process=False))[0]\n", - "df" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T14:43:17.192030Z", - "start_time": "2017-07-03T16:43:16.601046+02:00" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
value0.010.1FalseTrueinfectedneutral
tstep
01.01.0163.0337.00.0500.0
11.01.0163.0337.03.0497.0
21.01.0163.0337.06.0494.0
31.01.0163.0337.012.0488.0
41.01.0163.0337.023.0477.0
51.01.0163.0337.036.0464.0
61.01.0163.0337.053.0447.0
71.01.0163.0337.079.0421.0
81.01.0163.0337.0119.0381.0
91.01.0163.0337.0164.0336.0
101.01.0163.0337.0204.0296.0
111.01.0163.0337.0254.0246.0
121.01.0163.0337.0293.0207.0
131.01.0163.0337.0336.0164.0
141.01.0163.0337.0365.0135.0
151.01.0163.0337.0391.0109.0
161.01.0163.0337.0407.093.0
171.01.0163.0337.0424.076.0
181.01.0163.0337.0442.058.0
191.01.0163.0337.0452.048.0
201.01.0163.0337.0464.036.0
\n", - "
" - ], - "text/plain": [ - "value 0.01 0.1 False True infected neutral\n", - "tstep \n", - "0 1.0 1.0 163.0 337.0 0.0 500.0\n", - "1 1.0 1.0 163.0 337.0 3.0 497.0\n", - "2 1.0 1.0 163.0 337.0 6.0 494.0\n", - "3 1.0 1.0 163.0 337.0 12.0 488.0\n", - "4 1.0 1.0 163.0 337.0 23.0 477.0\n", - "5 1.0 1.0 163.0 337.0 36.0 464.0\n", - "6 1.0 1.0 163.0 337.0 53.0 447.0\n", - "7 1.0 1.0 163.0 337.0 79.0 421.0\n", - "8 1.0 1.0 163.0 337.0 119.0 381.0\n", - "9 1.0 1.0 163.0 337.0 164.0 336.0\n", - "10 1.0 1.0 163.0 337.0 204.0 296.0\n", - "11 1.0 1.0 163.0 337.0 254.0 246.0\n", - "12 1.0 1.0 163.0 337.0 293.0 207.0\n", - "13 1.0 1.0 163.0 337.0 336.0 164.0\n", - "14 1.0 1.0 163.0 337.0 365.0 135.0\n", - "15 1.0 1.0 163.0 337.0 391.0 109.0\n", - "16 1.0 1.0 163.0 337.0 407.0 93.0\n", - "17 1.0 1.0 163.0 337.0 424.0 76.0\n", - "18 1.0 1.0 163.0 337.0 442.0 58.0\n", - "19 1.0 1.0 163.0 337.0 452.0 48.0\n", - "20 1.0 1.0 163.0 337.0 464.0 36.0" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "list(analysis.get_data('soil_output/Spread_barabasi*prob_0.1*', process=True))[0][1]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you don't want to work with pandas, you can also use some pre-defined functions from soil to conveniently plot the results:" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T14:43:20.937324Z", - "start_time": "2017-07-03T16:43:17.193845+02:00" - }, - "scrolled": true - }, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\nESilVID7f/7YFJ+blHWwAAAAAElFTkSuQmCC\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\noUMmlSunJdAAAAAASUVORK5CYII=\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "analysis.plot_all('soil_output/Spread_barabasi*', attributes=['id'])" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": { - "ExecuteTime": { - "end_time": "2017-07-03T14:43:49.238790Z", - "start_time": "2017-07-03T16:43:20.939175+02:00" - } - }, - "outputs": [ - { - "data": { - "image/png": "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\ntZXGxkYefPBBAPbdd18aGhq6A0F7ezsrVqwo6vcpFF0RiMhua+bMmWzdupXJkyczceJEFi5cyMkn\nn8zcuXOZM2cO++23X5/PTJ06ldNPP51Zs2YxY8YMDjooqhkvLy9n8eLFXHTRRTQ2NtLR0cEXvvAF\nZs6cWeyvlXc2HDr0zJ0715cuXTrU2RCRInnxxRfZf/9MtyNJNpmOmZktc/e5O7ttVQ2JiMScAoGI\nSMwpEIiIxJwCgYhIzCkQiIjEnAKBiEjMKRCISCy95z3vGTDNo48+ysyZM5kzZw4tLS2D2v7vfvc7\nXnjhhUHnayiGw1YgEJFYevzxxwdMs2jRIr7yla/w7LPPMmLEiEFtf0cDwVBQIBCRWEqeeS9ZsoSj\njz6a+fPns99++7Fw4ULcnZ///OfccccdfOtb32LhwoUAXH311Rx66KHMmjWLyy+/vHtbt9xyC7Nm\nzWL27NmcccYZPP7449xzzz189atfZc6cOaxatYpVq1Zx/PHHc8ghh/C+972Pl156CYDXXnuNI444\ngkMPPZSvf/3rxT8QaIgJERli3/zvFbyw9u28bvOASaO4/OTch374y1/+wooVK5g0aRJHHnkkjz32\nGJ/85Cf505/+xEknncT8+fO5//77WblyJX/+859xd0455RQeeeQRxo4dy5VXXsljjz3GuHHj2LRp\nE3V1dZxyyindnwWYN28eP/nJT5gxYwZPPfUUF1xwAQ899BCf//zn+cxnPsOZZ57Jddddl9fjkCsF\nAhGJvcMOO4wpU6YAMGfOHFavXs173/veXmnuv/9+7r///u6xh5qamli5ciXPPfcc8+fPZ9y4cQDU\n1dX12X5TUxOPP/44p53WM0J/a2srAI899hh33nknAGeccQYXX3xx/r/gABQIRGRIDebMvVAqKiq6\np0tLS+no6OiTxt352te+xqc+9aley6+99lrMMj2qvUdXVxe1tbU8++yzGdcP9PlCUxuBiEgOjjvu\nOG688UaampoAWLNmDRs2bGDevHnccccdbNy4EYBNm6JHtNfU1LB161YARo0axfTp0/nNb34DREHl\nueeeA+DII4/ktttuA6LG6aGgQCAikoNjjz2Wj3/84xxxxBEceOCBzJ8/n61btzJz5kwuu+wyjjrq\nKGbPns2XvvQlIHoWwtVXX81BBx3EqlWrWLRoETfccAOzZ89m5syZ3c9L/v73v891113HoYceSmNj\n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\nAAAASUVORK5CYII=\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\nhPdhAd1fv7EAAAAASUVORK5CYII=\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\nIjLK/X+WBgkuYDfsgAAAAABJRU5ErkJggg==\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "analysis.plot_all('soil_output/Spread_erdos*', attributes=['id'])" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.1" - }, - "toc": { - "colors": { - "hover_highlight": "#DAA520", - "navigate_num": "#000000", - "navigate_text": "#333333", - "running_highlight": "#FF0000", - "selected_highlight": "#FFD700", - "sidebar_border": "#EEEEEE", - "wrapper_background": "#FFFFFF" - }, - "moveMenuLeft": true, - "nav_menu": { - "height": "31px", - "width": "252px" - }, - "navigate_menu": true, - "number_sections": true, - "sideBar": true, - "threshold": 4, - "toc_cell": false, - "toc_section_display": "block", - "toc_window_display": true, - "widenNotebook": false - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/requirements.txt b/requirements.txt old mode 100644 new mode 100755 index 1921c99..0b541b4 --- a/requirements.txt +++ b/requirements.txt @@ -2,5 +2,4 @@ nxsim simpy networkx numpy -matplotlib -pyyaml +matplotlib \ No newline at end of file diff --git a/settings.json b/settings.json new file mode 100755 index 0000000..daf5a39 --- /dev/null +++ b/settings.json @@ -0,0 +1,23 @@ +[ + { + "network_type": 0, + "number_of_nodes": 80, + "max_time": 50, + "num_trials": 1, + "timeout": 2 + }, + + { + "agent": ["TerroristModel"], + + "initial_population": 0.85, + "initial_havens": 0.1, + "initial_training_enviroments": 0.05, + + "initial_radicalism": 0.12, + "relative_inequality": 0.33, + "information_spread_intensity": 0.1, + "influence": 0.4, + "additional_influence": 0.1 + } +] \ No newline at end of file diff --git a/settings.py b/settings.py new file mode 100755 index 0000000..33d6d4f --- /dev/null +++ b/settings.py @@ -0,0 +1,13 @@ +# General configuration +import json + +with open('settings.json', 'r') as f: + settings = json.load(f) + +network_params = settings[0] +environment_params = settings[1] + +centrality_param = {} +partition_param={} +leaders={} + diff --git a/setup.py b/setup.py deleted file mode 100644 index 166063a..0000000 --- a/setup.py +++ /dev/null @@ -1,39 +0,0 @@ -import pip -from setuptools import setup -# parse_requirements() returns generator of pip.req.InstallRequirement objects -from pip.req import parse_requirements -from soil import __version__ - -try: - install_reqs = parse_requirements( - "requirements.txt", session=pip.download.PipSession()) - test_reqs = parse_requirements( - "test-requirements.txt", session=pip.download.PipSession()) -except AttributeError: - install_reqs = parse_requirements("requirements.txt") - test_reqs = parse_requirements("test-requirements.txt") - -install_reqs = [str(ir.req) for ir in install_reqs] -test_reqs = [str(ir.req) for ir in test_reqs] - - -setup( - name='soil', - packages=['soil'], # this must be the same as the name above - version=__version__, - description=('An Agent-Based Social Simulator for Social Networks'), - author='J. Fernando Sanchez', - author_email='jf.sanchez@upm.es', - url='https://github.com/gsi-upm/soil', # use the URL to the github repo - download_url='https://github.com/gsi-upm/soil/archive/{}.tar.gz'.format( - __version__), - keywords=['agent', 'social', 'simulator'], - classifiers=[], - install_requires=install_reqs, - tests_require=test_reqs, - setup_requires=['pytest-runner', ], - include_package_data=True, - entry_points={ - 'console_scripts': - ['soil = soil.__init__:main'] - }) diff --git a/sim_01/log.0.state.pickled b/sim_01/log.0.state.pickled new file mode 100755 index 0000000..c104f74 Binary files /dev/null and b/sim_01/log.0.state.pickled differ diff --git a/sim_01/log.1.state.pickled b/sim_01/log.1.state.pickled new file mode 100644 index 0000000..f71d1a4 Binary files /dev/null and b/sim_01/log.1.state.pickled differ diff --git a/simulation.yml b/simulation.yml deleted file mode 100644 index a396f9f..0000000 --- a/simulation.yml +++ /dev/null @@ -1,63 +0,0 @@ ---- -name: ControlModelM2_sim -max_time: 50 -num_trials: 1 -timeout: 2 -network_params: - generator: barabasi_albert_graph - n: 100 - m: 2 -agent_distribution: - - agent_type: ControlModelM2 - weight: 0.1 - state: - id: 1 - - agent_type: ControlModelM2 - weight: 0.9 - state: - id: 0 -environment_params: - prob_neutral_making_denier: 0.035 - prob_infect: 0.075 - prob_cured_healing_infected: 0.035 - prob_cured_vaccinate_neutral: 0.035 - prob_vaccinated_healing_infected: 0.035 - prob_vaccinated_vaccinate_neutral: 0.035 - prob_generate_anti_rumor: 0.035 - standard_variance: 0.055 ---- -name: SISA_sm -max_time: 50 -num_trials: 2 -timeout: 2 -network_params: - generator: erdos_renyi_graph - n: 10000 - p: 0.05 -#other_agents: -# - agent_type: DrawingAgent -agent_distribution: - - agent_type: SISaModel - weight: 1 - state: - id: content - - agent_type: SISaModel - weight: 1 - state: - id: neutral - - agent_type: SISaModel - weight: 1 - state: - id: discontent -environment_params: - neutral_discontent_spon_prob: 0.04 - neutral_discontent_infected_prob: 0.04 - neutral_content_spon_prob: 0.18 - neutral_content_infected_prob: 0.02 - discontent_neutral: 0.13 - discontent_content: 0.07 - variance_d_c: 0.02 - content_discontent: 0.009 - variance_c_d: 0.003 - content_neutral: 0.088 - standard_variance: 0.055 diff --git a/soil.py b/soil.py new file mode 100755 index 0000000..d36fdfc --- /dev/null +++ b/soil.py @@ -0,0 +1,215 @@ +from models import * +from nxsim import NetworkSimulation +# import numpy +from matplotlib import pyplot as plt +import networkx as nx +import settings +import models +import math +import json +import operator +import community + + + +POPULATION = 0 +LEADERS = 1 +HAVEN = 2 +TRAINING = 3 + +NON_RADICAL = 0 +NEUTRAL = 1 +RADICAL = 2 +################# +# Visualization # +################# + +def visualization(graph_name): + + for x in range(0, settings.network_params["number_of_nodes"]): + attributes = {} + spells = [] + for attribute in models.networkStatus["agent_%s" % x]: + if attribute == 'visible': + lastvisible = False + laststep = 0 + for t_step in models.networkStatus["agent_%s" % x][attribute]: + nowvisible = models.networkStatus["agent_%s" % x][attribute][t_step] + if nowvisible and not lastvisible: + laststep = t_step + if not nowvisible and lastvisible: + spells.append((laststep, t_step)) + + lastvisible = nowvisible + if lastvisible: + spells.append((laststep, None)) + else: + emotionStatusAux = [] + for t_step in models.networkStatus["agent_%s" % x][attribute]: + prec = 2 + output = math.floor(models.networkStatus["agent_%s" % x][attribute][t_step] * (10 ** prec)) / (10 ** prec) # 2 decimals + emotionStatusAux.append((output, t_step, t_step + settings.network_params["timeout"])) + attributes[attribute] = emotionStatusAux + if spells: + G.add_node(x, attributes, spells=spells) + else: + G.add_node(x, attributes) + + print("Done!") + + + with open('data.txt', 'w') as outfile: + json.dump(models.networkStatus, outfile, sort_keys=True, indent=4, separators=(',', ': ')) + + for node in range(settings.network_params["number_of_nodes"]): + G.node[node]['x'] = G.node[node]['pos'][0] + G.node[node]['y'] = G.node[node]['pos'][1] + G.node[node]['viz'] = {"position": {"x": G.node[node]['pos'][0], "y": G.node[node]['pos'][1], "z": 0.0}} + del (G.node[node]['pos']) + + nx.write_gexf(G, graph_name+".gexf", version="1.2draft") + +########### +# Results # +########### + +def results(model_name): + x_values = [] + neutral_values = [] + non_radical_values = [] + radical_values = [] + + attribute_plot = 'status' + for time in range(0, settings.network_params["max_time"]): + value_neutral = 0 + value_non_radical = 0 + value_radical = 0 + real_time = time * settings.network_params["timeout"] + activity = False + for x in range(0, settings.network_params["number_of_nodes"]): + if attribute_plot in models.networkStatus["agent_%s" % x]: + if real_time in models.networkStatus["agent_%s" % x][attribute_plot]: + if models.networkStatus["agent_%s" % x][attribute_plot][real_time] == NON_RADICAL: + value_non_radical += 1 + activity = True + if models.networkStatus["agent_%s" % x][attribute_plot][real_time] == NEUTRAL: + value_neutral += 1 + activity = True + if models.networkStatus["agent_%s" % x][attribute_plot][real_time] == RADICAL: + value_radical += 1 + activity = True + + + if activity: + x_values.append(real_time) + neutral_values.append(value_neutral) + non_radical_values.append(value_non_radical) + radical_values.append(value_radical) + activity = False + + fig1 = plt.figure() + ax1 = fig1.add_subplot(111) + + non_radical_line = ax1.plot(x_values, non_radical_values, label='Non radical') + neutral_line = ax1.plot(x_values, neutral_values, label='Neutral') + radical_line = ax1.plot(x_values, radical_values, label='Radical') + ax1.legend() + fig1.savefig(model_name+'.png') + plt.show() + +########### +# Results # +########### + +def resultadosTipo(model_name): + x_values = [] + population_values = [] + leaders_values = [] + havens_values = [] + training_enviroments_values = [] + + attribute_plot = 'type' + for time in range(0, settings.network_params["max_time"]): + value_population = 0 + value_leaders = 0 + value_havens = 0 + value_training_enviroments = 0 + real_time = time * settings.network_params["timeout"] + activity = False + for x in range(0, settings.network_params["number_of_nodes"]): + if attribute_plot in models.networkStatus["agent_%s" % x]: + if real_time in models.networkStatus["agent_%s" % x][attribute_plot]: + if models.networkStatus["agent_%s" % x][attribute_plot][real_time] == POPULATION: + value_population += 1 + activity = True + if models.networkStatus["agent_%s" % x][attribute_plot][real_time] == LEADERS: + value_leaders += 1 + activity = True + if models.networkStatus["agent_%s" % x][attribute_plot][real_time] == HAVEN: + value_havens += 1 + activity = True + if models.networkStatus["agent_%s" % x][attribute_plot][real_time] == TRAINING: + value_training_enviroments += 1 + activity = True + if activity: + x_values.append(real_time) + population_values.append(value_population) + leaders_values.append(value_leaders) + havens_values.append(value_havens) + training_enviroments_values.append(value_training_enviroments) + activity = False + + fig2 = plt.figure() + ax2 = fig2.add_subplot(111) + + population_line = ax2.plot(x_values, population_values, label='Population') + leaders_line = ax2.plot(x_values, leaders_values, label='Leader') + havens_line = ax2.plot(x_values, havens_values, label='Havens') + training_enviroments_line = ax2.plot(x_values, training_enviroments_values, label='Training Enviroments') + ax2.legend() + fig2.savefig(model_name+'_type'+'.png') + plt.show() + +#################### +# Network creation # +#################### + +# nx.degree_centrality(G); + +if settings.network_params["network_type"] == 0: + G = nx.random_geometric_graph(settings.network_params["number_of_nodes"], 0.2) + + settings.partition_param = community.best_partition(G) + settings.centrality_param = nx.betweenness_centrality(G).copy() + + + # print(settings.centrality_param) + # print(settings.partition_param) +# More types of networks can be added here + +############## +# Simulation # +############## + +agents = settings.environment_params['agent'] + +print("Using Agent(s): {agents}".format(agents=agents)) + +if len(agents) > 1: + for agent in agents: + sim = NetworkSimulation(topology=G, states=init_states, agent_type=locals()[agent], max_time=settings.network_params["max_time"], + num_trials=settings.network_params["num_trials"], logging_interval=1.0, **settings.environment_params) + sim.run_simulation() + print(str(agent)) + results(str(agent)) + resultadosTipo(str(agent)) + visualization(str(agent)) +else: + agent = agents[0] + sim = NetworkSimulation(topology=G, states=init_states, agent_type=locals()[agent], max_time=settings.network_params["max_time"], + num_trials=settings.network_params["num_trials"], logging_interval=1.0, **settings.environment_params) + sim.run_simulation() + results(str(agent)) + resultadosTipo(str(agent)) + + visualization(str(agent)) \ No newline at end of file diff --git a/soil.py~ b/soil.py~ new file mode 100755 index 0000000..d6d6204 --- /dev/null +++ b/soil.py~ @@ -0,0 +1,394 @@ +from nxsim import NetworkSimulation +from nxsim import BaseNetworkAgent +from nxsim import BaseLoggingAgent +from random import randint +from matplotlib import pyplot as plt +import random +import numpy as np +import networkx as nx +import settings + + +settings.init() + +if settings.network_type == 0: + G = nx.complete_graph(settings.number_of_nodes) +if settings.network_type == 1: + G = nx.barabasi_albert_graph(settings.number_of_nodes,3) +if settings.network_type == 2: + G = nx.margulis_gabber_galil_graph(settings.number_of_nodes, None) + + +myList=[] +networkStatus=[] +for x in range(0, settings.number_of_nodes): + networkStatus.append({'id':x}) + + + +# # Just like subclassing a process in SimPy +# class MyAgent(BaseNetworkAgent): +# def __init__(self, environment=None, agent_id=0, state=()): # Make sure to have these three keyword arguments +# super().__init__(environment=environment, agent_id=agent_id, state=state) +# # Add your own attributes here + +# def run(self): +# # Add your behaviors here + + + + +class SentimentCorrelationModel(BaseNetworkAgent): + def __init__(self, environment=None, agent_id=0, state=()): + super().__init__(environment=environment, agent_id=agent_id, state=state) + self.outside_effects_prob = settings.outside_effects_prob + self.anger_prob = settings.anger_prob + self.joy_prob = settings.joy_prob + self.sadness_prob = settings.sadness_prob + self.disgust_prob = settings.disgust_prob + self.time_awareness=[] + for i in range(4): + self.time_awareness.append(0) #0-> Anger, 1-> joy, 2->sadness, 3 -> disgust + networkStatus[self.id][self.env.now]=0 + + + def run(self): + while True: + if self.env.now > 10: + G.add_node(205) + G.add_edge(205,0) + angry_neighbors_1_time_step=[] + joyful_neighbors_1_time_step=[] + sad_neighbors_1_time_step=[] + disgusted_neighbors_1_time_step=[] + + + angry_neighbors = self.get_neighboring_agents(state_id=1) + for x in angry_neighbors: + if x.time_awareness[0] > (self.env.now-500): + angry_neighbors_1_time_step.append(x) + num_neighbors_angry = len(angry_neighbors_1_time_step) + + + joyful_neighbors = self.get_neighboring_agents(state_id=2) + for x in joyful_neighbors: + if x.time_awareness[1] > (self.env.now-500): + joyful_neighbors_1_time_step.append(x) + num_neighbors_joyful = len(joyful_neighbors_1_time_step) + + + sad_neighbors = self.get_neighboring_agents(state_id=3) + for x in sad_neighbors: + if x.time_awareness[2] > (self.env.now-500): + sad_neighbors_1_time_step.append(x) + num_neighbors_sad = len(sad_neighbors_1_time_step) + + + disgusted_neighbors = self.get_neighboring_agents(state_id=4) + for x in disgusted_neighbors: + if x.time_awareness[3] > (self.env.now-500): + disgusted_neighbors_1_time_step.append(x) + num_neighbors_disgusted = len(disgusted_neighbors_1_time_step) + + # #Outside effects. Asignamos un estado aleatorio + # if random.random() < settings.outside_effects_prob: + # if self.state['id'] == 0: + # self.state['id'] = random.randint(1,4) + # myList.append(self.id) + # networkStatus[self.id][self.env.now]=self.state['id'] #Almaceno cuando se ha infectado para la red dinamica + # self.time_awareness = self.env.now #Para saber cuando se han contagiado + # yield self.env.timeout(settings.timeout) + # else: + # yield self.env.timeout(settings.timeout) + + + # #Imitation effects-Joy + + # if random.random() < (settings.joy_prob*(num_neighbors_joyful)/10): + # myList.append(self.id) + # self.state['id'] = 2 + # networkStatus[self.id][self.env.now]=2 + # yield self.env.timeout(settings.timeout) + + + # #Imitation effects-Sadness + + # if random.random() < (settings.sadness_prob*(num_neighbors_sad)/10): + # myList.append(self.id) + # self.state['id'] = 3 + # networkStatus[self.id][self.env.now]=3 + # yield self.env.timeout(settings.timeout) + + + # #Imitation effects-Disgust + + # if random.random() < (settings.disgust_prob*(num_neighbors_disgusted)/10): + # myList.append(self.id) + # self.state['id'] = 4 + # networkStatus[self.id][self.env.now]=4 + # yield self.env.timeout(settings.timeout) + + # #Imitation effects-Anger + + # if random.random() < (settings.anger_prob*(num_neighbors_angry)/10): + # myList.append(self.id) + # self.state['id'] = 1 + # networkStatus[self.id][self.env.now]=1 + # yield self.env.timeout(settings.timeout) + + # yield self.env.timeout(settings.timeout) + +########################################### + + + anger_prob= settings.anger_prob+(len(angry_neighbors_1_time_step)*settings.anger_prob) + print("anger_prob " + str(anger_prob)) + joy_prob= settings.joy_prob+(len(joyful_neighbors_1_time_step)*settings.joy_prob) + print("joy_prob " + str(joy_prob)) + sadness_prob = settings.sadness_prob+(len(sad_neighbors_1_time_step)*settings.sadness_prob) + print("sadness_prob "+ str(sadness_prob)) + disgust_prob = settings.disgust_prob+(len(disgusted_neighbors_1_time_step)*settings.disgust_prob) + print("disgust_prob " + str(disgust_prob)) + outside_effects_prob= settings.outside_effects_prob + print("outside_effects_prob " + str(outside_effects_prob)) + + + num = random.random() + + + if(numanger_prob): + + myList.append(self.id) + self.state['id'] = 2 + networkStatus[self.id][self.env.now]=2 + self.time_awareness[self.state['id']-1] = self.env.now + elif (numjoy_prob+anger_prob): + + myList.append(self.id) + self.state['id'] = 3 + networkStatus[self.id][self.env.now]=3 + self.time_awareness[self.state['id']-1] = self.env.now + elif (numsadness_prob+anger_prob+joy_prob): + + myList.append(self.id) + self.state['id'] = 4 + networkStatus[self.id][self.env.now]=4 + self.time_awareness[self.state['id']-1] = self.env.now + + yield self.env.timeout(settings.timeout) + + + # anger_propagation = settings.anger_prob*num_neighbors_angry/10 + # joy_propagation = anger_propagation + (settings.joy_prob*num_neighbors_joyful/10) + # sadness_propagation = joy_propagation + (settings.sadness_prob*num_neighbors_sad/10) + # disgust_propagation = sadness_propagation + (settings.disgust_prob*num_neighbors_disgusted/10) + # outside_effects_propagation = disgust_propagation + settings.outside_effects_prob + + # if (num 1: - x.sentiment_about[self.id] = 1 - if x.sentiment_about[self.id]< -1: - x.sentiment_about[self.id] = -1 - - x.attrs['sentiment_enterprise_%s'% self.enterprises[self.id]] = x.sentiment_about[self.id] - - def userBehaviour(self): - - if random.random() < self.tweet_probability: # Tweets - if random.random() < self.tweet_relevant_probability: # Tweets something relevant - # Tweet probability per enterprise - for i in range(self.number_of_enterprises): - random_num = random.random() - if random_num < self.tweet_probability_about[i]: - # The condition is fulfilled, sentiments are evaluated towards that enterprise - if self.sentiment_about[i] < 0: - # NEGATIVO - self.userTweets("negative",i) - elif self.sentiment_about[i] == 0: - # NEUTRO - pass - else: - # POSITIVO - self.userTweets("positive",i) - - def userTweets(self,sentiment,enterprise): - aware_neighbors = self.get_neighboring_agents(state_id=self.number_of_enterprises) # Nodes neighbours users - for x in aware_neighbors: - if sentiment == "positive": - x.sentiment_about[enterprise] +=0.003 - elif sentiment == "negative": - x.sentiment_about[enterprise] -=0.003 - else: - pass - - # Establecemos limites - if x.sentiment_about[enterprise] > 1: - x.sentiment_about[enterprise] = 1 - if x.sentiment_about[enterprise] < -1: - x.sentiment_about[enterprise] = -1 - - x.attrs['sentiment_enterprise_%s'% self.enterprises[enterprise]] = x.sentiment_about[enterprise] diff --git a/soil/agents/CounterModel.py b/soil/agents/CounterModel.py deleted file mode 100644 index 186ed45..0000000 --- a/soil/agents/CounterModel.py +++ /dev/null @@ -1,31 +0,0 @@ -from . import NetworkAgent - - -class CounterModel(NetworkAgent): - """ - Dummy behaviour. It counts the number of nodes in the network and neighbors - in each step and adds it to its state. - """ - - def step(self): - # Outside effects - total = len(self.get_all_agents()) - neighbors = len(self.get_neighboring_agents()) - self.state['times'] = self.state.get('times', 0) + 1 - self.state['neighbors'] = neighbors - self.state['total'] = total - - -class AggregatedCounter(NetworkAgent): - """ - Dummy behaviour. It counts the number of nodes in the network and neighbors - in each step and adds it to its state. - """ - - def step(self): - # Outside effects - total = len(self.get_all_agents()) - neighbors = len(self.get_neighboring_agents()) - self.state['times'] = self.state.get('times', 0) + 1 - self.state['neighbors'] = self.state.get('neighbors', 0) + neighbors - self.state['total'] = self.state.get('total', 0) + total diff --git a/soil/agents/DrawingAgent.py b/soil/agents/DrawingAgent.py deleted file mode 100644 index ccf0aa8..0000000 --- a/soil/agents/DrawingAgent.py +++ /dev/null @@ -1,18 +0,0 @@ -from . import BaseAgent - -import os.path -import matplotlib -import matplotlib.pyplot as plt -import networkx as nx - - -class DrawingAgent(BaseAgent): - """ - Agent that draws the state of the network. - """ - - def step(self): - # Outside effects - f = plt.figure() - nx.draw(self.env.G, node_size=10, width=0.2, pos=nx.spring_layout(self.env.G, scale=100), ax=f.add_subplot(111)) - f.savefig(os.path.join(self.env.sim().dir_path, "graph-"+str(self.env.now)+".png")) diff --git a/soil/agents/IndependentCascadeModel.py b/soil/agents/IndependentCascadeModel.py deleted file mode 100644 index 80e58ca..0000000 --- a/soil/agents/IndependentCascadeModel.py +++ /dev/null @@ -1,49 +0,0 @@ -import random -from . import BaseAgent - - -class IndependentCascadeModel(BaseAgent): - """ - Settings: - innovation_prob - - imitation_prob - """ - - def __init__(self, environment=None, agent_id=0, state=()): - super().__init__(environment=environment, agent_id=agent_id, state=state) - self.innovation_prob = environment.environment_params['innovation_prob'] - self.imitation_prob = environment.environment_params['imitation_prob'] - self.state['time_awareness'] = 0 - self.state['sentimentCorrelation'] = 0 - - def step(self): - self.behaviour() - - def behaviour(self): - aware_neighbors_1_time_step = [] - # Outside effects - if random.random() < self.innovation_prob: - if self.state['id'] == 0: - self.state['id'] = 1 - self.state['sentimentCorrelation'] = 1 - self.state['time_awareness'] = self.env.now # To know when they have been infected - else: - pass - - return - - # Imitation effects - if self.state['id'] == 0: - aware_neighbors = self.get_neighboring_agents(state_id=1) - for x in aware_neighbors: - if x.state['time_awareness'] == (self.env.now-1): - aware_neighbors_1_time_step.append(x) - num_neighbors_aware = len(aware_neighbors_1_time_step) - if random.random() < (self.imitation_prob*num_neighbors_aware): - self.state['id'] = 1 - self.state['sentimentCorrelation'] = 1 - else: - pass - - return diff --git a/soil/agents/ModelM2.py b/soil/agents/ModelM2.py deleted file mode 100644 index 750dd4b..0000000 --- a/soil/agents/ModelM2.py +++ /dev/null @@ -1,242 +0,0 @@ -import random -import numpy as np -from . import NetworkAgent - - -class SpreadModelM2(NetworkAgent): - """ - Settings: - prob_neutral_making_denier - - prob_infect - - prob_cured_healing_infected - - prob_cured_vaccinate_neutral - - prob_vaccinated_healing_infected - - prob_vaccinated_vaccinate_neutral - - prob_generate_anti_rumor - """ - - def __init__(self, environment=None, agent_id=0, state=()): - super().__init__(environment=environment, agent_id=agent_id, state=state) - - self.prob_neutral_making_denier = np.random.normal(environment.environment_params['prob_neutral_making_denier'], - environment.environment_params['standard_variance']) - - self.prob_infect = np.random.normal(environment.environment_params['prob_infect'], - environment.environment_params['standard_variance']) - - self.prob_cured_healing_infected = np.random.normal(environment.environment_params['prob_cured_healing_infected'], - environment.environment_params['standard_variance']) - self.prob_cured_vaccinate_neutral = np.random.normal(environment.environment_params['prob_cured_vaccinate_neutral'], - environment.environment_params['standard_variance']) - - self.prob_vaccinated_healing_infected = np.random.normal(environment.environment_params['prob_vaccinated_healing_infected'], - environment.environment_params['standard_variance']) - self.prob_vaccinated_vaccinate_neutral = np.random.normal(environment.environment_params['prob_vaccinated_vaccinate_neutral'], - environment.environment_params['standard_variance']) - self.prob_generate_anti_rumor = np.random.normal(environment.environment_params['prob_generate_anti_rumor'], - environment.environment_params['standard_variance']) - - def step(self): - - if self.state['id'] == 0: # Neutral - self.neutral_behaviour() - elif self.state['id'] == 1: # Infected - self.infected_behaviour() - elif self.state['id'] == 2: # Cured - self.cured_behaviour() - elif self.state['id'] == 3: # Vaccinated - self.vaccinated_behaviour() - - def neutral_behaviour(self): - - # Infected - infected_neighbors = self.get_neighboring_agents(state_id=1) - if len(infected_neighbors) > 0: - if random.random() < self.prob_neutral_making_denier: - self.state['id'] = 3 # Vaccinated making denier - - def infected_behaviour(self): - - # Neutral - neutral_neighbors = self.get_neighboring_agents(state_id=0) - for neighbor in neutral_neighbors: - if random.random() < self.prob_infect: - neighbor.state['id'] = 1 # Infected - - def cured_behaviour(self): - - # Vaccinate - neutral_neighbors = self.get_neighboring_agents(state_id=0) - for neighbor in neutral_neighbors: - if random.random() < self.prob_cured_vaccinate_neutral: - neighbor.state['id'] = 3 # Vaccinated - - # Cure - infected_neighbors = self.get_neighboring_agents(state_id=1) - for neighbor in infected_neighbors: - if random.random() < self.prob_cured_healing_infected: - neighbor.state['id'] = 2 # Cured - - def vaccinated_behaviour(self): - - # Cure - infected_neighbors = self.get_neighboring_agents(state_id=1) - for neighbor in infected_neighbors: - if random.random() < self.prob_cured_healing_infected: - neighbor.state['id'] = 2 # Cured - - # Vaccinate - neutral_neighbors = self.get_neighboring_agents(state_id=0) - for neighbor in neutral_neighbors: - if random.random() < self.prob_cured_vaccinate_neutral: - neighbor.state['id'] = 3 # Vaccinated - - # Generate anti-rumor - infected_neighbors_2 = self.get_neighboring_agents(state_id=1) - for neighbor in infected_neighbors_2: - if random.random() < self.prob_generate_anti_rumor: - neighbor.state['id'] = 2 # Cured - - -class ControlModelM2(NetworkAgent): - """ - Settings: - prob_neutral_making_denier - - prob_infect - - prob_cured_healing_infected - - prob_cured_vaccinate_neutral - - prob_vaccinated_healing_infected - - prob_vaccinated_vaccinate_neutral - - prob_generate_anti_rumor - """ - - - def __init__(self, environment=None, agent_id=0, state=()): - super().__init__(environment=environment, agent_id=agent_id, state=state) - - self.prob_neutral_making_denier = np.random.normal(environment.environment_params['prob_neutral_making_denier'], - environment.environment_params['standard_variance']) - - self.prob_infect = np.random.normal(environment.environment_params['prob_infect'], - environment.environment_params['standard_variance']) - - self.prob_cured_healing_infected = np.random.normal(environment.environment_params['prob_cured_healing_infected'], - environment.environment_params['standard_variance']) - self.prob_cured_vaccinate_neutral = np.random.normal(environment.environment_params['prob_cured_vaccinate_neutral'], - environment.environment_params['standard_variance']) - - self.prob_vaccinated_healing_infected = np.random.normal(environment.environment_params['prob_vaccinated_healing_infected'], - environment.environment_params['standard_variance']) - self.prob_vaccinated_vaccinate_neutral = np.random.normal(environment.environment_params['prob_vaccinated_vaccinate_neutral'], - environment.environment_params['standard_variance']) - self.prob_generate_anti_rumor = np.random.normal(environment.environment_params['prob_generate_anti_rumor'], - environment.environment_params['standard_variance']) - - def step(self): - - if self.state['id'] == 0: # Neutral - self.neutral_behaviour() - elif self.state['id'] == 1: # Infected - self.infected_behaviour() - elif self.state['id'] == 2: # Cured - self.cured_behaviour() - elif self.state['id'] == 3: # Vaccinated - self.vaccinated_behaviour() - elif self.state['id'] == 4: # Beacon-off - self.beacon_off_behaviour() - elif self.state['id'] == 5: # Beacon-on - self.beacon_on_behaviour() - - def neutral_behaviour(self): - self.state['visible'] = False - - # Infected - infected_neighbors = self.get_neighboring_agents(state_id=1) - if len(infected_neighbors) > 0: - if random.random() < self.prob_neutral_making_denier: - self.state['id'] = 3 # Vaccinated making denier - - def infected_behaviour(self): - - # Neutral - neutral_neighbors = self.get_neighboring_agents(state_id=0) - for neighbor in neutral_neighbors: - if random.random() < self.prob_infect: - neighbor.state['id'] = 1 # Infected - self.state['visible'] = False - - def cured_behaviour(self): - - self.state['visible'] = True - # Vaccinate - neutral_neighbors = self.get_neighboring_agents(state_id=0) - for neighbor in neutral_neighbors: - if random.random() < self.prob_cured_vaccinate_neutral: - neighbor.state['id'] = 3 # Vaccinated - - # Cure - infected_neighbors = self.get_neighboring_agents(state_id=1) - for neighbor in infected_neighbors: - if random.random() < self.prob_cured_healing_infected: - neighbor.state['id'] = 2 # Cured - - def vaccinated_behaviour(self): - self.state['visible'] = True - - # Cure - infected_neighbors = self.get_neighboring_agents(state_id=1) - for neighbor in infected_neighbors: - if random.random() < self.prob_cured_healing_infected: - neighbor.state['id'] = 2 # Cured - - # Vaccinate - neutral_neighbors = self.get_neighboring_agents(state_id=0) - for neighbor in neutral_neighbors: - if random.random() < self.prob_cured_vaccinate_neutral: - neighbor.state['id'] = 3 # Vaccinated - - # Generate anti-rumor - infected_neighbors_2 = self.get_neighboring_agents(state_id=1) - for neighbor in infected_neighbors_2: - if random.random() < self.prob_generate_anti_rumor: - neighbor.state['id'] = 2 # Cured - - def beacon_off_behaviour(self): - self.state['visible'] = False - infected_neighbors = self.get_neighboring_agents(state_id=1) - if len(infected_neighbors) > 0: - self.state['id'] == 5 # Beacon on - - def beacon_on_behaviour(self): - self.state['visible'] = False - # Cure (M2 feature added) - infected_neighbors = self.get_neighboring_agents(state_id=1) - for neighbor in infected_neighbors: - if random.random() < self.prob_generate_anti_rumor: - neighbor.state['id'] = 2 # Cured - neutral_neighbors_infected = neighbor.get_neighboring_agents(state_id=0) - for neighbor in neutral_neighbors_infected: - if random.random() < self.prob_generate_anti_rumor: - neighbor.state['id'] = 3 # Vaccinated - infected_neighbors_infected = neighbor.get_neighboring_agents(state_id=1) - for neighbor in infected_neighbors_infected: - if random.random() < self.prob_generate_anti_rumor: - neighbor.state['id'] = 2 # Cured - - # Vaccinate - neutral_neighbors = self.get_neighboring_agents(state_id=0) - for neighbor in neutral_neighbors: - if random.random() < self.prob_cured_vaccinate_neutral: - neighbor.state['id'] = 3 # Vaccinated diff --git a/soil/agents/SISaModel.py b/soil/agents/SISaModel.py deleted file mode 100644 index 9aa6c2e..0000000 --- a/soil/agents/SISaModel.py +++ /dev/null @@ -1,93 +0,0 @@ -import random -import numpy as np -from . import FSM, state - - -class SISaModel(FSM): - """ - Settings: - neutral_discontent_spon_prob - - neutral_discontent_infected_prob - - neutral_content_spong_prob - - neutral_content_infected_prob - - discontent_neutral - - discontent_content - - variance_d_c - - content_discontent - - variance_c_d - - content_neutral - - standard_variance - """ - - def __init__(self, environment=None, agent_id=0, state=()): - super().__init__(environment=environment, agent_id=agent_id, state=state) - - self.neutral_discontent_spon_prob = np.random.normal(environment.environment_params['neutral_discontent_spon_prob'], - environment.environment_params['standard_variance']) - self.neutral_discontent_infected_prob = np.random.normal(environment.environment_params['neutral_discontent_infected_prob'], - environment.environment_params['standard_variance']) - self.neutral_content_spon_prob = np.random.normal(environment.environment_params['neutral_content_spon_prob'], - environment.environment_params['standard_variance']) - self.neutral_content_infected_prob = np.random.normal(environment.environment_params['neutral_content_infected_prob'], - environment.environment_params['standard_variance']) - - self.discontent_neutral = np.random.normal(environment.environment_params['discontent_neutral'], - environment.environment_params['standard_variance']) - self.discontent_content = np.random.normal(environment.environment_params['discontent_content'], - environment.environment_params['variance_d_c']) - - self.content_discontent = np.random.normal(environment.environment_params['content_discontent'], - environment.environment_params['variance_c_d']) - self.content_neutral = np.random.normal(environment.environment_params['content_neutral'], - environment.environment_params['standard_variance']) - - @state - def neutral(self): - # Spontaneous effects - if random.random() < self.neutral_discontent_spon_prob: - return self.discontent - if random.random() < self.neutral_content_spon_prob: - return self.content - - # Infected - discontent_neighbors = self.count_neighboring_agents(state_id=self.discontent) - if random.random() < discontent_neighbors * self.neutral_discontent_infected_prob: - return self.discontent - content_neighbors = self.count_neighboring_agents(state_id=self.content.id) - if random.random() < content_neighbors * self.neutral_content_infected_prob: - return self.content - return self.neutral - - @state - def discontent(self): - # Healing - if random.random() < self.discontent_neutral: - return self.neutral - - # Superinfected - content_neighbors = self.count_neighboring_agents(state_id=self.content.id) - if random.random() < content_neighbors * self.discontent_content: - return self.content - return self.discontent - - @state - def content(self): - # Healing - if random.random() < self.content_neutral: - return self.neutral - - # Superinfected - discontent_neighbors = self.count_neighboring_agents(state_id=self.discontent.id) - if random.random() < discontent_neighbors * self.content_discontent: - self.discontent - return self.content diff --git a/soil/agents/SentimentCorrelationModel.py b/soil/agents/SentimentCorrelationModel.py deleted file mode 100644 index 2e034cf..0000000 --- a/soil/agents/SentimentCorrelationModel.py +++ /dev/null @@ -1,102 +0,0 @@ -import random -from . import NetworkAgent - - -class SentimentCorrelationModel(NetworkAgent): - """ - Settings: - outside_effects_prob - - anger_prob - - joy_prob - - sadness_prob - - disgust_prob - """ - - def __init__(self, environment=None, agent_id=0, state=()): - super().__init__(environment=environment, agent_id=agent_id, state=state) - self.outside_effects_prob = environment.environment_params['outside_effects_prob'] - self.anger_prob = environment.environment_params['anger_prob'] - self.joy_prob = environment.environment_params['joy_prob'] - self.sadness_prob = environment.environment_params['sadness_prob'] - self.disgust_prob = environment.environment_params['disgust_prob'] - self.state['time_awareness'] = [] - for i in range(4): # In this model we have 4 sentiments - self.state['time_awareness'].append(0) # 0-> Anger, 1-> joy, 2->sadness, 3 -> disgust - self.state['sentimentCorrelation'] = 0 - - def step(self): - self.behaviour() - - def behaviour(self): - - angry_neighbors_1_time_step = [] - joyful_neighbors_1_time_step = [] - sad_neighbors_1_time_step = [] - disgusted_neighbors_1_time_step = [] - - angry_neighbors = self.get_neighboring_agents(state_id=1) - for x in angry_neighbors: - if x.state['time_awareness'][0] > (self.env.now-500): - angry_neighbors_1_time_step.append(x) - num_neighbors_angry = len(angry_neighbors_1_time_step) - - joyful_neighbors = self.get_neighboring_agents(state_id=2) - for x in joyful_neighbors: - if x.state['time_awareness'][1] > (self.env.now-500): - joyful_neighbors_1_time_step.append(x) - num_neighbors_joyful = len(joyful_neighbors_1_time_step) - - sad_neighbors = self.get_neighboring_agents(state_id=3) - for x in sad_neighbors: - if x.state['time_awareness'][2] > (self.env.now-500): - sad_neighbors_1_time_step.append(x) - num_neighbors_sad = len(sad_neighbors_1_time_step) - - disgusted_neighbors = self.get_neighboring_agents(state_id=4) - for x in disgusted_neighbors: - if x.state['time_awareness'][3] > (self.env.now-500): - disgusted_neighbors_1_time_step.append(x) - num_neighbors_disgusted = len(disgusted_neighbors_1_time_step) - - anger_prob = self.anger_prob+(len(angry_neighbors_1_time_step)*self.anger_prob) - joy_prob = self.joy_prob+(len(joyful_neighbors_1_time_step)*self.joy_prob) - sadness_prob = self.sadness_prob+(len(sad_neighbors_1_time_step)*self.sadness_prob) - disgust_prob = self.disgust_prob+(len(disgusted_neighbors_1_time_step)*self.disgust_prob) - outside_effects_prob = self.outside_effects_prob - - num = random.random() - - if numanger_prob): - - self.state['id'] = 2 - self.state['sentimentCorrelation'] = 2 - self.state['time_awareness'][self.state['id']-1] = self.env.now - elif (numjoy_prob+anger_prob): - - self.state['id'] = 3 - self.state['sentimentCorrelation'] = 3 - self.state['time_awareness'][self.state['id']-1] = self.env.now - elif (numsadness_prob+anger_prob+joy_prob): - - self.state['id'] = 4 - self.state['sentimentCorrelation'] = 4 - self.state['time_awareness'][self.state['id']-1] = self.env.now - - self.state['sentiment'] = self.state['id'] diff --git a/soil/agents/__init__.py b/soil/agents/__init__.py deleted file mode 100644 index b951058..0000000 --- a/soil/agents/__init__.py +++ /dev/null @@ -1,166 +0,0 @@ -# networkStatus = {} # Dict that will contain the status of every agent in the network -# sentimentCorrelationNodeArray = [] -# for x in range(0, settings.network_params["number_of_nodes"]): -# sentimentCorrelationNodeArray.append({'id': x}) -# Initialize agent states. Let's assume everyone is normal. - - -import nxsim -from collections import OrderedDict -from copy import deepcopy -import json - -from functools import wraps - - -agent_types = {} - - -class MetaAgent(type): - def __init__(cls, name, bases, nmspc): - super(MetaAgent, cls).__init__(name, bases, nmspc) - agent_types[name] = cls - - -class BaseAgent(nxsim.BaseAgent, metaclass=MetaAgent): - """ - A special simpy BaseAgent that keeps track of its state history. - """ - - def __init__(self, *args, **kwargs): - self._history = OrderedDict() - self._neighbors = None - super().__init__(*args, **kwargs) - - def __getitem__(self, key): - if isinstance(key, tuple): - k, t_step = key - if k is not None: - if t_step is not None: - return self._history[t_step][k] - else: - return {tt: tv.get(k, None) for tt, tv in self._history.items()} - else: - return self._history[t_step] - return self.state[key] - - def __setitem__(self, key, value): - self.state[key] = value - - def save_state(self): - self._history[self.now] = deepcopy(self.state) - - @property - def now(self): - try: - return self.env.now - except AttributeError: - # No environment - return None - - def run(self): - while True: - res = self.step() - yield res or self.env.timeout(self.env.interval) - - def step(self): - pass - - def to_json(self): - return json.dumps(self._history) - - -class NetworkAgent(BaseAgent, nxsim.BaseNetworkAgent): - - def count_agents(self, state_id=None, limit_neighbors=False): - if limit_neighbors: - agents = self.global_topology.neighbors(self.id) - else: - agents = self.global_topology.nodes() - count = 0 - for agent in agents: - if state_id and state_id != self.global_topology.node[agent]['agent'].state['id']: - continue - count += 1 - return count - - def count_neighboring_agents(self, state_id=None): - return self.count_agents(state_id, limit_neighbors=True) - - -def state(func): - - @wraps(func) - def func_wrapper(self): - when = None - next_state = func(self) - try: - next_state, when = next_state - except TypeError: - pass - if next_state: - try: - self.state['id'] = next_state.id - except AttributeError: - raise NotImplemented('State id %s is not valid.' % next_state) - return when - - func_wrapper.id = func.__name__ - func_wrapper.is_default = False - return func_wrapper - - -def default_state(func): - func.is_default = True - return func - - -class MetaFSM(MetaAgent): - def __init__(cls, name, bases, nmspc): - super(MetaFSM, cls).__init__(name, bases, nmspc) - states = {} - # Re-use states from inherited classes - default_state = None - for i in bases: - if isinstance(i, MetaFSM): - for state_id, state in i.states.items(): - if state.is_default: - default_state = state - states[state_id] = state - - # Add new states - for name, func in nmspc.items(): - if hasattr(func, 'id'): - if func.is_default: - default_state = func - states[func.id] = func - cls.default_state = default_state - cls.states = states - - -class FSM(BaseAgent, metaclass=MetaFSM): - def __init__(self, *args, **kwargs): - super(FSM, self).__init__(*args, **kwargs) - if 'id' not in self.state: - self.state['id'] = self.default_state.id - - def step(self): - if 'id' in self.state: - next_state = self.state['id'] - elif self.default_state: - next_state = self.default_state.id - else: - raise Exception('{} has no valid state id or default state'.format(self)) - if next_state not in self.states: - raise Exception('{} is not a valid id for {}'.format(next_state, self)) - self.states[next_state](self) - - -from .BassModel import * -from .BigMarketModel import * -from .IndependentCascadeModel import * -from .ModelM2 import * -from .SentimentCorrelationModel import * -from .SISaModel import * -from .CounterModel import * -from .DrawingAgent import * diff --git a/soil/analysis.py b/soil/analysis.py deleted file mode 100644 index 6a5789b..0000000 --- a/soil/analysis.py +++ /dev/null @@ -1,23 +0,0 @@ -import pandas as pd - -import glob -import yaml -from os.path import join - - -def get_data(pattern, process=True, attributes=None): - for folder in glob.glob(pattern): - config_file = glob.glob(join(folder, '*.yml'))[0] - config = yaml.load(open(config_file)) - for trial_data in sorted(glob.glob(join(folder, '*.environment.csv'))): - df = pd.read_csv(trial_data) - if process: - if attributes is not None: - df = df[df['attribute'].isin(attributes)] - df = df.pivot_table(values='attribute', index='tstep', columns=['value'], aggfunc='count').fillna(0) - yield config_file, df, config - - -def plot_all(*args, **kwargs): - for config_file, df, config in sorted(get_data(*args, **kwargs)): - df.plot(title=config['name']) diff --git a/soil/environment.py b/soil/environment.py deleted file mode 100644 index 927063c..0000000 --- a/soil/environment.py +++ /dev/null @@ -1,190 +0,0 @@ -import os -import csv -import weakref -from random import random -from copy import deepcopy - -import networkx as nx -import nxsim - - -class SoilEnvironment(nxsim.NetworkEnvironment): - - def __init__(self, name=None, - network_agents=None, - environment_agents=None, - states=None, - default_state=None, - interval=1, - *args, **kwargs): - self.name = name or 'UnnamedEnvironment' - self.states = deepcopy(states) or {} - self.default_state = deepcopy(default_state) or {} - super().__init__(*args, **kwargs) - self._env_agents = {} - self._history = {} - self.interval = interval - self.logger = None - # Add environment agents first, so their events get - # executed before network agents - self.environment_agents = environment_agents or [] - self.network_agents = network_agents or [] - self.process(self.save_state()) - - @property - def agents(self): - yield from self.environment_agents - yield from self.network_agents - - @property - def environment_agents(self): - for ref in self._env_agents.values(): - yield ref() - - @environment_agents.setter - def environment_agents(self, environment_agents): - # Set up environmental agent - self._env_agents = {} - for item in environment_agents: - kwargs = deepcopy(item) - atype = kwargs.pop('agent_type') - kwargs['agent_id'] = kwargs.get('agent_id', atype.__name__) - kwargs['state'] = kwargs.get('state', {}) - a = atype(**kwargs, - environment=self) - self._env_agents[a.id] = weakref.ref(a) - - @property - def network_agents(self): - for i in self.G.nodes(): - node = self.G.node[i] - if 'agent' in node: - yield node['agent'] - - @network_agents.setter - def network_agents(self, network_agents): - for ix in self.G.nodes(): - i = ix - node = self.G.node[i] - v = random() - found = False - for d in network_agents: - threshold = d['threshold'] - if v >= threshold[0] and v < threshold[1]: - agent = d['agent_type'] - state = None - if 'state' in d: - state = deepcopy(d['state']) - else: - try: - state = self.states[i] - except (IndexError, KeyError): - state = deepcopy(self.default_state) - node['agent'] = agent(environment=self, - agent_id=i, - state=state) - found = True - break - assert found - - def run(self, *args, **kwargs): - self._save_state() - super().run(*args, **kwargs) - self._save_state() - - def _save_state(self): - for agent in self.agents: - agent.save_state() - self._history[self.now] = deepcopy(self.environment_params) - - def save_state(self): - while True: - ev = self.event() - ev._ok = True - # Schedule the event with minimum priority so - # that it executes after all agents are done - self.schedule(ev, -1, self.interval) - yield ev - self._save_state() - - def __getitem__(self, key): - return self.environment_params[key] - - def __setitem__(self, key, value): - self.environment_params[key] = value - - def get_path(self, dir_path=None): - dir_path = dir_path or self.sim().dir_path - if not os.path.exists(dir_path): - os.makedirs(dir_path) - return dir_path - - def get_agent(self, agent_id): - return self.G.node[agent_id]['agent'] - - def get_agents(self): - return list(self.agents) - - def dump_csv(self, dir_path=None): - csv_name = os.path.join(self.get_path(dir_path), - '{}.environment.csv'.format(self.name)) - - with open(csv_name, 'w') as f: - cr = csv.writer(f) - cr.writerow(('agent_id', 'tstep', 'attribute', 'value')) - for i in self.history_to_tuples(): - cr.writerow(i) - - def dump_gexf(self, dir_path=None): - G = self.history_to_graph() - graph_path = os.path.join(self.get_path(dir_path), - self.name+".gexf") - nx.write_gexf(G, graph_path, version="1.2draft") - - def history_to_tuples(self): - for tstep, state in self._history.items(): - for attribute, value in state.items(): - yield ('env', tstep, attribute, value) - for agent in self.agents: - for tstep, state in agent._history.items(): - for attribute, value in state.items(): - yield (agent.id, tstep, attribute, value) - - def history_to_graph(self): - G = nx.Graph(self.G) - - for agent in self.agents: - - attributes = {'agent': str(agent.__class__)} - lastattributes = {} - spells = [] - lastvisible = False - laststep = None - for t_step, state in reversed(agent._history.items()): - for attribute, value in state.items(): - if attribute == 'visible': - nowvisible = state[attribute] - if nowvisible and not lastvisible: - laststep = t_step - if not nowvisible and lastvisible: - spells.append((laststep, t_step)) - - lastvisible = nowvisible - else: - if attribute not in lastattributes or lastattributes[attribute][0] != value: - laststep = lastattributes.get(attribute, - (None, None))[1] - value = (state[attribute], t_step, laststep) - key = 'attr_' + attribute - if key not in attributes: - attributes[key] = list() - attributes[key].append(value) - lastattributes[attribute] = (state[attribute], t_step) - if lastvisible: - spells.append((laststep, None)) - if spells: - G.add_node(agent.id, attributes, spells=spells) - else: - G.add_node(agent.id, attributes) - - return G diff --git a/soil/settings.py b/soil/settings.py deleted file mode 100644 index a95cf2f..0000000 --- a/soil/settings.py +++ /dev/null @@ -1 +0,0 @@ -# General configuration diff --git a/soil/simulation.py b/soil/simulation.py deleted file mode 100644 index 838cd65..0000000 --- a/soil/simulation.py +++ /dev/null @@ -1,241 +0,0 @@ -import weakref -import os -import csv -import time -import yaml -import networkx as nx -from networkx.readwrite import json_graph - -from copy import deepcopy -from random import random -from matplotlib import pyplot as plt - -import pickle - -from nxsim import NetworkSimulation - -from . import agents, utils, environment, basestring - - -class SoilSimulation(NetworkSimulation): - """ - Subclass of nsim.NetworkSimulation with three main differences: - 1) agent type can be specified by name or by class. - 2) instead of just one type, an network_agents can be used. - The distribution specifies the weight (or probability) of each - agent type in the topology. This is an example distribution: :: - - [ - {'agent_type': 'agent_type_1', - 'weight': 0.2, - 'state': { - 'id': 0 - } - }, - {'agent_type': 'agent_type_2', - 'weight': 0.8, - 'state': { - 'id': 1 - } - } - ] - - In this example, 20% of the nodes will be marked as type - 'agent_type_1'. - 3) if no initial state is given, each node's state will be set - to `{'id': 0}`. - """ - def __init__(self, name=None, topology=None, network_params=None, - network_agents=None, agent_type=None, states=None, - default_state=None, interval=1, - dir_path=None, num_trials=3, max_time=100, - agent_module=None, - environment_agents=None, environment_params=None): - - if topology is None: - topology = utils.load_network(network_params, - dir_path=dir_path) - elif isinstance(topology, basestring) or isinstance(topology, dict): - topology = json_graph.node_link_graph(topology) - - self.topology = nx.Graph(topology) - self.network_params = network_params - self.name = name or 'UnnamedSimulation' - self.num_trials = num_trials - self.max_time = max_time - self.default_state = default_state or {} - self.dir_path = dir_path or os.getcwd() - self.interval = interval - self.environment_params = environment_params or {} - - environment_agents = environment_agents or [] - self.environment_agents = self._convert_agent_types(environment_agents) - - distro = self.calculate_distribution(network_agents, - agent_type) - self.network_agents = self._convert_agent_types(distro) - - self.states = self.validate_states(states, - topology) - - def calculate_distribution(self, - network_agents=None, - agent_type=None): - if network_agents: - network_agents = deepcopy(network_agents) - elif agent_type: - network_agents = [{'agent_type': agent_type}] - else: - return [] - - # Calculate the thresholds - total = sum(x.get('weight', 1) for x in network_agents) - acc = 0 - for v in network_agents: - upper = acc + (v.get('weight', 1)/total) - v['threshold'] = [acc, upper] - acc = upper - return network_agents - - def serialize_distribution(self): - d = self._convert_agent_types(self.network_agents, - to_string=True) - for v in d: - if 'threshold' in v: - del v['threshold'] - return d - - def _convert_agent_types(self, ind, to_string=False): - d = deepcopy(ind) - for v in d: - agent_type = v['agent_type'] - if to_string and not isinstance(agent_type, str): - v['agent_type'] = str(agent_type.__name__) - elif not to_string and isinstance(agent_type, str): - v['agent_type'] = agents.agent_types[agent_type] - return d - - def validate_states(self, states, topology): - states = states or [] - # Validate states to avoid ignoring states during - # initialization - if isinstance(states, dict): - for x in states: - assert x in self.topology.node - else: - assert len(states) <= len(self.topology) - return states - - def run_simulation(self): - return self.run() - - def run(self): - return list(self.run_simulation_gen()) - - def run_simulation_gen(self): - with utils.timer('simulation'): - for i in range(self.num_trials): - yield self.run_trial(i) - - def run_trial(self, trial_id=0): - """Run a single trial of the simulation - - Parameters - ---------- - trial_id : int - """ - # Set-up trial environment and graph - print('Trial: {}'.format(trial_id)) - env_name = '{}_trial_{}'.format(self.name, trial_id) - env = environment.SoilEnvironment(name=env_name, - topology=self.topology.copy(), - initial_time=0, - interval=self.interval, - network_agents=self.network_agents, - states=self.states, - default_state=self.default_state, - environment_agents=self.environment_agents, - **self.environment_params) - - env.sim = weakref.ref(self) - # Set up agents on nodes - print('\tRunning') - with utils.timer('trial'): - env.run(until=self.max_time) - return env - - def to_dict(self): - return self.__getstate__() - - def to_yaml(self): - return yaml.dump(self.to_dict()) - - def dump_yaml(self, dir_path=None, file_name=None): - dir_path = dir_path or self.dir_path - if not os.path.exists(dir_path): - os.makedirs(dir_path) - if not file_name: - file_name = os.path.join(dir_path, - '{}.dumped.yml'.format(self.name)) - with open(file_name, 'w') as f: - f.write(self.to_yaml()) - - def dump_pickle(self, dir_path=None, pickle_name=None): - dir_path = dir_path or self.dir_path - if not os.path.exists(dir_path): - os.makedirs(dir_path) - if not pickle_name: - pickle_name = os.path.join(dir_path, - '{}.simulation.pickle'.format(self.name)) - with open(pickle_name, 'wb') as f: - pickle.dump(self, f) - - def __getstate__(self): - state = self.__dict__.copy() - state['topology'] = json_graph.node_link_data(self.topology) - state['network_agents'] = self.serialize_distribution() - state['environment_agents'] = self._convert_agent_types(self.environment_agents, - to_string=True) - return state - - def __setstate__(self, state): - self.__dict__ = state - self.topology = json_graph.node_link_graph(state['topology']) - self.network_agents = self._convert_agent_types(self.network_agents) - self.environment_agents = self._convert_agent_types(self.environment_agents) - return state - - -def from_config(config, G=None): - config = list(utils.load_config(config)) - if len(config) > 1: - raise AttributeError('Provide only one configuration') - config = config[0][0] - sim = SoilSimulation(**config) - return sim - - -def run_from_config(*configs, dump=True, results_dir=None, timestamp=False): - if not results_dir: - results_dir = 'soil_output' - for config_def in configs: - for config, cpath in utils.load_config(config_def): - name = config.get('name', 'unnamed') - print("Using config(s): {name}".format(name=name)) - - sim = SoilSimulation(**config) - if timestamp: - sim_folder = '{}_{}'.format(sim.name, - time.strftime("%Y-%m-%d_%H:%M:%S")) - else: - sim_folder = sim.name - dir_path = os.path.join(results_dir, - sim_folder) - results = sim.run_simulation() - - if dump: - sim.dump_pickle(dir_path) - sim.dump_yaml(dir_path) - for env in results: - env.dump_gexf(dir_path) - env.dump_csv(dir_path) diff --git a/soil/utils.py b/soil/utils.py deleted file mode 100644 index 86bba4b..0000000 --- a/soil/utils.py +++ /dev/null @@ -1,61 +0,0 @@ -import os -import yaml -from time import time -from glob import glob - -import networkx as nx - -from contextlib import contextmanager - - -def load_network(network_params, dir_path=None): - path = network_params.get('path', None) - if path: - if dir_path and not os.path.isabs(path): - path = os.path.join(dir_path, path) - extension = os.path.splitext(path)[1][1:] - kwargs = {} - if extension == 'gexf': - kwargs['version'] = '1.2draft' - kwargs['node_type'] = int - try: - method = getattr(nx.readwrite, 'read_' + extension) - except AttributeError: - raise AttributeError('Unknown format') - return method(path, **kwargs) - - net_args = network_params.copy() - net_type = net_args.pop('generator') - - method = getattr(nx.generators, net_type) - return method(**net_args) - - -def load_file(infile): - with open(infile, 'r') as f: - return list(yaml.load_all(f)) - - -def load_files(*patterns): - for pattern in patterns: - for i in glob(pattern): - for config in load_file(i): - yield config, os.path.abspath(i) - - -def load_config(config): - if isinstance(config, dict): - yield config, None - else: - yield from load_files(config) - - -@contextmanager -def timer(name='task', pre="", function=print, to_object=None): - start = time() - yield start - end = time() - function('{}Finished {} in {} seconds'.format(pre, name, str(end-start))) - if to_object: - to_object.start = start - to_object.end = end diff --git a/soil_tutorial.ipynb b/soil_tutorial.ipynb new file mode 100755 index 0000000..fc1a68b --- /dev/null +++ b/soil_tutorial.ipynb @@ -0,0 +1,913 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\"Grupo" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# SOIL Tutorial " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This notebook contains a tutorial to learn how to use the SOcial network sImuLator (SOIL) written in Python. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Introduction" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "SOIL is based in 2 main files:\n", + "* __soil.py__: It's the main file of SOIL. The network creation, simulation and visualization are done in this file.\n", + "+ __settings.json__: This file contains every variable needed in the simulation in order to be modified easily.\n", + "- __models__: All the spread models already implemented are stored in this directory as modules." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Requirements" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "SOIL requires to install:\n", + "* **Python 3** - you can use the Conda distribution\n", + "* **NetworkX** - install with conda install networkx or pip install networkx\n", + "* **simpy** - install with pip install simpy\n", + "* **nxsim** - install with pip install nxsim\n", + "* **Gephi** - Available at https://gephi.org" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Soil.py" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Imports and data initialization" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First of all, you need to make all the imports. This simulator is based on [nxsim](https://pypi.python.org/pypi/nxsim), using [networkx](https://networkx.github.io/) for network management. We will also include the models and settings files where the spread models and initialization variables are stored." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from models import *\n", + "from nxsim import NetworkSimulation\n", + "# import numpy\n", + "from matplotlib import pyplot as plt\n", + "import networkx as nx\n", + "import settings\n", + "import models\n", + "import math\n", + "import json" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Network creation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Using a parameter provided in the settings file, we can choose what type of network we want to create, as well as the number of nodes and some other parameters. More types of networks can be implemented using [networkx](https://networkx.github.io/)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "if settings.network_params[\"network_type\"] == 0:\n", + " G = nx.complete_graph(settings.network_params[\"number_of_nodes\"])\n", + "if settings.network_params[\"network_type\"] == 1:\n", + " G = nx.barabasi_albert_graph(settings.network_params[\"number_of_nodes\"], 10)\n", + "if settings.network_params[\"network_type\"] == 2:\n", + " G = nx.margulis_gabber_galil_graph(settings.network_params[\"number_of_nodes\"], None)\n", + "# More types of networks can be added here" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Visualization" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In order to analyse the results of the simulation. We include them in the topology and a .gexf file is generated. This allows the user to picture the network in [Gephi](https://gephi.org/). A JSON file is also generated to permit further analysis.\n", + "\n", + "The JSON file follows this schema. The file has three depth levels. In the first one we can find the identifier of each agent in the network. Secondly, inside every agent we can observe every attribute that the creator of the model wanted to make visible. In the deepest level the different values of each attribute are\n", + "visible.\n", + "\n", + "\t{\n", + "\t\t\"agent_0\": {\n", + "\t\t\t\"attribute_X\": {\n", + "\t\t\t\t\"0\": 0,\n", + "\t\t\t\t\"2\": 0,\n", + "\t\t\t\t\"4\": 1,\n", + "\t\t\t\t\"6\": 2,\n", + "\t\t\t\t...\n", + "\t\t\t}\n", + "\t\t},\n", + "\t\t\"agent_1\": {\n", + "\t\t\t\"attribute_X\": {\n", + "\t\t\t\t\"0\": 0,\n", + "\t\t\t\t\"2\": 3,\n", + "\t\t\t\t...\n", + "\t\t\t}\n", + "\t\t},\n", + "\t\t...\t\t\n", + "\t}\n", + "\n", + "This is done with the following code:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def visualization(graph_name):\n", + "\n", + " for x in range(0, settings.network_params[\"number_of_nodes\"]):\n", + " for attribute in models.networkStatus[\"agent_%s\" % x]:\n", + " emotionStatusAux = []\n", + " for t_step in models.networkStatus[\"agent_%s\" % x][attribute]:\n", + " prec = 2\n", + " output = math.floor(models.networkStatus[\"agent_%s\" % x][attribute][t_step] * (10 ** prec)) / (10 ** prec) # 2 decimals\n", + " emotionStatusAux.append((output, t_step, t_step + settings.network_params[\"timeout\"]))\n", + " attributes = {}\n", + " attributes[attribute] = emotionStatusAux\n", + " G.add_node(x, attributes)\n", + "\n", + " print(\"Done!\")\n", + "\n", + " with open('data.txt', 'w') as outfile:\n", + " json.dump(models.networkStatus, outfile, sort_keys=True, indent=4, separators=(',', ': '))\n", + "\n", + " nx.write_gexf(G, graph_name+\".gexf\", version=\"1.2draft\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That's only the basic visualization. Everything you need can be implemented as well. For example:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def results(model_name):\n", + " x_values = []\n", + " infected_values = []\n", + " neutral_values = []\n", + " cured_values = []\n", + " vaccinated_values = []\n", + "\n", + " attribute_plot = 'status'\n", + " for time in range(0, settings.network_params[\"max_time\"]):\n", + " value_infectados = 0\n", + " value_neutral = 0\n", + " value_cured = 0\n", + " value_vaccinated = 0\n", + " real_time = time * settings.network_params[\"timeout\"]\n", + " activity = False\n", + " for x in range(0, settings.network_params[\"number_of_nodes\"]):\n", + " if attribute_plot in models.networkStatus[\"agent_%s\" % x]:\n", + " if real_time in models.networkStatus[\"agent_%s\" % x][attribute_plot]:\n", + " if models.networkStatus[\"agent_%s\" % x][attribute_plot][real_time] == 1: ## Infected\n", + " value_infectados += 1\n", + " activity = True\n", + " if models.networkStatus[\"agent_%s\" % x][attribute_plot][real_time] == 0: ## Neutral\n", + " value_neutral += 1\n", + " activity = True\n", + " if models.networkStatus[\"agent_%s\" % x][attribute_plot][real_time] == 2: ## Cured\n", + " value_cured += 1\n", + " activity = True\n", + " if models.networkStatus[\"agent_%s\" % x][attribute_plot][real_time] == 3: ## Vaccinated\n", + " value_vaccinated += 1\n", + " activity = True\n", + "\n", + " if activity:\n", + " x_values.append(real_time)\n", + " infected_values.append(value_infectados)\n", + " neutral_values.append(value_neutral)\n", + " cured_values.append(value_cured)\n", + " vaccinated_values.append(value_vaccinated)\n", + " activity = False\n", + "\n", + " fig1 = plt.figure()\n", + " ax1 = fig1.add_subplot(111)\n", + "\n", + " infected_line = ax1.plot(x_values, infected_values, label='Infected')\n", + " neutral_line = ax1.plot(x_values, neutral_values, label='Neutral')\n", + " cured_line = ax1.plot(x_values, cured_values, label='Cured')\n", + " vaccinated_line = ax1.plot(x_values, vaccinated_values, label='Vaccinated')\n", + " ax1.legend()\n", + " fig1.savefig(model_name + '.png')\n", + " # plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Simulation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The simulation starts with the following code. The user can provide the network topology, the maximum time of simulation, the spread model to be used as well as other parameters." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "agents = settings.environment_params['agent']\n", + "\n", + "print(\"Using Agent(s): {agents}\".format(agents=agents))\n", + "\n", + "if len(agents) > 1:\n", + " for agent in agents:\n", + " sim = NetworkSimulation(topology=G, states=init_states, agent_type=locals()[agent], max_time=settings.network_params[\"max_time\"],\n", + " num_trials=settings.network_params[\"num_trials\"], logging_interval=1.0, **settings.environment_params)\n", + " sim.run_simulation()\n", + " print(str(agent))\n", + " results(str(agent))\n", + " visualization(str(agent))\n", + "else:\n", + " agent = agents[0]\n", + " sim = NetworkSimulation(topology=G, states=init_states, agent_type=locals()[agent], max_time=settings.network_params[\"max_time\"],\n", + " num_trials=settings.network_params[\"num_trials\"], logging_interval=1.0, **settings.environment_params)\n", + " sim.run_simulation()\n", + " results(str(agent))\n", + " visualization(str(agent))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Models" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Imports and initialization" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import settings\n", + "\n", + "networkStatus = {} # Dict that will contain the status of every agent in the network\n", + "\n", + "sentimentCorrelationNodeArray = []\n", + "for x in range(0, settings.network_params[\"number_of_nodes\"]):\n", + " sentimentCorrelationNodeArray.append({'id': x})\n", + "# Initialize agent states. Let's assume everyone is normal.\n", + "init_states = [{'id': 0, } for _ in range(settings.network_params[\"number_of_nodes\"])]\n", + " # add keys as as necessary, but \"id\" must always refer to that state category" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Base behaviour" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Every spread model used in SOIL should extend the base behaviour class. By doing this the exportation of the attributes values will be automatic. This feature will be explained in the Spread Models section. The class looks like this:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import settings\n", + "from nxsim import BaseNetworkAgent\n", + "\n", + "\n", + "class BaseBehaviour(BaseNetworkAgent):\n", + "\n", + " def __init__(self, environment=None, agent_id=0, state=()):\n", + " super().__init__(environment=environment, agent_id=agent_id, state=state)\n", + " self._attrs = {}\n", + "\n", + " @property\n", + " def attrs(self):\n", + " now = self.env.now\n", + " if now not in self._attrs:\n", + " self._attrs[now] = {}\n", + " return self._attrs[now]\n", + "\n", + " @attrs.setter\n", + " def attrs(self, value):\n", + " self._attrs[self.env.now] = value\n", + "\n", + " def run(self):\n", + " while True:\n", + " self.step(self.env.now)\n", + " yield self.env.timeout(settings.network_params[\"timeout\"])\n", + "\n", + " def step(self, now):\n", + " networkStatus['agent_%s'% self.id] = self.to_json()\n", + "\n", + " def to_json(self):\n", + " final = {}\n", + " for stamp, attrs in self._attrs.items():\n", + " for a in attrs:\n", + " if a not in final:\n", + " final[a] = {}\n", + " final[a][stamp] = attrs[a]\n", + " return final" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Spread models" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Every model to be implemented must include an init and a step function. Depending on your model, you would need different attributes. If you want them to be automatic exported for a further analysis, you must name them like this *self.attrs['name_of_attribute']*. Moreover, the last thing you should do inside the step function is call the following method *super().step(now)*. This call will store the values.\n", + "\n", + "Some other tips:\n", + "* __self.state['id']__: To check the id of the current agent/node.\n", + "* __self.get_neighboring_agents(state_id=x)__: Returns the neighbours agents/nodes with the id provided\n", + "\n", + "An example of a spread model already implemented and working:\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import settings\n", + "import random\n", + "import numpy as np\n", + "\n", + "\n", + "class ControlModelM2(BaseBehaviour):\n", + "\n", + " # Init infected\n", + " init_states[random.randint(0, settings.network_params[\"number_of_nodes\"]-1)] = {'id': 1}\n", + " init_states[random.randint(0, settings.network_params[\"number_of_nodes\"]-1)] = {'id': 1}\n", + "\n", + " # Init beacons\n", + " init_states[random.randint(0, settings.network_params[\"number_of_nodes\"]-1)] = {'id': 4}\n", + " init_states[random.randint(0, settings.network_params[\"number_of_nodes\"]-1)] = {'id': 4}\n", + "\n", + " def __init__(self, environment=None, agent_id=0, state=()):\n", + " super().__init__(environment=environment, agent_id=agent_id, state=state)\n", + "\n", + " self.prob_neutral_making_denier = np.random.normal(environment.environment_params['prob_neutral_making_denier'],\n", + " environment.environment_params['standard_variance'])\n", + "\n", + " self.prob_infect = np.random.normal(environment.environment_params['prob_infect'],\n", + " environment.environment_params['standard_variance'])\n", + "\n", + " self.prob_cured_healing_infected = np.random.normal(environment.environment_params['prob_cured_healing_infected'],\n", + " environment.environment_params['standard_variance'])\n", + " self.prob_cured_vaccinate_neutral = np.random.normal(environment.environment_params['prob_cured_vaccinate_neutral'],\n", + " environment.environment_params['standard_variance'])\n", + "\n", + " self.prob_vaccinated_healing_infected = np.random.normal(environment.environment_params['prob_vaccinated_healing_infected'],\n", + " environment.environment_params['standard_variance'])\n", + " self.prob_vaccinated_vaccinate_neutral = np.random.normal(environment.environment_params['prob_vaccinated_vaccinate_neutral'],\n", + " environment.environment_params['standard_variance'])\n", + " self.prob_generate_anti_rumor = np.random.normal(environment.environment_params['prob_generate_anti_rumor'],\n", + " environment.environment_params['standard_variance'])\n", + "\n", + " def step(self, now):\n", + "\n", + " if self.state['id'] == 0: # Neutral\n", + " self.neutral_behaviour()\n", + " elif self.state['id'] == 1: # Infected\n", + " self.infected_behaviour()\n", + " elif self.state['id'] == 2: # Cured\n", + " self.cured_behaviour()\n", + " elif self.state['id'] == 3: # Vaccinated\n", + " self.vaccinated_behaviour()\n", + " elif self.state['id'] == 4: # Beacon-off\n", + " self.beacon_off_behaviour()\n", + " elif self.state['id'] == 5: # Beacon-on\n", + " self.beacon_on_behaviour()\n", + "\n", + " self.attrs['status'] = self.state['id']\n", + " super().step(now)\n", + "\n", + " def neutral_behaviour(self):\n", + "\n", + " # Infected\n", + " infected_neighbors = self.get_neighboring_agents(state_id=1)\n", + " if len(infected_neighbors) > 0:\n", + " if random.random() < self.prob_neutral_making_denier:\n", + " self.state['id'] = 3 # Vaccinated making denier\n", + "\n", + " def infected_behaviour(self):\n", + "\n", + " # Neutral\n", + " neutral_neighbors = self.get_neighboring_agents(state_id=0)\n", + " for neighbor in neutral_neighbors:\n", + " if random.random() < self.prob_infect:\n", + " neighbor.state['id'] = 1 # Infected\n", + "\n", + " def cured_behaviour(self):\n", + "\n", + " # Vaccinate\n", + " neutral_neighbors = self.get_neighboring_agents(state_id=0)\n", + " for neighbor in neutral_neighbors:\n", + " if random.random() < self.prob_cured_vaccinate_neutral:\n", + " neighbor.state['id'] = 3 # Vaccinated\n", + "\n", + " # Cure\n", + " infected_neighbors = self.get_neighboring_agents(state_id=1)\n", + " for neighbor in infected_neighbors:\n", + " if random.random() < self.prob_cured_healing_infected:\n", + " neighbor.state['id'] = 2 # Cured\n", + "\n", + " def vaccinated_behaviour(self):\n", + "\n", + " # Cure\n", + " infected_neighbors = self.get_neighboring_agents(state_id=1)\n", + " for neighbor in infected_neighbors:\n", + " if random.random() < self.prob_cured_healing_infected:\n", + " neighbor.state['id'] = 2 # Cured\n", + "\n", + " # Vaccinate\n", + " neutral_neighbors = self.get_neighboring_agents(state_id=0)\n", + " for neighbor in neutral_neighbors:\n", + " if random.random() < self.prob_cured_vaccinate_neutral:\n", + " neighbor.state['id'] = 3 # Vaccinated\n", + "\n", + " # Generate anti-rumor\n", + " infected_neighbors_2 = self.get_neighboring_agents(state_id=1)\n", + " for neighbor in infected_neighbors_2:\n", + " if random.random() < self.prob_generate_anti_rumor:\n", + " neighbor.state['id'] = 2 # Cured\n", + "\n", + " def beacon_off_behaviour(self):\n", + " infected_neighbors = self.get_neighboring_agents(state_id=1)\n", + " if len(infected_neighbors) > 0:\n", + " self.state['id'] == 5 # Beacon on\n", + "\n", + " def beacon_on_behaviour(self):\n", + "\n", + " # Cure (M2 feature added)\n", + " infected_neighbors = self.get_neighboring_agents(state_id=1)\n", + " for neighbor in infected_neighbors:\n", + " if random.random() < self.prob_generate_anti_rumor:\n", + " neighbor.state['id'] = 2 # Cured\n", + " neutral_neighbors_infected = neighbor.get_neighboring_agents(state_id=0)\n", + " for neighbor in neutral_neighbors_infected:\n", + " if random.random() < self.prob_generate_anti_rumor:\n", + " neighbor.state['id'] = 3 # Vaccinated\n", + " infected_neighbors_infected = neighbor.get_neighboring_agents(state_id=1)\n", + " for neighbor in infected_neighbors_infected:\n", + " if random.random() < self.prob_generate_anti_rumor:\n", + " neighbor.state['id'] = 2 # Cured\n", + "\n", + " # Vaccinate\n", + " neutral_neighbors = self.get_neighboring_agents(state_id=0)\n", + " for neighbor in neutral_neighbors:\n", + " if random.random() < self.prob_cured_vaccinate_neutral:\n", + " neighbor.state['id'] = 3 # Vaccinated" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Settings.json" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This file contains all the variables that can be modified from the simulation. In case of implementing a new spread model, the new variables should be also included in this file." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "[\n", + " {\n", + " \"network_type\": 1,\n", + " \"number_of_nodes\": 1000,\n", + " \"max_time\": 50,\n", + " \"num_trials\": 1,\n", + " \"timeout\": 2\n", + " },\n", + "\n", + " {\n", + " \"agent\": [\"BaseBehaviour\",\"SISaModel\",\"ControlModelM2\"],\n", + "\n", + "\n", + " \"bite_prob\": 0.01,\n", + " \"heal_prob\": 0.01,\n", + "\n", + " \"innovation_prob\": 0.001,\n", + " \"imitation_prob\": 0.005,\n", + "\n", + " \"outside_effects_prob\": 0.2,\n", + " \"anger_prob\": 0.06,\n", + " \"joy_prob\": 0.05,\n", + " \"sadness_prob\": 0.02,\n", + " \"disgust_prob\": 0.02,\n", + "\n", + " \"enterprises\": [\"BBVA\", \"Santander\", \"Bankia\"],\n", + "\n", + " \"tweet_probability_users\": 0.44,\n", + " \"tweet_relevant_probability\": 0.25,\n", + " \"tweet_probability_about\": [0.15, 0.15, 0.15],\n", + " \"sentiment_about\": [0, 0, 0],\n", + "\n", + " \"tweet_probability_enterprises\": [0.3, 0.3, 0.3],\n", + "\n", + " \"neutral_discontent_spon_prob\": 0.04,\n", + " \"neutral_discontent_infected_prob\": 0.04,\n", + " \"neutral_content_spon_prob\": 0.18,\n", + " \"neutral_content_infected_prob\": 0.02,\n", + "\n", + " \"discontent_neutral\": 0.13,\n", + " \"discontent_content\": 0.07,\n", + " \"variance_d_c\": 0.02,\n", + "\n", + " \"content_discontent\": 0.009,\n", + " \"variance_c_d\": 0.003,\n", + " \"content_neutral\": 0.088,\n", + "\n", + " \"standard_variance\": 0.055,\n", + "\n", + "\n", + " \"prob_neutral_making_denier\": 0.035,\n", + "\n", + " \"prob_infect\": 0.075,\n", + "\n", + " \"prob_cured_healing_infected\": 0.035,\n", + " \"prob_cured_vaccinate_neutral\": 0.035,\n", + "\n", + " \"prob_vaccinated_healing_infected\": 0.035,\n", + " \"prob_vaccinated_vaccinate_neutral\": 0.035,\n", + " \"prob_generate_anti_rumor\": 0.035\n", + " }\n", + "]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Model Library" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To test this simulator in all the experiments we have used the Albert\n", + "Barabasi Graph [34] to automatically generate the network and the con-\n", + "nections among the agents due it is one of the most suitable graphs to\n", + "recreate social networks.\n", + "\n", + "Using different human behaviour models we will recreate the different\n", + "decisions of each agent.\n", + "\n", + "Moreover there are some parameters regarding the basic simulation that\n", + "have to be settled. In addition, more parameters will be needed depend-\n", + "ing on the spread model used for the experiment." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Spread Model M2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This model is based on the New Spread Model\n", + "M2 [1] which also refers to the cascade model [2]. Agents, usually Twit-\n", + "ter users, have four states regarding a rumour: neutral (initial state),\n", + "infected, vaccinated and cured.\n", + "\n", + "An agent becomes: infected when believes the rumour; vaccinated when is\n", + "influenced before being infected by a cured or already vaccinated agent\n", + "and cured when after becoming infected the agent is influenced by a\n", + "vaccinated/cured user.\n", + "\n", + "After a certain period of time, a random infected user develops an anti-\n", + "rumour and spreads it to its neighbours in order to vaccinate the neutral\n", + "and cure the infected ones.\n", + "\n", + "This model includes the fact that infected users who made a mistake\n", + "believing in the rumour will not be in favour of spreading theirs mistakes\n", + "through the network. Therefore, only vaccinated users will spread anti-\n", + "rumours. The probability of making a denier and becoming vaccinated\n", + "when a neutral user has an infected neighbour and the first already had\n", + "information about the rumour being false.\n", + "\n", + "* [1] E. Serrano and C. A. Iglesias. “Validating viral marketing\n", + "strategies in Twitter via agent-based social simulation”. In:\n", + "Expert Systems with Applications 50.1 (2016),\n", + "* [2] L. Weng et al. “Virality prediction and community structure\n", + "in social networks”. In: Scientific Reports 3 (2013)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Control model M2,2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This model is based on the New Control Model\n", + "M2,2 [1]. It includes the use of beacons, special agents, that represent\n", + "an authority which can work against the rumour once it is detected. It\n", + "only has two states: on or off. Beacons will switch to on status when they\n", + "detect the misinformation in an infected neighbour agent.\n", + "Once the beacon is activated, they will try to cure and vaccinate other\n", + "agents starting a anti-rumour. Therefore this model also takes into ac-\n", + "count that infected users might not admit a previous mistake.\n", + "\n", + "* [1] E. Serrano and C. A. Iglesias. “Validating viral marketing\n", + "strategies in Twitter via agent-based social simulation”. In:\n", + "Expert Systems with Applications 50.1 (2016)," + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### SISa Model" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The SISa model of infection is already included in the simulator. Its the evolution of the classic disease spread Susceptible-Infective-Susceptible (SIS) model [1, 2].\n", + "\n", + "The SISa model is proposed by [3] and the main new feature is considering the spontaneous generation process of sentiment. This model has two assumptions: first, a susceptible agent who is close and more exposed to the infected has a higher probability of infection that other agent; second, the number of infected agents does not affect the probability of recovery.\n", + "\n", + "Based on some recent implementations of the SISa model [3], every agent can be in three states: neutral (initial), content and discontent.\n", + "\n", + "All the transitions between every different state are allowed depending on customizable probabilities. This model includes the fact that an agent will be more likely to change state as the number of neighbours with this state increases.\n", + "\n", + "* [1] P. Weng and X.-Q. Zhao. “Spreading speed and traveling waves for a multi-type SIS epidemic model”. In: Journal of Differential Equations 229.1 (2006)\n", + "\n", + "* [2] P. V. Mieghem. “Epidemic phase transition of the SIS type in networks”. In: A Letters Journal Exploring the Frontiers of Physics 97.4 (2012).\n", + "* [3] A. L. Hill et al. “Emotions as infectious diseases in a large social network: the SISa model”. In: Proceedings of the Royal Society of London B: Biological Sciences 277.1701 (2010)," + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Big Market Model" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As stated in several papers [2–4], social networks like Twitter are the perfect scenario to study the propagation of ideas, sentiments and marketing strategies. In this scenario several enterprises want to take advantage of social networks to promote their companies and connect with their clients.\n", + "\n", + "The goal of this model [1] is to recreate the behaviour of several enterprises in a social network. Following the example of HashtKat, we want to measure the effect of different marketing strategies in social networks.\n", + "Depending on the sentiment towards an enterprise the user will post positive or negative tweets about these enterprises. The fact that an user can increase its probabilities of posting a relevant tweet about a certain\n", + "company depending on its sentiment towards it is also considered.\n", + "In this model the number of enterprises as well as tweet rate probabilities of both companies and users can be changed.\n", + "\n", + "* [1] E. Serrano and C. A. Iglesias. “Validating viral marketing\n", + "strategies in Twitter via agent-based social simulation”. In:\n", + "Expert Systems with Applications 50.1 (2016)\n", + "* [2] B. A. Huberman et al. “Social Networks that Matter: Twitter\n", + "Under the Microscope”. In: Social Science Research Network\n", + "(2008).\n", + "* [3] M. Cha et al. “Measuring User Influence in Twitter: The\n", + "Million Follower Fallacy.” In: ICWSM 10.10-17 (2010),\n", + "* [4] M. Bulearca and S. Bulearca. “Twitter: a viable marketing\n", + "tool for SMEs?” In: Global business and management research\n", + "2.4 (2010)," + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Sentiment Correlation Model" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With this model we want to study\n", + "the influence of different sentiments in a social network. In order to do so, we base our model on the research made by [1]. In this paper the authors found out that in a social network (in this case Weibo) the correlation\n", + "of anger is significantly higher than joy and sadness meaning that the anger sentiment would occasionally spread faster than the others.\n", + "\n", + "They also confirmed some intuitive ideas such as a pair of users who have higher interactions are more likely to be influenced by each other, and that users with more friends would influence their neighbours more than other agents.\n", + "\n", + "In this simulation we have four emotions: anger, joy, sadness and disgust.\n", + "\n", + "Using the probabilities extracted from the dataset used by [1] we can visualise the graph and confirm the conclusions of the paper. Anger sentiment propagation rate is much higher than any other. Joy sentiment also spreads easily to the neighbours. However, sadness and disgust propagation rate is really small, few neighbours get affected by them.\n", + "\n", + "* [1] R. Fan et al. “Anger is More Influential Than Joy: Sentiment\n", + "Correlation in Weibo”. In: CoRR abs/1309.2402 (2013)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Bass Model" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Even though Bass Model can be applied to many appli-\n", + "cations [57–60] it can be used to study the diffusion of information as\n", + "well.\n", + "This model is based on the implementation proposed by Rand and Wilen-\n", + "sky [13]. In this scenario there are only two states: unaware (initial) and\n", + "aware. For this simulation we assume that agents can only change status\n", + "from advertising (outside effects) and word of mouth (information inside\n", + "the network).\n", + "The probability of being affected by imitation (word of mouth effect)\n", + "increases as a function of the agent aware neighbours. In this model once\n", + "the user changes to aware status it remains in this state for the whole\n", + "simulation.\n", + "\n", + "* F. M. Bass. “A New Product Growth for Model ConsumerDurables”. In: Management Science 15.5 (1969),\n", + "W. Dodds. “An Application of the Bass Model in Long-TermNew Product Forecasting”. In: Journal of Marketing Research\n", + "10.3 (1973),\n", + "* F. Douglas Tigert. “The Bass New Product Growth Model: A Sensitivity Analysis for a High Technology Product”. In: Journal of Marketing 45.4 (1981),\n", + "* Z. Jiang et al. “Virtual Bass Model and the left-hand data-truncation bias in diffusion of innovation studies”. In: International Journal of Research in Marketing 23.1 (2006), " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Independent Cascade Model" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As stated by Rand and Wilensky [1], the Independent Cascade Model [61] suits better the case we want to\n", + "study as it is more appropriate for social networks than the Bass Model.\n", + "\n", + "In this scenario we also have two states: unaware (initial) and aware. The new feature in this model is that one agent will only get infected once at least one neighbour became aware the previous time step. There is also\n", + "a probability of becoming aware by outside effects (innovation).\n", + "\n", + "This new feature can be explained intuitively, one agent will have more influence on another if the first just infected and wants to spread the new information he acquired.\n", + "\n", + "\n", + "* [1] W. Rand and U. Wilensky. An Introduction to Agent-Based Modeling: Modeling Natural, Social, and Engineered Complex Systems with NetLogo. MIT Press, 2015.\n", + "* [2] J. Goldenberg et al. “Talk of the Network: A Complex Systems Look at the Underlying Process of Word-of-Mouth”. In: Marketing Letters 12.3 (2001),\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Copyright" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "SOIL has been developed by the Intelligent Systems Group, Universidad Politécnica de Madrid, 2016-2017.\n", + "\n", + "@Copyright Universidad Politécnica de Madrid, 2016-2017\n", + " \"Grupo" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.0" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/test-requirements.txt b/test-requirements.txt deleted file mode 100644 index e69de29..0000000 diff --git a/tests/test_main.py b/tests/test_main.py deleted file mode 100644 index d107d8c..0000000 --- a/tests/test_main.py +++ /dev/null @@ -1,225 +0,0 @@ -from unittest import TestCase - -import os -import yaml -from functools import partial - -from os.path import join -from soil import simulation, agents, utils - - -ROOT = os.path.abspath(os.path.dirname(__file__)) - -EXAMPLES = join(ROOT, '..', 'examples') - - -class TestMain(TestCase): - - def test_load_graph(self): - """ - Load a graph from file if the extension is known. - Raise an exception otherwise. - """ - config = { - 'network_params': { - 'path': join(ROOT, 'test.gexf') - } - } - G = utils.load_network(config['network_params']) - assert G - assert len(G) == 2 - with self.assertRaises(AttributeError): - config = { - 'network_params': { - 'path': join(ROOT, 'unknown.extension') - } - } - G = utils.load_network(config['network_params']) - print(G) - - def test_generate_barabasi(self): - """ - If no path is given, a generator and network parameters - should be used to generate a network - """ - config = { - 'network_params': { - 'generator': 'barabasi_albert_graph' - } - } - with self.assertRaises(TypeError): - G = utils.load_network(config['network_params']) - config['network_params']['n'] = 100 - config['network_params']['m'] = 10 - G = utils.load_network(config['network_params']) - assert len(G) == 100 - - def test_empty_simulation(self): - """A simulation with a base behaviour should do nothing""" - config = { - 'network_params': { - 'path': join(ROOT, 'test.gexf') - }, - 'agent_type': 'NetworkAgent', - 'environment_params': { - } - } - s = simulation.from_config(config) - s.run_simulation() - - def test_counter_agent(self): - """ - The initial states should be applied to the agent and the - agent should be able to update its state.""" - config = { - 'network_params': { - 'path': join(ROOT, 'test.gexf') - }, - 'agent_type': 'CounterModel', - 'states': [{'neighbors': 10}, {'total': 12}], - 'max_time': 2, - 'num_trials': 1, - 'environment_params': { - } - } - s = simulation.from_config(config) - env = s.run_simulation()[0] - assert env.get_agent(0)['neighbors', 0] == 10 - assert env.get_agent(0)['neighbors', 1] == 1 - assert env.get_agent(1)['total', 0] == 12 - assert env.get_agent(1)['neighbors', 1] == 1 - - def test_counter_agent_history(self): - """ - The evolution of the state should be recorded in the logging agent - """ - config = { - 'network_params': { - 'path': join(ROOT, 'test.gexf') - }, - 'network_agents': [{ - 'agent_type': 'AggregatedCounter', - 'weight': 1, - 'state': {'id': 0} - - }], - 'max_time': 10, - 'environment_params': { - } - } - s = simulation.from_config(config) - env = s.run_simulation()[0] - for agent in env.network_agents: - last = 0 - assert len(agent._history) == 11 - for step, total in agent['total', None].items(): - if step > 0: - assert total == last + 2 - last = total - - def test_custom_agent(self): - """Allow for search of neighbors with a certain state_id""" - class CustomAgent(agents.NetworkAgent): - def step(self): - self.state['neighbors'] = self.count_agents(state_id=0, - limit_neighbors=True) - config = { - 'network_params': { - 'path': join(ROOT, 'test.gexf') - }, - 'network_agents': [{ - 'agent_type': CustomAgent, - 'weight': 1, - 'state': {'id': 0} - - }], - 'max_time': 10, - 'environment_params': { - } - } - s = simulation.from_config(config) - env = s.run_simulation()[0] - assert env.get_agent(0).state['neighbors'] == 1 - - def test_torvalds_example(self): - """A complete example from a documentation should work.""" - config = utils.load_file(join(EXAMPLES, 'torvalds.yml'))[0] - config['network_params']['path'] = join(EXAMPLES, - config['network_params']['path']) - s = simulation.from_config(config) - env = s.run_simulation()[0] - for a in env.network_agents: - skill_level = a.state['skill_level'] - if a.id == 'Torvalds': - assert skill_level == 'God' - assert a.state['total'] == 3 - assert a.state['neighbors'] == 2 - elif a.id == 'balkian': - assert skill_level == 'developer' - assert a.state['total'] == 3 - assert a.state['neighbors'] == 1 - else: - assert skill_level == 'beginner' - assert a.state['total'] == 3 - assert a.state['neighbors'] == 1 - - def test_yaml(self): - """ - The YAML version of a newly created simulation - should be equivalent to the configuration file used - """ - with utils.timer('loading'): - config = utils.load_file(join(EXAMPLES, 'complete.yml'))[0] - s = simulation.from_config(config) - with utils.timer('serializing'): - serial = s.to_yaml() - with utils.timer('recovering'): - recovered = yaml.load(serial) - with utils.timer('deleting'): - del recovered['topology'] - assert config == recovered - - def test_configuration_changes(self): - """ - The configuration should not change after running - the simulation. - """ - config = utils.load_file('examples/complete.yml')[0] - s = simulation.from_config(config) - for i in range(5): - s.run_simulation() - nconfig = s.to_dict() - del nconfig['topology'] - assert config == nconfig - - def test_examples(self): - """ - Make sure all examples in the examples folder are correct - """ - - -def make_example_test(path, config): - def wrapped(self): - root = os.getcwd() - os.chdir(os.path.dirname(path)) - s = simulation.from_config(config) - envs = s.run_simulation() - for env in envs: - n = config['network_params'].get('n', None) - if n is not None: - assert len(env.get_agents()) == n - os.chdir(root) - return wrapped - - -def add_example_tests(): - for config, path in utils.load_config(join(EXAMPLES, '*.yml')): - p = make_example_test(path=path, config=config) - fname = os.path.basename(path) - p.__name__ = 'test_example_file_%s' % fname - p.__doc__ = '%s should be a valid configuration' % fname - setattr(TestMain, p.__name__, p) - del p - - -add_example_tests() diff --git a/tests/unknown.extension b/tests/unknown.extension deleted file mode 100644 index 01336dd..0000000 --- a/tests/unknown.extension +++ /dev/null @@ -1 +0,0 @@ -This is an unknown file \ No newline at end of file