You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效从宝可梦图鉴选全克制阵容,避免递归深度超限?

解决宝可梦属性全覆盖队伍的递归问题与优化方案

核心问题分析

你当前的随机选队逻辑完全依赖碰运气,效率极低,且盲目重复的尝试很容易触发递归深度上限。本质问题在于随机搜索的无目的性——既没有优先选择覆盖能力强的宝可梦,也没有对无效分支进行剪枝,导致程序在无意义的重试中耗尽栈空间。

优化方案:从盲目随机转为启发式搜索

1. 预处理宝可梦的属性覆盖能力

先提前计算每只宝可梦能克制的属性集合,避免重复计算浪费资源:

# 预处理:为每个宝可梦生成其覆盖的属性集合
pokemon_coverage = {}
for name, types in pokedex.items():
    coverage = set()
    for t in types:
        coverage.update(Effective_Against[t])
    pokemon_coverage[name] = coverage

2. 贪心算法快速构建基础队伍

优先选择能覆盖最多未克制属性的宝可梦,大幅减少搜索次数:

def build_greedy_team(target_types, pokemon_coverage, max_team_size=6):
    team = []
    covered = set()
    available = list(pokemon_coverage.items())
    
    while len(team) < max_team_size and not target_types.issubset(covered):
        # 筛选当前能覆盖最多未克制属性的宝可梦
        best_pokemon = None
        best_additional = 0
        for name, cov in available:
            new_coverage = cov - covered
            if len(new_coverage) > best_additional:
                best_additional = len(new_coverage)
                best_pokemon = name
        
        if best_pokemon is None:
            break  # 没有能增加覆盖的宝可梦了
        
        team.append(best_pokemon)
        covered.update(pokemon_coverage[best_pokemon])
        # 可选:移除已选宝可梦,避免重复选择(根据需求调整)
        available = [(n, c) for n, c in available if n != best_pokemon]
    
    return team if target_types.issubset(covered) else None

3. 回溯算法处理贪心无法覆盖的情况

如果贪心策略失败,用回溯法在合理范围内搜索,同时通过排序候选宝可梦减少无效分支:

def backtrack_team(target_types, pokemon_coverage, current_team, current_covered, max_team_size=6):
    if target_types.issubset(current_covered):
        return current_team.copy()
    if len(current_team) >= max_team_size:
        return None
    
    # 优先尝试覆盖能力强的宝可梦,减少搜索分支
    candidates = sorted(
        pokemon_coverage.items(), 
        key=lambda x: len(x[1] - current_covered), 
        reverse=True
    )
    
    for name, cov in candidates:
        if name in current_team:
            continue  # 避免重复选同一只宝可梦(可按需取消)
        new_covered = current_covered.union(cov)
        result = backtrack_team(
            target_types, 
            pokemon_coverage, 
            current_team + [name], 
            new_covered, 
            max_team_size
        )
        if result is not None:
            return result
    return None

4. 替换原随机逻辑的调用示例

# 先执行预处理
pokemon_coverage = {}
for name, types in pokedex.items():
    coverage = set()
    for t in types:
        coverage.update(Effective_Against[t])
    pokemon_coverage[name] = coverage

# 优先用贪心算法快速找队伍
team = build_greedy_team(Types, pokemon_coverage)
if not team:
    # 贪心失败,再尝试回溯搜索
    team = backtrack_team(Types, pokemon_coverage, [], set())

if team:
    print(f"找到有效队伍:{team}")
else:
    print("在6只宝可梦的限制内无法实现全属性覆盖")

额外优化建议

  • 去重候选:图鉴中进化链宝可梦(如妙蛙种子/妙蛙草/妙蛙花)的属性覆盖完全一致,可只保留一只候选,缩小搜索范围。
  • 迭代式回溯:把回溯算法改成栈模拟的迭代形式,彻底避免递归深度问题。
  • 剪枝策略:在回溯时,如果剩余空位能覆盖的最大属性数仍无法补全未覆盖属性,直接终止当前分支,减少无效计算。

内容的提问来源于stack exchange,提问作者iamlc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 20:50:29