diff --git a/output.csv b/output.csv index 91440609587d156f951da90857748eee02219a31..f03d312563dc366ec487708c23e0b7ba2a8ae341 100644 --- a/output.csv +++ b/output.csv @@ -1,772 +1,70 @@ SUCEPTIBLE,EXPOSED,RECOVERED,INFECTED 9994,5,0,1 -9980,16,0,4 -9953,34,0,13 -9867,106,0,27 -9753,175,0,72 -9592,247,5,156 -9401,314,13,272 -9184,386,27,403 -8928,434,54,584 -8643,501,88,768 -8305,589,144,962 -7943,639,197,1221 -7544,706,265,1485 -7139,754,360,1747 -6739,777,472,2012 -6333,812,606,2249 -5909,808,721,2562 -5487,827,880,2806 -5051,851,1057,3041 -4601,859,1246,3294 -4117,918,1432,3533 -3638,925,1661,3776 -3239,850,1923,3988 -2858,780,2167,4195 -2482,770,2423,4325 -2146,724,2692,4438 -1798,699,2954,4549 -1505,625,3221,4649 -1246,566,3508,4680 -1009,490,3783,4718 -775,465,4042,4718 -577,432,4342,4649 -418,363,4626,4593 -298,294,4926,4482 -222,217,5169,4392 -168,157,5428,4247 -113,113,5680,4094 -76,102,5925,3897 -32,98,6168,3702 -12,83,6399,3506 -3,50,6602,3345 -1,29,6821,3149 -0,15,7015,2970 -0,8,7184,2808 -0,4,7345,2651 -0,2,7495,2503 -0,0,7648,2352 -0,0,7798,2202 -0,0,7955,2045 -0,0,8087,1913 -0,0,8210,1790 -0,0,8312,1688 -0,0,8421,1579 -0,0,8519,1481 -0,0,8616,1384 -0,0,8698,1302 -0,0,8788,1212 -0,0,8856,1144 -0,0,8931,1069 -0,0,8992,1008 -0,0,9052,948 -0,0,9107,893 -0,0,9156,844 -0,0,9208,792 -0,0,9259,741 -0,0,9319,681 -0,0,9360,640 -0,0,9400,600 -0,0,9443,557 -0,0,9473,527 -0,0,9510,490 -0,0,9541,459 -0,0,9573,427 -0,0,9599,401 -0,0,9620,380 -0,0,9638,362 -0,0,9658,342 -0,0,9674,326 -0,0,9694,306 -0,0,9710,290 -0,0,9728,272 -0,0,9738,262 -0,0,9750,250 -0,0,9759,241 -0,0,9772,228 -0,0,9790,210 -0,0,9805,195 -0,0,9819,181 -0,0,9833,167 -0,0,9842,158 -0,0,9856,144 -0,0,9866,134 -0,0,9871,129 -0,0,9877,123 -0,0,9886,114 -0,0,9895,105 -0,0,9903,97 -0,0,9908,92 -0,0,9919,81 -0,0,9925,75 -0,0,9929,71 -0,0,9934,66 -0,0,9937,63 -0,0,9939,61 -0,0,9941,59 -0,0,9944,56 -0,0,9950,50 -0,0,9955,45 -0,0,9957,43 -0,0,9959,41 -0,0,9962,38 -0,0,9963,37 -0,0,9967,33 -0,0,9970,30 -0,0,9973,27 -0,0,9973,27 -0,0,9976,24 -0,0,9977,23 -0,0,9978,22 -0,0,9978,22 -0,0,9980,20 -0,0,9982,18 -0,0,9983,17 -0,0,9984,16 -0,0,9985,15 -0,0,9985,15 -0,0,9985,15 -0,0,9986,14 -0,0,9987,13 -0,0,9987,13 -0,0,9988,12 -0,0,9989,11 -0,0,9992,8 -0,0,9992,8 -0,0,9992,8 -0,0,9992,8 -0,0,9993,7 -0,0,9994,6 -0,0,9995,5 -0,0,9996,4 -0,0,9996,4 -0,0,9996,4 -0,0,9996,4 -0,0,9996,4 -0,0,9996,4 -0,0,9996,4 -0,0,9996,4 -0,0,9996,4 -0,0,9996,4 -0,0,9996,4 -0,0,9996,4 -0,0,9997,3 -0,0,9997,3 -0,0,9997,3 -0,0,9997,3 -0,0,9997,3 -0,0,9998,2 -0,0,9998,2 -0,0,9998,2 -0,0,9999,1 -0,0,9999,1 -0,0,9999,1 -0,0,9999,1 -0,0,9999,1 -0,0,9999,1 -0,0,9999,1 -0,0,9999,1 -0,0,9999,1 -0,0,9999,1 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 -0,0,10000,0 +9982,14,0,4 +9954,34,0,12 +9878,93,0,29 +9764,166,0,70 +9603,226,6,165 +9393,326,17,264 +9147,404,32,417 +8871,465,61,603 +8536,562,101,801 +8186,604,144,1066 +7837,636,201,1326 +7398,755,280,1567 +6979,799,365,1857 +6505,870,477,2148 +6038,891,613,2458 +5594,877,771,2758 +5175,854,957,3014 +4751,818,1146,3285 +4319,875,1348,3458 +3890,874,1574,3662 +3450,866,1829,3855 +3032,861,2053,4054 +2680,791,2299,4230 +2286,787,2582,4345 +1899,781,2874,4446 +1571,718,3112,4599 +1262,680,3396,4662 +987,609,3675,4729 +780,529,3984,4707 +559,488,4217,4736 +412,399,4513,4676 +298,316,4799,4587 +216,253,5070,4461 +144,192,5315,4349 +84,141,5574,4201 +38,105,5846,4011 +15,73,6097,3815 +2,49,6332,3617 +1,24,6570,3405 +0,14,6776,3210 +0,6,6967,3027 +0,1,7155,2844 +0,0,7325,2675 +0,0,7505,2495 +0,0,7644,2356 +0,0,7782,2218 +0,0,7901,2099 +0,0,8035,1965 +0,0,8161,1839 +0,0,8266,1734 +0,0,8366,1634 +0,0,8460,1540 +0,0,8559,1441 +0,0,8648,1352 +0,0,8727,1273 +0,0,8800,1200 +0,0,8869,1131 +0,0,8950,1050 +0,0,8994,1006 +0,0,9058,942 +0,0,9117,883 +0,0,9171,829 +0,0,9214,786 +0,0,9279,721 +0,0,9310,690 +0,0,9350,650 +0,0,9396,604 +0,0,9428,572 diff --git a/src/main/java/sma/SMA.java b/src/main/java/sma/SMA.java index 8eaf1f7b0cddd2a1f052f51d189d8ce966a3849c..b5fe03d4d0f6c7b7cb530e1cec88a81bb4425d00 100644 --- a/src/main/java/sma/SMA.java +++ b/src/main/java/sma/SMA.java @@ -1,12 +1,11 @@ package sma; import models.Parameters; -import sma.agents.Agent; +import sma.agents.RandomWalkingAgent; +import sma.agents.states.InfectedState; import sma.scheduler.FairAsynchronousScheduler; import sma.scheduler.FairSynchronousScheduler; import sma.scheduler.Scheduler; -import utils.DataAdapter; -import utils.Pair; import utils.StatsRecorder; import utils.YamlReader; import view.FrameBuilder; @@ -22,19 +21,19 @@ public class SMA { private Parameters parameters; private Random r; - private Agent[] agents; + private RandomWalkingAgent[] agents; private GraphicEnvironment environment; private Scheduler scheduler; private StatisticsCanvas statisticsCanvas; - private HashMap<Agent.State, Pair<Integer,Color>> stats; + private HashMap<String,Integer> stats; private FrameBuilder frameBuilder; public SMA() { parameters = YamlReader.getParams(); r = new Random(parameters.getSeed()); - agents = new Agent[parameters.getPopulation()]; + agents = new RandomWalkingAgent[parameters.getPopulation()]; statisticsCanvas = new StatisticsCanvas(500,500); frameBuilder = new FrameBuilder(); @@ -44,14 +43,15 @@ public class SMA { private void populateEnvironment() { for (int i = 0; i<parameters.getPopulation();i++) { Point position = new Point(r.nextInt(parameters.getSize()),r.nextInt(parameters.getSize())); - Agent agent = new Agent(position,parameters.getSeed()+i,environment); + RandomWalkingAgent agent = new RandomWalkingAgent(position,parameters.getSeed()+i,environment); agents[i] = agent; } } private void infectPatientZero() { for (int i=0 ; i< parameters.getNbOfPatientZero(); i++) { - agents[(r.nextInt(parameters.getPopulation()))].setState(Agent.State.INFECTED); + var agent = agents[(r.nextInt(parameters.getPopulation()))]; + agent.changeState(new InfectedState(agent)); } } @@ -87,7 +87,7 @@ public class SMA { private void doNextCycle() throws IOException, InterruptedException { scheduler.nextCycle(); stats = environment.getAgentStatus(); - StatsRecorder.writeToCSV(DataAdapter.adaptData(stats),"output.csv"); + StatsRecorder.writeToCSV(stats,"output.csv"); updateGraphics(); Thread.sleep(100); } diff --git a/src/main/java/sma/agents/Agent.java b/src/main/java/sma/agents/Agent.java index f8d029a1c0eb0e7e207a7425679f0e5a0ddbad84..1bff29593a25a9c8d773d335979fe3a746b73a16 100644 --- a/src/main/java/sma/agents/Agent.java +++ b/src/main/java/sma/agents/Agent.java @@ -1,114 +1,12 @@ package sma.agents; -import sma.environment.Environment; -import utils.YamlReader; -import view.GraphicEnvironment; +import sma.agents.states.State; -import java.awt.Point; -import java.util.Random; +public interface Agent { -public class Agent { - - public enum State { - SUSCEPTIBLE, - EXPOSED, - INFECTED, - RECOVERED - } - - private Point position; - private Random r; - private GraphicEnvironment environment; - - private State state; - private Boolean exposedThisCycle; - private Boolean infectedThisCycle; - - - public Agent(Point position, int seed, GraphicEnvironment environment) { - this.position = position; - this.state = State.SUSCEPTIBLE; - this.environment = environment; - this.r = new Random(seed); - } - - private void move() { - int move = r.nextInt(4); - - Point newPosition = switch (move) { - case Environment.LEFT -> new Point(position.x-environment.RADIUS,position.y); - case Environment.RIGHT -> new Point(position.x+environment.RADIUS,position.y); - case Environment.UP -> new Point(position.x,position.y-environment.RADIUS); - case Environment.DOWN -> new Point(position.x,position.y+environment.RADIUS); - default -> throw new IllegalStateException("Unexpected value: " + move); - }; - if (newPosition.x <= environment.getWidth()-1 && newPosition.x >= 0 && newPosition.y <= environment.getHeight()-1 && newPosition.y >=0 ) { - environment.notifyNewPosition(position,newPosition,this); - position = newPosition; - } - } - - private void contact() { - for (Agent neighbor: environment.getNeighbors(position)) { - if (neighbor.getState() == State.INFECTED) { - int roll = r.nextInt(100); - if (roll <= YamlReader.getParams().getInfectionChance()*100) { - state = State.EXPOSED; - exposedThisCycle = true; - } - } - } - } - - private void incubate() { - int roll = r.nextInt(100); - if (roll <= YamlReader.getParams().getIncubationRate()*100) { - state = State.INFECTED; - infectedThisCycle = true; - } - } - - private void recover() { - int roll = r.nextInt(100); - if (roll <= YamlReader.getParams().getRecoveryRate()*100) { - state = State.RECOVERED; - } - } - - public State getState() { - return this.state; - } - - public void setState(State state) { - this.state = state; - } - - public void wakeUp() { - exposedThisCycle = false; - infectedThisCycle = false; - move(); - if (state == State.SUSCEPTIBLE) { - contact(); - } - if (state == State.EXPOSED && !exposedThisCycle) { - incubate(); - } - if (state == State.INFECTED && !infectedThisCycle) { - recover(); - } - } - - public Point getPosition() { - return position; - } - - @Override - public String toString() { - return switch (state) { - case SUSCEPTIBLE -> "S"; - case EXPOSED -> "E"; - case INFECTED -> "I"; - case RECOVERED -> "R"; - }; - } + void changeState(State state); + boolean contact(); + boolean incubate(); + boolean recover(); + void move(); } diff --git a/src/main/java/sma/agents/RandomWalkingAgent.java b/src/main/java/sma/agents/RandomWalkingAgent.java new file mode 100644 index 0000000000000000000000000000000000000000..6be038c005a4725dc1a7b1f45b360753bd566058 --- /dev/null +++ b/src/main/java/sma/agents/RandomWalkingAgent.java @@ -0,0 +1,100 @@ +package sma.agents; + +import sma.agents.states.InfectedState; +import sma.agents.states.State; +import sma.agents.states.SuceptibleState; +import sma.environment.Environment; +import utils.YamlReader; +import view.GraphicEnvironment; + +import java.awt.Point; +import java.util.Random; + +public class RandomWalkingAgent implements Agent { + + private Point position; + private Random r; + private GraphicEnvironment environment; + + private State state; + private Boolean exposedThisCycle; + private Boolean infectedThisCycle; + + + public RandomWalkingAgent(Point position, int seed, GraphicEnvironment environment) { + this.position = position; + this.state = new SuceptibleState(this); + this.environment = environment; + this.r = new Random(seed); + } + + public void move() { + int move = r.nextInt(4); + + Point newPosition = switch (move) { + case Environment.LEFT -> new Point(position.x-environment.RADIUS,position.y); + case Environment.RIGHT -> new Point(position.x+environment.RADIUS,position.y); + case Environment.UP -> new Point(position.x,position.y-environment.RADIUS); + case Environment.DOWN -> new Point(position.x,position.y+environment.RADIUS); + default -> throw new IllegalStateException("Unexpected value: " + move); + }; + if (newPosition.x <= environment.getWidth()-1 && newPosition.x >= 0 && newPosition.y <= environment.getHeight()-1 && newPosition.y >=0 ) { + environment.notifyNewPosition(position,newPosition,this); + position = newPosition; + } + } + + @Override + public void changeState(State state) { + this.state = state; + } + + @Override + public boolean contact() { + boolean isExposed = false; + for (RandomWalkingAgent neighbor: environment.getNeighbors(position)) { + if (neighbor.getState() instanceof InfectedState) { + int roll = r.nextInt(100); + if (roll <= YamlReader.getParams().getInfectionChance()*100) { + isExposed = true; + } + } + } + return isExposed; + } + + @Override + public boolean incubate() { + boolean isSick = false; + int roll = r.nextInt(100); + if (roll <= YamlReader.getParams().getIncubationRate()*100) { + isSick = true; + } + return isSick; + } + + @Override + public boolean recover() { + boolean isHealed = false; + int roll = r.nextInt(100); + if (roll <= YamlReader.getParams().getRecoveryRate()*100) { + isHealed = true; + } + return isHealed; + } + + public State getState() { + return this.state; + } + + public void wakeUp() { + exposedThisCycle = false; + infectedThisCycle = false; + state.onMovement(); + } + + public Point getPosition() { + return position; + } + +} diff --git a/src/main/java/sma/agents/states/ExposedState.java b/src/main/java/sma/agents/states/ExposedState.java new file mode 100644 index 0000000000000000000000000000000000000000..2da7e831c28935d082b6c083e1d7c916c23e61d8 --- /dev/null +++ b/src/main/java/sma/agents/states/ExposedState.java @@ -0,0 +1,23 @@ +package sma.agents.states; + +import sma.agents.Agent; + +public class ExposedState extends State{ + + public ExposedState(Agent agent) { + super(agent); + } + + @Override + public void onMovement() { + agent.move(); + if (agent.incubate()) { + agent.changeState(new InfectedState(agent)); + } + } + + @Override + public String toString() { + return "EXPOSED"; + } +} diff --git a/src/main/java/sma/agents/states/InfectedState.java b/src/main/java/sma/agents/states/InfectedState.java new file mode 100644 index 0000000000000000000000000000000000000000..b8173e8087891a7aa59891d05604370cb1bb80dd --- /dev/null +++ b/src/main/java/sma/agents/states/InfectedState.java @@ -0,0 +1,23 @@ +package sma.agents.states; + +import sma.agents.Agent; + +public class InfectedState extends State{ + + public InfectedState(Agent agent) { + super(agent); + } + + @Override + public void onMovement() { + agent.move(); + if (agent.recover()) { + agent.changeState(new RecoveredState(agent)); + } + } + + @Override + public String toString() { + return "INFECTED"; + } +} diff --git a/src/main/java/sma/agents/states/RecoveredState.java b/src/main/java/sma/agents/states/RecoveredState.java new file mode 100644 index 0000000000000000000000000000000000000000..991ae851490b38a872b26149ef9c5689b35c4553 --- /dev/null +++ b/src/main/java/sma/agents/states/RecoveredState.java @@ -0,0 +1,20 @@ +package sma.agents.states; + +import sma.agents.Agent; + +public class RecoveredState extends State{ + + public RecoveredState(Agent agent) { + super(agent); + } + + @Override + public void onMovement() { + agent.move(); + } + + @Override + public String toString() { + return "RECOVERED"; + } +} diff --git a/src/main/java/sma/agents/states/State.java b/src/main/java/sma/agents/states/State.java new file mode 100644 index 0000000000000000000000000000000000000000..753bccb96b500aca2b8d81186405484dfa6af81c --- /dev/null +++ b/src/main/java/sma/agents/states/State.java @@ -0,0 +1,20 @@ +package sma.agents.states; + +import sma.agents.Agent; + +public abstract class State { + + public final static String EXPOSED = "EXPOSED"; + public final static String INFECTED = "INFECTED"; + public final static String SUCEPTIBLE = "SUCEPTIBLE"; + public final static String RECOVERED = "RECOVERED"; + + protected Agent agent; + + State(Agent agent) { + this.agent = agent; + } + + public void onMovement(){} + +} diff --git a/src/main/java/sma/agents/states/SuceptibleState.java b/src/main/java/sma/agents/states/SuceptibleState.java new file mode 100644 index 0000000000000000000000000000000000000000..b12d17f4d28f56e51b896483ff91c4442e7c75d9 --- /dev/null +++ b/src/main/java/sma/agents/states/SuceptibleState.java @@ -0,0 +1,23 @@ +package sma.agents.states; + +import sma.agents.Agent; + +public class SuceptibleState extends State{ + + public SuceptibleState(Agent agent) { + super(agent); + } + + @Override + public void onMovement() { + agent.move(); + if (agent.contact()) { + agent.changeState(new ExposedState(agent)); + } + } + + @Override + public String toString() { + return "SUCEPTIBLE"; + } +} diff --git a/src/main/java/sma/environment/Environment.java b/src/main/java/sma/environment/Environment.java index 5709c4e0f68bdf6eb0e0205214a855decff37665..f43db6eec3938a3f70dde6bb654edf23f184e854 100644 --- a/src/main/java/sma/environment/Environment.java +++ b/src/main/java/sma/environment/Environment.java @@ -1,6 +1,6 @@ package sma.environment; -import sma.agents.Agent; +import sma.agents.RandomWalkingAgent; import java.awt.Point; import java.util.List; @@ -17,5 +17,5 @@ public interface Environment { int DOWN_RIGHT = 8; int MAX_CHUNK = 9; - List<Agent> getNeighbors(Point position); + List<RandomWalkingAgent> getNeighbors(Point position); } diff --git a/src/main/java/sma/scheduler/FairAsynchronousScheduler.java b/src/main/java/sma/scheduler/FairAsynchronousScheduler.java index b9bb5e65d839d8070993da8a189e93c68500b4dc..a5d0295beef4c208a94668ee8da6b7fb9ca486f1 100644 --- a/src/main/java/sma/scheduler/FairAsynchronousScheduler.java +++ b/src/main/java/sma/scheduler/FairAsynchronousScheduler.java @@ -1,6 +1,6 @@ package sma.scheduler; -import sma.agents.Agent; +import sma.agents.RandomWalkingAgent; import java.util.Arrays; import java.util.List; @@ -12,16 +12,16 @@ import java.util.stream.Collectors; public class FairAsynchronousScheduler implements Scheduler{ private ExecutorService executor = Executors.newSingleThreadExecutor(); - private Queue<Agent> queue; + private Queue<RandomWalkingAgent> queue; - public FairAsynchronousScheduler(Agent[] agents) { + public FairAsynchronousScheduler(RandomWalkingAgent[] agents) { this.queue = new ConcurrentLinkedQueue<>(Arrays.stream(agents).toList()); } public void nextCycle() { - List<Future<Agent>> results = queue.parallelStream().map(agent -> executor.submit(() -> {agent.wakeUp(); return agent;})).collect(Collectors.toList()); - Function<Future<Agent>,Agent> futureTreatment = futureAgent -> { + List<Future<RandomWalkingAgent>> results = queue.parallelStream().map(agent -> executor.submit(() -> {agent.wakeUp(); return agent;})).collect(Collectors.toList()); + Function<Future<RandomWalkingAgent>, RandomWalkingAgent> futureTreatment = futureAgent -> { try { return futureAgent.get(); } catch (ExecutionException e) { @@ -32,7 +32,7 @@ public class FairAsynchronousScheduler implements Scheduler{ return null; }; - List<Agent> nextQueue = results.parallelStream().map(futureTreatment).collect(Collectors.toList()); + List<RandomWalkingAgent> nextQueue = results.parallelStream().map(futureTreatment).collect(Collectors.toList()); queue = new ConcurrentLinkedQueue<>(nextQueue); } diff --git a/src/main/java/sma/scheduler/FairSynchronousScheduler.java b/src/main/java/sma/scheduler/FairSynchronousScheduler.java index 6d365e9469adb5da9598c2a3873a78a7605a23b4..275d094d070d1d76df413c5ed118c889129aa5a9 100644 --- a/src/main/java/sma/scheduler/FairSynchronousScheduler.java +++ b/src/main/java/sma/scheduler/FairSynchronousScheduler.java @@ -1,16 +1,16 @@ package sma.scheduler; -import sma.agents.Agent; +import sma.agents.RandomWalkingAgent; import java.util.*; public class FairSynchronousScheduler implements Scheduler { - private Agent[] agents; + private RandomWalkingAgent[] agents; private Stack<Integer> executionOrder; private Random r; - public FairSynchronousScheduler(Agent[] agents, int seed) { + public FairSynchronousScheduler(RandomWalkingAgent[] agents, int seed) { this.agents = agents; r = new Random(seed); executionOrder = new Stack<>(); diff --git a/src/main/java/utils/DataAdapter.java b/src/main/java/utils/DataAdapter.java deleted file mode 100644 index a698185105599e8b64a4efe56b323967a9d11030..0000000000000000000000000000000000000000 --- a/src/main/java/utils/DataAdapter.java +++ /dev/null @@ -1,20 +0,0 @@ -package utils; - -import sma.agents.Agent; - -import java.awt.*; -import java.util.HashMap; - -public class DataAdapter { - - public static HashMap<String,String> adaptData(HashMap<Agent.State,Pair<Integer, Color>> data) { - var map = new HashMap<String,String>(); - - map.put("SUCEPTIBLE",data.get(Agent.State.SUSCEPTIBLE).getFirst().toString()); - map.put("EXPOSED",data.get(Agent.State.EXPOSED).getFirst().toString()); - map.put("INFECTED",data.get(Agent.State.INFECTED).getFirst().toString()); - map.put("RECOVERED",data.get(Agent.State.RECOVERED).getFirst().toString()); - - return map; - } -} diff --git a/src/main/java/utils/StatsRecorder.java b/src/main/java/utils/StatsRecorder.java index 4ccdde3f928950f7e804c0e03793fbb7ddc7dad1..b8aa0f28606f4b7d19d99777fd5222fd1c2c41d5 100644 --- a/src/main/java/utils/StatsRecorder.java +++ b/src/main/java/utils/StatsRecorder.java @@ -10,7 +10,7 @@ public class StatsRecorder { private static int nbOfCycles = 0; private static ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - public static void writeToCSV(HashMap<String,String> data, String outputFile) throws IOException { + public static void writeToCSV(HashMap<String,Integer> data, String outputFile) throws IOException { if (!outputFile.endsWith(".csv")) { throw new InvalidParameterException("outputFile is not a .csv file."); diff --git a/src/main/java/view/GraphicEnvironment.java b/src/main/java/view/GraphicEnvironment.java index a21a9a3ed92cf1ba2a9bcc6aa7c074e24e3d2827..ecf95d90ec03d260d3039c825070b14036031b56 100644 --- a/src/main/java/view/GraphicEnvironment.java +++ b/src/main/java/view/GraphicEnvironment.java @@ -1,10 +1,12 @@ package view; -import sma.agents.Agent; +import sma.agents.RandomWalkingAgent; +import sma.agents.states.*; import sma.environment.Environment; import utils.Pair; import java.awt.*; +import java.security.InvalidParameterException; import java.util.*; import java.util.List; @@ -14,14 +16,14 @@ public class GraphicEnvironment extends Canvas implements Environment { public final static int CHUNK_SIZE = 2*RADIUS; - private Agent[] agents; + private RandomWalkingAgent[] agents; - private List<Agent>[][] chunks; + private List<RandomWalkingAgent>[][] chunks; private int windowWidth; private int windowHeight; - public GraphicEnvironment(int width,int height,Agent[] agents) { + public GraphicEnvironment(int width, int height, RandomWalkingAgent[] agents) { this.windowWidth = width; this.windowHeight = height; this.agents = agents; @@ -36,14 +38,14 @@ public class GraphicEnvironment extends Canvas implements Environment { chunks[i][j] = new ArrayList<>(); } } - for (Agent agent : agents) { + for (RandomWalkingAgent agent : agents) { int x = agent.getPosition().x/CHUNK_SIZE; int y = agent.getPosition().y/CHUNK_SIZE; chunks[x][y].add(agent); } } - public void notifyNewPosition(Point oldPosition, Point newPosition, Agent agent) { + public void notifyNewPosition(Point oldPosition, Point newPosition, RandomWalkingAgent agent) { if (oldPosition.x/CHUNK_SIZE != newPosition.x/CHUNK_SIZE || oldPosition.y/CHUNK_SIZE != newPosition.y/CHUNK_SIZE) { chunks[oldPosition.x/CHUNK_SIZE][oldPosition.y/CHUNK_SIZE].remove(agent); chunks[newPosition.x/CHUNK_SIZE][newPosition.y/CHUNK_SIZE].add(agent); @@ -70,8 +72,8 @@ public class GraphicEnvironment extends Canvas implements Environment { } @Override - public List<Agent> getNeighbors(Point p) { - var neighbors = new ArrayList<Agent>(); + public List<RandomWalkingAgent> getNeighbors(Point p) { + var neighbors = new ArrayList<RandomWalkingAgent>(); for (int i = 0; i < MAX_CHUNK; i++) { neighbors.addAll(getChunkNeighbors(i,p)); @@ -79,7 +81,7 @@ public class GraphicEnvironment extends Canvas implements Environment { return neighbors; } - private List<Agent> getChunkNeighbors(int relativeTo, Point p) { + private List<RandomWalkingAgent> getChunkNeighbors(int relativeTo, Point p) { var x = p.x/CHUNK_SIZE; var y = p.y/CHUNK_SIZE; switch (relativeTo) { @@ -95,9 +97,9 @@ public class GraphicEnvironment extends Canvas implements Environment { default -> throw new IllegalStateException("Unexpected value: " + relativeTo); }; - var neighbors = new ArrayList<Agent>(); + var neighbors = new ArrayList<RandomWalkingAgent>(); try{ - for (Agent agent : chunks[x][y]) { + for (RandomWalkingAgent agent : chunks[x][y]) { if (detectCollision(p, agent.getPosition())) { neighbors.add(agent); } @@ -108,27 +110,19 @@ public class GraphicEnvironment extends Canvas implements Environment { return neighbors; } - public HashMap<Agent.State,Pair<Integer,Color>> getAgentStatus() { + public HashMap<String,Integer> getAgentStatus() { - Pair<Integer,Color> susceptible = new Pair<>(0,Color.GRAY); - Pair<Integer,Color> exposed = new Pair<>(0,Color.YELLOW); - Pair<Integer,Color> infected = new Pair<>(0,Color.RED); - Pair<Integer,Color> recovered = new Pair<>(0,Color.green); + var map = new HashMap<String,Integer>(); + map.put(State.EXPOSED,0); + map.put(State.INFECTED,0); + map.put(State.RECOVERED,0); + map.put(State.SUCEPTIBLE,0); - for (Agent agent : agents) { - switch (agent.getState()) { - case SUSCEPTIBLE -> susceptible.setFirst(susceptible.getFirst()+1); - case EXPOSED -> exposed.setFirst(exposed.getFirst()+1); - case INFECTED -> infected.setFirst(infected.getFirst()+1); - case RECOVERED -> recovered.setFirst(recovered.getFirst()+1); - } + for (RandomWalkingAgent agent : agents) { + String state = agent.getState().toString(); + map.put(state,map.get(state)+1); } - var result = new HashMap<Agent.State,Pair<Integer,Color>>(); - result.put(Agent.State.SUSCEPTIBLE,susceptible); - result.put(Agent.State.EXPOSED,exposed); - result.put(Agent.State.INFECTED,infected); - result.put(Agent.State.RECOVERED,recovered); - return result; + return map; } private Boolean detectCollision(Point pos1, Point pos2) { @@ -138,12 +132,13 @@ public class GraphicEnvironment extends Canvas implements Environment { return distanceSquared < (2*RADIUS) * (2*RADIUS); } - private void colorAgent(Graphics g,Agent a) { - switch (a.getState()) { - case SUSCEPTIBLE -> g.setColor(Color.GRAY); - case EXPOSED -> g.setColor(Color.YELLOW); - case INFECTED -> g.setColor(Color.RED); - case RECOVERED -> g.setColor(Color.GREEN); + private void colorAgent(Graphics g, RandomWalkingAgent a) { + var state = a.getState(); + switch (state.toString()) { + case State.SUCEPTIBLE-> g.setColor(Color.GRAY); + case State.EXPOSED -> g.setColor(Color.YELLOW); + case State.INFECTED -> g.setColor(Color.RED); + case State.RECOVERED -> g.setColor(Color.GREEN); } } } diff --git a/src/main/java/view/StatisticsCanvas.java b/src/main/java/view/StatisticsCanvas.java index fea95cf66297d9b94e2c743d14d14f26d2e6e856..b2b31ac4293b9cc0d9ea3ac68dcd611839549d3a 100644 --- a/src/main/java/view/StatisticsCanvas.java +++ b/src/main/java/view/StatisticsCanvas.java @@ -1,6 +1,7 @@ package view; -import sma.agents.Agent; +import sma.agents.RandomWalkingAgent; +import sma.agents.states.State; import utils.Pair; import utils.YamlReader; @@ -11,7 +12,7 @@ public class StatisticsCanvas extends Canvas { private int canvasWidth; private int canvasHeight; - private HashMap<Agent.State,Pair<Integer,Color>> values; + private HashMap<String,Integer> values; private int total; public StatisticsCanvas(int width,int height) { @@ -23,28 +24,36 @@ public class StatisticsCanvas extends Canvas { setVisible(true); } - public void updateValues(HashMap<Agent.State,Pair<Integer,Color>> values ) { + private Color stringToColor(String str) { + return switch (str){ + case State.EXPOSED -> Color.YELLOW; + case State.SUCEPTIBLE -> Color.GRAY; + case State.INFECTED -> Color.RED; + case State.RECOVERED -> Color.GREEN; + default -> throw new IllegalStateException("Illegal state : "+str); + }; + } + + public void updateValues(HashMap<String,Integer> values ) { this.values = values; } @Override public void paint(Graphics g) { int start = 0; + + for (String state : values.keySet()) { + + } for (int i=0 ; i <values.keySet().size();i++) { - Agent.State state = values.keySet().stream().toList().get(i); - Pair<Integer,Color> subpopulation = values.get(state); - g.setColor(subpopulation.getSecond()); - float height = ((float)subpopulation.getFirst()/total)*canvasHeight; + String state = (String) values.keySet().toArray()[i]; + int value = values.get(state); + g.setColor(stringToColor(state)); + float height = ((float)value/total)*canvasHeight; g.fillRect(10,start,canvasWidth/4,start+(int)height); start +=height; - g.setColor(Color.BLACK); - switch (state) { - case SUSCEPTIBLE -> g.drawString("SUSCEPTIBLE : " + subpopulation.getFirst(),canvasWidth/2,canvasHeight/values.keySet().size()*(1+i)-100); - case EXPOSED -> g.drawString("EXPOSED : " + subpopulation.getFirst(),canvasWidth/2,canvasHeight/values.keySet().size()*(1+i)-100); - case INFECTED -> g.drawString("INFECTED : " + subpopulation.getFirst(),canvasWidth/2,canvasHeight/values.keySet().size()*(1+i)-100); - case RECOVERED -> g.drawString("RECOVERED : " + subpopulation.getFirst(),canvasWidth/2,canvasHeight/values.keySet().size()*(1+i)-100); - } + g.drawString(state + " : "+value,canvasWidth/2,canvasHeight/values.keySet().size()*(1+i)-100); } }