7
votes

Algorithme de minimisation du panier d'achat

J'ai une liste de produits code>, qui consiste en une liste des magasins code>, qui la vendit.

{
    'Book A': [ShopA, ShopB, ShopC],
    'Book B': [ShopC, ShopD],
    'Movie C': [ShopA, ShopB, ShopD, ShopE],
    ...
}


2 commentaires

Pouvez-vous donner des estimations du nombre de magasins et de produits dont vous aurez besoin pour traiter. Actuellement, je suis arrivé avec un algorithme qui ne fonctionne bien que pour une très petite quantité de produits, et j'ai le sentiment que ce n'est pas le cas ...


Pour l'amour de Dieu, veuillez la mettre en œuvre. C'est ce que je déteste la plupart des sites comme Amazon: non seulement je ne connais pas les frais d'expédition à l'avance, mais je ne sais en fait pas s'ils expédieront à une certaine adresse du tout jusqu'à ce que je reçoive vérifier.


4 Réponses :


6
votes

Ce problème est NP Hard .
Nous allons montrer une réduction du Frapper le problème défini .
Frapper Défini Problème FORT>: Ensembles données S1, S2, ..., SN CODE> et un numéro k code>: Chose Set S code> de la taille k code>, tel que pour chaque si code> il y a un élément s code> dans s code> tel que s code> est dans si code>. [Définition alternative: l'intersection entre chaque SI code> et s code> n'est pas vide].

réduction: strong>
Compte tenu d'une instance de frappe définie, sous la forme de (S1, ..., sn, k) code> Créer une instance de ce problème: p>

All books cost nothing. In order to buy from each store you pay 1. 
The book i is sold by each store denoted in Si, minimal price for this instance is k.


1 commentaires

Je ne pense pas que cette réponse soit correcte. Peut-être que vous n'avez pas besoin de réserver d'un produit à partir d'un magasin spécifique, car tous les produits proposés dans ce magasin sont moins chers dans d'autres magasins. En outre, le «coût d'expédition» n'est pas inclus dans votre explication.



0
votes

Une bonne heuristique peut être l'optimisation de la colonie de fourmis. Je l'utilise pour résoudre le problème du vendeur de voyage. Vous pouvez trouver un exemple de travail à partir de Google Tsp Solver. C'est une bibliothèque JavaScript qui utilise également une force brute et une solution de programmation dynamique. L'AOC est utilisé lorsque vous avez plus de villes à calculer, puis à la limite actuelle de 20 villes. Je crois que vous pouvez utiliser la bibliothèque pour résoudre votre problème et il a juste besoin d'une petite réécriture. Avec 20 villes, le programme doit vérifier 20! posibilites. Dans votre cas, il est un peu plus léger mais peut-être seulement une magnitude.


0 commentaires

5
votes

avec tant de petits articles que j'ai une solution. C'est dynamique.

Nous traiterons chaque magasin de manière itérative. À chaque étape, nous stockons le meilleur prix actuel avec lequel nous pouvons couvrir tous les sous-ensembles d'articles. Au début, tous sont Infinity Code> dans le prix sauf pour le sous-ensemble vide qui est 0 code> du prix. Notez que tous les sous-ensembles sont 2 ^ num_products code> dans le décompte, mais dans votre cas, il ne s'agit que d'environ 1000. P>

MAINTENANT Comment traitons-nous la prochaine boutique: considérez que vous couvrez tout le possible. Sous-ensemble des produits avec ce magasin (je veux dire sous-ensemble que le magasin peut réellement fournir) et tout le reste des produits couverts par des magasins que vous avez déjà observés, améliorant ainsi les coûts minimes de couvrant chaque sous-ensemble. Cette étape prend 2 ^ num_products * 2 ^ num_products = 4 ^ Num_Products code>, toujours environ un million qui est garanti. Vous faites cela pour chaque magasin et à la fin de la réponse est le coût de la couverture de tous les éléments. Toute la complexité de la solution proposée est 4 ^ Num_Products * Num_shops code> qui est d'environ 50 millions qui est bon à partir. P>

Notez que cela reste exponentiel et cela n'est pas surprenant. Merci d'amiter pour son incroyable preuve de NP dur. p>

EDIT EDIT FORT> Ajout d'une explication plus poussée de l'algorithme de pseudocode: p>

init:
 cost[subset] = infi
 cost[{}] = 0
for shop in shops
 new_prices = costs.dup()
 for set : subsets
   for covered_set : all_subsets(set)
     price = covered_set == {} ? 0 : delivery[shop]
     remaining = set
     for element : covered_set
       if shop do not sale element
         break for, choose next covered_set
       price += el_price[element]
       remaining.remove(element)
     price += costs[remaining]
     new_prices[set] = min(new_prices[set], price)
 costs = new_prices
return costs[all]


5 commentaires

Ce n'est toujours pas complètement clair pour moi. Pourriez-vous fournir un pseudocode ou suivre les étapes de certains petits livres / boutiques?


Fait, dis-moi si vous avez besoin de plus d'explications sur la représentation sous-ensemble.


Eh bien, j'ai mis en œuvre cela et il semble fonctionner. Je n'ai que deux questions à être sûres: 1) Si définir et couvert_set sont des bitmasks, alors fait restant simplement égal set - couvert_set , donc nous n'avons pas besoin restant.remove logique de tableau? 2) casse pour sur couvert_set signifie que nous passons dans le prochain couvert_set dans pour couvert_set: all_subsets (SET) BOOP ou Abandon à l'ensemble suivant dans pour définir: sous-ensembles ?


Merci pour les commentaires. Les deux questions sont totalement raisonnables. Je vais placer les réponses dans la prochaine édition de ma réponse.


Je pense actuellement si cet algorithme / approche pourrait être étendu à la prise en charge de "quantités": chaque magasin n'a qu'un certain nombre de livres en stock, et mon panier a ressemble quelque chose comme "2x Réserver A, 3 Livre C". Quelqu'un a-t-il une idée de savoir comment cela pourrait être résolu?



2
votes

J'ai traité ce problème exact une fois. Je n'ai pas trouvé d'autre solution que de tester toutes les combinaisons possibles de magasins, mais il existe un moyen facile de filtrer plusieurs des magasins de chaque produit.

1. Calculez le prix le plus bas (coût d'expédition inclus) de chaque produit, appelons-le best_price.

2. Dans chaque produit, ne conserve que les magasins où le prix du magasin (sans frais d'expédition) <= best_price (avec coût d'expédition)

3. Testez toutes les combinaisons possibles de magasins pour les moins chers.


1 commentaires

En outre, un autre changement de temps énorme pour l'algorithme: garder une trace du total de la meilleure combinaison. Passer à la prochaine itération Si la somme actuelle est plus grande que la mieux trouvée jusqu'à présent. Ces deux optimisations ont fait ma solution réalisable pour une quantité raisonnable de combinaisons.