修改绘图
This commit is contained in:
parent
7ca00525bb
commit
bffda01a6d
Binary file not shown.
Before Width: | Height: | Size: 179 KiB After Width: | Height: | Size: 220 KiB |
File diff suppressed because one or more lines are too long
@ -1,29 +1,26 @@
|
||||
import numpy as np
|
||||
import random
|
||||
from typing import List, Tuple, Dict
|
||||
from typing import Dict, List, Tuple
|
||||
|
||||
def generate_dataset(num_items: int, container_size: Tuple[int, int], seed: int = 2025) -> Dict[str, Tuple[List[Tuple[int, int]], Tuple[int, int]]]:
|
||||
def generate_instance() -> Dict[str, Tuple[List[Tuple[int, int]], Tuple[int, int]]]:
|
||||
"""
|
||||
生成二维装箱问题的数据集
|
||||
|
||||
Args:
|
||||
num_items: 物品数量
|
||||
container_size: 容器的宽度和高度
|
||||
seed: 随机种子,默认为2025
|
||||
Generate a single instance for the 2D Bin Packing Problem.
|
||||
|
||||
Returns:
|
||||
Dict[str, Tuple[List[Tuple[int, int]], Tuple[int, int]]]: 包含物品列表和容器尺寸的字典
|
||||
A dictionary containing:
|
||||
- 'items': A list of tuples, where each tuple represents the (width, height) of an item.
|
||||
- 'bin_dimensions': A tuple representing the (width, height) of the bin.
|
||||
"""
|
||||
random.seed(seed)
|
||||
np.random.seed(seed)
|
||||
np.random.seed(2025) # Set seed for reproducibility
|
||||
|
||||
items = []
|
||||
for _ in range(num_items):
|
||||
width = random.randint(1, container_size[0] // 2)
|
||||
height = random.randint(1, container_size[1] // 2)
|
||||
items.append((width, height))
|
||||
# Generate random item dimensions, ensuring no item exceeds the bin dimensions
|
||||
bin_width, bin_height = 100, 100
|
||||
n_items = 100
|
||||
item_widths = np.random.randint(10, bin_width - 10, size=n_items)
|
||||
item_heights = np.random.randint(10, bin_height - 10, size=n_items)
|
||||
items = list(zip(item_widths, item_heights))
|
||||
bin_dimensions = (bin_width, bin_height)
|
||||
|
||||
return {"data": (items, container_size)}
|
||||
return {"items": items, "bin_dimensions": bin_dimensions}
|
||||
|
||||
class ProblemDataLoader:
|
||||
def __init__(self, problem_path: str):
|
||||
@ -31,12 +28,11 @@ class ProblemDataLoader:
|
||||
|
||||
def get_data(self) -> Dict[str, Tuple[List[Tuple[int, int]], Tuple[int, int]]]:
|
||||
"""
|
||||
加载二维装箱问题的数据集
|
||||
Load the 2D Bin Packing Problem dataset.
|
||||
|
||||
Returns:
|
||||
Dict[str, Tuple[List[Tuple[int, int]], Tuple[int, int]]]: 包含物品列表和容器尺寸的字典
|
||||
A dictionary containing:
|
||||
- 'items': A list of tuples, where each tuple represents the (width, height) of an item.
|
||||
- 'bin_dimensions': A tuple representing the (width, height) of the bin.
|
||||
"""
|
||||
# 使用固定随机种子生成数据集
|
||||
num_items = 10
|
||||
container_size = (100, 100)
|
||||
return generate_dataset(num_items, container_size, seed=2025)
|
||||
return generate_instance()
|
@ -2,99 +2,87 @@ import numpy as np
|
||||
import time
|
||||
from typing import Callable, Dict, List, Tuple
|
||||
|
||||
def evaluate(packing_func: Callable[[Dict[str, Tuple[List[Tuple[int, int]], Tuple[int, int]]]], List[Dict[str, int]]],
|
||||
def evaluate(packing_func: Callable[[Dict[str, Tuple[List[Tuple[int, int]], Tuple[int, int]]]], List[List[Tuple[Tuple[int, int], Tuple[int, int]]]]],
|
||||
input_data: Dict[str, Tuple[List[Tuple[int, int]], Tuple[int, int]]]) -> Dict[str, float]:
|
||||
"""评估二维装箱算法的多目标性能
|
||||
"""
|
||||
Evaluate the performance of a 2D bin packing algorithm.
|
||||
|
||||
Args:
|
||||
packing_func: 装箱算法函数
|
||||
input_data: 一个字典,包含两个部分:
|
||||
- 'data': 一个元组,包含物品列表和容器尺寸
|
||||
packing_func: The bin packing algorithm function.
|
||||
input_data: A dictionary containing:
|
||||
- 'items': A list of tuples, where each tuple represents the (width, height) of an item.
|
||||
- 'bin_dimensions': A tuple representing the (width, height) of the bin.
|
||||
|
||||
Returns:
|
||||
Dict[str, float]: 包含两个目标值的字典:
|
||||
- vacancy_rate: 容器的利用率
|
||||
- execution_time: 运行时间(秒)
|
||||
如果解不合法(物品超出容器边界或重叠)则返回无穷大
|
||||
Dict[str, float]: A dictionary containing:
|
||||
- bins_used: The number of bins used.
|
||||
- execution_time: The execution time in seconds.
|
||||
If the solution is invalid (e.g., items overlap or exceed bin boundaries), returns infinity for both metrics.
|
||||
"""
|
||||
try:
|
||||
# 解包输入数据
|
||||
items, container = input_data["data"]
|
||||
# Extract items and bin dimensions from input_data
|
||||
items = input_data["items"]
|
||||
bin_dimensions = input_data["bin_dimensions"]
|
||||
|
||||
# 计时并执行装箱算法
|
||||
# Measure execution time
|
||||
start_time = time.time()
|
||||
packing_result = packing_func(input_data)
|
||||
print(f"[DEBUG] Packing result: {packing_result}")
|
||||
bins = packing_func(input_data)
|
||||
print(f"[DEBUG] Raw bins returned from packing_func: {bins}")
|
||||
end_time = time.time()
|
||||
execution_time = end_time - start_time
|
||||
|
||||
# 检查解的合法性
|
||||
container_width, container_height = container
|
||||
occupied_area = 0
|
||||
# Validate the solution
|
||||
bin_width, bin_height = bin_dimensions
|
||||
total_bins_used = len(bins)
|
||||
|
||||
# 尝试标准化 packing_result 的结构
|
||||
standardized_result = []
|
||||
for placement in packing_result:
|
||||
if isinstance(placement, tuple) and len(placement) >= 3:
|
||||
x, y, rotated = placement[:3]
|
||||
standardized_result.append({"x": x, "y": y, "rotated": rotated})
|
||||
elif isinstance(placement, dict):
|
||||
standardized_result.append(placement)
|
||||
else:
|
||||
print(f"[ERROR] Invalid packing_result structure: {packing_result}")
|
||||
return {
|
||||
"vacancy_rate": float('inf'),
|
||||
"execution_time": float('inf')
|
||||
}
|
||||
packing_result = standardized_result
|
||||
for bin_content in bins:
|
||||
occupied_area = 0
|
||||
for item in bin_content:
|
||||
corner = item["corner"]
|
||||
width, height = item["dimensions"]
|
||||
x, y = corner
|
||||
|
||||
for item, placement in zip(items, packing_result):
|
||||
item_width, item_height = item
|
||||
x, y, rotated = placement["x"], placement["y"], placement["rotated"]
|
||||
|
||||
if rotated:
|
||||
item_width, item_height = item_height, item_width
|
||||
|
||||
# 检查是否超出容器边界
|
||||
if x + item_width > container_width or y + item_height > container_height:
|
||||
print(f"非法解:物品超出容器边界")
|
||||
return {
|
||||
"vacancy_rate": float('inf'),
|
||||
"execution_time": float('inf')
|
||||
}
|
||||
|
||||
# 检查是否重叠
|
||||
for other_item, other_placement in zip(items, packing_result):
|
||||
if placement == other_placement:
|
||||
continue
|
||||
other_x, other_y, other_rotated = other_placement["x"], other_placement["y"], other_placement["rotated"]
|
||||
other_width, other_height = other_item
|
||||
if other_rotated:
|
||||
other_width, other_height = other_height, other_width
|
||||
|
||||
if not (x + item_width <= other_x or other_x + other_width <= x or
|
||||
y + item_height <= other_y or other_y + other_height <= y):
|
||||
print(f"非法解:物品重叠")
|
||||
# Check if the item exceeds bin boundaries
|
||||
if x + width > bin_width or y + height > bin_height:
|
||||
print(f"Invalid solution: Item at ({x}, {y}) with size ({width}, {height}) exceeds bin boundaries.")
|
||||
return {
|
||||
"vacancy_rate": float('inf'),
|
||||
"bins_used": float('inf'),
|
||||
"execution_time": float('inf')
|
||||
}
|
||||
|
||||
occupied_area += item_width * item_height
|
||||
# Check for overlaps with other items in the same bin
|
||||
for other_corner, (other_width, other_height) in bin_content:
|
||||
if (corner == other_corner):
|
||||
continue
|
||||
other_x, other_y = other_corner
|
||||
if not (x + width <= other_x or other_x + other_width <= x or
|
||||
y + height <= other_y or other_y + other_height <= y):
|
||||
print(f"Invalid solution: Items at ({x}, {y}) and ({other_x}, {other_y}) overlap.")
|
||||
return {
|
||||
"bins_used": float('inf'),
|
||||
"execution_time": float('inf')
|
||||
}
|
||||
|
||||
# 计算容器利用率
|
||||
vacancy_rate = 1 - (occupied_area / (container_width * container_height))
|
||||
occupied_area += width * height
|
||||
|
||||
print(f"执行时间:{execution_time:.4f}秒, 容器空置率:{vacancy_rate:.4f}")
|
||||
# Ensure no item exceeds the bin's capacity
|
||||
if occupied_area > bin_width * bin_height:
|
||||
print(f"Invalid solution: Bin capacity exceeded.")
|
||||
return {
|
||||
"bins_used": float('inf'),
|
||||
"execution_time": float('inf')
|
||||
}
|
||||
|
||||
print(f"Execution time: {execution_time:.4f} seconds, Bins used: {total_bins_used}")
|
||||
|
||||
return {
|
||||
"vacancy_rate": vacancy_rate,
|
||||
"bins_used": total_bins_used,
|
||||
"execution_time": execution_time
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
print(f"评估过程出错: {str(e)}")
|
||||
print(f"Error during evaluation: {str(e)}")
|
||||
return {
|
||||
"vacancy_rate": float('inf'),
|
||||
"bins_used": float('inf'),
|
||||
"execution_time": float('inf')
|
||||
}
|
@ -7,3 +7,12 @@ Generation 0004 | Pareto Front Size: 1 | Timestamp: 2025-05-13T15:56:18.905940
|
||||
Generation 0005 | Pareto Front Size: 1 | Timestamp: 2025-05-13T15:59:55.953455
|
||||
Generation 0006 | Pareto Front Size: 1 | Timestamp: 2025-05-13T16:00:39.951690
|
||||
Generation 0007 | Pareto Front Size: 1 | Timestamp: 2025-05-13T16:02:14.607527
|
||||
Generation 0000 | Pareto Front Size: 2 | Timestamp: 2025-05-15T15:47:17.387937
|
||||
Generation 0000 | Pareto Front Size: 1 | Timestamp: 2025-05-15T15:50:11.979996
|
||||
Generation 0001 | Pareto Front Size: 1 | Timestamp: 2025-05-15T15:52:01.064112
|
||||
Generation 0002 | Pareto Front Size: 1 | Timestamp: 2025-05-15T15:53:46.976949
|
||||
Generation 0003 | Pareto Front Size: 1 | Timestamp: 2025-05-15T15:55:05.807839
|
||||
Generation 0004 | Pareto Front Size: 1 | Timestamp: 2025-05-15T15:56:30.922968
|
||||
Generation 0005 | Pareto Front Size: 1 | Timestamp: 2025-05-15T16:00:15.734229
|
||||
Generation 0006 | Pareto Front Size: 1 | Timestamp: 2025-05-15T16:01:31.540137
|
||||
Generation 0007 | Pareto Front Size: 1 | Timestamp: 2025-05-15T16:05:09.684054
|
||||
|
@ -1,10 +1,10 @@
|
||||
{
|
||||
"description": "尝试开发一个高效的算法用于解决二维装箱问题。你被给定了一组矩形物品和一个固定大小的矩形容器,目标是通过算法的规划将所有物品放入容器中,使得容器的利用率最大化。",
|
||||
"description": "开发一个高效的算法用于解决二维装箱问题。给定一组矩形物品和一个固定大小的矩形容器,目标是通过算法规划将所有物品放入尽可能少的容器中。",
|
||||
"function_name": "solve_bp",
|
||||
"input_format": "一个字典,包含两个部分:\n1. 'data': 一个元组,包含多个矩形物品的列表和一个表示容器宽度和高度的元组。\n - 矩形物品列表的每个元素是一个元组,表示物品的宽度和高度。\n - 容器元组表示容器的宽度和高度。\n",
|
||||
"output_format": "返回一个列表,表示每个物品在容器中的位置和旋转状态。\n每个元素是一个字典,包含以下键:\n1. 'x': 物品左上角的x坐标。\n2. 'y': 物品左上角的y坐标。\n3. 'rotated': 一个布尔值,表示物品是否旋转。",
|
||||
"input_format": "一个字典,包含以下两部分:\n1. 'items': 一个列表,包含多个矩形物品的尺寸,每个物品由其宽度和高度表示为一个元组 (width, height)。\n2. 'bin_dimensions': 一个元组,表示容器的宽度和高度 (width, height)。",
|
||||
"output_format": "返回一个列表,表示每个容器中的物品放置情况。\n每个容器是一个列表,包含多个物品的放置信息,每个物品由以下两部分组成:\n1. corner: 一个元组,表示物品左上角的坐标 (x, y)。\n2. dimensions: 一个元组,表示物品的宽度和高度 (width, height)。",
|
||||
"multi_objective": true,
|
||||
"objective_names": ["vacancy_rate", "execution_time"],
|
||||
"objective_names": ["bins_used", "execution_time"],
|
||||
"evaluation_timeout": 60,
|
||||
"llm_config": {
|
||||
"api_key": "sk-cOqgMkQ605Om9Z28q3UtAfOAtOn7c53tld94Cu01oOEoVTmg",
|
||||
@ -16,7 +16,7 @@
|
||||
"evolution_params": {
|
||||
"algorithm": "MO",
|
||||
"population_size": 2,
|
||||
"generations": 8,
|
||||
"generations": 2,
|
||||
"mutation_rate": 0.5,
|
||||
"crossover_rate": 0.4,
|
||||
"F": 0.8,
|
||||
|
@ -39,6 +39,7 @@ class MultiObjectiveEvaluator:
|
||||
|
||||
# 使用超时控制调用评估函数
|
||||
timeout = Timeout(self.timeout)
|
||||
# print(f"[DEBUG] Dataset structure: {self.dataset}")
|
||||
if self.dataset is not None:
|
||||
results = timeout.run(self.evaluation_module.evaluate, func, self.dataset)
|
||||
else:
|
||||
|
BIN
tsp_data/tsp_pareto.png
Normal file
BIN
tsp_data/tsp_pareto.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 377 KiB |
File diff suppressed because one or more lines are too long
Binary file not shown.
Before Width: | Height: | Size: 283 KiB After Width: | Height: | Size: 686 KiB |
Loading…
x
Reference in New Issue
Block a user