新增二维装箱问题
This commit is contained in:
parent
805e99b8a1
commit
f96c9c56c7
42
src/lead/problems/bp/dataset/data_loader.py
Normal file
42
src/lead/problems/bp/dataset/data_loader.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import numpy as np
|
||||||
|
import random
|
||||||
|
from typing import List, Tuple, Dict
|
||||||
|
|
||||||
|
def generate_dataset(num_items: int, container_size: Tuple[int, int], seed: int = 2025) -> Dict[str, Tuple[List[Tuple[int, int]], Tuple[int, int]]]:
|
||||||
|
"""
|
||||||
|
生成二维装箱问题的数据集
|
||||||
|
|
||||||
|
Args:
|
||||||
|
num_items: 物品数量
|
||||||
|
container_size: 容器的宽度和高度
|
||||||
|
seed: 随机种子,默认为2025
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, Tuple[List[Tuple[int, int]], Tuple[int, int]]]: 包含物品列表和容器尺寸的字典
|
||||||
|
"""
|
||||||
|
random.seed(seed)
|
||||||
|
np.random.seed(seed)
|
||||||
|
|
||||||
|
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))
|
||||||
|
|
||||||
|
return {"data": (items, container_size)}
|
||||||
|
|
||||||
|
class ProblemDataLoader:
|
||||||
|
def __init__(self, problem_path: str):
|
||||||
|
self.problem_path = problem_path
|
||||||
|
|
||||||
|
def get_data(self) -> Dict[str, Tuple[List[Tuple[int, int]], Tuple[int, int]]]:
|
||||||
|
"""
|
||||||
|
加载二维装箱问题的数据集
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, Tuple[List[Tuple[int, int]], Tuple[int, int]]]: 包含物品列表和容器尺寸的字典
|
||||||
|
"""
|
||||||
|
# 使用固定随机种子生成数据集
|
||||||
|
num_items = 10
|
||||||
|
container_size = (100, 100)
|
||||||
|
return generate_dataset(num_items, container_size, seed=2025)
|
100
src/lead/problems/bp/evaluation.py
Normal file
100
src/lead/problems/bp/evaluation.py
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
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]]],
|
||||||
|
input_data: Dict[str, Tuple[List[Tuple[int, int]], Tuple[int, int]]]) -> Dict[str, float]:
|
||||||
|
"""评估二维装箱算法的多目标性能
|
||||||
|
|
||||||
|
Args:
|
||||||
|
packing_func: 装箱算法函数
|
||||||
|
input_data: 一个字典,包含两个部分:
|
||||||
|
- 'data': 一个元组,包含物品列表和容器尺寸
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, float]: 包含两个目标值的字典:
|
||||||
|
- utilization_rate: 容器的利用率
|
||||||
|
- execution_time: 运行时间(秒)
|
||||||
|
如果解不合法(物品超出容器边界或重叠)则返回无穷大
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# 解包输入数据
|
||||||
|
items, container = input_data["data"]
|
||||||
|
|
||||||
|
# 计时并执行装箱算法
|
||||||
|
start_time = time.time()
|
||||||
|
packing_result = packing_func(input_data)
|
||||||
|
print(f"[DEBUG] Packing result: {packing_result}")
|
||||||
|
end_time = time.time()
|
||||||
|
execution_time = end_time - start_time
|
||||||
|
|
||||||
|
# 检查解的合法性
|
||||||
|
container_width, container_height = container
|
||||||
|
occupied_area = 0
|
||||||
|
|
||||||
|
# 尝试标准化 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 {
|
||||||
|
"utilization_rate": float('inf'),
|
||||||
|
"execution_time": float('inf')
|
||||||
|
}
|
||||||
|
packing_result = standardized_result
|
||||||
|
|
||||||
|
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 {
|
||||||
|
"utilization_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"非法解:物品重叠")
|
||||||
|
return {
|
||||||
|
"utilization_rate": float('inf'),
|
||||||
|
"execution_time": float('inf')
|
||||||
|
}
|
||||||
|
|
||||||
|
occupied_area += item_width * item_height
|
||||||
|
|
||||||
|
# 计算容器利用率
|
||||||
|
vacancy_rate = 1 - (occupied_area / (container_width * container_height))
|
||||||
|
|
||||||
|
print(f"执行时间:{execution_time:.4f}秒, 容器空置率:{vacancy_rate:.4f}")
|
||||||
|
|
||||||
|
return {
|
||||||
|
"vacancy_rate": vacancy_rate,
|
||||||
|
"execution_time": execution_time
|
||||||
|
}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"评估过程出错: {str(e)}")
|
||||||
|
return {
|
||||||
|
"utilization_rate": float('inf'),
|
||||||
|
"execution_time": float('inf')
|
||||||
|
}
|
1
src/lead/problems/bp/multi_objective_evolution.log
Normal file
1
src/lead/problems/bp/multi_objective_evolution.log
Normal file
@ -0,0 +1 @@
|
|||||||
|
Generation 0000 | Pareto Front Size: 12 | Timestamp: 2025-05-13T15:44:39.489046
|
@ -0,0 +1,275 @@
|
|||||||
|
{
|
||||||
|
"generation": 0,
|
||||||
|
"population": [
|
||||||
|
{
|
||||||
|
"code": "def solve_bp(data):\n def rectangle_area(rect):\n return rect[0] * rect[1]\n\n def can_place(rect, x, y, occupied):\n width, height = rect\n for ox, oy, owidth, oheight in occupied:\n if not (x + width <= ox or x >= ox + owidth or y + height <= oy or y >= oy + oheight):\n return False\n return True\n\n def find_position(rect, occupied, container_width, container_height):\n width, height = rect\n for y in range(container_height - height + 1):\n for x in range(container_width - width + 1):\n if can_place(rect, x, y, occupied):\n return x, y\n return None\n\n items, (container_width, container_height) = data['data']\n items_with_info = []\n for idx, (w, h) in enumerate(items):\n area = w * h\n items_with_info.append({'index': idx, 'w': w, 'h': h, 'area': area})\n\n items_with_info.sort(key=lambda x: x['area'], reverse=True)\n\n placed_items = []\n occupied = []\n\n for item in items_with_info:\n w, h = item['w'], item['h']\n position = find_position((w, h), occupied, container_width, container_height)\n rotated = False\n if position:\n x, y = position\n else:\n w_rot, h_rot = h, w\n position = find_position((w_rot, h_rot), occupied, container_width, container_height)\n if position:\n x, y = position\n w, h = w_rot, h_rot\n rotated = True\n else:\n continue\n placed_items.append({\n 'index': item['index'],\n 'x': x,\n 'y': y,\n 'rotated': rotated,\n 'width': w,\n 'height': h\n })\n occupied.append((x, y, w, h))\n\n result = [None] * len(items)\n for p in placed_items:\n idx = p['index']\n result[idx] = {\n 'x': p['x'],\n 'y': p['y'],\n 'rotated': p['rotated']\n }\n return result",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"utilization_rate": Infinity,
|
||||||
|
"execution_time": Infinity
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "使用贪心策略逐个放置最大面积物品到剩余空间中"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "def solve_bp(input_data):\n items, container_size = input_data['data']\n container_width, container_height = container_size\n placements = []\n\n def fit_items(placed_items, remaining_items):\n if not remaining_items:\n return True\n \n item = remaining_items[0]\n width, height = item\n for rotated in [False, True]:\n if rotated:\n width, height = height, width\n \n for x in range(container_width - width + 1):\n for y in range(container_height - height + 1):\n if can_place(placed_items, (x, y, width, height)):\n placed_items.append({'x': x, 'y': y, 'rotated': rotated})\n if fit_items(placed_items, remaining_items[1:]):\n return True\n placed_items.pop()\n\n return False\n\n def can_place(placed_items, new_item):\n new_x, new_y, new_w, new_h = new_item\n for item in placed_items:\n item_x = item['x']\n item_y = item['y']\n item_w = item['rotated'] and item['height'] or item['width']\n item_h = item['rotated'] and item['width'] or item['height']\n\n if not (new_x + new_w <= item_x or new_x >= item_x + item_w or \n new_y + new_h <= item_y or new_y >= item_y + item_h):\n return False\n return True\n\n fit_items([], items)\n return placements",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"utilization_rate": Infinity,
|
||||||
|
"execution_time": Infinity
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "利用分支限界法搜索所有可能的布局以找到最优解"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "import random\n\ndef solve_bp(input_dict):\n items, (W, H) = input_dict['data']\n\n POPSIZE = 50\n GENERATIONS = 150\n MUTATION_RATE = 0.2\n TOURNAMENT_SIZE = 5\n\n def create_individual():\n order = list(range(len(items)))\n random.shuffle(order)\n rotates = [random.choice([False, True]) for _ in items]\n return (order, rotates)\n\n def rect_fits(x, y, w, h):\n return 0 <= x <= W - w and 0 <= y <= H - h\n\n def overlap(r1, r2):\n x1, y1, w1, h1 = r1\n x2, y2, w2, h2 = r2\n return not (x1 + w1 <= x2 or x2 + w2 <= x1 or y1 + h1 <= y2 or y2 + h2 <= y1)\n\n def place_items(order, rotates):\n placed = []\n taken_area = 0\n for idx in order:\n w, h = items[idx]\n if rotates[idx]:\n w, h = h, w\n pos = try_place(w, h, placed)\n if pos is None:\n return None, 0\n x, y = pos\n placed.append((x, y, w, h))\n taken_area += w * h\n return placed, taken_area\n\n def try_place(w, h, placed):\n STEP = 5\n for y in range(0, H - h + 1, STEP):\n for x in range(0, W - w + 1, STEP):\n r = (x, y, w, h)\n if all(not overlap(r, p) for p in placed):\n return (x, y)\n return None\n\n def fitness(ind):\n placed, area = place_items(ind[0], ind[1])\n return area / (W * H), placed\n\n def tournament(pop):\n best = None\n for _ in range(TOURNAMENT_SIZE):\n ind = random.choice(pop)\n if best is None or ind[2] > best[2]:\n best = ind\n return best\n\n def crossover(p1, p2):\n o1, r1 = p1[0][:], p1[1][:]\n o2, r2 = p2[0][:], p2[1][:]\n size = len(o1)\n\n start, end = sorted(random.sample(range(size), 2))\n o1_new = [-1]*size\n o2_new = [-1]*size\n\n o1_new[start:end] = o2[start:end]\n o2_new[start:end] = o1[start:end]\n\n def fill_offspring(o_new, o_old, start, end):\n for i in range(size):\n if i >= start and i < end:\n continue\n candidate = o_old[i]\n while candidate in o_new[start:end]:\n candidate = o_old[o_old.index(candidate)]\n o_new[i] = candidate\n\n fill_offspring(o1_new, o1, start, end)\n fill_offspring(o2_new, o2, start, end)\n\n cross_pt = random.randint(1, size - 1)\n r1_new = r1[:cross_pt] + r2[cross_pt:]\n r2_new = r2[:cross_pt] + r1[cross_pt:]\n\n return (o1_new, r1_new), (o2_new, r2_new)\n\n def mutate(ind):\n order, rotates = ind[0][:], ind[1][:]\n\n for i in range(len(rotates)):\n if random.random() < MUTATION_RATE:\n rotates[i] = not rotates[i]\n\n if random.random() < MUTATION_RATE:\n i, j = random.sample(range(len(order)), 2)\n order[i], order[j] = order[j], order[i]\n\n return (order, rotates)\n\n population = []\n for _ in range(POPSIZE):\n ind = create_individual()\n fit, placed = fitness(ind)\n population.append((ind[0], ind[1], fit, placed))\n\n for _ in range(GENERATIONS):\n new_pop = []\n while len(new_pop) < POPSIZE:\n p1 = tournament(population)\n p2 = tournament(population)\n c1, c2 = crossover((p1[0], p1[1]), (p2[0], p2[1]))\n c1 = mutate(c1)\n c2 = mutate(c2)\n for c in [c1, c2]:\n fit, placed = fitness(c)\n new_pop.append((c[0], c[1], fit, placed))\n if len(new_pop) >= POPSIZE:\n break\n population = sorted(new_pop, key=lambda x: x[2], reverse=True)[:POPSIZE]\n\n best = population[0]\n order, rotates, _, placed = best\n\n pos_dict = [{} for _ in items]\n for i, idx in enumerate(order):\n x, y, w, h = placed[i]\n rotated = rotates[idx]\n pos_dict[idx] = {'x': x, 'y': y, 'rotated': rotated}\n return pos_dict",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"utilization_rate": Infinity,
|
||||||
|
"execution_time": Infinity
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "采用遗传算法模拟物品的组合与位置优化"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "import random\nimport math\n\ndef solve_bp(data):\n items, container_size = data['data']\n container_width, container_height = container_size\n\n def area_used(placed_items):\n return sum(item['width'] * item['height'] for item in placed_items)\n\n def check_fit(item, x, y, placed_items):\n item_width, item_height = item['width'], item['height']\n if x + item_width > container_width or y + item_height > container_height:\n return False\n for placed in placed_items:\n if (x < placed['x'] + placed['width'] and\n x + item_width > placed['x'] and\n y < placed['y'] + placed['height'] and\n y + item_height > placed['y']):\n return False\n return True\n\n def simulated_annealing(items):\n current_solution = []\n for item in items:\n placed = False\n for rotation in [False, True]:\n width, height = (item['width'], item['height']) if not rotation else (item['height'], item['width'])\n for x in range(container_width - width + 1):\n for y in range(container_height - height + 1):\n if check_fit({'width': width, 'height': height}, x, y, current_solution):\n current_solution.append({'x': x, 'y': y, 'rotated': rotation, 'width': width, 'height': height})\n placed = True\n break\n if placed:\n break\n if placed:\n break\n \n return current_solution\n\n result = simulated_annealing([{'width': w, 'height': h} for w, h in items])\n return [{'x': item['x'], 'y': item['y'], 'rotated': item['rotated']} for item in result]",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"utilization_rate": Infinity,
|
||||||
|
"execution_time": Infinity
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "应用模拟退火算法逐步降低布局的空余空间"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "def solve_bp(input_data):\n items, container_size = input_data['data']\n container_width, container_height = container_size\n item_count = len(items)\n \n best_arrangement = []\n max_area_used = 0\n\n def can_place(item, position):\n width, height, rotated = item\n x, y = position\n if rotated:\n width, height = height, width\n return (0 <= x <= container_width - width) and (0 <= y <= container_height - height)\n\n def pack(items_left, positions):\n nonlocal best_arrangement, max_area_used\n\n if not items_left:\n current_area_used = sum(pos['width'] * pos['height'] for pos in positions)\n if current_area_used > max_area_used:\n max_area_used = current_area_used\n best_arrangement = positions[:]\n return\n\n item = items_left[0]\n width, height = item\n for y in range(container_height):\n for x in range(container_width):\n for rotated in [False, True]:\n if can_place(item, (x, y)):\n new_position = {'x': x, 'y': y, 'rotated': rotated, 'width': width if not rotated else height, 'height': height if not rotated else width}\n pack(items_left[1:], positions + [new_position])\n\n pack(items, [])\n \n return best_arrangement",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"utilization_rate": Infinity,
|
||||||
|
"execution_time": Infinity
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "使用动态规划判断子空间的最佳装载方案"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "def solve_bp(input_data):\n items, container_size = input_data['data']\n container_width, container_height = container_size\n placements = []\n\n def can_place(item, x, y, rotated):\n width, height = item[1], item[0] if rotated else item\n return x + width <= container_width and y + height <= container_height\n\n def place_item(item, x, y, rotated):\n width, height = item[1], item[0] if rotated else item\n placements.append({'x': x, 'y': y, 'rotated': rotated})\n\n def recursive_backtrack(remaining_items, current_x, current_y):\n if not remaining_items:\n return True\n\n for i, item in enumerate(remaining_items):\n for rotated in (False, True):\n if can_place(item, current_x, current_y, rotated):\n place_item(item, current_x, current_y, rotated)\n \n next_x = current_x + (item[1] if rotated else item[0])\n next_y = current_y\n\n if next_x >= container_width:\n next_x = 0\n next_y += max(item[0], item[1]) if rotated else min(item[0], item[1])\n \n if next_y < container_height:\n if recursive_backtrack(remaining_items[:i] + remaining_items[i+1:], next_x, next_y):\n return True\n \n placements.pop()\n\n return False\n\n recursive_backtrack(items, 0, 0)\n return placements",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"utilization_rate": Infinity,
|
||||||
|
"execution_time": Infinity
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "基于矩形分割的递归空间划分与放置策略"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "def solve_bp(input_dict):\n items, (W, H) = input_dict['data']\n \n def score(item):\n w, h = item\n return w*h*1000 + abs(w - h)\n items_sorted = sorted(enumerate(items), key=lambda x: score(x[1]), reverse=True)\n \n placed = [None]*len(items)\n \n skyline = [(0, 0, W)]\n \n def find_position(w, h):\n best_x, best_y = None, None\n best_y_min = None\n for i in range(len(skyline)):\n x_start, y, width = skyline[i]\n if width >= w:\n x_end = x_start + w\n max_y = y\n curr_x = x_start\n j = i\n cover_width = 0\n while cover_width < w and j < len(skyline):\n xs, ys, ws = skyline[j]\n seg_end = xs + ws\n seg_cover = min(seg_end, x_start+w) - curr_x\n if seg_cover <= 0:\n break\n max_y = max(max_y, ys)\n cover_width += seg_cover\n curr_x += seg_cover\n j += 1\n if cover_width >= w and max_y + h <= H:\n if best_y_min is None or max_y < best_y_min or (max_y == best_y_min and x_start < best_x):\n best_y_min = max_y\n best_x = x_start\n best_y = max_y\n return best_x, best_y\n \n def update_skyline(x, y, w):\n new_skyline = []\n i = 0\n while i < len(skyline):\n sx, sy, sw = skyline[i]\n if sx + sw <= x:\n new_skyline.append((sx, sy, sw))\n i += 1\n elif sx >= x + w:\n break\n else:\n if sx < x:\n new_skyline.append((sx, sy, x - sx))\n if sx + sw > x + w:\n skyline[i] = (x + w, sy, sx + sw - (x + w))\n i -= 1\n i += 1\n break\n new_skyline.append((x, y, w))\n while i < len(skyline):\n new_skyline.append(skyline[i])\n i += 1\n \n merged = []\n for seg in new_skyline:\n if merged and merged[-1][1] == seg[1]:\n merged[-1] = (merged[-1][0], merged[-1][1], merged[-1][2]+seg[2])\n else:\n merged.append(seg)\n return merged\n \n def try_place(i, w, h):\n x, y = find_position(w, h)\n if x is None:\n return None\n nonlocal skyline\n skyline = update_skyline(x, y + h, w)\n return {'x': x, 'y': y, 'rotated': False}\n \n def try_place_rotated(i, w, h):\n x, y = find_position(h, w)\n if x is None:\n return None\n nonlocal skyline\n skyline = update_skyline(x, y + w, h)\n return {'x': x, 'y': y, 'rotated': True}\n \n for idx, (w, h) in items_sorted:\n pos = try_place(idx, w, h)\n if pos is None:\n pos = try_place_rotated(idx, w, h)\n if pos is None:\n pos = {'x': -1, 'y': -1, 'rotated': False}\n placed[idx] = pos\n \n return placed",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"utilization_rate": Infinity,
|
||||||
|
"execution_time": Infinity
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "实现启发式排序,将面积大或形状特殊的物品优先放入"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "def solve_bp(input_data):\n items, container_size = input_data['data']\n container_width, container_height = container_size\n placements = []\n best_placement = []\n\n def can_place(x, y, item_width, item_height):\n if x + item_width > container_width or y + item_height > container_height:\n return False\n for placement in placements:\n if (x < placement['x'] + placement['width'] and\n x + item_width > placement['x'] and\n y < placement['y'] + placement['height'] and\n y + item_height > placement['y']):\n return False\n return True\n\n def place_item(x, y, width, height, rotated):\n placements.append({\n 'x': x,\n 'y': y,\n 'width': width,\n 'height': height,\n 'rotated': rotated\n })\n\n def remove_item():\n placements.pop()\n\n def backtrack(index):\n if index == len(items):\n nonlocal best_placement\n if len(placements) > len(best_placement):\n best_placement = placements.copy()\n return\n\n item_width, item_height = items[index]\n for x in range(container_width):\n for y in range(container_height):\n if can_place(x, y, item_width, item_height):\n place_item(x, y, item_width, item_height, False)\n backtrack(index + 1)\n remove_item()\n \n if can_place(x, y, item_height, item_width):\n place_item(x, y, item_height, item_width, True)\n backtrack(index + 1)\n remove_item()\n\n backtrack(0)\n\n return [{'x': p['x'], 'y': p['y'], 'rotated': p['rotated']} for p in best_placement]",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"utilization_rate": Infinity,
|
||||||
|
"execution_time": Infinity
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "利用剪枝技术在搜索过程中提前排除不可行布局"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "def solve_bp(input_data):\n items, container_size = input_data['data']\n container_width, container_height = container_size\n placed_items = []\n \n def can_place(x, y, width, height):\n if x + width > container_width or y + height > container_height:\n return False\n for item in placed_items:\n if not (x + width <= item['x'] or x >= item['x'] + item['width'] or\n y + height <= item['y'] or y >= item['y'] + item['height']):\n return False\n return True\n\n def place_item(x, y, width, height, rotated):\n placed_items.append({\n 'x': x,\n 'y': y,\n 'width': width,\n 'height': height,\n 'rotated': rotated\n })\n \n def arrange_items():\n for width, height in items:\n rotated = False\n if not can_place(0, 0, width, height):\n if can_place(0, 0, height, width):\n width, height = height, width\n rotated = True\n\n placed = False\n for x in range(container_width + 1 - width):\n for y in range(container_height + 1 - height):\n if can_place(x, y, width, height):\n place_item(x, y, width, height, rotated)\n placed = True\n break\n if placed:\n break\n \n arrange_items()\n \n result = [{'x': item['x'], 'y': item['y'], 'rotated': item['rotated']} for item in placed_items]\n return result",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"utilization_rate": Infinity,
|
||||||
|
"execution_time": Infinity
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "结合局部搜索优化已有的装箱布局以提升空间利用率"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "def solve_bp(input_data):\n items, container_size = input_data['data']\n container_width, container_height = container_size\n\n grid_size = 10\n grid = [[None for _ in range(container_width // grid_size + 1)] for _ in range(container_height // grid_size + 1)]\n\n def can_place(item, x, y, rotated):\n width, height = (item[1], item[0]) if rotated else item\n if x + width > container_width or y + height > container_height:\n return False\n for i in range(y // grid_size, (y + height) // grid_size + 1):\n for j in range(x // grid_size, (x + width) // grid_size + 1):\n if grid[i][j] is not None:\n return False\n return True\n\n def place_item(item, x, y, rotated):\n width, height = (item[1], item[0]) if rotated else item\n for i in range(y // grid_size, (y + height) // grid_size + 1):\n for j in range(x // grid_size, (x + width) // grid_size + 1):\n grid[i][j] = item\n\n placements = []\n \n for item in items:\n placed = False\n for rotated in [False, True]:\n width, height = (item[1], item[0]) if rotated else item\n for y in range(0, container_height - height + 1, grid_size):\n for x in range(0, container_width - width + 1, grid_size):\n if can_place(item, x, y, rotated):\n place_item(item, x, y, rotated)\n placements.append({'x': x, 'y': y, 'rotated': rotated})\n placed = True\n break\n if placed:\n break\n if placed:\n break\n\n return placements",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"utilization_rate": Infinity,
|
||||||
|
"execution_time": Infinity
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "引入多层次网格划分,逐层细化装箱方案"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "import random\n\ndef solve_bp(params):\n data = params['data']\n items, container_size = data\n container_width, container_height = container_size\n \n items = sorted(items, key=lambda item: item[0] * item[1], reverse=True)\n positions = []\n \n def can_place(x, y, width, height):\n if x + width > container_width or y + height > container_height:\n return False\n for pos in positions:\n if (x < pos['x'] + (pos['rotated'] * pos['height'] or pos['width']) and\n x + width > pos['x'] and\n y < pos['y'] + (pos['rotated'] * pos['width'] or pos['height']) and\n y + height > pos['y']):\n return False\n return True\n\n def place_item(width, height, rotated):\n for x in range(container_width):\n for y in range(container_height):\n if can_place(x, y, width, height):\n return {'x': x, 'y': y, 'rotated': rotated}\n return None\n\n for width, height in items:\n placed = place_item(width, height, False)\n if not placed:\n placed = place_item(height, width, True)\n if placed:\n positions.append(placed)\n \n return positions",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"utilization_rate": Infinity,
|
||||||
|
"execution_time": Infinity
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "利用机器学习模型预测最佳物品排序和放置顺序"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "def solve_bp(data):\n items, (container_width, container_height) = data['data']\n positions = []\n used_space = [[False] * container_width for _ in range(container_height)]\n\n def can_place(x, y, width, height):\n if x + width > container_width or y + height > container_height:\n return False\n for i in range(y, y + height):\n for j in range(x, x + width):\n if used_space[i][j]:\n return False\n return True\n\n def place_item(x, y, width, height):\n for i in range(y, y + height):\n for j in range(x, x + width):\n used_space[i][j] = True\n\n for width, height in items:\n placed = False\n \n for y in range(container_height):\n for x in range(container_width):\n if can_place(x, y, width, height):\n positions.append({'x': x, 'y': y, 'rotated': False})\n place_item(x, y, width, height)\n placed = True\n break\n if placed:\n break\n\n if not placed:\n for y in range(container_height):\n for x in range(container_width):\n if can_place(x, y, height, width):\n positions.append({'x': x, 'y': y, 'rotated': True})\n place_item(x, y, height, width)\n placed = True\n break\n if placed:\n break\n\n return positions",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"utilization_rate": Infinity,
|
||||||
|
"execution_time": Infinity
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "采用混合算法,结合启发式与精确算法进行优化"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pareto_front": [
|
||||||
|
{
|
||||||
|
"code": "def solve_bp(data):\n def rectangle_area(rect):\n return rect[0] * rect[1]\n\n def can_place(rect, x, y, occupied):\n width, height = rect\n for ox, oy, owidth, oheight in occupied:\n if not (x + width <= ox or x >= ox + owidth or y + height <= oy or y >= oy + oheight):\n return False\n return True\n\n def find_position(rect, occupied, container_width, container_height):\n width, height = rect\n for y in range(container_height - height + 1):\n for x in range(container_width - width + 1):\n if can_place(rect, x, y, occupied):\n return x, y\n return None\n\n items, (container_width, container_height) = data['data']\n items_with_info = []\n for idx, (w, h) in enumerate(items):\n area = w * h\n items_with_info.append({'index': idx, 'w': w, 'h': h, 'area': area})\n\n items_with_info.sort(key=lambda x: x['area'], reverse=True)\n\n placed_items = []\n occupied = []\n\n for item in items_with_info:\n w, h = item['w'], item['h']\n position = find_position((w, h), occupied, container_width, container_height)\n rotated = False\n if position:\n x, y = position\n else:\n w_rot, h_rot = h, w\n position = find_position((w_rot, h_rot), occupied, container_width, container_height)\n if position:\n x, y = position\n w, h = w_rot, h_rot\n rotated = True\n else:\n continue\n placed_items.append({\n 'index': item['index'],\n 'x': x,\n 'y': y,\n 'rotated': rotated,\n 'width': w,\n 'height': h\n })\n occupied.append((x, y, w, h))\n\n result = [None] * len(items)\n for p in placed_items:\n idx = p['index']\n result[idx] = {\n 'x': p['x'],\n 'y': p['y'],\n 'rotated': p['rotated']\n }\n return result",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"utilization_rate": Infinity,
|
||||||
|
"execution_time": Infinity
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "使用贪心策略逐个放置最大面积物品到剩余空间中"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "def solve_bp(input_data):\n items, container_size = input_data['data']\n container_width, container_height = container_size\n placements = []\n\n def fit_items(placed_items, remaining_items):\n if not remaining_items:\n return True\n \n item = remaining_items[0]\n width, height = item\n for rotated in [False, True]:\n if rotated:\n width, height = height, width\n \n for x in range(container_width - width + 1):\n for y in range(container_height - height + 1):\n if can_place(placed_items, (x, y, width, height)):\n placed_items.append({'x': x, 'y': y, 'rotated': rotated})\n if fit_items(placed_items, remaining_items[1:]):\n return True\n placed_items.pop()\n\n return False\n\n def can_place(placed_items, new_item):\n new_x, new_y, new_w, new_h = new_item\n for item in placed_items:\n item_x = item['x']\n item_y = item['y']\n item_w = item['rotated'] and item['height'] or item['width']\n item_h = item['rotated'] and item['width'] or item['height']\n\n if not (new_x + new_w <= item_x or new_x >= item_x + item_w or \n new_y + new_h <= item_y or new_y >= item_y + item_h):\n return False\n return True\n\n fit_items([], items)\n return placements",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"utilization_rate": Infinity,
|
||||||
|
"execution_time": Infinity
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "利用分支限界法搜索所有可能的布局以找到最优解"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "import random\n\ndef solve_bp(input_dict):\n items, (W, H) = input_dict['data']\n\n POPSIZE = 50\n GENERATIONS = 150\n MUTATION_RATE = 0.2\n TOURNAMENT_SIZE = 5\n\n def create_individual():\n order = list(range(len(items)))\n random.shuffle(order)\n rotates = [random.choice([False, True]) for _ in items]\n return (order, rotates)\n\n def rect_fits(x, y, w, h):\n return 0 <= x <= W - w and 0 <= y <= H - h\n\n def overlap(r1, r2):\n x1, y1, w1, h1 = r1\n x2, y2, w2, h2 = r2\n return not (x1 + w1 <= x2 or x2 + w2 <= x1 or y1 + h1 <= y2 or y2 + h2 <= y1)\n\n def place_items(order, rotates):\n placed = []\n taken_area = 0\n for idx in order:\n w, h = items[idx]\n if rotates[idx]:\n w, h = h, w\n pos = try_place(w, h, placed)\n if pos is None:\n return None, 0\n x, y = pos\n placed.append((x, y, w, h))\n taken_area += w * h\n return placed, taken_area\n\n def try_place(w, h, placed):\n STEP = 5\n for y in range(0, H - h + 1, STEP):\n for x in range(0, W - w + 1, STEP):\n r = (x, y, w, h)\n if all(not overlap(r, p) for p in placed):\n return (x, y)\n return None\n\n def fitness(ind):\n placed, area = place_items(ind[0], ind[1])\n return area / (W * H), placed\n\n def tournament(pop):\n best = None\n for _ in range(TOURNAMENT_SIZE):\n ind = random.choice(pop)\n if best is None or ind[2] > best[2]:\n best = ind\n return best\n\n def crossover(p1, p2):\n o1, r1 = p1[0][:], p1[1][:]\n o2, r2 = p2[0][:], p2[1][:]\n size = len(o1)\n\n start, end = sorted(random.sample(range(size), 2))\n o1_new = [-1]*size\n o2_new = [-1]*size\n\n o1_new[start:end] = o2[start:end]\n o2_new[start:end] = o1[start:end]\n\n def fill_offspring(o_new, o_old, start, end):\n for i in range(size):\n if i >= start and i < end:\n continue\n candidate = o_old[i]\n while candidate in o_new[start:end]:\n candidate = o_old[o_old.index(candidate)]\n o_new[i] = candidate\n\n fill_offspring(o1_new, o1, start, end)\n fill_offspring(o2_new, o2, start, end)\n\n cross_pt = random.randint(1, size - 1)\n r1_new = r1[:cross_pt] + r2[cross_pt:]\n r2_new = r2[:cross_pt] + r1[cross_pt:]\n\n return (o1_new, r1_new), (o2_new, r2_new)\n\n def mutate(ind):\n order, rotates = ind[0][:], ind[1][:]\n\n for i in range(len(rotates)):\n if random.random() < MUTATION_RATE:\n rotates[i] = not rotates[i]\n\n if random.random() < MUTATION_RATE:\n i, j = random.sample(range(len(order)), 2)\n order[i], order[j] = order[j], order[i]\n\n return (order, rotates)\n\n population = []\n for _ in range(POPSIZE):\n ind = create_individual()\n fit, placed = fitness(ind)\n population.append((ind[0], ind[1], fit, placed))\n\n for _ in range(GENERATIONS):\n new_pop = []\n while len(new_pop) < POPSIZE:\n p1 = tournament(population)\n p2 = tournament(population)\n c1, c2 = crossover((p1[0], p1[1]), (p2[0], p2[1]))\n c1 = mutate(c1)\n c2 = mutate(c2)\n for c in [c1, c2]:\n fit, placed = fitness(c)\n new_pop.append((c[0], c[1], fit, placed))\n if len(new_pop) >= POPSIZE:\n break\n population = sorted(new_pop, key=lambda x: x[2], reverse=True)[:POPSIZE]\n\n best = population[0]\n order, rotates, _, placed = best\n\n pos_dict = [{} for _ in items]\n for i, idx in enumerate(order):\n x, y, w, h = placed[i]\n rotated = rotates[idx]\n pos_dict[idx] = {'x': x, 'y': y, 'rotated': rotated}\n return pos_dict",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"utilization_rate": Infinity,
|
||||||
|
"execution_time": Infinity
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "采用遗传算法模拟物品的组合与位置优化"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "import random\nimport math\n\ndef solve_bp(data):\n items, container_size = data['data']\n container_width, container_height = container_size\n\n def area_used(placed_items):\n return sum(item['width'] * item['height'] for item in placed_items)\n\n def check_fit(item, x, y, placed_items):\n item_width, item_height = item['width'], item['height']\n if x + item_width > container_width or y + item_height > container_height:\n return False\n for placed in placed_items:\n if (x < placed['x'] + placed['width'] and\n x + item_width > placed['x'] and\n y < placed['y'] + placed['height'] and\n y + item_height > placed['y']):\n return False\n return True\n\n def simulated_annealing(items):\n current_solution = []\n for item in items:\n placed = False\n for rotation in [False, True]:\n width, height = (item['width'], item['height']) if not rotation else (item['height'], item['width'])\n for x in range(container_width - width + 1):\n for y in range(container_height - height + 1):\n if check_fit({'width': width, 'height': height}, x, y, current_solution):\n current_solution.append({'x': x, 'y': y, 'rotated': rotation, 'width': width, 'height': height})\n placed = True\n break\n if placed:\n break\n if placed:\n break\n \n return current_solution\n\n result = simulated_annealing([{'width': w, 'height': h} for w, h in items])\n return [{'x': item['x'], 'y': item['y'], 'rotated': item['rotated']} for item in result]",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"utilization_rate": Infinity,
|
||||||
|
"execution_time": Infinity
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "应用模拟退火算法逐步降低布局的空余空间"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "def solve_bp(input_data):\n items, container_size = input_data['data']\n container_width, container_height = container_size\n item_count = len(items)\n \n best_arrangement = []\n max_area_used = 0\n\n def can_place(item, position):\n width, height, rotated = item\n x, y = position\n if rotated:\n width, height = height, width\n return (0 <= x <= container_width - width) and (0 <= y <= container_height - height)\n\n def pack(items_left, positions):\n nonlocal best_arrangement, max_area_used\n\n if not items_left:\n current_area_used = sum(pos['width'] * pos['height'] for pos in positions)\n if current_area_used > max_area_used:\n max_area_used = current_area_used\n best_arrangement = positions[:]\n return\n\n item = items_left[0]\n width, height = item\n for y in range(container_height):\n for x in range(container_width):\n for rotated in [False, True]:\n if can_place(item, (x, y)):\n new_position = {'x': x, 'y': y, 'rotated': rotated, 'width': width if not rotated else height, 'height': height if not rotated else width}\n pack(items_left[1:], positions + [new_position])\n\n pack(items, [])\n \n return best_arrangement",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"utilization_rate": Infinity,
|
||||||
|
"execution_time": Infinity
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "使用动态规划判断子空间的最佳装载方案"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "def solve_bp(input_data):\n items, container_size = input_data['data']\n container_width, container_height = container_size\n placements = []\n\n def can_place(item, x, y, rotated):\n width, height = item[1], item[0] if rotated else item\n return x + width <= container_width and y + height <= container_height\n\n def place_item(item, x, y, rotated):\n width, height = item[1], item[0] if rotated else item\n placements.append({'x': x, 'y': y, 'rotated': rotated})\n\n def recursive_backtrack(remaining_items, current_x, current_y):\n if not remaining_items:\n return True\n\n for i, item in enumerate(remaining_items):\n for rotated in (False, True):\n if can_place(item, current_x, current_y, rotated):\n place_item(item, current_x, current_y, rotated)\n \n next_x = current_x + (item[1] if rotated else item[0])\n next_y = current_y\n\n if next_x >= container_width:\n next_x = 0\n next_y += max(item[0], item[1]) if rotated else min(item[0], item[1])\n \n if next_y < container_height:\n if recursive_backtrack(remaining_items[:i] + remaining_items[i+1:], next_x, next_y):\n return True\n \n placements.pop()\n\n return False\n\n recursive_backtrack(items, 0, 0)\n return placements",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"utilization_rate": Infinity,
|
||||||
|
"execution_time": Infinity
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "基于矩形分割的递归空间划分与放置策略"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "def solve_bp(input_dict):\n items, (W, H) = input_dict['data']\n \n def score(item):\n w, h = item\n return w*h*1000 + abs(w - h)\n items_sorted = sorted(enumerate(items), key=lambda x: score(x[1]), reverse=True)\n \n placed = [None]*len(items)\n \n skyline = [(0, 0, W)]\n \n def find_position(w, h):\n best_x, best_y = None, None\n best_y_min = None\n for i in range(len(skyline)):\n x_start, y, width = skyline[i]\n if width >= w:\n x_end = x_start + w\n max_y = y\n curr_x = x_start\n j = i\n cover_width = 0\n while cover_width < w and j < len(skyline):\n xs, ys, ws = skyline[j]\n seg_end = xs + ws\n seg_cover = min(seg_end, x_start+w) - curr_x\n if seg_cover <= 0:\n break\n max_y = max(max_y, ys)\n cover_width += seg_cover\n curr_x += seg_cover\n j += 1\n if cover_width >= w and max_y + h <= H:\n if best_y_min is None or max_y < best_y_min or (max_y == best_y_min and x_start < best_x):\n best_y_min = max_y\n best_x = x_start\n best_y = max_y\n return best_x, best_y\n \n def update_skyline(x, y, w):\n new_skyline = []\n i = 0\n while i < len(skyline):\n sx, sy, sw = skyline[i]\n if sx + sw <= x:\n new_skyline.append((sx, sy, sw))\n i += 1\n elif sx >= x + w:\n break\n else:\n if sx < x:\n new_skyline.append((sx, sy, x - sx))\n if sx + sw > x + w:\n skyline[i] = (x + w, sy, sx + sw - (x + w))\n i -= 1\n i += 1\n break\n new_skyline.append((x, y, w))\n while i < len(skyline):\n new_skyline.append(skyline[i])\n i += 1\n \n merged = []\n for seg in new_skyline:\n if merged and merged[-1][1] == seg[1]:\n merged[-1] = (merged[-1][0], merged[-1][1], merged[-1][2]+seg[2])\n else:\n merged.append(seg)\n return merged\n \n def try_place(i, w, h):\n x, y = find_position(w, h)\n if x is None:\n return None\n nonlocal skyline\n skyline = update_skyline(x, y + h, w)\n return {'x': x, 'y': y, 'rotated': False}\n \n def try_place_rotated(i, w, h):\n x, y = find_position(h, w)\n if x is None:\n return None\n nonlocal skyline\n skyline = update_skyline(x, y + w, h)\n return {'x': x, 'y': y, 'rotated': True}\n \n for idx, (w, h) in items_sorted:\n pos = try_place(idx, w, h)\n if pos is None:\n pos = try_place_rotated(idx, w, h)\n if pos is None:\n pos = {'x': -1, 'y': -1, 'rotated': False}\n placed[idx] = pos\n \n return placed",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"utilization_rate": Infinity,
|
||||||
|
"execution_time": Infinity
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "实现启发式排序,将面积大或形状特殊的物品优先放入"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "def solve_bp(input_data):\n items, container_size = input_data['data']\n container_width, container_height = container_size\n placements = []\n best_placement = []\n\n def can_place(x, y, item_width, item_height):\n if x + item_width > container_width or y + item_height > container_height:\n return False\n for placement in placements:\n if (x < placement['x'] + placement['width'] and\n x + item_width > placement['x'] and\n y < placement['y'] + placement['height'] and\n y + item_height > placement['y']):\n return False\n return True\n\n def place_item(x, y, width, height, rotated):\n placements.append({\n 'x': x,\n 'y': y,\n 'width': width,\n 'height': height,\n 'rotated': rotated\n })\n\n def remove_item():\n placements.pop()\n\n def backtrack(index):\n if index == len(items):\n nonlocal best_placement\n if len(placements) > len(best_placement):\n best_placement = placements.copy()\n return\n\n item_width, item_height = items[index]\n for x in range(container_width):\n for y in range(container_height):\n if can_place(x, y, item_width, item_height):\n place_item(x, y, item_width, item_height, False)\n backtrack(index + 1)\n remove_item()\n \n if can_place(x, y, item_height, item_width):\n place_item(x, y, item_height, item_width, True)\n backtrack(index + 1)\n remove_item()\n\n backtrack(0)\n\n return [{'x': p['x'], 'y': p['y'], 'rotated': p['rotated']} for p in best_placement]",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"utilization_rate": Infinity,
|
||||||
|
"execution_time": Infinity
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "利用剪枝技术在搜索过程中提前排除不可行布局"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "def solve_bp(input_data):\n items, container_size = input_data['data']\n container_width, container_height = container_size\n placed_items = []\n \n def can_place(x, y, width, height):\n if x + width > container_width or y + height > container_height:\n return False\n for item in placed_items:\n if not (x + width <= item['x'] or x >= item['x'] + item['width'] or\n y + height <= item['y'] or y >= item['y'] + item['height']):\n return False\n return True\n\n def place_item(x, y, width, height, rotated):\n placed_items.append({\n 'x': x,\n 'y': y,\n 'width': width,\n 'height': height,\n 'rotated': rotated\n })\n \n def arrange_items():\n for width, height in items:\n rotated = False\n if not can_place(0, 0, width, height):\n if can_place(0, 0, height, width):\n width, height = height, width\n rotated = True\n\n placed = False\n for x in range(container_width + 1 - width):\n for y in range(container_height + 1 - height):\n if can_place(x, y, width, height):\n place_item(x, y, width, height, rotated)\n placed = True\n break\n if placed:\n break\n \n arrange_items()\n \n result = [{'x': item['x'], 'y': item['y'], 'rotated': item['rotated']} for item in placed_items]\n return result",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"utilization_rate": Infinity,
|
||||||
|
"execution_time": Infinity
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "结合局部搜索优化已有的装箱布局以提升空间利用率"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "def solve_bp(input_data):\n items, container_size = input_data['data']\n container_width, container_height = container_size\n\n grid_size = 10\n grid = [[None for _ in range(container_width // grid_size + 1)] for _ in range(container_height // grid_size + 1)]\n\n def can_place(item, x, y, rotated):\n width, height = (item[1], item[0]) if rotated else item\n if x + width > container_width or y + height > container_height:\n return False\n for i in range(y // grid_size, (y + height) // grid_size + 1):\n for j in range(x // grid_size, (x + width) // grid_size + 1):\n if grid[i][j] is not None:\n return False\n return True\n\n def place_item(item, x, y, rotated):\n width, height = (item[1], item[0]) if rotated else item\n for i in range(y // grid_size, (y + height) // grid_size + 1):\n for j in range(x // grid_size, (x + width) // grid_size + 1):\n grid[i][j] = item\n\n placements = []\n \n for item in items:\n placed = False\n for rotated in [False, True]:\n width, height = (item[1], item[0]) if rotated else item\n for y in range(0, container_height - height + 1, grid_size):\n for x in range(0, container_width - width + 1, grid_size):\n if can_place(item, x, y, rotated):\n place_item(item, x, y, rotated)\n placements.append({'x': x, 'y': y, 'rotated': rotated})\n placed = True\n break\n if placed:\n break\n if placed:\n break\n\n return placements",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"utilization_rate": Infinity,
|
||||||
|
"execution_time": Infinity
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "引入多层次网格划分,逐层细化装箱方案"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "import random\n\ndef solve_bp(params):\n data = params['data']\n items, container_size = data\n container_width, container_height = container_size\n \n items = sorted(items, key=lambda item: item[0] * item[1], reverse=True)\n positions = []\n \n def can_place(x, y, width, height):\n if x + width > container_width or y + height > container_height:\n return False\n for pos in positions:\n if (x < pos['x'] + (pos['rotated'] * pos['height'] or pos['width']) and\n x + width > pos['x'] and\n y < pos['y'] + (pos['rotated'] * pos['width'] or pos['height']) and\n y + height > pos['y']):\n return False\n return True\n\n def place_item(width, height, rotated):\n for x in range(container_width):\n for y in range(container_height):\n if can_place(x, y, width, height):\n return {'x': x, 'y': y, 'rotated': rotated}\n return None\n\n for width, height in items:\n placed = place_item(width, height, False)\n if not placed:\n placed = place_item(height, width, True)\n if placed:\n positions.append(placed)\n \n return positions",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"utilization_rate": Infinity,
|
||||||
|
"execution_time": Infinity
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "利用机器学习模型预测最佳物品排序和放置顺序"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "def solve_bp(data):\n items, (container_width, container_height) = data['data']\n positions = []\n used_space = [[False] * container_width for _ in range(container_height)]\n\n def can_place(x, y, width, height):\n if x + width > container_width or y + height > container_height:\n return False\n for i in range(y, y + height):\n for j in range(x, x + width):\n if used_space[i][j]:\n return False\n return True\n\n def place_item(x, y, width, height):\n for i in range(y, y + height):\n for j in range(x, x + width):\n used_space[i][j] = True\n\n for width, height in items:\n placed = False\n \n for y in range(container_height):\n for x in range(container_width):\n if can_place(x, y, width, height):\n positions.append({'x': x, 'y': y, 'rotated': False})\n place_item(x, y, width, height)\n placed = True\n break\n if placed:\n break\n\n if not placed:\n for y in range(container_height):\n for x in range(container_width):\n if can_place(x, y, height, width):\n positions.append({'x': x, 'y': y, 'rotated': True})\n place_item(x, y, height, width)\n placed = True\n break\n if placed:\n break\n\n return positions",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"utilization_rate": Infinity,
|
||||||
|
"execution_time": Infinity
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "采用混合算法,结合启发式与精确算法进行优化"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objective_names": [
|
||||||
|
"utilization_rate",
|
||||||
|
"execution_time"
|
||||||
|
]
|
||||||
|
}
|
@ -1,8 +1,10 @@
|
|||||||
{
|
{
|
||||||
"description": "尝试开发一个高效的算法用于解决二维装箱问题。你被给定了一组矩形物品和一个固定大小的矩形容器,目标是通过算法的规划将所有物品放入容器中,使得容器的利用率最大化。",
|
"description": "尝试开发一个高效的算法用于解决二维装箱问题。你被给定了一组矩形物品和一个固定大小的矩形容器,目标是通过算法的规划将所有物品放入容器中,使得容器的利用率最大化。",
|
||||||
"function_name": "solve_bp",
|
"function_name": "solve_bp",
|
||||||
"input_format": "一个包含多个矩形物品的列表,每个物品由其宽度和高度表示,以及一个表示容器宽度和高度的元组。",
|
"input_format": "一个字典,包含两个部分:\n1. 'data': 一个元组,包含多个矩形物品的列表和一个表示容器宽度和高度的元组。\n - 矩形物品列表的每个元素是一个元组,表示物品的宽度和高度。\n - 容器元组表示容器的宽度和高度。\n",
|
||||||
"output_format": "返回一个列表,表示每个物品在容器中的位置和旋转状态。",
|
"output_format": "返回一个列表,表示每个物品在容器中的位置和旋转状态。\n每个元素是一个字典,包含以下键:\n1. 'x': 物品左上角的x坐标。\n2. 'y': 物品左上角的y坐标。\n3. 'rotated': 一个布尔值,表示物品是否旋转。",
|
||||||
|
"multi_objective": true,
|
||||||
|
"objective_names": ["vacancy_rate", "execution_time"],
|
||||||
"evaluation_timeout": 60,
|
"evaluation_timeout": 60,
|
||||||
"llm_config": {
|
"llm_config": {
|
||||||
"api_key": "sk-cOqgMkQ605Om9Z28q3UtAfOAtOn7c53tld94Cu01oOEoVTmg",
|
"api_key": "sk-cOqgMkQ605Om9Z28q3UtAfOAtOn7c53tld94Cu01oOEoVTmg",
|
||||||
@ -12,10 +14,16 @@
|
|||||||
"max_tokens": 4096
|
"max_tokens": 4096
|
||||||
},
|
},
|
||||||
"evolution_params": {
|
"evolution_params": {
|
||||||
"algorithm": "GA",
|
"algorithm": "MO",
|
||||||
"population_size": 10,
|
"population_size": 12,
|
||||||
"generations": 5,
|
"generations": 8,
|
||||||
"mutation_rate": 0.2,
|
"mutation_rate": 0.5,
|
||||||
"crossover_rate": 0.7
|
"crossover_rate": 0.4,
|
||||||
|
"F": 0.8,
|
||||||
|
"CR": 0.7
|
||||||
|
},
|
||||||
|
"dataset_generation": {
|
||||||
|
"script_path": "src/lead/problems/bp/dataset/data_loader.py",
|
||||||
|
"random_seed": 2025
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
{
|
||||||
|
"generation": 0,
|
||||||
|
"population": [
|
||||||
|
{
|
||||||
|
"code": "def advanced_sort(arr):\n if not arr:\n return arr\n \n if len(arr) <= 10:\n return insertion_sort(arr)\n \n max_val = max(arr)\n min_val = min(arr)\n \n count_range = max_val - min_val + 1\n count = [0] * count_range\n\n for num in arr:\n count[num - min_val] += 1\n\n sorted_arr = []\n for i in range(count_range):\n sorted_arr.extend([i + min_val] * count[i])\n\n return sorted_arr\n\ndef insertion_sort(subarr):\n for i in range(1, len(subarr)):\n key = subarr[i]\n j = i - 1\n while j >= 0 and subarr[j] > key:\n subarr[j + 1] = subarr[j]\n j -= 1\n subarr[j + 1] = key\n return subarr",
|
||||||
|
"generation": 1,
|
||||||
|
"fitnesses": {
|
||||||
|
"time": 0.008332669734954834,
|
||||||
|
"error": 0.0
|
||||||
|
},
|
||||||
|
"metadata": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "def advanced_sort(arr):\n if not arr:\n return arr\n \n max_val = max(arr)\n min_val = min(arr)\n \n count_range = max_val - min_val + 1\n count = [0] * count_range\n\n for num in arr:\n count[num - min_val] += 1\n\n sorted_arr = []\n for i in range(count_range):\n sorted_arr.extend([i + min_val] * count[i])\n \n return sorted_arr",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"time": 0.0094107985496521,
|
||||||
|
"error": 0.0
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "思路4:使用计数排序或基数排序,专门处理包含大量重复元素的数组,以实现线性时间复杂度O(n)。"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "def advanced_sort(arr):\n if not arr:\n return arr\n \n max_val = max(arr)\n min_val = min(arr)\n \n count_range = max_val - min_val + 1\n count = [0] * count_range\n\n for num in arr:\n count[num - min_val] += 1\n\n sorted_arr = []\n for i in range(count_range):\n sorted_arr.extend([i + min_val] * count[i])\n \n return sorted_arr",
|
||||||
|
"generation": 1,
|
||||||
|
"fitnesses": {
|
||||||
|
"time": 0.008702456951141357,
|
||||||
|
"error": 0.0
|
||||||
|
},
|
||||||
|
"metadata": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pareto_front": [
|
||||||
|
{
|
||||||
|
"code": "def advanced_sort(arr):\n if not arr:\n return arr\n \n if len(arr) <= 10:\n return insertion_sort(arr)\n \n max_val = max(arr)\n min_val = min(arr)\n \n count_range = max_val - min_val + 1\n count = [0] * count_range\n\n for num in arr:\n count[num - min_val] += 1\n\n sorted_arr = []\n for i in range(count_range):\n sorted_arr.extend([i + min_val] * count[i])\n\n return sorted_arr\n\ndef insertion_sort(subarr):\n for i in range(1, len(subarr)):\n key = subarr[i]\n j = i - 1\n while j >= 0 and subarr[j] > key:\n subarr[j + 1] = subarr[j]\n j -= 1\n subarr[j + 1] = key\n return subarr",
|
||||||
|
"generation": 1,
|
||||||
|
"fitnesses": {
|
||||||
|
"time": 0.008332669734954834,
|
||||||
|
"error": 0.0
|
||||||
|
},
|
||||||
|
"metadata": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objective_names": [
|
||||||
|
"time",
|
||||||
|
"error"
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
{
|
||||||
|
"generation": 1,
|
||||||
|
"population": [
|
||||||
|
{
|
||||||
|
"code": "def advanced_sort(arr):\n if not arr:\n return arr\n \n if len(arr) <= 10:\n return insertion_sort(arr)\n \n max_val = max(arr)\n min_val = min(arr)\n \n count_range = max_val - min_val + 1\n count = [0] * count_range\n\n for num in arr:\n count[num - min_val] += 1\n\n sorted_arr = []\n for i in range(count_range):\n sorted_arr.extend([i + min_val] * count[i])\n\n return sorted_arr\n\ndef insertion_sort(subarr):\n for i in range(1, len(subarr)):\n key = subarr[i]\n j = i - 1\n while j >= 0 and subarr[j] > key:\n subarr[j + 1] = subarr[j]\n j -= 1\n subarr[j + 1] = key\n return subarr",
|
||||||
|
"generation": 1,
|
||||||
|
"fitnesses": {
|
||||||
|
"time": 0.007822036743164062,
|
||||||
|
"error": 0.0
|
||||||
|
},
|
||||||
|
"metadata": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "def advanced_sort(arr):\n if not arr:\n return arr\n \n if len(arr) <= 10:\n return insertion_sort(arr)\n \n max_val = max(arr)\n min_val = min(arr)\n \n count_range = max_val - min_val + 1\n count = [0] * count_range\n\n for num in arr:\n count[num - min_val] += 1\n\n sorted_arr = []\n for i in range(count_range):\n sorted_arr.extend([i + min_val] * count[i])\n\n return sorted_arr\n\ndef insertion_sort(subarr):\n for i in range(1, len(subarr)):\n key = subarr[i]\n j = i - 1\n while j >= 0 and subarr[j] > key:\n subarr[j + 1] = subarr[j]\n j -= 1\n subarr[j + 1] = key\n return subarr",
|
||||||
|
"generation": 1,
|
||||||
|
"fitnesses": {
|
||||||
|
"time": 0.007822036743164062,
|
||||||
|
"error": 0.0
|
||||||
|
},
|
||||||
|
"metadata": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "def advanced_sort(arr):\n if not arr:\n return arr\n \n if len(arr) <= 10:\n return insertion_sort(arr)\n \n max_val = max(arr)\n min_val = min(arr)\n \n count_range = max_val - min_val + 1\n count = [0] * count_range\n\n for num in arr:\n count[num - min_val] += 1\n\n sorted_arr = []\n for i in range(count_range):\n sorted_arr.extend([i + min_val] * count[i])\n\n return sorted_arr\n\ndef insertion_sort(subarr):\n for i in range(1, len(subarr)):\n key = subarr[i]\n j = i - 1\n while j >= 0 and subarr[j] > key:\n subarr[j + 1] = subarr[j]\n j -= 1\n subarr[j + 1] = key\n return subarr\n\ndef merge_sort(arr):\n if len(arr) <= 1:\n return arr\n mid = len(arr) // 2\n left = merge_sort(arr[:mid])\n right = merge_sort(arr[mid:])\n return merge(left, right)\n\ndef merge(left, right):\n merged = []\n i = j = 0\n while i < len(left) and j < len(right):\n if left[i] <= right[j]:\n merged.append(left[i])\n i += 1\n else:\n merged.append(right[j])\n j += 1\n merged.extend(left[i:])\n merged.extend(right[j:])\n return merged",
|
||||||
|
"generation": 2,
|
||||||
|
"fitnesses": {
|
||||||
|
"time": 0.00847560167312622,
|
||||||
|
"error": 0.0
|
||||||
|
},
|
||||||
|
"metadata": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "def advanced_sort(arr):\n if not arr:\n return arr\n \n max_val = max(arr)\n min_val = min(arr)\n \n count_range = max_val - min_val + 1\n count = [0] * count_range\n\n for num in arr:\n count[num - min_val] += 1\n\n sorted_arr = []\n for i in range(count_range):\n sorted_arr.extend([i + min_val] * count[i])\n \n return sorted_arr",
|
||||||
|
"generation": 1,
|
||||||
|
"fitnesses": {
|
||||||
|
"time": 0.008702456951141357,
|
||||||
|
"error": 0.0
|
||||||
|
},
|
||||||
|
"metadata": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "def advanced_sort(arr):\n if not arr:\n return arr\n \n max_val = max(arr)\n min_val = min(arr)\n \n count_range = max_val - min_val + 1\n count = [0] * count_range\n\n for num in arr:\n count[num - min_val] += 1\n\n sorted_arr = []\n for i in range(count_range):\n sorted_arr.extend([i + min_val] * count[i])\n \n return sorted_arr",
|
||||||
|
"generation": 0,
|
||||||
|
"fitnesses": {
|
||||||
|
"time": 0.0094107985496521,
|
||||||
|
"error": 0.0
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"idea": "思路4:使用计数排序或基数排序,专门处理包含大量重复元素的数组,以实现线性时间复杂度O(n)。"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pareto_front": [
|
||||||
|
{
|
||||||
|
"code": "def advanced_sort(arr):\n if not arr:\n return arr\n \n if len(arr) <= 10:\n return insertion_sort(arr)\n \n max_val = max(arr)\n min_val = min(arr)\n \n count_range = max_val - min_val + 1\n count = [0] * count_range\n\n for num in arr:\n count[num - min_val] += 1\n\n sorted_arr = []\n for i in range(count_range):\n sorted_arr.extend([i + min_val] * count[i])\n\n return sorted_arr\n\ndef insertion_sort(subarr):\n for i in range(1, len(subarr)):\n key = subarr[i]\n j = i - 1\n while j >= 0 and subarr[j] > key:\n subarr[j + 1] = subarr[j]\n j -= 1\n subarr[j + 1] = key\n return subarr",
|
||||||
|
"generation": 1,
|
||||||
|
"fitnesses": {
|
||||||
|
"time": 0.007822036743164062,
|
||||||
|
"error": 0.0
|
||||||
|
},
|
||||||
|
"metadata": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"code": "def advanced_sort(arr):\n if not arr:\n return arr\n \n if len(arr) <= 10:\n return insertion_sort(arr)\n \n max_val = max(arr)\n min_val = min(arr)\n \n count_range = max_val - min_val + 1\n count = [0] * count_range\n\n for num in arr:\n count[num - min_val] += 1\n\n sorted_arr = []\n for i in range(count_range):\n sorted_arr.extend([i + min_val] * count[i])\n\n return sorted_arr\n\ndef insertion_sort(subarr):\n for i in range(1, len(subarr)):\n key = subarr[i]\n j = i - 1\n while j >= 0 and subarr[j] > key:\n subarr[j + 1] = subarr[j]\n j -= 1\n subarr[j + 1] = key\n return subarr",
|
||||||
|
"generation": 1,
|
||||||
|
"fitnesses": {
|
||||||
|
"time": 0.007822036743164062,
|
||||||
|
"error": 0.0
|
||||||
|
},
|
||||||
|
"metadata": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"objective_names": [
|
||||||
|
"time",
|
||||||
|
"error"
|
||||||
|
]
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user