Decision support system for supplier selection and order allocation

时间:2016-07-11 22:59:40

标签: python mathematical-optimization linear-programming integer-programming

I wrote a small program to solve a problem i have but having trouble to scale it and could need some points/help.

There are 3 matrices for data

1) Price of an item

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) Difference nominal where 100 = best price

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) Possible suppliers who can fully or partly deliver my products

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],
]

Every supplier can have a constraint of min order and only one item per row.

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

I then iterate over all possible combinations and calculate a score value and if the path taken from top to bottom can be delivered and contains all items.

    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

In this step i just sort my return values of my top solutions. Here i need to add another constrained to find the least amount of deliverer and step up till i have the maximum amount of deliverer who can deliver all items.

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])

My problem is now how can i make this kind of problems scale. What techniques are viable to deal with a matrix for 60x10 or more.

I would appreciate any help.

0 个答案:

没有答案