Exemplo n.º 1
0
def calc_equip_value(selected_combination, selected_has_god, prefer_god):
    set_list = ["1" + str(get_set_name(selected_combination[x])) for x in range(0, len(selected_combination))]
    set_val = Counter(set_list)
    for exclude_set in not_set_list:
        del set_val[exclude_set]
    # 1件词条数=0,两件=1,三件、四件=2,五件=3
    setopt_num = sum([floor(x * 0.7) for x in set_val.values()])

    return setopt_num
Exemplo n.º 2
0
def try_equip(step: CalcStepData, equip):
    # 剪枝条件1:若当前组合序列已经有神话装备(god),且当前这个部位遍历到的仍是一个神话装备,则可以直接跳过
    if step.has_god and is_god(equip):
        return

    # 保存回溯状态
    current_index = step.current_index
    has_god = step.has_god

    set_name = get_set_name(equip)
    if set_name not in step.calc_data.selected_set_2_equips_map:
        step.calc_data.selected_set_2_equips_map[set_name] = set()

    # 更新搜索状态
    step.calc_data.selected_combination.append(equip)
    step.calc_data.selected_set_2_equips_map[set_name].add(equip)
    step.current_index += 1
    step.has_god = step.has_god or is_god(equip)

    if current_index < len(step.items) - 1:
        # 未到最后一层,继续迭代

        # 剪枝条件2:预计算出后面装备部位能够获得的最大价值量,若当前已有价值量与之相加低于已处理的最高价值量,则剪枝
        pruned = False
        if not step.dont_pruning:
            ub = upper_bound(step.items, step.calc_data.selected_combination,
                             has_god or is_god(equip), current_index + 1,
                             step.prefer_god, step.last_god_slot)
            if ub < step.local_max_setop - step.set_perfect - step.prune_cfg.delta_between_lower_bound_and_max:
                # 如果比缓存的历史最高词条数少,则剪枝
                pruned = True
            else:
                if step.local_max_setop < step.max_possiable_setopt:
                    # 否则尝试更新最新值,再判断一次
                    step.local_max_setop = step.max_setopt.value
                    if ub < step.local_max_setop - step.set_perfect - step.prune_cfg.delta_between_lower_bound_and_max:
                        pruned = True

        if not pruned:
            if current_index != step.start_parallel_computing_at_depth_n:
                # 未到开始进行并发计算的层数,串行搜索
                parallel_dfs(step)
            else:
                # 此层数的所有子树采用并行搜索
                step.producer(copy_step(step))
    else:
        # 最后一层,即形成了一个装备搭配方案
        if not step.dont_pruning:
            # 检查是否有神话装备
            god = 0
            if step.prefer_god and (has_god or is_god(equip)):
                god = 1
            # 计算套装数目
            set_list = [
                "1" + str(get_set_name(step.calc_data.selected_combination[x]))
                for x in range(0, 11)
            ]
            set_val = Counter(set_list)
            for exclude_set in not_set_list:
                del set_val[exclude_set]
            # 套装词条数:1件价值量=0,两件=1,三件、四件=2,五件=3,神话额外增加1价值量
            setopt_num = sum([floor(x * 0.7) for x in set_val.values()]) + god

            # 仅当当前搭配的词条数不低于历史最高值时才视为有效搭配
            if setopt_num >= step.local_max_setop - step.set_perfect - step.prune_cfg.delta_between_lower_bound_and_max:
                # 尝试获取全局历史最高词条数
                if step.local_max_setop < step.max_possiable_setopt:
                    step.local_max_setop = step.max_setopt.value
                # 二次对比
                if setopt_num >= step.local_max_setop - step.set_perfect - step.prune_cfg.delta_between_lower_bound_and_max:
                    # 尝试更新全局最高词条数和本进程缓存的历史最高词条数
                    if step.local_max_setop <= setopt_num - god * step.set_perfect:
                        max_setopt = setopt_num - god * step.set_perfect
                        step.max_setopt.value = max_setopt
                        step.local_max_setop = max_setopt

                    # 开始计算装备搭配
                    step.process_func(step)
        else:
            # 不进行任何剪枝操作,装备搭配对比的标准是最终计算出的伤害与奶量倍率
            step.process_func(step)

    # 回溯状态
    step.has_god = has_god
    step.current_index = current_index
    step.calc_data.selected_set_2_equips_map[set_name].remove(equip)
    step.calc_data.selected_combination.pop()