How to calculate the best price [duplicate]

左心房为你撑大大i 提交于 2019-12-04 18:32:01

How to calculate the best price

It look like this algorithms will be run more than one time. So I feel free to use an eavy pre-compute step (sorry if it is not the case).

Computing the best price, is computing the group of combos than can by apply. So I'm only printing combos that can be apply.

working data types

define thoses type in sml notation

type index =  (productId, tag) Hashtbl.t
and  tag = {
   combos : combo list  [default is empty list]
   subIndex : index     [default is empty hash]
}
and  combo = {
   comboId : int;   
   comboName : string     
   constituentProducts : list product;
   comboPrice : int
}
and product = { 
   productId : int;
   productName : string,   
   price : int (*In fact as I understand the problem this price don't change any thing. *) 
}

pre-compute

The precompute step is index building.

Sort all products in your combos by the productsId. vital

let insertIntoIndex(Index index, Combo combo, int level = 0) ->
    assert level < combo.constituentProducts.length;
    tag entry = index[combo.constituentProducts[level].productId];
    if entry is null/notFound then { entry = new tag(); }
    if level + 1 == combo.constituentProducts.length
    then
    {
      entry.combos.add combo;
    }
    else
    {
      if null/notFound = entry.subIndex.get(combo.constituentProducts[level])
      then entry.subIndex.add (combo.constituentProducts[level].productId) (new tag());

      insertIntoIndex(entry.subIndex, combo, level+1)
    }

iter insertIntoIndex over all your combos, for the same index.

As you can see this index is a form of tree. Each node can math a combo and be a part of a greater combo.

computation

Put all the basket products into an array (with repetition if need);

Sort that array by productId in the same order as use for sorting combos. vital

for(int position = 0; position < array.length ; position++)
  scan(index, product, position);

let scan(index,product, position) ->
  entry = index.get array[position];
  if entry != null/notfound 
  then 
  {
    iter print entry.combos; (* or build a set of result *)

    foreach(product key : entry.subIndex.keys)
    {
      positionOfFoundKey = array.find(from = position, to = length-1 , look = key )
      if (positionOfFoundKey != -1) (* -1 for not found / null is the find function *)
    scan(entry.subIndex[key], array[positionOfFoundKey], positionOfFoundKey)
    }
  }

as product are sorted, there will be no combos counts twice, unless the combos is really present. You can improve the scan function by adding a bag to found the matching product, remove from the bag the product that have been scan.

Complexity of the search :

n x scan

Complexity of scan :

size of bucket x maximum size of combo x number of combo

I believe this is just an upper bound that should never append.

I don't know if it is the best, but it look fast enouph to me as I don't know what your inputs look like.

Have a HashMap whose key is the number of products in a combo and whose value is another HashMap < Alphabetically Sorted List of Products, Combo >.

HashMap<Integer, HashMap<List<Products>, Combo>> comboMap;

Now alphabetically sort the products in the shopping cart and keep track of the lowest price seen currently and the List of Combos that is associated with that price:

float lowestCurrentPrice;
List<Combo> minComboList;

Have a recursive function that starts with either the highest possible number of products in a combo or the size of the list, and try to find a combo in the shopping cart with that number of products.

If found, remove the products in the combo, keep track of the cost of combo, and add this to the result of your recursive function that now repeats using the smaller list.

If you had already found a combo with that number of products, compare the two prices and keep the list of combos that was less expensive in your HashMap.

Do this until you run out of combos of that number. Then you decrement the number of items you are looking for in a combo. If this number is one then you just sum up all the items in the list, otherwise repeat using this number.

You should have the correct answer by the end of this decrement at the end of your first function call!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!