diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..fc0ac63 Binary files /dev/null and b/.DS_Store differ diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/VictimSim.iml b/.idea/VictimSim.iml new file mode 100644 index 0000000..8e5446a --- /dev/null +++ b/.idea/VictimSim.iml @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..3f3e15f --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..401c506 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/datasets/.DS_Store b/datasets/.DS_Store new file mode 100644 index 0000000..961a5ca Binary files /dev/null and b/datasets/.DS_Store differ diff --git a/datasets/data_12x12_10vic/env_size.txt b/datasets/data_12x12_10vic/env_size.txt index e9d492a..9992dd6 100644 --- a/datasets/data_12x12_10vic/env_size.txt +++ b/datasets/data_12x12_10vic/env_size.txt @@ -3,4 +3,4 @@ GRID_WIDTH 12 GRID_HEIGHT 12 WINDOW_WIDTH 300 WINDOW_HEIGHT 300 -DELAY 0.01 \ No newline at end of file +DELAY 0.1 \ No newline at end of file diff --git a/datasets/data_20x20_42vic/env_size.txt b/datasets/data_20x20_42vic/env_size.txt index 07b33b3..55312f8 100644 --- a/datasets/data_20x20_42vic/env_size.txt +++ b/datasets/data_20x20_42vic/env_size.txt @@ -1,6 +1,6 @@ -BASE 0,0 +BASE 10,10 GRID_WIDTH 20 GRID_HEIGHT 20 WINDOW_WIDTH 400 WINDOW_HEIGHT 400 -DELAY 0.02 \ No newline at end of file +DELAY 0.01 \ No newline at end of file diff --git a/datasets/data_20x20_42vic/explorer_config.txt b/datasets/data_20x20_42vic/explorer_config.txt index db3e9c3..33250da 100644 --- a/datasets/data_20x20_42vic/explorer_config.txt +++ b/datasets/data_20x20_42vic/explorer_config.txt @@ -1,7 +1,7 @@ NAME EXPLORER COLOR (0, 0, 255) TRACE_COLOR (153, 153, 255) -TLIM 600 +TLIM 100 COST_LINE 1.0 COST_DIAG 1.5 COST_READ 2.0 diff --git a/datasets/data_teste_sala/env_size.txt b/datasets/data_teste_sala/env_size.txt new file mode 100644 index 0000000..b09115e --- /dev/null +++ b/datasets/data_teste_sala/env_size.txt @@ -0,0 +1,6 @@ +BASE 25,33 +GRID_WIDTH 100 +GRID_HEIGHT 80 +WINDOW_WIDTH 940 +WINDOW_HEIGHT 720 +DELAY 0.02 \ No newline at end of file diff --git a/datasets/data_teste_sala/env_victims.txt b/datasets/data_teste_sala/env_victims.txt new file mode 100644 index 0000000..44b320a --- /dev/null +++ b/datasets/data_teste_sala/env_victims.txt @@ -0,0 +1,132 @@ +0,47 +0,74 +0,77 +2,48 +2,75 +4,78 +4,79 +5,1 +5,5 +5,40 +5,43 +6,2 +7,39 +7,69 +9,20 +10,0 +13,4 +13,10 +13,21 +14,39 +16,2 +16,23 +17,20 +18,42 +20,8 +20,16 +20,21 +20,25 +21,2 +23,13 +25,16 +26,12 +26,14 +28,2 +28,68 +28,75 +30,58 +32,72 +33,8 +33,62 +34,8 +35,9 +35,54 +36,7 +36,50 +36,72 +37,23 +37,32 +37,48 +38,47 +38,70 +39,12 +39,52 +40,49 +40,74 +41,37 +41,41 +42,77 +43,4 +43,66 +44,12 +44,14 +44,51 +44,65 +45,29 +45,53 +45,75 +45,78 +47,19 +47,49 +48,50 +48,58 +49,8 +50,16 +50,61 +52,1 +52,22 +53,45 +54,42 +56,6 +57,28 +58,13 +59,3 +61,22 +65,15 +66,31 +66,58 +66,61 +67,30 +68,10 +68,27 +69,29 +69,33 +69,39 +69,60 +70,77 +72,12 +72,20 +72,74 +74,6 +75,75 +76,27 +76,61 +77,9 +79,13 +79,17 +79,29 +79,69 +79,78 +82,13 +83,17 +83,67 +85,20 +86,6 +87,74 +89,70 +90,18 +91,23 +91,77 +92,53 +92,66 +95,31 +96,12 +96,23 +96,29 +97,13 +97,41 +97,71 +98,25 +98,35 +98,52 +98,74 diff --git a/datasets/data_teste_sala/env_walls.txt b/datasets/data_teste_sala/env_walls.txt new file mode 100644 index 0000000..6859146 --- /dev/null +++ b/datasets/data_teste_sala/env_walls.txt @@ -0,0 +1,856 @@ +0,0 +0,44 +0,48 +0,60 +0,79 +1,1 +1,61 +1,78 +1,79 +2,2 +2,51 +2,62 +2,77 +2,78 +3,43 +3,45 +3,63 +3,76 +3,77 +4,6 +4,40 +4,53 +4,63 +4,64 +4,65 +4,75 +4,76 +5,7 +5,37 +5,38 +5,39 +5,45 +5,65 +5,74 +5,75 +6,8 +6,37 +6,47 +6,53 +6,66 +6,73 +6,74 +7,9 +7,27 +7,28 +7,29 +7,30 +7,31 +7,32 +7,36 +7,37 +7,49 +7,51 +7,67 +7,72 +7,73 +8,0 +8,1 +8,2 +8,3 +8,4 +8,5 +8,6 +8,7 +8,8 +8,9 +8,10 +8,26 +8,27 +8,33 +8,36 +8,71 +8,72 +9,26 +9,33 +9,36 +9,70 +9,71 +10,26 +10,34 +10,35 +10,36 +10,68 +10,69 +10,70 +11,26 +11,36 +12,26 +12,36 +12,38 +12,39 +13,36 +13,37 +13,40 +14,37 +15,43 +16,8 +16,9 +16,10 +16,12 +16,14 +16,16 +16,38 +17,6 +17,7 +17,8 +17,12 +17,17 +17,39 +17,45 +18,5 +18,7 +18,12 +18,14 +18,40 +19,7 +19,12 +19,14 +19,18 +19,45 +20,4 +20,14 +20,18 +20,41 +20,44 +20,60 +21,42 +21,60 +22,3 +22,19 +22,20 +22,29 +22,30 +22,31 +22,32 +22,33 +22,34 +22,35 +22,36 +22,37 +22,38 +22,61 +23,2 +23,20 +23,29 +23,38 +23,61 +24,20 +24,29 +24,38 +24,62 +25,2 +25,14 +25,19 +25,29 +25,38 +25,62 +25,64 +25,66 +25,68 +25,70 +25,72 +25,74 +25,76 +25,77 +25,78 +26,3 +26,11 +26,19 +26,29 +26,36 +26,38 +26,62 +26,78 +27,24 +27,25 +27,26 +27,27 +27,28 +27,29 +27,35 +27,36 +27,38 +27,63 +27,67 +27,70 +27,78 +28,4 +28,18 +28,24 +28,26 +28,27 +28,28 +28,34 +28,35 +28,36 +28,38 +28,60 +28,63 +28,67 +28,70 +28,76 +28,77 +28,78 +29,18 +29,24 +29,25 +29,26 +29,27 +29,28 +29,32 +29,33 +29,34 +29,35 +29,36 +29,60 +29,63 +29,64 +29,67 +29,70 +29,76 +30,5 +30,16 +30,17 +30,24 +30,26 +30,27 +30,28 +30,31 +30,32 +30,33 +30,34 +30,35 +30,36 +30,60 +30,61 +30,64 +30,67 +30,68 +30,69 +30,70 +30,71 +30,72 +30,73 +30,74 +30,76 +31,3 +31,4 +31,6 +31,8 +31,10 +31,12 +31,14 +31,16 +31,24 +31,25 +31,26 +31,27 +31,28 +31,56 +31,60 +31,61 +31,64 +31,70 +31,74 +31,76 +32,3 +32,4 +32,7 +32,9 +32,11 +32,13 +32,15 +32,28 +32,29 +32,56 +32,57 +32,59 +32,60 +32,64 +32,65 +32,70 +32,74 +32,76 +33,3 +33,5 +33,10 +33,12 +33,57 +33,58 +33,59 +33,65 +33,70 +34,2 +34,3 +34,4 +34,6 +34,11 +34,48 +34,49 +34,50 +34,57 +34,58 +34,65 +34,66 +34,70 +34,71 +34,72 +35,2 +35,3 +35,4 +35,7 +35,10 +35,46 +35,47 +35,48 +35,50 +35,51 +35,52 +35,57 +35,58 +35,66 +35,71 +35,72 +35,75 +35,76 +35,77 +35,78 +35,79 +36,3 +36,8 +36,46 +36,47 +36,52 +36,59 +36,66 +36,67 +36,68 +36,71 +37,3 +37,9 +37,10 +37,44 +37,45 +37,46 +37,52 +37,53 +37,59 +37,60 +37,66 +37,67 +37,71 +37,72 +37,73 +37,74 +37,75 +37,76 +37,77 +37,78 +38,10 +38,42 +38,43 +38,44 +38,53 +38,54 +38,60 +38,67 +38,78 +39,10 +39,42 +39,43 +39,54 +39,60 +39,61 +39,67 +39,68 +39,72 +39,73 +39,74 +39,75 +39,76 +39,78 +40,11 +40,12 +40,54 +40,61 +40,62 +40,68 +40,72 +40,76 +40,78 +41,11 +41,14 +41,54 +41,55 +41,62 +41,68 +41,69 +41,72 +41,74 +41,75 +41,76 +41,78 +42,10 +42,12 +42,27 +42,55 +42,56 +42,62 +42,63 +42,69 +42,72 +42,74 +42,78 +43,9 +43,15 +43,16 +43,28 +43,29 +43,30 +43,31 +43,56 +43,57 +43,62 +43,63 +43,69 +43,70 +43,72 +43,74 +43,75 +43,76 +43,77 +43,78 +44,8 +44,28 +44,31 +44,34 +44,35 +44,36 +44,37 +44,42 +44,43 +44,57 +44,58 +44,63 +44,69 +44,70 +44,72 +45,7 +45,17 +45,28 +45,31 +45,34 +45,36 +45,37 +45,44 +45,58 +45,59 +45,63 +45,64 +45,67 +45,68 +45,69 +45,72 +45,76 +46,8 +46,9 +46,11 +46,13 +46,14 +46,22 +46,25 +46,28 +46,31 +46,34 +46,37 +46,45 +46,59 +46,60 +46,64 +46,65 +46,66 +46,67 +46,71 +46,72 +46,73 +46,74 +46,75 +46,76 +46,77 +46,78 +46,79 +47,25 +47,28 +47,30 +47,31 +47,34 +47,37 +47,46 +47,60 +47,64 +47,65 +48,25 +48,26 +48,27 +48,28 +48,30 +48,34 +48,36 +48,37 +48,47 +48,60 +48,62 +48,63 +48,64 +49,30 +49,31 +49,32 +49,33 +49,34 +49,36 +49,48 +49,59 +49,60 +49,61 +49,62 +50,36 +50,49 +50,57 +50,58 +50,59 +51,36 +51,38 +51,39 +51,40 +51,41 +51,42 +51,43 +51,44 +51,45 +51,46 +51,47 +51,48 +51,49 +51,55 +51,56 +51,57 +52,36 +52,53 +52,54 +52,55 +53,36 +53,51 +53,52 +53,53 +54,10 +54,49 +54,50 +54,51 +55,14 +55,47 +55,48 +55,49 +56,15 +56,45 +56,46 +56,47 +57,44 +57,45 +57,51 +57,55 +57,58 +57,59 +57,67 +58,17 +58,40 +58,41 +58,42 +58,43 +58,68 +59,39 +59,40 +59,41 +59,69 +60,37 +60,38 +60,39 +60,70 +61,17 +61,35 +61,36 +61,37 +61,45 +61,71 +62,35 +62,43 +62,45 +62,58 +62,60 +62,61 +62,73 +63,32 +63,33 +63,34 +63,35 +63,57 +63,62 +63,74 +63,78 +64,17 +64,32 +64,56 +64,63 +64,75 +65,29 +65,30 +65,31 +65,32 +65,55 +65,64 +65,75 +66,26 +66,27 +66,28 +66,29 +66,48 +66,55 +66,64 +67,15 +67,26 +67,53 +67,55 +67,64 +67,74 +68,14 +68,23 +68,24 +68,25 +68,26 +68,55 +68,64 +68,72 +69,10 +69,11 +69,13 +69,23 +69,24 +69,25 +69,26 +69,27 +69,55 +69,64 +69,70 +69,72 +70,3 +70,4 +70,5 +70,6 +70,7 +70,8 +70,9 +70,10 +70,27 +70,28 +70,29 +70,30 +70,31 +70,56 +70,63 +70,69 +71,2 +71,31 +71,32 +71,57 +71,62 +72,1 +72,32 +72,33 +72,58 +72,59 +72,60 +72,61 +72,68 +73,1 +73,33 +73,34 +73,67 +74,1 +74,34 +74,35 +74,54 +74,55 +74,56 +74,57 +74,58 +74,59 +74,60 +74,61 +74,62 +74,63 +74,68 +75,1 +75,15 +75,35 +75,36 +75,37 +75,63 +75,70 +76,1 +76,15 +76,37 +76,38 +76,63 +77,2 +77,15 +77,38 +77,39 +77,63 +77,73 +78,2 +78,3 +78,15 +78,39 +78,40 +78,41 +78,43 +78,45 +78,63 +79,3 +79,4 +79,5 +79,15 +79,40 +79,49 +79,63 +79,66 +80,5 +80,6 +80,15 +80,36 +80,66 +80,67 +80,74 +81,6 +81,9 +81,10 +81,11 +81,12 +81,13 +81,14 +81,15 +81,16 +81,17 +81,18 +81,19 +81,20 +81,21 +81,22 +81,23 +81,24 +81,66 +81,68 +82,15 +82,16 +82,66 +82,69 +82,76 +83,15 +83,33 +83,49 +83,66 +83,70 +84,15 +84,66 +85,15 +85,28 +85,77 +86,15 +86,47 +86,68 +87,15 +87,29 +87,30 +87,68 +87,69 +87,78 +88,15 +88,68 +88,70 +89,15 +89,32 +89,45 +89,68 +89,71 +89,79 +90,14 +90,28 +90,33 +90,36 +90,68 +91,14 +91,42 +91,68 +92,14 +92,35 +92,68 +93,14 +93,20 +93,21 +93,22 +93,23 +93,24 +93,25 +93,26 +93,27 +93,28 +93,29 +93,30 +93,31 +93,32 +93,33 +93,34 +93,35 +93,68 +94,14 +94,20 +94,21 +94,35 +94,68 +95,14 +95,20 +95,35 +95,36 +95,37 +95,68 +95,70 +96,14 +96,20 +96,35 +96,36 +96,37 +96,70 +96,71 +97,20 +97,37 +97,38 +97,39 +97,70 +97,72 +98,13 +98,20 +98,39 +98,70 +99,13 +99,39 +99,70 diff --git a/datasets/data_teste_sala/explorer_config.txt b/datasets/data_teste_sala/explorer_config.txt new file mode 100644 index 0000000..3a28974 --- /dev/null +++ b/datasets/data_teste_sala/explorer_config.txt @@ -0,0 +1,8 @@ +NAME EXPLORER +COLOR (0, 0, 255) +TRACE_COLOR (153, 153, 255) +TLIM 1000 +COST_LINE 1.0 +COST_DIAG 1.5 +COST_READ 2.0 +COST_FIRST_AID 1.0 diff --git a/datasets/data_teste_sala/rescuer_config.txt b/datasets/data_teste_sala/rescuer_config.txt new file mode 100644 index 0000000..ceeff24 --- /dev/null +++ b/datasets/data_teste_sala/rescuer_config.txt @@ -0,0 +1,8 @@ +NAME RESCUER +COLOR (255, 0, 127) +TRACE_COLOR (255, 153, 204) +TLIM 1000 +COST_LINE 1.0 +COST_DIAG 1.5 +COST_READ 2.0 +COST_FIRST_AID 1.0 diff --git a/datasets/data_teste_sala/sinais_vitais.txt b/datasets/data_teste_sala/sinais_vitais.txt new file mode 100644 index 0000000..12a2db2 --- /dev/null +++ b/datasets/data_teste_sala/sinais_vitais.txt @@ -0,0 +1,132 @@ +1,18.907009,12.220855,8.733333,134.454047,17.972046,34.192304,2 +2,14.698109,13.586879,8.614814,86.302237,4.168373,40.000000,2 +3,16.428095,1.904802,-4.333333,138.880782,2.721256,27.122605,2 +4,14.616501,13.700638,8.602531,51.356913,18.061923,47.188993,2 +5,10.955766,9.485389,-0.000000,1.951730,14.033748,68.333333,3 +6,14.621462,1.463106,-4.362660,106.456614,0.354636,41.428771,2 +7,10.037773,4.177473,-3.780947,55.878393,19.711002,50.696989,3 +8,17.223722,8.203223,4.666667,189.246031,11.338251,37.278451,2 +9,20.084017,14.362603,8.733333,181.288653,11.979483,31.981457,2 +10,18.862776,14.473328,8.733333,78.536915,13.341729,63.470950,3 +11,16.895326,2.364196,-4.337934,4.971047,16.729597,46.806638,2 +12,16.306264,14.558892,8.733333,134.287359,18.817631,31.196184,2 +13,19.974414,14.357504,8.733333,167.434127,8.423106,13.222719,1 +14,21.567229,7.280635,4.666667,194.299928,1.862282,25.170490,2 +15,20.669863,12.004207,8.733333,11.386577,16.145213,39.496205,2 +16,3.841922,2.128295,0.000000,90.064763,7.303765,68.268108,3 +17,12.069793,6.326419,0.211387,116.494060,18.474490,62.226541,3 +18,16.787080,13.736033,8.733333,137.327563,8.177913,13.222719,1 +19,18.813468,11.883110,8.710609,143.886551,18.220736,32.960275,2 +20,18.941295,14.392386,8.733333,130.008150,3.883410,19.327424,1 +21,19.437846,9.836110,4.749161,145.382910,2.849437,24.652787,1 +22,8.427097,0.535675,-5.509081,74.769533,19.357439,69.419681,3 +23,14.645388,12.736940,8.606922,116.316417,0.969741,29.251559,2 +24,14.702373,14.009899,8.615446,23.223703,15.107840,40.000000,2 +25,19.304493,10.181027,4.982862,11.530872,16.143004,46.018998,2 +26,13.553224,11.366102,5.639167,195.953045,9.617794,17.943211,1 +27,15.360904,11.146987,8.696152,56.964745,8.356456,33.697171,2 +28,14.776196,5.883405,4.468720,118.994860,21.552464,42.904831,2 +29,12.618033,9.832168,1.569744,192.432206,8.777855,36.655909,2 +30,15.042119,2.567800,-4.348994,37.155653,9.684112,31.615823,2 +31,16.118277,10.590691,6.418728,38.607963,3.449774,20.577727,1 +32,3.745589,0.477493,0.000000,68.328821,7.172754,66.339246,3 +33,18.108324,4.153845,-0.744046,186.579579,6.909362,38.470552,2 +34,2.836233,0.692571,0.000000,78.133507,19.679015,85.495664,4 +35,7.497988,1.456977,-6.713589,54.643342,5.434532,32.185656,2 +36,14.642074,12.351867,8.606421,30.389416,6.834938,13.263466,1 +37,16.568640,10.422429,5.728301,79.421769,8.995116,41.948075,2 +38,6.334251,4.756492,-0.635086,74.944493,15.576240,85.297977,4 +39,17.393175,14.253331,8.733333,26.222941,3.160027,13.222719,1 +40,2.769136,0.516691,0.000000,87.008144,19.169085,84.912249,4 +41,8.312453,6.581165,0.000000,18.302633,1.829430,40.000000,2 +42,18.491214,5.723377,4.833042,122.925392,10.158232,36.525665,2 +43,14.549269,11.482752,7.155830,2.195818,0.668559,13.896490,1 +44,18.006788,11.927999,8.722314,114.652077,16.570412,51.829730,3 +45,21.317025,2.803089,-4.352375,157.945972,15.400939,67.990734,3 +46,13.683900,7.346466,3.297574,47.073355,4.719269,45.111710,2 +47,17.324761,6.683793,4.681215,89.603943,14.957903,71.874432,3 +48,19.023338,9.694695,4.726229,113.871637,12.260439,49.589482,2 +49,15.555085,10.640472,6.638480,12.280288,18.714936,30.977739,2 +50,18.320822,11.320300,8.617869,99.257777,12.288441,51.822081,3 +51,6.100560,4.140376,-4.094402,128.463047,19.839021,41.337470,2 +52,21.218071,10.195540,5.011175,44.253146,9.229389,34.489500,2 +53,12.108530,9.826470,0.325684,167.411289,7.878824,39.334247,2 +54,7.645853,2.439176,-6.397811,194.215046,10.757725,32.113758,2 +55,17.913132,1.784965,-4.333333,169.274578,5.631167,27.122605,2 +56,14.557681,7.475461,4.238231,101.199891,20.441724,49.903183,2 +57,20.243195,14.396159,8.733333,55.775122,10.268650,34.918227,2 +58,11.796009,5.105786,-0.000000,149.323444,5.588173,40.000000,2 +59,12.387536,8.779016,1.056502,47.386077,9.486806,50.144025,3 +60,4.051338,3.357179,0.000000,191.469056,15.455660,68.333333,3 +61,18.494130,11.269006,8.646427,124.052007,8.851257,24.653839,1 +62,11.633148,3.826427,-4.462620,120.052429,4.000482,38.454967,2 +63,14.099209,7.589356,3.764001,34.520900,18.837525,42.806290,2 +64,17.507954,10.486151,5.983553,18.069348,12.852427,35.693471,2 +65,13.876582,13.363549,8.473727,51.052441,8.218733,30.674276,2 +66,16.792895,14.389371,8.733333,171.714106,4.877280,13.222719,1 +67,18.865437,8.208233,4.666667,182.213411,4.817871,25.170490,2 +68,15.952753,2.079367,-4.333726,139.926753,11.489114,41.990883,2 +69,4.716048,2.239410,0.000000,145.036471,9.535300,40.000000,2 +70,6.223230,3.862624,-8.401810,45.977216,16.308688,50.358357,3 +71,13.477877,12.610759,8.393752,115.210691,1.549892,29.784412,2 +72,3.956451,3.814233,0.000000,162.125621,18.641336,55.267187,3 +73,16.354706,12.214272,8.733333,80.768674,14.957365,68.308631,3 +74,15.680758,3.652875,-4.398136,197.687853,3.006333,26.758771,2 +75,19.766466,13.938954,8.733333,17.999763,18.884848,30.048193,2 +76,14.147642,5.249756,3.815389,64.188207,4.396351,48.559575,2 +77,5.022027,2.948929,-8.620209,102.281788,13.361478,59.889172,3 +78,15.285723,3.766258,-4.406177,12.121273,11.946990,40.934288,2 +79,10.854724,9.240670,-0.000000,145.137585,3.571143,40.000000,2 +80,9.100542,7.099333,-0.000000,111.311150,0.124367,55.439661,3 +81,6.923889,5.274893,-0.000000,105.871980,16.972673,72.608126,3 +82,13.817024,12.462429,8.461833,165.996486,16.825326,37.177427,2 +83,11.003418,8.778961,-0.000000,171.751807,9.263526,40.000000,2 +84,10.945090,8.245854,-0.000000,157.805785,1.249890,40.000000,2 +85,16.374603,13.757905,8.733333,63.566611,12.886434,55.577327,3 +86,9.892307,4.287585,-3.011415,90.441491,3.831415,55.818306,3 +87,13.673311,11.358003,5.795235,150.445594,16.029435,41.349520,2 +88,13.990594,11.305936,6.257891,21.972341,11.754403,30.744626,2 +89,20.255351,5.706688,4.835485,21.948474,5.567414,24.092859,1 +90,17.998655,8.517325,4.666667,53.976733,20.175248,42.607589,2 +91,12.731722,1.137814,-4.397289,104.927469,16.680280,61.873631,3 +92,4.717539,0.809252,0.000000,194.530215,19.514676,48.018356,2 +93,10.938460,7.961963,-0.000000,142.081737,1.513560,40.000000,2 +94,12.485147,11.687508,5.837070,62.371989,4.037620,36.670451,2 +95,21.311279,14.010160,8.733333,58.291426,16.215598,57.538745,3 +96,16.119228,1.948593,-4.333333,170.071467,15.327727,67.989083,3 +97,16.044459,8.532355,4.666667,182.329485,17.093844,43.584188,2 +98,11.729488,7.040860,-0.000000,127.855229,11.041875,53.286788,3 +99,3.805337,0.178531,0.000000,51.074060,9.360930,54.637262,3 +100,15.603911,5.056840,4.672637,17.733168,13.447217,45.907548,2 +101,21.763916,2.432735,-4.339415,167.651118,18.826982,42.988034,2 +102,13.633200,11.914268,6.971202,116.943724,14.757536,52.869162,3 +103,9.136223,4.668226,-1.140008,189.621747,11.519025,49.401727,2 +104,13.511758,7.927997,3.082556,12.205786,6.573939,32.481027,2 +105,3.928759,2.484731,0.000000,116.928261,15.487320,75.708580,4 +106,17.902640,9.029729,4.667063,57.021617,8.395439,40.144849,2 +107,11.209864,3.944569,-4.629273,165.546435,12.489070,49.011064,2 +108,21.790781,9.811186,4.744786,38.197288,19.532941,38.674387,2 +109,15.028400,10.338218,5.396578,88.505992,18.544884,55.870930,3 +110,17.911706,11.222274,8.669639,78.682301,19.773568,44.240630,2 +111,9.111009,6.758124,-0.000000,165.314796,20.658068,40.000000,2 +112,9.167442,1.257321,-5.098045,135.374219,17.939573,47.646390,2 +113,6.426162,3.434655,-8.513265,41.520607,0.029872,23.268835,1 +114,19.992348,13.700060,8.733333,63.620945,0.067995,36.768421,2 +115,19.459042,2.285670,-4.336124,26.762197,1.924314,27.107022,2 +116,15.759182,12.387255,8.724978,134.292578,5.736002,14.175797,1 +117,17.621128,8.075137,4.666667,114.198215,0.501571,37.221759,2 +118,17.018116,14.942021,8.733333,33.953413,9.329866,13.585059,1 +119,12.224244,1.172633,-4.379033,29.531155,7.503429,26.866534,2 +120,19.426052,6.640174,4.685234,95.215944,11.909787,55.664525,3 +121,13.788716,1.599792,-4.398726,181.620483,20.375720,26.755431,2 +122,16.967291,14.428471,8.733333,110.435005,6.566988,31.905775,2 +123,6.631664,0.069513,-8.661248,6.587979,7.437865,13.245825,1 +124,16.319912,11.623657,8.583405,10.772585,18.908562,29.902073,2 +125,16.376308,12.259548,8.733333,161.012646,7.490523,13.222719,1 +126,16.255938,13.030421,8.733333,90.274971,3.038649,39.884135,2 +127,12.842428,1.266538,-4.402501,76.529246,11.171577,55.821514,3 +128,17.879886,5.996740,4.778407,157.928741,18.846442,36.597067,2 +129,11.579341,3.898056,-4.488050,72.857374,8.454900,49.378694,2 +130,16.294144,12.001027,8.733333,106.469987,15.305200,57.604290,3 +131,8.410331,6.471207,-0.000000,142.331341,13.813892,66.823875,3 +132,13.863501,13.659714,8.471160,174.295304,9.908539,14.083613,1 diff --git a/environment.py b/environment.py index 7a30200..c733b43 100644 --- a/environment.py +++ b/environment.py @@ -9,6 +9,7 @@ import time from abstract_agent import AbstractAgent from physical_agent import PhysAgent +from fuzzy import Fuzzy ## Class Environment @@ -47,6 +48,8 @@ def __init__(self, data_folder): self.found = [[]] # positional: Physical agents that found each victim [[ag1] [ag2, ag3], ...] ag1 found vict 0, ag2 and 3, vict 1, ... self.saved = [[]] # positional: Physical agents that saved each victim + self.fuz = Fuzzy() #Cria objeto fuzzy + # Read the environment config file self.__read_config() # print(self.dic) @@ -104,6 +107,15 @@ def __init__(self, data_folder): if self.nb_of_victims < len(self.signals): print("from env: nb of victims of env_victims.txt less than vital signals") print("from env: Assuming nb of victims of env_victims.txt") + + victims = [[var[3], var[4], var[5]] for var in self.signals] #Cria vetor de vitimas contendo variaveis pressao, batimentos e respiração + out = self.fuz.defuzzyfy(victims) #Saida do fuzzy + + real_gravity = [] #Vetor com grupos originais, para comparação + for vic in self.signals: + real_gravity.append(vic[7]) + + self.fuz.measurement(out,real_gravity) #Realiza as contas entre o vetor inferido e o original # Set up found and saved victims' lists self.found = [[] for v in range(self.nb_of_victims)] @@ -343,6 +355,3 @@ def print_results(self): saved = body.get_saved_victims() self.__print_victims(saved, "saved","s") - - - diff --git a/explorer.py b/explorer.py index 414677c..fdf3292 100644 --- a/explorer.py +++ b/explorer.py @@ -7,11 +7,14 @@ import random from abstract_agent import AbstractAgent from physical_agent import PhysAgent +from map import Map from abc import ABC, abstractmethod - +import heapq +from node import Node +import time class Explorer(AbstractAgent): - def __init__(self, env, config_file, resc): + def __init__(self, env, config_file, resc, path_priorities): """ Construtor do agente random on-line @param env referencia o ambiente @config_file: the absolute path to the explorer's config file @@ -22,56 +25,256 @@ def __init__(self, env, config_file, resc): # Specific initialization for the rescuer self.resc = resc # reference to the rescuer agent - self.rtime = self.TLIM # remaining time to explore + self.rtime = self.TLIM # remaining time to explore + self.horizontal = 0 # Incrementa se andar para a direita e decrementa se andar para a esquerda + self.vertical = 0 # Incrementa se andar para baixo e decrementa se andar para cima + self.number_of_moves = 0 + self.known_victims = [] + self.known_map = [] + self.best_route = [] + self.map_graph = {} + self.returning_to_base = False - + self.map = Map(path_priorities) def deliberate(self) -> bool: """ The agent chooses the next action. The simulator calls this method at each cycle. Must be implemented in every agent""" - # No more actions, time almost ended - if self.rtime < 10.0: - # time to wake up the rescuer - # pass the walls and the victims (here, they're empty) - print(f"{self.NAME} I believe I've remaining time of {self.rtime:.1f}") - self.resc.go_save_victims([],[]) - return False + self.update_known_map() # Adiciona base na lista - dx = random.choice([-1, 0, 1]) + if self.time_to_get_back(): + # Returns to base and notify the rescuer + # If agent is not at the base, returns True + return self.get_back_to_base() - if dx == 0: - dy = random.choice([-1, 1]) - else: - dy = random.choice([-1, 0, 1]) + return self.explore() + + def calc_best_return_route(self, graphed_map): + init_pos, init_neighbours = list(graphed_map.items())[-1] + base_pos = (0, 0) + result = self.astar(graphed_map, init_pos, base_pos) + return result + + def astar(self, graph, start, goal): - # Check the neighborhood obstacles - obstacles = self.body.check_obstacles() + open_list = [] # Lista de nós a serem avaliados + closed_set = set() # Conjunto de nós já avaliados + heur = self.get_heuristic_estimate(start[0], start[1]) + + start_node = Node(start, None, 0, heur) + heapq.heappush(open_list, start_node) + + while open_list: + current_node = heapq.heappop(open_list) + if current_node.state == goal: + # Se chegamos ao objetivo, reconstrua o caminho e retorne-o + return self.build_path(current_node) + closed_set.add(current_node.state) + + for neighbor, cost in graph[current_node.state]: + if neighbor not in closed_set: + # Cria um novo nó para o vizinho + neighbor_node = Node(neighbor, current_node, current_node.cost + cost, + self.get_heuristic_estimate(neighbor[0], neighbor[1])) + + # Se o vizinho já está na lista aberta com um custo menor, ignore-o + if not any(neighbor_node.state == node.state and neighbor_node.cost >= node.cost for node in + open_list): + heapq.heappush(open_list, neighbor_node) + # Se não encontramos um caminho, retornamos None + return None + + def build_path(self, node): + # Reconstrói o caminho de volta do objetivo para o início + path = [] + while node: + path.append(node.state) + node = node.parent + return list(reversed(path)) + + def movement_cost(self, pos1, pos2): + if pos1[0] != pos2[0] and pos1[1] != pos2[1]: # Diagonal + return self.COST_DIAG + return self.COST_LINE + + + def explore(self): + # Check the neighborhood obstacles + obstacles = self.body.check_obstacles() + + mov = self.map.get_action() + dy = mov[0] + dx = mov[1] + + while not self.authorize(obstacles, dx, dy): + mov = self.map.get_action() + dy = mov[0] + dx = mov[1] + # Moves the body to another position result = self.body.walk(dx, dy) - # Update remaining time - if dx != 0 and dy != 0: - self.rtime -= self.COST_DIAG - else: - self.rtime -= self.COST_LINE + # Updates travel information + self.update_distance_to_base(dx, dy) + self.update_known_map() + self.update_number_of_moves() - # Test the result of the walk action - if result == PhysAgent.BUMPED: - walls = 1 # build the map- to do - # print(self.name() + ": wall or grid limit reached") + # Update remaining time + self.update_remaining_time(dx, dy) if result == PhysAgent.EXECUTED: # check for victim returns -1 if there is no victim or the sequential # the sequential number of a found victim + self.map.update_agent_position(dx,dy) seq = self.body.check_for_victim() if seq >= 0: vs = self.body.read_vital_signals(seq) self.rtime -= self.COST_READ + if [self.horizontal, self.vertical] not in self.known_victims: + self.known_victims.append(((self.horizontal, self.vertical), vs)) # print("exp: read vital signals of " + str(seq)) # print(vs) return True + def get_back_to_base(self): + + init_pos = (self.horizontal, self.vertical) + movements = self.best_route + mov = movements.pop(0) + + dx = mov[0] - init_pos[0] + dy = mov[1] - init_pos[1] + + self.update_distance_to_base(dx, dy) + + # Moves the body to another position + result = self.body.walk(dx, dy) + # Update remaining time + self.update_remaining_time(dx, dy) + + if not self.at_base(): + return True + else: + for i, r in enumerate(self.resc): + self.resc[i].merge_maps(list(self.known_map), list(self.known_victims)) + return False + + def time_to_get_back(self): + + if self.returning_to_base: + return True + + self.best_route = self.calc_best_return_route(self.map_graph) + cost = self.calculate_cost_to_base(list(self.best_route)) + + if(cost + 2*self.COST_DIAG + self.COST_READ >= self.rtime): + self.returning_to_base = True + self.best_route.pop(0) + return True + + return False + + def calculate_cost_to_base(self, best_route): + cost = 0 + for i in range(len(best_route) - 1): + x1 = best_route[i][0] + y1 = best_route[i][1] + x2 = best_route[i + 1][0] + y2 = best_route[i + 1][1] + + mov = (x2 - x1, y2 - y1) + + if(mov == (0,1) or mov == (0,-1) or mov == (1,0) or mov == (-1,0)): + cost += self.COST_LINE + else: + cost += self.COST_DIAG + + return cost + + + def update_remaining_time(self, dx, dy): + # Update remaining time + if dx != 0 and dy != 0: + self.rtime -= self.COST_DIAG + else: + self.rtime -= self.COST_LINE + + def at_base(self): + return self.horizontal == 0 and self.vertical == 0 + + def update_distance_to_base(self, dx, dy): + self.horizontal += dx + self.vertical += dy + + def update_number_of_moves(self): + self.number_of_moves += 1 + + def update_known_map(self): + if [self.horizontal, self.vertical] not in self.known_map: + self.known_map.append([self.horizontal, self.vertical]) + discovered = (self.horizontal, self.vertical) + self.map_graph[discovered] = [] + for coord in self.map_graph.keys(): + cost = self.is_neighbour(discovered, coord) + if cost != None: + self.map_graph[discovered].append([coord, cost]) + self.map_graph[coord].append([discovered, cost]) + end_time = time.time() + + def is_neighbour(self, coord1, coord2): + if (coord1[0] - 1, coord1[1]) == coord2: + return self.COST_LINE + if (coord1[0], coord1[1] - 1) == coord2: + return self.COST_LINE + if (coord1[0] - 1, coord1[1] - 1) == coord2: + return self.COST_DIAG + if (coord1[0] + 1, coord1[1]) == coord2: + return self.COST_LINE + if (coord1[0], coord1[1] + 1) == coord2: + return self.COST_LINE + if (coord1[0] + 1, coord1[1] + 1) == coord2: + return self.COST_DIAG + if (coord1[0] + 1, coord1[1] - 1) == coord2: + return self.COST_DIAG + if (coord1[0] - 1, coord1[1] + 1) == coord2: + return self.COST_DIAG + return None + + def get_heuristic_estimate(self, dx, dy): + # Estima o gasto necessário para voltar para a base a partir da coord atual + valor = min(abs(dx), abs(dy)) * self.COST_DIAG # Anda o máximo que pode na diagonal + valor += abs((abs(dx) - abs(dy))) * self.COST_LINE # Anda o restante na vertical/horizontal + return valor + + def authorize(self, obstacles, x, y): + if x == 0 and y == -1: + if obstacles[0] != 0: + return False + if x == 1 and y == -1: + if obstacles[1] != 0: + return False + if x == 1 and y == 0: + if obstacles[2] != 0: + return False + if x == 1 and y == 1: + if obstacles[3] != 0: + return False + if x == 0 and y == 1: + if obstacles[4] != 0: + return False + if x == -1 and y == 1: + if obstacles[5] != 0: + return False + if x == -1 and y == 0: + if obstacles[6] != 0: + return False + if x == -1 and y == -1: + if obstacles[7] != 0: + return False + return True + + diff --git a/fuzzy.py b/fuzzy.py new file mode 100644 index 0000000..848e2c4 --- /dev/null +++ b/fuzzy.py @@ -0,0 +1,279 @@ +from enum import Enum +from collections import defaultdict +import os +import csv + +class Fuzzy: + def __init__(self): + self.small_rules_set = {} #Mapa das regras inferidas pelo Wang-Mendel + self.medium_rules_set = {} + self.big_rules_set = {} + self.small_dictionary = defaultdict(int) #Dicionario, conta quantas vezes uma regra aparece - 2 passo do wang mendel + self.medium_dictionary = defaultdict(int) + self.big_dictionary = defaultdict(int) + self.wang_mendel("datasets/data_800vic/sinais_vitais_com_label.txt") #Treina com varios arquivos + self.wang_mendel("datasets/data_12x12_10vic/sinais_vitais.txt") + self.wang_mendel("datasets/data_20x20_42vic/sinais_vitais.txt") + self.wang_mendel("datasets/data_teste_sala/sinais_vitais.txt") + #self.teste_800vit() + + def small_fuzzyfy(self,max,var): #Divide cada variavel em 5 grupos - fuzzy triangular + fuz_vec = [0,0,0,0,0] #Cada posicao indica o valor fuzzy + if(var < max/4): + fuz_vec[0] = -(800/max) * var + 100 + fuz_vec[1] = (800/max) * var + elif(var >= max/4 and var < max/2): + fuz_vec[1] = -(800/max) * var + 200 + fuz_vec[2] = (800/max) * var - 100 + elif(var >= max/2 and var < max*3/4): + fuz_vec[2] = -(800/max) * var + 300 + fuz_vec[3] = (800/max) * var - 200 + else: + fuz_vec[3] = -(800/max) * var + 400 + fuz_vec[4] = (800/max) * var - 300 + return fuz_vec + + def medium_fuzzyfy(self,max,var): #Divide cada variavel em 9 grupos - fuzzy triangular + fuz_vec = [0,0,0,0,0,0,0,0,0] #Cada posicao indica o valor fuzzy + if(var < max/8): + fuz_vec[0] = -(800/max) * var + 100 + fuz_vec[1] = (800/max) * var + elif(var >= max/8 and var < max/4): + fuz_vec[1] = -(800/max) * var + 200 + fuz_vec[2] = (800/max) * var - 100 + elif(var >= max/4 and var < max*3/8): + fuz_vec[2] = -(800/max) * var + 300 + fuz_vec[3] = (800/max) * var - 200 + elif(var >= max*3/8 and var < max/2): + fuz_vec[3] = -(800/max) * var + 400 + fuz_vec[4] = (800/max) * var - 300 + elif(var >= max/2 and var < max*5/8): + fuz_vec[4] = -(800/max) * var + 500 + fuz_vec[5] = (800/max) * var - 400 + elif(var >= max*5/8 and var < max*3/4): + fuz_vec[5] = -(800/max) * var + 600 + fuz_vec[6] = (800/max) * var - 500 + elif(var >= max*3/4 and var < max*7/8): + fuz_vec[6] = -(800/max) * var + 700 + fuz_vec[7] = (800/max) * var - 600 + else: + fuz_vec[7] = -(800/max) * var + 800 + fuz_vec[8] = (800/max) * var - 700 + return fuz_vec + + def big_fuzzyfy(self,max,var): #Divide cada variavel em 17 grupos - fuzzy triangular + fuz_vec = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] #Cada posicao indica o valor fuzzy + if(var < max/8): + fuz_vec[0] = -(1600/max) * var + 100 + fuz_vec[1] = (1600/max) * var + elif(var >= max/16 and var < max/8): + fuz_vec[1] = -(1600/max) * var + 200 + fuz_vec[2] = (1600/max) * var - 100 + elif(var >= max/8 and var < max*3/16): + fuz_vec[2] = -(1600/max) * var + 300 + fuz_vec[3] = (1600/max) * var - 200 + elif(var >= max*3/16 and var < max/4): + fuz_vec[3] = -(1600/max) * var + 400 + fuz_vec[4] = (1600/max) * var - 300 + elif(var >= max/4 and var < max*5/16): + fuz_vec[4] = -(1600/max) * var + 500 + fuz_vec[5] = (1600/max) * var - 400 + elif(var >= max*5/16 and var < max*3/8): + fuz_vec[5] = -(1600/max) * var + 600 + fuz_vec[6] = (1600/max) * var - 500 + elif(var >= max*3/8 and var < max*7/16): + fuz_vec[6] = -(1600/max) * var + 700 + fuz_vec[7] = (1600/max) * var - 600 + elif(var >= max*7/16 and var < max/2): + fuz_vec[7] = -(1600/max) * var + 800 + fuz_vec[8] = (1600/max) * var - 700 + elif(var >= max/2 and var < max*9/16): + fuz_vec[8] = -(1600/max) * var + 900 + fuz_vec[9] = (1600/max) * var - 800 + elif(var >= max*9/16 and var < max*5/8): + fuz_vec[9] = -(1600/max) * var + 1000 + fuz_vec[10] = (1600/max) * var - 900 + elif(var >= max*5/8 and var < max*11/16): + fuz_vec[10] = -(1600/max) * var + 1100 + fuz_vec[11] = (1600/max) * var - 1000 + elif(var >= max*11/16 and var < max*3/4): + fuz_vec[11] = -(1600/max) * var + 1200 + fuz_vec[12] = (1600/max) * var - 1100 + elif(var >= max*3/4 and var < max*13/16): + fuz_vec[12] = -(1600/max) * var + 1300 + fuz_vec[13] = (1600/max) * var - 1200 + elif(var >= max*13/16 and var < max*7/8): + fuz_vec[13] = -(1600/max) * var + 1400 + fuz_vec[14] = (1600/max) * var - 1300 + elif(var >= max*7/8 and var < max*15/16): + fuz_vec[14] = -(1600/max) * var + 1500 + fuz_vec[15] = (1600/max) * var - 1400 + else: + fuz_vec[15] = -(1600/max) * var + 1600 + fuz_vec[16] = (1600/max) * var - 1500 + return fuz_vec + + def wang_mendel(self, path): + s_rules = [] #Todas as regras geradas, mesmo as repetidas + m_rules = [] + b_rules = [] + signals = [] #Vetor das caracteristicas da vitima (pressão, batimentos, etc) + + vs_file = os.path.join(path) #Arquivo de teste + + with open(vs_file, 'r') as csvfile: + csvreader = csv.reader(csvfile) + for row in csvreader: + qp = float(row[3]) #Pressao + pf = float(row[4]) #Batimentos + rf = float(row[5]) #Respiração + lb = int(row[7]) #Grupo verdadeiro + + signals.append([qp, pf, rf, lb]) + + for vic in signals: + fuz_qPA = self.small_fuzzyfy(20,vic[0]+10) #Chama a fuzzyfy para as tres caracteristicas + fuz_pulse = self.small_fuzzyfy(200,vic[1]) + fuz_fResp = self.small_fuzzyfy(22,vic[2]) + s_rules.append([fuz_qPA.index(max(fuz_qPA)),fuz_pulse.index(max(fuz_pulse)),fuz_fResp.index(max(fuz_fResp)),vic[3]]) #cria uma regra, usando o grupo com maior valor obtido para cada variavel + fuz_qPA = self.medium_fuzzyfy(20,vic[0]+10) #Chama a fuzzyfy para as tres caracteristicas + fuz_pulse = self.medium_fuzzyfy(200,vic[1]) + fuz_fResp = self.medium_fuzzyfy(22,vic[2]) + m_rules.append([fuz_qPA.index(max(fuz_qPA)),fuz_pulse.index(max(fuz_pulse)),fuz_fResp.index(max(fuz_fResp)),vic[3]]) + fuz_qPA = self.big_fuzzyfy(20,vic[0]+10) #Chama a fuzzyfy para as tres caracteristicas + fuz_pulse = self.big_fuzzyfy(200,vic[1]) + fuz_fResp = self.big_fuzzyfy(22,vic[2]) + b_rules.append([fuz_qPA.index(max(fuz_qPA)),fuz_pulse.index(max(fuz_pulse)),fuz_fResp.index(max(fuz_fResp)),vic[3]]) + + for rule in s_rules: + precedent = tuple(rule[:3]) #A tupla das variaveis precedentes + consequent = rule[3] #O grupo de gravidade (Verdadeiro) + + if precedent not in self.small_rules_set or self.small_dictionary[precedent] < self.small_dictionary[precedent + (consequent,)]: #Adiciona as regras unicas se for a primeira aparição, ou se a regra apareceu mais vezes + self.small_rules_set[precedent] = consequent + + self.small_dictionary[precedent + (consequent,)] += 1 + + for rule in m_rules: + precedent = tuple(rule[:3]) #A tupla das variaveis precedentes + consequent = rule[3] #O grupo de gravidade (Verdadeiro) + + if precedent not in self.medium_rules_set or self.medium_dictionary[precedent] < self.medium_dictionary[precedent + (consequent,)]: #Adiciona as regras unicas se for a primeira aparição, ou se a regra apareceu mais vezes + self.medium_rules_set[precedent] = consequent + + self.medium_dictionary[precedent + (consequent,)] += 1 + + for rule in b_rules: + precedent = tuple(rule[:3]) #A tupla das variaveis precedentes + consequent = rule[3] #O grupo de gravidade (Verdadeiro) + + if precedent not in self.big_rules_set or self.big_dictionary[precedent] < self.big_dictionary[precedent + (consequent,)]: #Adiciona as regras unicas se for a primeira aparição, ou se a regra apareceu mais vezes + self.big_rules_set[precedent] = consequent + + self.big_dictionary[precedent + (consequent,)] += 1 + + + def defuzzyfy(self,vec): #Para um vetor de vitimas com pressao, batimentos e respiração, retorna um vetor com os grupos inferidos pelo processo fuzzy + out = [] + for vic in vec: + grav = [0,0,0,0] #Vetor que armazena a maior inferencia para cada grupo, dentre todas as regras + big_fuz_qPA = self.big_fuzzyfy(20,vic[0]+10) + big_fuz_pulse = self.big_fuzzyfy(200,vic[1]) + big_fuz_fResp = self.big_fuzzyfy(22,vic[2]) + medium_fuz_qPA = self.medium_fuzzyfy(20,vic[0]+10) + medium_fuz_pulse = self.medium_fuzzyfy(200,vic[1]) + medium_fuz_fResp = self.medium_fuzzyfy(22,vic[2]) + small_fuz_qPA = self.small_fuzzyfy(20,vic[0]+10) + small_fuz_pulse = self.small_fuzzyfy(200,vic[1]) + small_fuz_fResp = self.small_fuzzyfy(22,vic[2]) + for rule, value in self.big_rules_set.items(): #Testa todas as regras + smallest_fuzzy = min(big_fuz_qPA[rule[0]], big_fuz_pulse[rule[1]], big_fuz_fResp[rule[2]]) #Como é um and, pega sempre o menor valor + if smallest_fuzzy > grav[value - 1]: #Armazena se o resultado for maior que o ja existente (para o grupo) + grav[value - 1] = smallest_fuzzy + if grav == [0,0,0,0]: + for rule, value in self.medium_rules_set.items(): #Testa todas as regras + smallest_fuzzy = min(medium_fuz_qPA[rule[0]], medium_fuz_pulse[rule[1]], medium_fuz_fResp[rule[2]]) #Como é um and, pega sempre o menor valor + if smallest_fuzzy > grav[value - 1]: #Armazena se o resultado for maior que o ja existente (para o grupo) + grav[value - 1] = smallest_fuzzy + if grav == [0,0,0,0]: + for rule, value in self.small_rules_set.items(): #Testa todas as regras + smallest_fuzzy = min(small_fuz_qPA[rule[0]], small_fuz_pulse[rule[1]], small_fuz_fResp[rule[2]]) #Como é um and, pega sempre o menor valor + if smallest_fuzzy > grav[value - 1]: #Armazena se o resultado for maior que o ja existente (para o grupo) + grav[value - 1] = smallest_fuzzy + out.append(grav.index(max(grav))+1) + return out + + def measurement(self, generated, original): #Calcula as métricas + matrix = [[0 for _ in range(4)] for _ in range(4)] + + for i in range(len(original)): + matrix[original[i]-1][generated[i]-1] += 1 + + precision_1 = matrix[0][0]/sum(matrix[0]) + precision_2 = matrix[1][1]/sum(matrix[1]) + precision_3 = matrix[2][2]/sum(matrix[2]) + precision_4 = matrix[3][3]/sum(matrix[3]) + + recall_1 = matrix[0][0]/sum(line[0] for line in matrix) + recall_2 = matrix[1][1]/sum(line[1] for line in matrix) + recall_3 = matrix[2][2]/sum(line[2] for line in matrix) + recall_4 = matrix[3][3]/sum(line[3] for line in matrix) + + accuracy = (matrix[0][0] + matrix[1][1] + matrix[2][2] + matrix[3][3])/ len(original) + + f_measure_1 = 2 * precision_1 * recall_1 / (precision_1 + recall_1) + f_measure_2 = 2 * precision_2 * recall_2 / (precision_2 + recall_2) + f_measure_3 = 2 * precision_3 * recall_3 / (precision_3 + recall_3) + f_measure_4 = 2 * precision_4 * recall_4 / (precision_4 + recall_4) + + print("\n\n*****MEASUREMENT*****") + print("Inferred groups:") + print(generated) + print("Real groups:") + print(original) + print("\nConfusion Matrix:") + print(matrix[0]) + print(matrix[1]) + print(matrix[2]) + print(matrix[3]) + print("\nPrecision:") + print(f"Group 1: {precision_1:.3f}") + print(f"Group 2: {precision_2:.3f}") + print(f"Group 3: {precision_3:.3f}") + print(f"Group 4: {precision_4:.3f}") + print("\nRecall:") + print(f"Group 1: {recall_1:.3f}") + print(f"Group 2: {recall_2:.3f}") + print(f"Group 3: {recall_3:.3f}") + print(f"Group 4: {recall_4:.3f}") + print("\nF-Measure:") + print(f"Group 1: {f_measure_1:.3f}") + print(f"Group 2: {f_measure_2:.3f}") + print(f"Group 3: {f_measure_3:.3f}") + print(f"Group 4: {f_measure_4:.3f}") + print(f"\nTOTAL ACCURACY: {accuracy:.3f}\n") + + def teste_800vit(self): + signals = [] + + vs_file = os.path.join("datasets/data_800vic/sinais_vitais_com_label.txt") + + with open(vs_file, 'r') as csvfile: + csvreader = csv.reader(csvfile) + for row in csvreader: + qp = float(row[3]) #Pressao + pf = float(row[4]) #Batimentos + rf = float(row[5]) #Respiração + lb = int(row[7]) #Grupo verdadeiro + + signals.append([qp, pf, rf, lb]) + + original = [] + saida = [] + for x in signals: + original.append(tuple(x[:3])) + saida.append(x[3]) + + teste = self.defuzzyfy(original) + + self.measurement(teste,saida) \ No newline at end of file diff --git a/genetic.py b/genetic.py new file mode 100644 index 0000000..b7016c1 --- /dev/null +++ b/genetic.py @@ -0,0 +1,9 @@ +import math + +class Genetic: + + def __init__(self): + pass + + def fitness(self, individual): + pass \ No newline at end of file diff --git a/kmeans.py b/kmeans.py new file mode 100644 index 0000000..ad44c14 --- /dev/null +++ b/kmeans.py @@ -0,0 +1,121 @@ +import random +import math + +class KMeans(): + + def __init__(self): + self.redistributed = True + + def execute(self, victims, n): + + groups = self.generate_random_groups(victims, n) + + while self.redistributed: + groups = self.update_groups(groups) + + return groups + + def update_groups(self, groups): + + for group in groups: + new_centroid = self.centroid(group[1]) + if(new_centroid != None): + group[0] = new_centroid + + return self.redistribute(groups) + + def generate_random_groups(self, victims, n): + centroids = self.initial_centroids(victims, n) + return self.distribute(victims, centroids) + + def distribute(self, victims, centroids): + # Distribuição das vítimas para formar os grupos iniciais + groups = [[centroid, []] for centroid in centroids] + + for victim in victims: + minor_distance = float(9999) + centroid_index = 0 + # Checa a qual centróide a vítima da iteração irá pertencer + for i, centroid in enumerate(centroids): + distance_to_centroid = self.distance_to_centroid(victim, centroid) + if distance_to_centroid < minor_distance: + minor_distance = distance_to_centroid + centroid_index = i + + groups[centroid_index][1].append(victim) + + return groups + + + def redistribute(self, groups): + self.redistributed = False + + centroids = [group[0] for group in groups] + new_groups = [[centroid, []] for centroid in centroids] + victim_groups = [group[1] for group in groups] + + for i, victims in enumerate(victim_groups): + + for victim in victims: + minor_distance = float(9999) + current_centroid_index = i + next_centroid_index = i + + # Checa a qual centróide a vítima da iteração irá pertencer + for j, centroid in enumerate(centroids): + distance_to_centroid = self.distance_to_centroid(victim, centroid) + if distance_to_centroid < minor_distance: + minor_distance = distance_to_centroid + next_centroid_index = j + + # Caso a vítima tenha que ser redirecionada a outro grupo + if next_centroid_index != current_centroid_index: + self.redistributed = True + + new_groups[next_centroid_index][1].append(victim) + + return new_groups + + def initial_centroids(self, victims, n): + centroids = [] + + for i in range(0, n): + min_x = 9999 + max_x = -9999 + min_y = 9999 + max_y = -9999 + + for victim in victims: + if victim[0][0] > max_x: + max_x = victim[0][0] + if victim[0][0] < min_x: + min_x = victim[0][0] + if victim[0][1] > max_y: + max_y = victim[0][1] + if victim[0][1] < min_y: + min_y = victim[0][1] + + x = random.randint(min_x, max_x) + y = random.randint(min_y, max_y) + centroids.append((x, y)) + + return centroids + + def centroid(self, group): + # Caso não haja ninguém no grupo + if(len(group) == 0): + return None + + x_average = 0 + y_average = 0 + + for victim in group: + x_average += victim[0][0] + y_average += victim[0][1] + + x_average /= len(group) + y_average /= len(group) + return (x_average, y_average) + + def distance_to_centroid(self, victim, centroid): + return math.sqrt((centroid[0] - victim[0][0])**2 + (centroid[1] - victim[0][1])**2) \ No newline at end of file diff --git a/main.py b/main.py old mode 100644 new mode 100755 index e2fcaaa..0ffad15 --- a/main.py +++ b/main.py @@ -1,3 +1,4 @@ +import random import sys import os import time @@ -13,12 +14,11 @@ def main(data_folder_name): # Set the path to config files and data files for the environment current_folder = os.path.abspath(os.getcwd()) data_folder = os.path.abspath(os.path.join(current_folder, data_folder_name)) - # Instantiate the environment env = Env(data_folder) - # config files for the agents + # config files for the agen5ts rescuer_file = os.path.join(data_folder, "rescuer_config.txt") explorer_file = os.path.join(data_folder, "explorer_config.txt") @@ -27,7 +27,15 @@ def main(data_folder_name): # Explorer needs to know rescuer to send the map # that's why rescuer is instatiated before - exp = Explorer(env, explorer_file, resc) + # lista = ['E', 'N', 'NW', 'SW', 'NE', 'SE', 'W', 'S'] + # exp = Explorer(env, explorer_file, [resc], random.sample(lista, len(lista))) + # exp = Explorer(env, explorer_file, [resc], random.sample(lista, len(lista))) + # exp = Explorer(env, explorer_file, [resc], random.sample(lista, len(lista))) + # exp = Explorer(env, explorer_file, [resc], random.sample(lista, len(lista))) + exp = Explorer(env, explorer_file, [resc], ['E', 'N', 'S', 'W', 'NE', 'NW', 'SW', 'SE']) + exp = Explorer(env, explorer_file, [resc], ['N', 'W', 'E', 'S', 'NW', 'NE', 'SE', 'SW']) + exp = Explorer(env, explorer_file, [resc], ['W', 'S', 'N', 'E', 'SW', 'SE', 'NE', 'NW']) + exp = Explorer(env, explorer_file, [resc], ['S', 'E', 'W', 'N', 'SE', 'NE', 'NW', 'SW']) # Run the environment simulator env.run() @@ -40,6 +48,6 @@ def main(data_folder_name): if len(sys.argv) > 1: data_folder_name = sys.argv[1] else: - data_folder_name = os.path.join("datasets", "data_12x12_10vic") + data_folder_name = os.path.join("datasets", "data_teste_sala") main(data_folder_name) diff --git a/map.py b/map.py new file mode 100644 index 0000000..3145ee2 --- /dev/null +++ b/map.py @@ -0,0 +1,89 @@ + + +class Map: + def __init__(self, path_priorities): + self.coord_x = 0 + self.coord_y = 0 + self.coordinates_map = {'SE': [1,1], 'S': [1,0], 'SW': [1,-1], 'W': [0,-1], 'NW': [-1,-1], 'N': [-1,0], 'NE': [-1,1], 'E': [0,1]} + self.path_priorities = path_priorities + self.position = Position(self.path_priorities) + self.last_position = Position(self.path_priorities) + self.last_action = '' + self.backtracking = False + self.map = {(0,0)} + self.map = {(0, 0): self.position} + + def get_action(self): + self.backtracking = False + mov = (0,0) + action = '' + while (self.coord_x+mov[1],self.coord_y+mov[0]) in self.map and action is not None: + action = self.position.pop_untried() + if action is not None: + mov = self.coordinates_map[action] + self.last_action = action + if action is None: + action = self.get_opposite_action(self.position.last_action) + mov = self.coordinates_map[action] + self.backtracking = True + self.last_action = action + return mov + + def get_opposite_action(self,action): + if action == 'E': + return 'W' + elif action == 'NE': + return 'SW' + elif action == 'N': + return 'S' + elif action == 'NW': + return 'SE' + elif action == 'W': + return 'E' + elif action == 'SW': + return 'NE' + elif action == 'S': + return 'N' + elif action == 'SE': + return 'NW' + else: + return + + def update_agent_position(self, dx, dy): + self.coord_x = self.coord_x + dx + self.coord_y = self.coord_y + dy + if (self.coord_x,self.coord_y) not in self.map: + pos = Position(self.path_priorities) + pos.coord_x = self.coord_x + pos.coord_y = self.coord_y + self.map[(self.coord_x,self.coord_y)] = pos + pos.last_action = self.last_action + else: + pos = self.map[(self.coord_x,self.coord_y)] + if self.backtracking is not True: + pos.last_action = self.last_action + self.position.set_results(self.last_action,pos) + pos.set_results(self.get_opposite_action(self.last_action),self.position) + self.last_position = self.position + self.position = pos + + def get_map(self): + return self.map + +class Position: + def __init__(self, path_priorities): + self.coord_x = 0 + self.coord_y = 0 + self.results = {'SE': None, 'S': None, 'SW': None, 'W': None, 'NW': None, 'N': None, 'NE': None, 'E': None} + self.untried = list(path_priorities) + self.last_action = '' + + def pop_untried(self): + if len(self.untried) != 0: + return self.untried.pop(0) + else: + return + + def set_results(self,res,pos): + self.results[(res)] = pos + \ No newline at end of file diff --git a/node.py b/node.py new file mode 100644 index 0000000..c098790 --- /dev/null +++ b/node.py @@ -0,0 +1,11 @@ + +class Node: + def __init__(self, state, parent=None, cost=0, heuristic=0): + self.state = state # O estado deste nó no grafo + self.parent = parent # O nó pai (nó anterior) neste caminho + self.cost = cost # Custo acumulado para alcançar este nó + self.heuristic = heuristic # Valor heurístico estimado para o objetivo + + def __lt__(self, other): + # Comparação com base no custo total (f = custo + heurística) + return (self.cost + self.heuristic) < (other.cost + other.heuristic) \ No newline at end of file diff --git a/rescue_route.py b/rescue_route.py new file mode 100644 index 0000000..50304b2 --- /dev/null +++ b/rescue_route.py @@ -0,0 +1,26 @@ +import math + +class RescueRoute: + + def __init__(self): + self.victim_sequence = [] + + def fitness(self): + pass + + def add_victim(self, victim): + self.victim_sequence(victim) + + def total_distance(self): + + distance = 0 + + for i in range(len(self.victim_sequence) - 1): + distance += self.distance_between_victims(self.victim_sequence[i], self.victim_sequence[i + 1]) + + return distance + + + def distance_between_victims(self, v1, v2): + #A* para encontrar a melhor rota entre duas vítimas + pass \ No newline at end of file diff --git a/rescuer.py b/rescuer.py index ce516ab..3927477 100644 --- a/rescuer.py +++ b/rescuer.py @@ -7,6 +7,7 @@ from abstract_agent import AbstractAgent from physical_agent import PhysAgent from abc import ABC, abstractmethod +from kmeans import KMeans ## Classe que define o Agente Rescuer com um plano fixo @@ -25,17 +26,37 @@ def __init__(self, env, config_file): # Starts in IDLE state. # It changes to ACTIVE when the map arrives self.body.set_state(PhysAgent.IDLE) + self.known_map = [] + self.known_victims = [] + self.received_maps = 0 # planning self.__planner() - def go_save_victims(self, walls, victims): + def go_save_victims(self): """ The explorer sends the map containing the walls and victims' location. The rescuer becomes ACTIVE. From now, the deliberate method is called by the environment""" + print(len(self.known_victims)) + #exit() self.body.set_state(PhysAgent.ACTIVE) - - + cluster = KMeans() + cluster.execute(self.known_victims, 4) + + def merge_maps(self, path, victims): + # for i, coord in enumerate(path): + # if coord not in self.known_map: + # self.known_map.append(coord) + self.received_maps +=1 + + for i, victim in enumerate(victims): + if victim not in self.known_victims: + self.known_victims.append(victim) + + if self.received_maps == 4: + self.go_save_victims() + #self.go_save_victims() + def __planner(self): """ A private method that calculates the walk actions to rescue the victims. Further actions may be necessary and should be added in the @@ -53,7 +74,7 @@ def __planner(self): self.plan.append((-1,-1)) self.plan.append((-1,1)) self.plan.append((1,1)) - + def deliberate(self) -> bool: """ This is the choice of the next action. The simulator calls this method at each reasonning cycle if the agent is ACTIVE. diff --git a/results.txt b/results.txt new file mode 100644 index 0000000..587a7d9 --- /dev/null +++ b/results.txt @@ -0,0 +1,125 @@ +pygame 2.4.0 (SDL 2.28.4, Python 3.11.5) +Hello from the pygame community. https://www.pygame.org/contribute.html +from env: ag EXPLORER succesfully terminated, it is at the base +from env: ag EXPLORER succesfully terminated, it is at the base +from env: ag EXPLORER succesfully terminated, it is at the base +35 +from env: ag EXPLORER succesfully terminated, it is at the base +from env: ag RESCUER succesfully terminated, it is at the base +from env: no active or idle agent scheduled for execution... terminating + + + +*** Numbers of Victims in the Environment *** +Critical victims (V1) = 5 +Instable victims (V2) = 21 +Pot. inst. victims (V3) = 8 +Stable victims (V4) = 8 +-------------------------------------- +Total of victims (V) = 42 + + +*** Final results per agent *** + +[ Agent RESCUER ] + +*** Used time *** +15.0 of 400.0 +No found victims + +saved victims: (id, severity, gravity) +(9, 3, 73.4) (15, 1, 24.4) + +Critical victims saved (Vs1) = 1 out of 5 (20.0)% +Instable victims saved (Vs2) = 0 out of 21 (0.0)% +Pot. inst. victims saved (Vs3) = 1 out of 8 (12.5)% +Stable victims saved (Vs4) = 0 out of 8 (0.0)% +-------------------------------------- +Total of saved victims (Vs) = 2 (4.76%) +Weighted saved victims per severity (Vsg) = 0.07 + +Sum of gravities of all saved victims = 97.77 of a total of 1983.64 + % of gravities of all saved victims = 0.05 + +[ Agent EXPLORER ] + +*** Used time *** +95.0 of 100.0 + +found victims: (id, severity, gravity) +(7, 3, 56.7) (8, 2, 43.8) (15, 1, 24.4) (21, 1, 13.3) (25, 4, 81.5) (31, 3, 68.3) (41, 4, 85.2) + +Critical victims found (Ve1) = 2 out of 5 (40.0)% +Instable victims found (Ve2) = 1 out of 21 (4.8)% +Pot. inst. victims found (Ve3) = 2 out of 8 (25.0)% +Stable victims found (Ve4) = 2 out of 8 (25.0)% +-------------------------------------- +Total of found victims (Ve) = 7 (16.67%) +Weighted found victims per severity (Veg) = 0.18 + +Sum of gravities of all found victims = 373.21 of a total of 1983.64 + % of gravities of all found victims = 0.19 +No saved victims + +[ Agent EXPLORER ] + +*** Used time *** +96.5 of 100.0 + +found victims: (id, severity, gravity) +(0, 1, 19.1) (12, 3, 61.6) (23, 2, 39.9) (26, 2, 49.0) (27, 3, 57.6) (28, 4, 77.6) (29, 4, 77.2) (34, 3, 56.4) (36, 2, 41.5) (40, 2, 27.1) + +Critical victims found (Ve1) = 1 out of 5 (20.0)% +Instable victims found (Ve2) = 4 out of 21 (19.0)% +Pot. inst. victims found (Ve3) = 3 out of 8 (37.5)% +Stable victims found (Ve4) = 2 out of 8 (25.0)% +-------------------------------------- +Total of found victims (Ve) = 10 (23.81%) +Weighted found victims per severity (Veg) = 0.22 + +Sum of gravities of all found victims = 506.83 of a total of 1983.64 + % of gravities of all found victims = 0.26 +No saved victims + +[ Agent EXPLORER ] + +*** Used time *** +96.5 of 100.0 + +found victims: (id, severity, gravity) +(6, 2, 37.2) (10, 3, 50.3) (16, 2, 40.5) (30, 4, 76.5) (38, 2, 42.8) (39, 2, 25.6) + +Critical victims found (Ve1) = 0 out of 5 (0.0)% +Instable victims found (Ve2) = 4 out of 21 (19.0)% +Pot. inst. victims found (Ve3) = 1 out of 8 (12.5)% +Stable victims found (Ve4) = 1 out of 8 (12.5)% +-------------------------------------- +Total of found victims (Ve) = 6 (14.29%) +Weighted found victims per severity (Veg) = 0.13 + +Sum of gravities of all found victims = 272.98 of a total of 1983.64 + % of gravities of all found victims = 0.14 +No saved victims + +[ Agent EXPLORER ] + +*** Used time *** +97.5 of 100.0 + +found victims: (id, severity, gravity) +(3, 2, 47.1) (4, 2, 25.2) (5, 2, 28.0) (9, 3, 73.4) (11, 4, 80.2) (13, 4, 85.1) (17, 2, 36.3) (19, 1, 13.3) (32, 2, 36.8) (33, 2, 44.0) (35, 2, 28.1) (37, 3, 68.2) + +Critical victims found (Ve1) = 1 out of 5 (20.0)% +Instable victims found (Ve2) = 7 out of 21 (33.3)% +Pot. inst. victims found (Ve3) = 2 out of 8 (25.0)% +Stable victims found (Ve4) = 2 out of 8 (25.0)% +-------------------------------------- +Total of found victims (Ve) = 12 (28.57%) +Weighted found victims per severity (Veg) = 0.28 + +Sum of gravities of all found victims = 565.54 of a total of 1983.64 + % of gravities of all found victims = 0.29 +No saved victims + +-------------- +from env: Tecle qualquer coisa para encerrar >> \ No newline at end of file