如何从所有蛮力组合中找到最佳解决方案? [英] How to find best solution from all brute force combinations?

查看:133
本文介绍了如何从所有蛮力组合中找到最佳解决方案?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从字典的所有蛮力组合中找到最佳解决方案。对于问题的背景,我需要找出在给定体重限制的情况下运输所有母牛所需的最少旅行次数。

I want to find the best solution from all brute force combinations of a dictionary. For the context of the problem, I need to find out the minimum number of trips needed to transport all the cows given a weight limit.

组合已经给我了使用辅助功能 get_partitions 。该函数返回一个嵌套列表,每个内部列表代表一个行程和该行程中的母牛的名字。

The combinations are already given to me with the helper functions get_partitions. The function returns a nested list, with each inner list represents a trip and names of cows on that trip.

Helper函数:

def partitions(set_):
    if not set_:
        yield []
        return
    for i in range(2**len(set_)//2):
        parts = [set(), set()]
        for item in set_:
            parts[i&1].add(item)
            i >>= 1
        for b in partitions(parts[1]):
            yield [parts[0]]+b

def get_partitions(set_):
    for partition in partitions(set_):
        yield [list(elt) for elt in partition]

我想做的是按长度对所有组合进行排序,然后使用嵌套循环对其进行迭代。如果总重量超过限制,那么我会跳出内循环并将下一个子列表附加到另一个列表中。问题在于下一个子列表仍然包含分区中的剩余列表,因为它们的总权重低于限制。

What I tried to do was sorting all combinations by length then iterate over them with a nested loop. If the total weight exceed the limit, then I break out of the inner loop and append the next sublist to another list. The problem is that the next sublist still contain leftover lists from the partition since their total weight is below the limit.

我的代码:

def brute_force_cow_transport(cows, limit):

    # Generate and sort all combinations by length
    partitions = [item for item in get_partitions(cows)]
    partitions.sort(key=len)

    # Iterate over each sublist of combinations
    possibles = []
    for partition in partitions:
        trips = []
        for section in partition:
            total = sum([cows.get(cow) for cow in section])
            if total > limit:
                break
            else:
                # Appending next sublists create duplicates
                trips.append(section)
            possibles.append(trips)

    # Remove duplicates from possible solutions
    best = []
    for item in possibles:
        if item and item not in best:
            best.append(item)
    return min(best)

当我运行函数时,每次都会返回不同的结果。我认为这是因为我追加到结果中的剩余子列表引起了问题,但我不确定:

When I run my function, it keeps returning a different result each time. I think it's because the leftover sublists I appended to the results is causing the problem but I'm not sure:

cows = {'MooMoo': 50, 'Miss Bella': 25, 'Boo': 20, 
        'Milkshake': 40, 'Horns': 25, 'Lotus': 40}

>>> brute_force_cow_transport(cows, limit=100)
[['Boo', 'Miss Bella', 'MooMoo']]

正确的结果:

[['MooMoo', 'Horns', 'Miss Bella'], ['Milkshake', 'Lotus', 'Boo']]

如果有人可以帮助我指出我在哪里出错了,将不胜感激。

If anyone can help me point out where I went wrong, that would be greatly appreciated.

编辑:添加了辅助函数

推荐答案

我们可以将其视为深度优先搜索问题。

We can approach this as a depth-first-search problem.

def getCows(dict, limit):
    best_solution = []
    best_solution_score = 0

    def dfs(current_cows, current_total):
        nonlocal best_solution_score
        nonlocal best_solution
        if current_total > best_solution_score:
            #replace best solution
            best_solution = [tuple(sorted(current_cows))]
            best_solution_score = current_total
        elif current_total == best_solution_score:
            #add to best solution
            best_solution.append(tuple(sorted(current_cows))) 
        for cow, weight in dict.items():
            if cow not in current_cows and current_total + weight <= limit:
                #if adding next cow under limit recurse
                dfs(current_cows + [cow], current_total + weight)

    dfs([], 0)
    return list(set(best_solution)) #remove duplicates

cows = {'MooMoo': 50, 'Miss Bella': 25, 'Boo': 20,
    'Milkshake': 40, 'Horns': 25, 'Lotus': 40}


print(getCows(cows, limit=100))
>>>[('Horns', 'Miss Bella', 'MooMoo'), ('Boo', 'Lotus', 'Milkshake')]

这篇关于如何从所有蛮力组合中找到最佳解决方案?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆