返回所需材料的可能组合批次的算法

时间:2016-12-08 05:41:21

标签: algorithm

我有一个问题,例如我需要用300米的皮革建造沙发。

我的材料分批不同。

10m
20m
30m
40m
40m
50m
100m
200m
300m

我的目标是找到符合我要求的最佳组合。

使用上述批次,可能的良好匹配将是

300m
200m + 100m
200m + 50m + 30m + 20m
200m + 40m + 40m + 10m
200m + 40m + 30m + 20m + 10m
No wastage for the above example

但如果我的批次是: 40米 百米 220米 250米

然后必须有浪费,我的组合将是

220 + 100 with 20m wastage, 
250 + 100 with 50m wastage  
220 + 250 with 170m wastage

2 个答案:

答案 0 :(得分:1)

您可以O(n)时间复杂度执行此操作。这个答案假定给定批次已经排序。

这个想法是从两边迭代直到它们相遇或者两边的总和小于所需的长度并且跟踪每个有效指数/指数的最小值。

假设我们的批次是

40m 100m 220m 250m
 ^             ^

我们检查它们或它们中的任何一个的总和是否可以单独地达到所需的长度。

即40米< 300米和250米< 300米和40米+ 250米< 300米

因此,我们将开始位置向前移动1

40m 100m 220m 250m
     ^         ^

再次100米< 300米& 250米< 300米但是100米+ 250米> 300米 - 由于这是一种可能性,我们需要的更大,我们标记指数和与这些指数相关的浪费,并将结束位置迭代1

40m 100m 220m 250m
       ^  ^

再说一次,他们中没有一个可以制造300米但是他们一起可以制造300米,浪费更少。所以我们更新了指数和浪费并返回,因为在下一次迭代中,开始将等于结束。

答案 1 :(得分:0)

我对这个问题的解决方案可能不是最好或最有效的算法,但至少它确实给我一个可能的匹配列表(我认为)。

首先,我需要对我拥有的一批物质资源进行过滤和排序。伪代码如下:

func filter_sort_batches(product, batches)
    newlist = []
    product_keys = product.keys

    foreach batch in batches:
        score = 0

        if split doesn't contain a product_key, ignore batch

        if the split doesn't contain a product_key but also contain other keys that the product doesn't require, ignore batch

        for each key in batch:
            if product[key] >= batch[key]:
                score += (product[key] - batch[key])
            else:
                score += (batch[key] - product[key]) * product[key]

        put [score, batch] to newlist
    newlist.sort_by score, where the lowest score is the best

要返回匹配需要2个函数, 主要功能如下:

func find_match(list, product)
    newlist = list.clone
    matches = Array.new
    find_match_recursive(newlist, product, matches, Array.new)
    result = matches.sort_by score, where the lowest score is the best
    print result

递归函数如下:

func find_match_recursive(list, product, matches, group)
    return if list is empty

    newlist = list.clone
    tuple = newlist.shift
    batch = tuple.last
    new_group = group.clone
    new_group << batch

    if has_met_quantity(check_outsanding_materials(product, new_group)):
        grp_tuple = score_group(new_group, product)
        score = grp_tuple[0]
        if score less than 2x of the sum of product's values:
            add grp_tuple to matches

    else:
        # recurse to get the next batch and try to meet quantity check
        find_match_recursive(newlist, product, matches, new_group)

    #ignore the current recursion and skip to next batch in the list
    find_match_recursive(newlist, product, matches, group)

我没有包含在psuedo代码中的其他函数:

score_group: computes the wastage for each material used.
check_outsanding_materials: calculate how much material is required after substracting the batches
has_met_quantity: check if the above for any materials qty has met or not.
相关问题