andrei 1 jaar geleden
bovenliggende
commit
0e9b1e42f9
12 gewijzigde bestanden met toevoegingen van 588 en 3 verwijderingen
  1. 3 0
      .gitignore
  2. 0 3
      README.md
  3. BIN
      ShipTraffic.exe
  4. 92 0
      data.py
  5. 14 0
      files/day_ice.csv
  6. 11 0
      files/ice_can.csv
  7. 271 0
      files/points.json
  8. 39 0
      files/requests.csv
  9. 125 0
      main.py
  10. 23 0
      ml_time.py
  11. 10 0
      readme.md
  12. BIN
      requirements.txt

+ 3 - 0
.gitignore

@@ -0,0 +1,3 @@
+/venv/
+/.idea
+.idea/

+ 0 - 3
README.md

@@ -1,3 +0,0 @@
-# hackathon-digital-breakthrough-2023-RZD
-
-В сентябре 2023 года команда Numerum участвовала в хокатоне: Цифровой прорыв: сезон ИИ. Кейс с атомными ледоколами от росатома. И заняла там 3 место со своеим проектом.

BIN
ShipTraffic.exe


+ 92 - 0
data.py

@@ -0,0 +1,92 @@
+import csv
+import datetime
+from pprint import pprint
+
+icebreakers = [
+    [
+        9152959, '8417493'
+    ],
+    [
+        9077549, 'Ямал'
+    ],
+    [
+        8417481, 'Таймыр'
+    ],
+    [
+        8417493, 'Вайгач'
+    ]
+]
+
+icebreakers_requests = []
+with open('files/requests.csv', encoding="utf8") as csvfile:
+    reader = csv.reader(csvfile, delimiter=';', quotechar='"')
+    for index, row in enumerate(reader):
+        # if index > 10:
+        #    break
+        icebreakers_requests.append(row)
+
+start_points = ['начальная точка в Баренцевом море', 'Сабетта-1', 'Сабетта-2', 'Сабетта-3']
+end_points = ['начальная точка в Баренцевом море', 'Сабетта-1', 'Сабетта-2', 'Сабетта-3']
+
+edges = {
+    1: 440.25,
+    2: 450.04,
+    3: 169.16,
+    4: 752.79,
+    5: 376.88,
+    6: 257.60,
+    7: 123.36,
+    8: 33.15,
+    9: 72.40,
+    10: 85.96,
+    11: 15.78,
+    12: 45.52,
+    13: 15.65,
+    14: 256.72
+}
+
+routes = {
+    'начальная точка в Баренцевом мореСабетта-3': [[11, 10, 9, 8, 7, 6, 5], [11, 10, 9, 8, 7, 3, 2, 1, 4]],
+    'Сабетта-3начальная точка в Баренцевом море': [[11, 10, 9, 8, 7, 6, 5][::-1], [11, 10, 9, 8, 7, 3, 2, 1, 4][::-1]],
+    'Сабетта-2начальная точка в Баренцевом море': [[13, 12, 10, 9, 8, 7, 6, 5], [13, 12, 10, 9, 8, 7, 3, 2, 1, 4]],
+    'начальная точка в Баренцевом мореСабетта-2': [[13, 12, 10, 9, 8, 7, 6, 5][::-1],
+                                                   [13, 12, 10, 9, 8, 7, 3, 2, 1, 4][::-1]],
+    'Сабетта-1начальная точка в Баренцевом море': [[14, 12, 10, 9, 8, 7, 6, 5], [14, 12, 10, 9, 8, 7, 3, 2, 1, 4]],
+    'начальная точка в Баренцевом мореСабетта-1': [[14, 12, 10, 9, 8, 7, 6, 5][::-1],
+                                                   [14, 12, 10, 9, 8, 7, 3, 2, 1, 4][::-1]]
+}
+
+day_ice = []
+with open('files/day_ice.csv', encoding="utf8") as csvfile:
+    reader = csv.reader(csvfile, delimiter=';', quotechar='"')
+    for index, row in enumerate(reader):
+        # if index > 10:
+        #    break
+        day_ice.append(row)
+
+ice_can = []
+with open('files/ice_can.csv', encoding="utf8") as csvfile:
+    reader = csv.reader(csvfile, delimiter=';', quotechar='"')
+    for index, row in enumerate(reader):
+        # if index > 10:
+        #    break
+        ice_can.append(row)
+
+skip_status = {
+    1: 'Самостоятельно',
+    2: 'Нужна проводка',
+    3: 'Проход невозможен'
+}
+class_can = {
+    'No ice class': 0,
+    'Arc1': 1,
+    'Arc2': 2,
+    'Arc3': 3,
+    'Arc4': 4,
+    'Arc5': 5,
+    'Arc6': 6,
+    'Arc7': 7,
+    'Arc8': 8,
+    'Arc9': 9,
+    'Arc10': 10,
+}

+ 14 - 0
files/day_ice.csv

@@ -0,0 +1,14 @@
+0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;2
+0;1;1;1;1;2;2;2;2;2;2;2;2;3;3;3;3;3;3;3;4;4;4;4;4;4;4;5;5;5
+1;1;1;1;2;2;2;2;2;2;3;3;3;3;3;3;3;4;4;4;4;4;5;5;5;5;6;6;6;6
+0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;2
+0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;2;2
+0;0;0;1;1;1;1;1;1;1;1;1;2;2;2;2;2;3;3;3;3;3;4;4;4;4;4;5;5;6
+1;1;1;2;2;2;2;2;2;3;3;3;3;3;3;4;4;4;4;4;5;5;5;5;6;6;6;6;6;7
+1;1;2;2;2;2;2;2;3;3;3;3;3;3;4;4;4;4;4;5;5;5;5;6;6;6;6;6;7;7
+2;2;2;2;3;3;3;3;4;4;4;4;4;5;5;5;5;5;6;6;6;6;7;7;7;7;7;8;8;8
+2;2;2;3;3;3;3;4;4;4;4;4;5;5;5;5;5;6;6;6;6;7;7;7;7;7;7;8;8;8
+3;3;3;3;3;3;3;3;4;4;4;5;5;5;5;5;6;6;6;6;7;7;7;7;7;7;7;7;7;7
+3;3;3;3;3;3;3;3;4;4;4;5;5;5;5;5;6;6;6;6;7;7;7;7;7;7;7;7;7;7
+3;3;3;3;3;3;3;3;4;4;4;5;5;5;5;5;6;6;6;6;7;7;7;7;7;7;7;7;7;7
+3;3;3;3;3;3;3;3;4;4;4;4;4;4;4;5;5;5;5;5;5;6;6;6;6;7;7;7;8;9

+ 11 - 0
files/ice_can.csv

@@ -0,0 +1,11 @@
+1;1;1;1;1;1;1;1;1;1;1
+1;1;1;1;1;1;1;1;1;1;1
+1;1;1;1;1;1;1;1;1;1;1
+1;1;1;1;1;1;1;1;1;1;1
+2;2;2;2;1;1;1;1;1;1;1
+2;2;2;2;1;1;1;1;1;1;1
+2;2;2;2;1;1;1;1;1;1;1
+3;3;3;3;2;2;2;1;1;1;1
+3;3;3;3;2;2;2;1;1;1;1
+3;3;3;3;2;2;2;1;1;1;1
+3;3;3;3;2;2;2;1;1;1;1

+ 271 - 0
files/points.json

@@ -0,0 +1,271 @@
+{
+  "type": "FeatureCollection",
+  "features": [
+    {
+      "type": "Feature",
+      "properties": {
+        "id": 1
+      },
+      "geometry": {
+        "type": "LineString",
+        "coordinates": [
+          [
+            46.142578125,
+            69.93030017617484
+          ],
+          [
+            57.74414062500001,
+            70.4367988185464
+          ]
+        ]
+      }
+    },
+    {
+      "type": "Feature",
+      "properties": {
+        "id": 2
+      },
+      "geometry": {
+        "type": "LineString",
+        "coordinates": [
+          [
+            57.74414062500001,
+            70.4367988185464
+          ],
+          [
+            66.20361328125,
+            73.53462847039683
+          ]
+        ]
+      }
+    },
+    {
+      "type": "Feature",
+      "properties": {
+        "id": 3
+      },
+      "geometry": {
+        "type": "LineString",
+        "coordinates": [
+          [
+            66.20361328125,
+            73.53462847039683
+          ],
+          [
+            71.54296874999999,
+            73.77577986189993
+          ]
+        ]
+      }
+    },
+    {
+      "type": "Feature",
+      "properties": {
+        "id": 4
+      },
+      "geometry": {
+        "type": "LineString",
+        "coordinates": [
+          [
+            46.142578125,
+            69.93030017617484
+          ],
+          [
+            55.01953125,
+            76.2059670431415
+          ]
+        ]
+      }
+    },
+    {
+      "type": "Feature",
+      "properties": {
+        "id": 5
+      },
+      "geometry": {
+        "type": "LineString",
+        "coordinates": [
+          [
+            55.01953125,
+            76.2059670431415
+          ],
+          [
+            68.90625,
+            77.44694030325893
+          ]
+        ]
+      }
+    },
+    {
+      "type": "Feature",
+      "properties": {
+        "id": 6
+      },
+      "geometry": {
+        "type": "LineString",
+        "coordinates": [
+          [
+            68.90625,
+            77.44694030325893
+          ],
+          [
+            71.54296874999999,
+            73.77577986189993
+          ]
+        ]
+      }
+    },
+    {
+      "type": "Feature",
+      "properties": {
+        "id": 7
+      },
+      "geometry": {
+        "type": "LineString",
+        "coordinates": [
+          [
+            71.54296874999999,
+            73.77577986189993
+          ],
+          [
+            73.125,
+            72.76406472320436
+          ]
+        ]
+      }
+    },
+    {
+      "type": "Feature",
+      "properties": {
+        "id": 8
+      },
+      "geometry": {
+        "type": "LineString",
+        "coordinates": [
+          [
+            73.125,
+            72.76406472320436
+          ],
+          [
+            74.02587890625,
+            72.63337363853837
+          ]
+        ]
+      }
+    },
+    {
+      "type": "Feature",
+      "properties": {
+        "id": 9
+      },
+      "geometry": {
+        "type": "LineString",
+        "coordinates": [
+          [
+            74.02587890625,
+            72.63337363853837
+          ],
+          [
+            72.92724609375,
+            72.0739114882038
+          ]
+        ]
+      }
+    },
+    {
+      "type": "Feature",
+      "properties": {
+        "id": 10
+      },
+      "geometry": {
+        "type": "LineString",
+        "coordinates": [
+          [
+            72.92724609375,
+            72.0739114882038
+          ],
+          [
+            72.59765625,
+            71.30783606806223
+          ]
+        ]
+      }
+    },
+    {
+      "type": "Feature",
+      "properties": {
+        "id": 11
+      },
+      "geometry": {
+        "type": "LineString",
+        "coordinates": [
+          [
+            72.59765625,
+            71.30783606806223
+          ],
+          [
+            72.2021484375,
+            71.24435551310674
+          ]
+        ]
+      }
+    },
+    {
+      "type": "Feature",
+      "properties": {
+        "id": 12
+      },
+      "geometry": {
+        "type": "LineString",
+        "coordinates": [
+          [
+            72.59765625,
+            71.30783606806223
+          ],
+          [
+            73.32275390625,
+            70.9722375547307
+          ]
+        ]
+      }
+    },
+    {
+      "type": "Feature",
+      "properties": {
+        "id": 13
+      },
+      "geometry": {
+        "type": "LineString",
+        "coordinates": [
+          [
+            73.32275390625,
+            70.9722375547307
+          ],
+          [
+            73.7127685546875,
+            71.03303495416577
+          ]
+        ]
+      }
+    },
+    {
+      "type": "Feature",
+      "properties": {
+        "id": 14
+      },
+      "geometry": {
+        "type": "LineString",
+        "coordinates": [
+          [
+            73.32275390625,
+            70.9722375547307
+          ],
+          [
+            73.52874755859375,
+            68.66455067163206
+          ]
+        ]
+      }
+    }
+  ]
+}

+ 39 - 0
files/requests.csv

@@ -0,0 +1,39 @@
+Штурман Кошелев;9759939;Arc7;15;Сабетта-3;начальная точка в Баренцевом море;13.01.2021 16:00;17.01.2021 14:00
+Штурман Кошелев;9759939;Arc7;15;начальная точка в Баренцевом море;Сабетта-3;17.01.2021 13:00;21.01.2021 16:20
+Штурман Кошелев;9759939;Arc7;15;Сабетта-3;начальная точка в Баренцевом море;22.01.2021 7:30;26.01.2021 19:00
+Штурман Кошелев;9759939;Arc7;15;начальная точка в Баренцевом море;Сабетта-3;28.01.2021 2:00;03.02.2021 19:00
+Лагорта;9194012;Arc5;15;начальная точка в Баренцевом море;Сабетта-3;27.12.2020 23:00;07.01.2021 17:00
+Лагорта;9194012;Arc5;15;Сабетта-3;начальная точка в Баренцевом море;20.01.2021 15:00;30.01.2021 22:00
+Михаил Лазарев;9837547;Arc7;15;Сабетта-2;начальная точка в Баренцевом море;14.01.2021 22:00;18.01.2021 10:00
+Михаил Лазарев;9837547;Arc7;15;начальная точка в Баренцевом море;Сабетта-2;19.01.2021 12:00;23.01.2021 12:00
+Юрий Кучиев;9804033;Arc7;14;Сабетта-1;начальная точка в Баренцевом море;07.01.2021 00:00;10.01.2021 14:00
+Юрий Кучиев;9804033;Arc7;14;начальная точка в Баренцевом море;Сабетта-1;26.01.2021 22:00;31.01.2021 20:00
+Эдуард Толль;9750696;Arc7;19;начальная точка в Баренцевом море;Сабетта-1;01.01.2021 17:30;04.01.2021 5:00
+Эдуард Толль;9750696;Arc7;19;Сабетта-1;начальная точка в Баренцевом море;07.01.2021 17:00;11.01.2021 12:30
+Борис Давыдов;9768394;Arc7;19;начальная точка в Баренцевом море;Сабетта-1;08.01.2021 22:00;10.01.2021 14:15
+Владимир Воронин;9750737;Arc7;19;начальная точка в Баренцевом море;Сабетта-1;16.01.2021 18:00;18.01.2021 19:00
+Владимир Воронин;9750737;Arc7;19;Сабетта-1;начальная точка в Баренцевом море;26.01.2021 10:00;29.01.2021 22:30
+Владимир Русанов;9750701;Arc7;19;Сабетта-1;начальная точка в Баренцевом море;01.01.2021 0:00;03.01.2021 12:45
+Арктика-2;9243801;Arc5;14;начальная точка в Баренцевом море;Сабетта-2;13.01.2021 1:30;16.01.2021 9:30
+Арктика-2;9243801;Arc5;14;Сабетта-2;начальная точка в Баренцевом море;24.01.2021 21:00;28.01.2021 21:00
+РЗК Константа;8711289;Arc5;15;Сабетта-2;начальная точка в Баренцевом море;29.12.2020 15:00;02.01.2021 19:30
+РЗК Константа;8711289;Arc5;15;начальная точка в Баренцевом море;Сабетта-1;09.01.2021 3:00;13.01.2021 21:30
+РЗК Константа;8711289;Arc5;15;Сабетта-1;начальная точка в Баренцевом море;19.01.2021 4:00;22.01.2021 18:00
+Беринг;9267297;Arc4;14;Сабетта-2;начальная точка в Баренцевом море;05.01.2021 21:00;08.01.2021 10:00
+Беринг;9267297;Arc4;14;начальная точка в Баренцевом море;Сабетта-2;24.01.2021 10:00;28.01.2021 22:00
+Северный проект;9202053;Arc4;12;начальная точка в Баренцевом море;Сабетта-2;23.01.2021 0:30;30.01.2021 21:00
+Мыс Желания;9366110;Arc4;16;начальная точка в Баренцевом море;Сабетта-2;31.12.2020 12:00;02.01.2021 12:00
+Мыс Желания;9366110;Arc4;16;Сабетта-2;начальная точка в Баренцевом море;16.01.2021 12:30;19.01.2021 22:00
+Мыс Желания;9366110;Arc4;16;начальная точка в Баренцевом море;Сабетта-2;29.01.2021 10:00;01.02.2021 23:30
+Никифор Бегичев;9014896;Arc4;14;начальная точка в Баренцевом море;Сабетта-2;16.01.2021 3:00;20.01.2021 3:00
+Никифор Бегичев;9014896;Arc4;14;Сабетта-2;начальная точка в Баренцевом море;22.01.2021 3:00;26.01.2021 22:00
+LNG PHECDA;9834313;No ice class;18;начальная точка в Баренцевом море;Сабетта-1;02.01.2021 12:30;04.01.2021 12:00
+LNG PHECDA;9834313;No ice class;18;Сабетта-1;начальная точка в Баренцевом море;04.01.2021 11:00;06.01.2021 14:00
+LNG PHECDA;9834313;No ice class;18;начальная точка в Баренцевом море;Сабетта-1;16.01.2021 9:00;18.01.2021 16:30
+LNG PHECDA;9834313;No ice class;18;Сабетта-1;начальная точка в Баренцевом море;20.01.2021 9:00;22.01.2021 22:00
+LNG DUBHE;9834296;No ice class;16;начальная точка в Баренцевом море;Сабетта-1;02.01.2021 0:30;03.01.2021 23:30
+LNG DUBHE;9834296;No ice class;16;Сабетта-1;начальная точка в Баренцевом море;06.01.2021 15:00;08.01.2021 16:00
+LNG DUBHE;9834296;No ice class;16;начальная точка в Баренцевом море;Сабетта-1;12.01.2021 10:00;14.01.2021 16:30
+LNG DUBHE;9834296;No ice class;16;Сабетта-1;начальная точка в Баренцевом море;13.01.2021 19:30;15.01.2021 10:00
+LNG DUBHE;9834296;No ice class;16;начальная точка в Баренцевом море;Сабетта-1;22.01.2021 7:00;24.01.2021 18:30
+LNG DUBHE;9834296;No ice class;16;Сабетта-1;начальная точка в Баренцевом море;23.01.2021 0:30;25.01.2021 23:30

+ 125 - 0
main.py

@@ -0,0 +1,125 @@
+import datetime
+import plotly.figure_factory as ff
+
+
+class ShipTraffic:
+    def parse_reqs(self, reqs):  # функция перебора заявок
+        reqs = list(map(lambda x: self.make_datetime(x), reqs))
+        resp = list(map(lambda x: self.processing_req(x),
+                        sorted(reqs, key=lambda x: (x[6], x[7]))))
+        self.made_gant(resp)
+        h = 0
+        while not all(list(map(lambda x: True if x[0] != 403 else False, resp))):
+            if h > 20:
+                break
+            not_allowed = list(filter(lambda x: x[0] == 403, resp))
+            not_reqs = []
+            for i in not_allowed:
+                start_id = i[1][-1][1]
+                req = list(filter(lambda x: x[6] == start_id, reqs))
+                reqs[reqs.index(req[0])][6] -= datetime.timedelta(days=1)
+                i[1][-1][1] -= datetime.timedelta(days=1)
+            resp = list(map(lambda x: self.processing_req(x),
+                            sorted(reqs, key=lambda x: (x[6], x[7]))))
+            h += 1
+        if h < 20:
+            self.made_gant(resp)
+
+    def processing_req(self, req):  # функция обработки заявки
+        time_interval = self.ship_graph_time(req)
+        route = self.can_swim(time_interval, req)
+        return route
+
+    def ship_graph_time(self, req):  # функция определения временного интервала для ребра: [rebro, time_start, time_end]
+        from data import routes
+        rout1, rout2 = routes[req[4] + req[5]]
+        time_rout1, time_rout2 = self.time_route_maker(rout1, req), self.time_route_maker(rout2, req)
+        return [time_rout1, time_rout2]
+
+    def can_swim(self, time_interval, req):  # функция определения плотности льда на пути транспортного судна
+        swim_route_1, swim_route_2 = self.ice_density(time_interval[0], req[2]), self.ice_density(time_interval[1],
+                                                                                                  req[2])
+        if swim_route_1 != 403 and swim_route_2 != 403:
+            optimal = sorted([swim_route_1, swim_route_2], key=lambda x: x[-1][2])[0]
+        elif swim_route_1 != 403 or swim_route_2 != 403:
+            optimal = swim_route_1 if swim_route_1 != 403 else swim_route_2
+        else:
+            optimal = [403, sorted([time_interval[0], time_interval[1]], key=lambda x: x[-1][2])[0]]
+        return optimal
+
+    @staticmethod
+    def ice_density(time_rout, req):  # функция определяет плотность льда и возможность прохождения в n-день
+        resp = []  # [rebro, time_start, time_end, status]
+        from data import class_can, ice_can, day_ice
+        for i in time_rout:
+            if i[1].date() == i[2].date():
+                weather = day_ice[i[0] - 1][i[1].day - 1 if i[1].day - 1 <= 29 else i[1].day - 2]
+                if ice_can[int(weather)][class_can[req]] == '3':
+                    return 403
+                resp.append([i[0], i[1], i[2], ice_can[int(weather)][class_can[req]]])
+            elif i[1].date() + datetime.timedelta(days=1) == i[2].date():
+                weather = max([day_ice[i[0] - 1][i[1].day - 1 if i[1].day - 1 <= 29 else i[1].day - 2],
+                               day_ice[i[0] - 1][i[2].day - 1 if i[2].day - 1 <= 29 else i[2].day - 2]])
+                if ice_can[int(weather)][class_can[req]] == '3':
+                    return 403
+                resp.append([i[0], i[1], i[2], ice_can[int(weather)][class_can[req]]])
+            elif i[1].date() + datetime.timedelta(days=2) == i[2].date():
+                weather = max([day_ice[i[0] - 1][i[1].day - 1 if i[1].day - 1 <= 29 else i[1].day - 2],
+                               day_ice[i[0] - 1][i[2].day - 1 if i[2].day - 1 <= 29 else i[2].day - 2],
+                               day_ice[i[0] - 1][i[2].day - 1]])
+                if ice_can[int(weather)][class_can[req]] == '3':
+                    return 403
+                resp.append([i[0], i[1], i[2], ice_can[int(weather)][class_can[req]]])
+        return resp[::-1]
+
+    @staticmethod
+    def make_datetime(req):
+        req[6] = datetime.datetime.strptime(req[6], '%d.%m.%Y %H:%M')
+        req[7] = datetime.datetime.strptime(req[7], '%d.%m.%Y %H:%M')
+        return req
+
+    @staticmethod
+    def time_route_maker(rout, req):
+        from data import edges
+        time_route = []
+        for i in rout:
+            time_rout = [i]
+            time_rout.append(req[6] if rout.index(i) == 0 else time_route[-1][2])
+            time_swim = round((edges[i] / (int(req[3]) * 1.852)) * 60)
+            time_swim = datetime.timedelta(hours=time_swim // 60, minutes=time_swim - 60 * (time_swim // 60))
+            time_rout.append(time_rout[1] + time_swim)
+            time_route.append(time_rout)
+        return time_route[::-1]
+
+    @staticmethod
+    def made_gant(data):
+        from data import skip_status
+        gant_data = []
+        h = 1
+        for i in data:
+            if i[0] == 403:
+                for j in i[1]:
+                    gant_data.append(dict(Task=f'Заявка №{str(h)}', Start=j[1], Finish=j[2], Resource=skip_status[3]))
+            else:
+                for j in i:
+                    gant_data.append(
+                        dict(Task=f'Заявка №{str(h)}', Start=j[1], Finish=j[2], Resource=skip_status[int(j[-1])]))
+            h += 1
+        colors = {'Проход невозможен': 'rgb(220, 0, 0)',
+                  'Нужна проводка': (1, 0.9, 0.16),
+                  'Самостоятельно': 'rgb(0, 255, 100)'}
+
+        fig = ff.create_gantt(gant_data, colors=colors, index_col='Resource', show_colorbar=True,
+                              group_tasks=True)
+        fig.show()
+
+
+def main():
+    from data import icebreakers_requests
+
+    sd = ShipTraffic()
+    sd.parse_reqs(icebreakers_requests)
+
+
+if __name__ == "__main__":
+    main()

+ 23 - 0
ml_time.py

@@ -0,0 +1,23 @@
+import random
+
+import tensorflow as tf
+
+model = tf.keras.Sequential([
+    tf.keras.layers.Dense(100, activation='relu', input_shape=(2,)),
+    tf.keras.layers.Dense(100, activation='relu'),
+    tf.keras.layers.Dense(1)
+])
+
+model.compile(optimizer='adam', loss='mean_squared_error')
+
+speeds = list(map(lambda x: random.randint(1, 100), range(4000)))
+distances = list(map(lambda x: random.randint(1, 100), range(4000)))
+times = list(map(lambda x: speeds[x] / distances[x], range(4000)))
+
+# times = list(map(lambda x: (distances[x] / (int(speeds[x]) * 1.852)) * 60, range(4000)))
+# print(speeds[0], distances[0], times[0])
+
+model.fit(list(zip(speeds, distances)), times, epochs=800)
+
+predicted_time = model.predict([[200, 100]])
+print("Predicted time:", round(float(predicted_time[0])))

+ 10 - 0
readme.md

@@ -0,0 +1,10 @@
+В сентябре 2023 года команда Numerum участвовала в хокатоне: Цифровой прорыв: сезон ИИ. Кейс с атомными ледоколами от росатома. И заняла там 3 место со своеим проектом.
+
+# Запуск программы
+
+Для использования программы запустите файл ShipTraffic.exe, не перемещайте файл в другие каталоги.
+
+Для запуска программы с помощью языка Python, установите необходимые зависимости командой `pip install -r requirements.txt`,
+дождитесь окончания установки, после введите команду запуска кода `python main.py`
+
+Обратите внимание, что перемещение файлов программы приведет к невозможности ее запуска.

BIN
requirements.txt