From 2fa19599467263dcf582bb12906e03328e03b4a4 Mon Sep 17 00:00:00 2001
From: zhang <zc857179121@qq.com>
Date: 星期三, 02 七月 2025 13:12:26 +0800
Subject: [PATCH] 初版提交

---
 config/environment.py |  360 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 360 insertions(+), 0 deletions(-)

diff --git a/config/environment.py b/config/environment.py
new file mode 100644
index 0000000..47f42d0
--- /dev/null
+++ b/config/environment.py
@@ -0,0 +1,360 @@
+"""
+鐜閰嶇疆妯″潡 - 璐熻矗瀹氫箟鍔犺浇浠撳簱鐜閰嶇疆
+"""
+import json
+from enum import Enum, auto
+import numpy as np
+from typing import Dict, List, Tuple, Optional, Union
+
+
+class CellType(Enum):
+    """鍗曞厓鏍肩被鍨嬫灇涓�"""
+    EMPTY = auto()  # 绌哄崟鍏冩牸
+    STATION = auto()  # 绔欑偣
+    PATH = auto()  # 璺緞
+    STORAGE = auto()  # 浠撳偍鍖哄煙
+    OBSTACLE = auto()  # 闅滅鐗�
+    LOADING = auto()  # 瑁呰浇鍖�
+    UNLOADING = auto()  # 鍗歌浇鍖�
+
+
+class EnvironmentConfig:
+    """鐜閰嶇疆绫�"""
+    
+    def __init__(self, width: int, height: int):
+        """鍒濆鍖栫幆澧冮厤缃�"""
+        self.width = width
+        self.height = height
+        # 鍒濆鍖栨墍鏈夊崟鍏冩牸涓虹┖
+        self.grid = np.full((height, width), CellType.EMPTY)
+        # 绔欑偣浣嶇疆鍙婂叾閰嶇疆
+        self.stations = {}  # 鏍煎紡: {(x, y): {"capacity": 4, "load_position": (x-1, y), "unload_position": (x+1, y)}}
+        # 璺緞鐐逛綅缃�
+        self.paths = set()  # 鏍煎紡: {(x1, y1), (x2, y2), ...}
+        # 浠撳偍鍖哄煙浣嶇疆
+        self.storage_areas = set()  # 鏍煎紡: {(x1, y1), (x2, y2), ...}
+        # 瑁呭嵏鍖轰綅缃�
+        self.loading_areas = set()  # 鏍煎紡: {(x1, y1), (x2, y2), ...}
+        self.unloading_areas = set()  # 鏍煎紡: {(x1, y1), (x2, y2), ...}
+        # 闅滅鐗╀綅缃�
+        self.obstacles = set()  # 鏍煎紡: {(x1, y1), (x2, y2), ...}
+        # 缃戞牸鐐归偦鎺ヨ〃锛堢敤浜庤矾寰勮鍒掞級
+        self.adjacency_list = {}  # 鏍煎紡: {(x1, y1): {(x2, y2): distance, ...}, ...}
+        
+    def set_cell_type(self, x: int, y: int, cell_type: CellType) -> bool:
+        """
+        璁剧疆鍗曞厓鏍肩被鍨�
+        
+        Args:
+            x: x鍧愭爣
+            y: y鍧愭爣
+            cell_type: 鍗曞厓鏍肩被鍨�
+            
+        Returns:
+            bool: 璁剧疆鏄惁鎴愬姛
+        """
+        if 0 <= x < self.width and 0 <= y < self.height:
+            self.grid[y, x] = cell_type
+            
+            # 鏍规嵁鍗曞厓鏍肩被鍨嬫洿鏂扮浉搴旂殑闆嗗悎
+            pos = (x, y)
+            if cell_type == CellType.PATH:
+                self.paths.add(pos)
+            elif cell_type == CellType.STATION:
+                if pos not in self.stations:
+                    self.stations[pos] = {
+                        "capacity": 4,  # 榛樿瀹归噺
+                        "load_position": (x-1, y),  # 榛樿鍔犺浇浣嶇疆
+                        "unload_position": (x+1, y)  # 榛樿鍗歌浇浣嶇疆
+                    }
+            elif cell_type == CellType.STORAGE:
+                self.storage_areas.add(pos)
+            elif cell_type == CellType.LOADING:
+                self.loading_areas.add(pos)
+            elif cell_type == CellType.UNLOADING:
+                self.unloading_areas.add(pos)
+            elif cell_type == CellType.OBSTACLE:
+                self.obstacles.add(pos)
+            
+            return True
+        return False
+    
+    def add_station(self, x: int, y: int, capacity: int = 4,
+                   load_position: Tuple[int, int] = None,
+                   unload_position: Tuple[int, int] = None) -> bool:
+        """
+        娣诲姞绔欑偣
+        
+        Args:
+            x: 绔欑偣x鍧愭爣
+            y: 绔欑偣y鍧愭爣
+            capacity: 绔欑偣瀹归噺
+            load_position: 鍔犺浇浣嶇疆
+            unload_position: 鍗歌浇浣嶇疆
+            
+        Returns:
+            bool: 娣诲姞鏄惁鎴愬姛
+        """
+        if 0 <= x < self.width and 0 <= y < self.height:
+            # 璁剧疆榛樿鐨勮鍗镐綅缃�
+            if load_position is None:
+                load_position = (x-1, y)  # 宸︿晶涓哄嵏鏂欑浣嶇疆
+            if unload_position is None:
+                unload_position = (x+1, y)  # 鍙充晶涓哄彇鏂欑浣嶇疆
+                
+            # 鏇存柊缃戞牸鍜岀珯鐐逛俊鎭�
+            self.grid[y, x] = CellType.STATION
+            self.stations[(x, y)] = {
+                "capacity": capacity,
+                "load_position": load_position,
+                "unload_position": unload_position
+            }
+            
+            # 纭繚瑁呭嵏浣嶇疆涔熻鏍囪
+            self.set_cell_type(load_position[0], load_position[1], CellType.LOADING)
+            self.set_cell_type(unload_position[0], unload_position[1], CellType.UNLOADING)
+            
+            return True
+        return False
+    
+    def add_path(self, x: int, y: int) -> bool:
+        """
+        娣诲姞璺緞鐐�
+        
+        Args:
+            x: x鍧愭爣
+            y: y鍧愭爣
+            
+        Returns:
+            bool: 娣诲姞鏄惁鎴愬姛
+        """
+        return self.set_cell_type(x, y, CellType.PATH)
+    
+    def add_storage_area(self, x: int, y: int) -> bool:
+        """
+        娣诲姞浠撳偍鍖哄煙
+        
+        Args:
+            x: x鍧愭爣
+            y: y鍧愭爣
+            
+        Returns:
+            bool: 娣诲姞鏄惁鎴愬姛
+        """
+        return self.set_cell_type(x, y, CellType.STORAGE)
+    
+    def add_obstacle(self, x: int, y: int) -> bool:
+        """
+        娣诲姞闅滅鐗�
+        
+        Args:
+            x: x鍧愭爣
+            y: y鍧愭爣
+            
+        Returns:
+            bool: 娣诲姞鏄惁鎴愬姛
+        """
+        return self.set_cell_type(x, y, CellType.OBSTACLE)
+    
+    def is_valid_position(self, x: int, y: int) -> bool:
+        """
+        妫�鏌ヤ綅缃槸鍚﹀悎娉曪紙鍦ㄧ綉鏍煎唴涓旈潪闅滅鐗╋級
+        
+        Args:
+            x: x鍧愭爣
+            y: y鍧愭爣
+            
+        Returns:
+            bool: 浣嶇疆鏄惁鍚堟硶
+        """
+        return (0 <= x < self.width and 
+                0 <= y < self.height and 
+                self.grid[y, x] != CellType.OBSTACLE)
+    
+    def build_adjacency_list(self):
+        """鏋勫缓缃戞牸鐐归偦鎺ヨ〃锛堢敤浜庤矾寰勮鍒掞級"""
+        # 娓呯┖鐜版湁閭绘帴琛�
+        self.adjacency_list = {}
+        
+        # AGV杩涜鍥涙柟鍚戠Щ鍔�
+        directions = [
+            (0, 1),   # 涓�
+            (1, 0),   # 鍙�  
+            (0, -1),  # 涓�
+            (-1, 0)   # 宸�
+        ]
+        
+        # 涓烘瘡涓矾寰勭偣鏋勫缓閭绘帴琛�
+        for x, y in self.paths:
+            if (x, y) not in self.adjacency_list:
+                self.adjacency_list[(x, y)] = {}
+                
+            # 妫�鏌ュ洓涓柟鍚戠殑閭诲眳
+            for dx, dy in directions:
+                nx, ny = x + dx, y + dy
+                # 妫�鏌ョ浉閭荤偣鏄惁涓烘湁鏁堣矾寰勭偣
+                if (nx, ny) in self.paths:
+                    # 绉诲姩璺濈缁熶竴涓�1.0
+                    distance = 1.0
+                    self.adjacency_list[(x, y)][(nx, ny)] = distance
+        
+        # 娣诲姞绔欑偣鐨勮鍗哥偣鍒伴偦鎺ヨ〃
+        for station_pos, station_info in self.stations.items():
+            load_pos = station_info["load_position"]
+            unload_pos = station_info["unload_position"]
+            
+            # 纭繚瑁呭嵏鐐瑰凡娣诲姞鍒伴偦鎺ヨ〃
+            if load_pos not in self.adjacency_list:
+                self.adjacency_list[load_pos] = {}
+            if unload_pos not in self.adjacency_list:
+                self.adjacency_list[unload_pos] = {}
+                
+            # 杩炴帴瑁呭嵏鐐瑰埌鏈�杩戠殑璺緞鐐�
+            for pos in [load_pos, unload_pos]:
+                # 鎵惧埌鏈�杩戠殑璺緞鐐瑰苟杩炴帴
+                min_dist = float('inf')
+                nearest_path = None
+                
+                for path_pos in self.paths:
+                    dist = ((pos[0] - path_pos[0]) ** 2 + (pos[1] - path_pos[1]) ** 2) ** 0.5
+                    if dist < min_dist:
+                        min_dist = dist
+                        nearest_path = path_pos
+                
+                if nearest_path:
+                    self.adjacency_list[pos][nearest_path] = min_dist
+                    self.adjacency_list[nearest_path][pos] = min_dist
+    
+    def save_to_file(self, filepath: str):
+        """
+        灏嗙幆澧冮厤缃繚瀛樺埌鏂囦欢
+        
+        Args:
+            filepath: 鏂囦欢璺緞
+        """
+        config_data = {
+            "width": self.width,
+            "height": self.height,
+            "stations": {f"{x},{y}": info for (x, y), info in self.stations.items()},
+            "paths": [{"x": x, "y": y} for x, y in self.paths],
+            "storage_areas": [{"x": x, "y": y} for x, y in self.storage_areas],
+            "loading_areas": [{"x": x, "y": y} for x, y in self.loading_areas],
+            "unloading_areas": [{"x": x, "y": y} for x, y in self.unloading_areas],
+            "obstacles": [{"x": x, "y": y} for x, y in self.obstacles]
+        }
+        
+        with open(filepath, 'w') as f:
+            json.dump(config_data, f, indent=2)
+    
+    @classmethod
+    def load_from_file(cls, filepath: str) -> 'EnvironmentConfig':
+        """
+        浠庢枃浠跺姞杞界幆澧冮厤缃�
+        
+        Args:
+            filepath: 鏂囦欢璺緞
+            
+        Returns:
+            EnvironmentConfig: 鐜閰嶇疆瀵硅薄
+        """
+        with open(filepath, 'r') as f:
+            config_data = json.load(f)
+        
+        env_config = cls(config_data["width"], config_data["height"])
+        
+        # 鍔犺浇绔欑偣
+        for pos_str, info in config_data["stations"].items():
+            x, y = map(int, pos_str.split(','))
+            load_x, load_y = info["load_position"]
+            unload_x, unload_y = info["unload_position"]
+            env_config.add_station(x, y, info["capacity"], 
+                                  (load_x, load_y), (unload_x, unload_y))
+        
+        # 鍔犺浇璺緞
+        for path in config_data["paths"]:
+            env_config.add_path(path["x"], path["y"])
+        
+        # 鍔犺浇浠撳偍鍖哄煙
+        for area in config_data["storage_areas"]:
+            env_config.add_storage_area(area["x"], area["y"])
+        
+        # 鍔犺浇闅滅鐗�
+        for obstacle in config_data["obstacles"]:
+            env_config.add_obstacle(obstacle["x"], obstacle["y"])
+        
+        # 鏋勫缓閭绘帴琛�
+        env_config.build_adjacency_list()
+        
+        return env_config
+    
+    def create_default_environment(self) -> 'EnvironmentConfig':
+        """
+        鍒涘缓榛樿鐜閰嶇疆锛堟寜鐓ч渶姹傛弿杩伴厤缃珯鐐瑰拰璺緞锛�
+        
+        Returns:
+            EnvironmentConfig: 鐜閰嶇疆瀵硅薄
+        """
+        # 娓呯┖褰撳墠閰嶇疆
+        self.grid = np.full((self.height, self.width), CellType.EMPTY)
+        self.stations = {}
+        self.paths = set()
+        self.storage_areas = set()
+        self.loading_areas = set()
+        self.unloading_areas = set()
+        self.obstacles = set()
+        
+        # 閰嶇疆20涓珯鐐�
+        station_y = self.height - 5 
+        station_spacing = self.width // 25  # 绔欑偣闂磋窛
+        
+        for i in range(20):
+            station_x = (i + 1) * station_spacing
+            self.add_station(station_x, station_y)
+        
+        # 浠撳偍鍖哄煙
+        storage_start_y = 5
+        storage_end_y = station_y - 10
+        
+        for col in range(5):
+            col_x = (col + 1) * (self.width // 6)
+            
+            for row_y in range(storage_start_y, storage_end_y, 5):
+                for dx in range(-1, 2):
+                    for dy in range(-1, 2):
+                        self.add_storage_area(col_x + dx, row_y + dy)
+        
+        # 閰嶇疆璺緞
+        # 姘村钩涓昏矾寰�
+        for x in range(5, self.width - 5):
+            # 绔欑偣鍓嶆按骞宠矾寰�
+            self.add_path(x, station_y - 5)
+            # 璐ф灦鍖哄煙姘村钩璺緞
+            for path_y in range(10, storage_end_y, 10):
+                self.add_path(x, path_y)
+        
+        # 鍨傜洿杩炴帴璺緞
+        for col in range(7):
+            path_x = col * (self.width // 7)
+            for y in range(5, station_y):
+                self.add_path(path_x, y)
+        
+        # 鏋勫缓閭绘帴琛�
+        self.build_adjacency_list()
+        
+        return self
+
+
+# 鍒涘缓鍜屽垵濮嬪寲榛樿鐜鐨勮緟鍔╁嚱鏁�
+def create_default_environment(width=100, height=100) -> EnvironmentConfig:
+    """
+    鍒涘缓榛樿鐜閰嶇疆
+    
+    Args:
+        width: 鐜瀹藉害
+        height: 鐜楂樺害
+        
+    Returns:
+        EnvironmentConfig: 榛樿鐜閰嶇疆
+    """
+    env_config = EnvironmentConfig(width, height)
+    return env_config.create_default_environment()
\ No newline at end of file

--
Gitblit v1.9.1