0

問題を解決するための小さなプログラムを作成しましたが、スケーリングに問題があり、いくつかのポイント/ヘルプが必要になる可能性があります。

データには 3 つの行列があります

1) 商品の価格

price = [
    [11.5, 12.5, 10.75, 11.5],
    [19, 13.5, 12.85, 11.9],
    [1.95, 1.9, 1.75],
    [2.95, 2.45, 1.65, 1.59],
    [8.5, 6.45, 8.5, 8.5],
    [12.5, 10.5, 10.25, 10.5],
    [4.25, 5.5, 5.5, 5],
    [4.25, 5.5, 5.5, 5],
    [4.25, 5.5, 5.5, 5],
    [50],
    [30],
]

2) 100 = 最良価格の名目上の差異

diff = [
    [80, 86, 100, 80],
    [47, 66, 93, 100],
    [90, 92, 100],
    [54, 65, 96, 100],
    [100, 66, 100, 100],
    [82, 98, 100, 81],
    [97, 100, 88, 83],
    [97, 100, 88, 83],
    [97, 100, 88, 83],
    [100],
    [100]
]

3) 私の製品の全部または一部を配送できる可能性のあるサプライヤー

data = [
    [0, 1, 2, 3],
    [0, 1, 2, 3],
    [0, 1, 2],
    [0, 1, 2, 3],
    [0, 1, 2, 3],
    [0, 1, 2, 3],
    [0, 1, 2, 3],
    [0, 1, 2, 3],
    [0, 1, 2, 3],
    [0],
    [0],
]

すべてのサプライヤーは、最小注文の制約と、行ごとに 1 つのアイテムのみを持つことができます。

deliverer = [0, 1, 2, 3]
min_order = {0: 50, 1: 30, 2: 0, 3: 100}   

combinations = list(itertools.product(*data))

def compute(combinations):

    def get_score(comb):
        score = 0
        available = []
        for index, item in enumerate(comb):
            score += diff[index][item]
            available.append(diff[index][item])
        return (score, all(i > 0 for i in available))

    def get_price(comb):
        price_dict = {key: {'price': 0, 'reached': False} for key in comb}
        for index, item in enumerate(comb):
            p = price[index][item]
            price_dict[item]["price"] += p
            if price_dict[item]["price"] >= min_order[item]:
                price_dict[item]["reached"] = True

        return price_dict

次に、考えられるすべての組み合わせを反復処理してスコア値を計算し、上から下へのパスが配信可能で、すべてのアイテムが含まれているかどうかを計算します。

    new_comb = []
    for comb in combinations:
        score, all_items = get_score(comb)
        price_dict = get_price(comb)
        check = [value["reached"] for value in price_dict.values()]
        can_deliver = False
        if all(i is True for i in check):
            can_deliver = True

        if can_deliver is False:
            continue

        new_comb.append({"way": comb, "score": score, "all_items": all_items, "price": price_dict,
                        "can_deliver": can_deliver, "d_count": len(price_dict.keys())})

    return new_comb

このステップでは、上位のソリューションの戻り値を並べ替えるだけです。ここで、別の制約を追加して、最小量の配達者を見つけ、すべてのアイテムを配達できる最大量の配達者になるまでステップアップする必要があります。

new_comb = compute(combinations)

new_comb = sorted(new_comb, key=lambda k: (k["can_deliver"], k["all_items"], k["score"]), reverse=True)

best_solutions = []
for item in new_comb:
    if item["can_deliver"] is True:
        best_solutions.append(item)

print(best_solutions[:15])

私の問題は、この種の問題をどのように拡大できるかです。60x10 以上のマトリックスを処理するために実行可能な手法は何ですか?

助けていただければ幸いです。

4

0 に答える 0