Skip to content

Commit 0552f27

Browse files
authored
Merge pull request #118 from adf-python/docs
ドキュメントの内容の修正
2 parents 5288590 + 0005cb7 commit 0552f27

File tree

4 files changed

+63
-60
lines changed

4 files changed

+63
-60
lines changed

docs/source/hands-on/clustering.md

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## クラスタリングモジュールの目的
44

5-
複数のエージェントを動かす場合は、それらのエージェントにどのように協調させるかが重要になります。RRSでは多くのチームが、エージェントに各々の担当地域を持たせ役割分担をおこなう協調を取り入れています(他の手段による協調も取り入れています)。担当地域を割り振るためには、地図上のオブジェクトをいくつかのグループに分ける必要があります。このようなグループ分けをしてそれらを管理する場合には、クラスタリングモジュールと呼ばれるモジュールを用います。
5+
複数のエージェントを動かす場合は、それらのエージェントにどのように協調させるかが重要になります。RRS では多くのチームが、エージェントに各々の担当地域を持たせ役割分担をおこなう協調を取り入れています(他の手段による協調も取り入れています)。担当地域を割り振るためには、地図上のオブジェクトをいくつかのグループに分ける必要があります。このようなグループ分けをしてそれらを管理する場合には、クラスタリングモジュールと呼ばれるモジュールを用います。
66

77
本資料では、多くの世界大会参加チームが使用しているアルゴリズムを用いたクラスタリングモジュールの実装をおこないます。
88

@@ -11,7 +11,7 @@
1111
本資料で開発するモジュールは下の画像のように、
1212

1313
1. k-means++アルゴリズムによって地図上のオブジェクトをエージェント数分の区画に分けます。
14-
1. Hungarianアルゴリズムによってそれらの区画とエージェントを (間の距離の総和が最も小さくなるように)1対1で結びつけます
14+
1. Hungarian アルゴリズムによってそれらの区画とエージェントを (間の距離の総和が最も小さくなるように)1 対 1 で結びつけます
1515

1616
![クラスタリングの画像](./../images/clustering_image.jpg)
1717

@@ -39,17 +39,19 @@ from adf_core_python.core.agent.info.world_info import WorldInfo
3939
from adf_core_python.core.agent.module.module_manager import ModuleManager
4040
from adf_core_python.core.component.module.algorithm.clustering import Clustering
4141
from adf_core_python.core.logger.logger import get_logger
42-
from rcrs_core.connection.URN import Entity as EntityURN
43-
from rcrs_core.entities.ambulanceCenter import AmbulanceCentre
44-
from rcrs_core.entities.building import Building
45-
from rcrs_core.entities.entity import Entity
46-
from rcrs_core.entities.fireStation import FireStation
47-
from rcrs_core.entities.gasStation import GasStation
48-
from rcrs_core.entities.hydrant import Hydrant
49-
from rcrs_core.entities.policeOffice import PoliceOffice
50-
from rcrs_core.entities.refuge import Refuge
51-
from rcrs_core.entities.road import Road
52-
from rcrs_core.worldmodel.entityID import EntityID
42+
from rcrscore.entities import (
43+
AmbulanceCenter,
44+
Building,
45+
Entity,
46+
EntityID,
47+
FireStation,
48+
GasStation,
49+
Hydrant,
50+
PoliceOffice,
51+
Refuge,
52+
Road,
53+
)
54+
from rcrscore.urn import EntityURN
5355
from scipy.optimize import linear_sum_assignment
5456
from sklearn.cluster import KMeans
5557

@@ -74,7 +76,13 @@ class KMeansPPClustering(Clustering):
7476

7577
# クラスター数の設定
7678
self._cluster_number: int = 1
77-
match agent_info.get_myself().get_urn():
79+
80+
me = agent_info.get_myself()
81+
if not me:
82+
self._logger.error("Myself entity is None.")
83+
return
84+
85+
match me.get_urn():
7886
# エージェントのクラスに応じてクラスター数を設定
7987
case EntityURN.AMBULANCE_TEAM:
8088
self._cluster_number = scenario_info.get_value(
@@ -95,7 +103,7 @@ class KMeansPPClustering(Clustering):
95103
# 自分と同じクラスのエージェントのリストを取得
96104
self._agents: list[Entity] = world_info.get_entities_of_types(
97105
[
98-
agent_info.get_myself().__class__,
106+
me.__class__,
99107
]
100108
)
101109

@@ -105,7 +113,7 @@ class KMeansPPClustering(Clustering):
105113
# クラスタリング対象のエンティティのリストを取得
106114
self._entities: list[Entity] = world_info.get_entities_of_types(
107115
[
108-
AmbulanceCentre,
116+
AmbulanceCenter,
109117
FireStation,
110118
GasStation,
111119
Hydrant,
@@ -180,7 +188,9 @@ class KMeansPPClustering(Clustering):
180188
"""
181189
if cluster_index >= len(self._cluster_entities):
182190
return []
183-
return [entity.get_id() for entity in self._cluster_entities[cluster_index]]
191+
return [
192+
entity.get_entity_id() for entity in self._cluster_entities[cluster_index]
193+
]
184194

185195
def prepare(self) -> Clustering:
186196
"""
@@ -205,17 +215,17 @@ class KMeansPPClustering(Clustering):
205215

206216
# エージェントとクラスターの対応付け結果を保持
207217
self._agent_cluster_indices = {
208-
entity.get_id(): cluster_index
218+
entity.get_entity_id(): cluster_index
209219
for entity, cluster_index in zip(self._agents, agent_cluster_indices)
210220
}
211221

212222
# デバッグ用のログ出力
213223
self._logger.info(
214-
f"Clustered entities: {[[entity.get_id().get_value() for entity in cluster] for cluster in self._cluster_entities]}"
224+
f"Clustered entities: {[[entity.get_entity_id().get_value() for entity in cluster] for cluster in self._cluster_entities]}"
215225
)
216226

217227
self._logger.info(
218-
f"Agent cluster indices: {[([self._world_info.get_entity(entity_id).get_x(), self._world_info.get_entity(entity_id).get_y()], int(cluster_index)) for entity_id, cluster_index in self._agent_cluster_indices.items()]}"
228+
f"Agent cluster indices: {[([e.get_x(), e.get_y()] if (e is not None and e.get_x() is not None and e.get_y() is not None) else [None, None], int(cluster_index)) for entity_id, cluster_index in self._agent_cluster_indices.items() for e in (self._world_info.get_entity(entity_id),)]}"
219229
)
220230

221231
return self
@@ -292,9 +302,9 @@ class KMeansPPClustering(Clustering):
292302
return col_ind
293303
```
294304

295-
k-means++の実装は、scikit-learnの`KMeans`クラスを使用しています。`KMeans`クラスは、`n_clusters`で指定したクラスター数によって地図上のオブジェクトをクラスタリングします。クラスタリング結果は、`labels_`属性に格納されます。また、`cluster_centers_`属性には各クラスターの中心座標が格納されます。
305+
k-means++の実装は、scikit-learn の`KMeans`クラスを使用しています。`KMeans`クラスは、`n_clusters`で指定したクラスター数によって地図上のオブジェクトをクラスタリングします。クラスタリング結果は、`labels_`属性に格納されます。また、`cluster_centers_`属性には各クラスターの中心座標が格納されます。
296306

297-
hungarianアルゴリズムの実装は、scipyの`linear_sum_assignment`関数を使用しています。`linear_sum_assignment`関数は、コスト行列を引数として受け取り、最適な割り当てを行います。
307+
hungarian アルゴリズムの実装は、scipy の`linear_sum_assignment`関数を使用しています。`linear_sum_assignment`関数は、コスト行列を引数として受け取り、最適な割り当てを行います。
298308

299309
次に、作成したモジュールを登録します。`config/module.yaml` を以下のように編集してください。
300310

@@ -307,7 +317,7 @@ SampleHumanDetector:
307317
Clustering: src.<your_team_name>.module.algorithm.k_means_pp_clustering.KMeansPPClustering
308318
```
309319
310-
ターミナルを2つ起動します
320+
ターミナルを 2 つ起動します
311321
312322
片方のターミナルを開き、シミュレーションサーバーを以下のコマンドで起動します:
313323

docs/source/hands-on/search.md

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,6 @@ touch src/<your_team_name>/module/complex/k_means_pp_search.py
2323
import random
2424
from typing import Optional, cast
2525

26-
from rcrs_core.entities.building import Building
27-
from rcrs_core.entities.entity import Entity
28-
from rcrs_core.entities.refuge import Refuge
29-
from rcrs_core.worldmodel.entityID import EntityID
30-
3126
from adf_core_python.core.agent.develop.develop_data import DevelopData
3227
from adf_core_python.core.agent.info.agent_info import AgentInfo
3328
from adf_core_python.core.agent.info.scenario_info import ScenarioInfo
@@ -36,6 +31,7 @@ from adf_core_python.core.agent.module.module_manager import ModuleManager
3631
from adf_core_python.core.component.module.algorithm.clustering import Clustering
3732
from adf_core_python.core.component.module.complex.search import Search
3833
from adf_core_python.core.logger.logger import get_agent_logger
34+
from rcrscore.entities import Building, Entity, Refuge, EntityID
3935

4036

4137
class KMeansPPSearch(Search):
@@ -109,7 +105,7 @@ class KMeansPPSearch(Search):
109105
agent_info, world_info, scenario_info, module_manager, develop_data
110106
)
111107
self._result: Optional[EntityID] = None
112-
108+
113109
# ロガーの取得
114110
self._logger = get_agent_logger(
115111
f"{self.__class__.__module__}.{self.__class__.__qualname__}",
@@ -148,16 +144,16 @@ class KMeansPPSearch(Search):
148144
# 乱数で選択
149145
if cluster_entity_ids:
150146
self._result = random.choice(cluster_entity_ids)
151-
147+
152148
# ログ出力
153149
self._logger.info(f"Target entity ID: {self._result}")
154-
150+
155151
return self
156152
```
157153

158154
以上で、`KMeansPPClustering` モジュールを用いた `KMeansPPSearch` モジュールの実装が完了しました。
159155

160-
ターミナルを2つ起動します
156+
ターミナルを 2 つ起動します
161157

162158
片方のターミナルを開き、シミュレーションサーバーを以下のコマンドで起動します:
163159

@@ -208,7 +204,7 @@ python main.py
208204
一度選択した探索対象に到達するまで、探索対象を変更しないようにする
209205
```
210206

211-
```{admonition} プログラム例
207+
`````{admonition} プログラム例
212208
:class: hint dropdown
213209
214210
````python
@@ -236,12 +232,12 @@ python main.py
236232
# 探索対象が未選択の場合
237233
if not self._result and cluster_entity_ids:
238234
self._result = random.choice(cluster_entity_ids)
239-
235+
240236
# ログ出力
241237
self._logger.info(f"Target entity ID: {self._result}")
242238
243239
return self
244-
```
240+
`````
245241

246242
### すでに探索したエンティティを再度探索対象として選択してしまう問題
247243

@@ -251,7 +247,7 @@ python main.py
251247
すでに探索したエンティティを何かしらの方法で記録し、再度探索対象として選択しないようにする
252248
```
253249

254-
```{admonition} プログラム例
250+
`````{admonition} プログラム例
255251
:class: hint dropdown
256252
257253
````python
@@ -319,12 +315,12 @@ python main.py
319315
# 探索対象が未選択の場合(変更)
320316
if not self._result and self._search_entity_ids:
321317
self._result = random.choice(self._search_entity_ids)
322-
318+
323319
# ログ出力
324320
self._logger.info(f"Target entity ID: {self._result}")
325321
326322
return self
327-
```
323+
`````
328324

329325
### 近くに未探索のエンティティがあるのに、遠くのエンティティを探索対象として選択してしまう
330326

@@ -334,7 +330,7 @@ python main.py
334330
エンティティ間の距離を計算し、もっとも近いエンティティを探索対象として選択する
335331
```
336332

337-
```{admonition} プログラム例
333+
`````{admonition} プログラム例
338334
:class: hint dropdown
339335
340336
````python
@@ -375,9 +371,9 @@ python main.py
375371
nearest_entity_id = entity_id
376372
nearest_distance = distance
377373
self._result = nearest_entity_id
378-
374+
379375
# ログ出力
380376
self._logger.info(f"Target entity ID: {self._result}")
381377
382378
return self
383-
```
379+
`````

0 commit comments

Comments
 (0)