0

Here is an example:

Customer orders 57 single peaces of an item. The company only sells in units of 15 and 6.

The algorithm has to figure out the best possible combination of UOMs (unit of measure) with the following priorities in order of importance

  1. least amount of overage
  2. using highest unit of measure

In this example the expected result is List<int>:

{ 15, 15, 15, 6, 6 } //sum=57

I've researched "bin packing" and "knapsack problem" but couldn't figure out how it could be applied in this case.

So far I have this which is clearly doesn't accomplish the best combination.

    void Main()
{
    var solver = new Solver();

    var r  = solver.Solve(57, new decimal [] {6, 15}).Dump();

}

public class Solver
{
    public List<decimal> mResults;

    public List<decimal> Solve(decimal goal, decimal[] elements)
    {

        mResults = new List<decimal>();
        RSolve(goal, 0m, elements, elements.Where(e => e <= goal).OrderByDescending(x => x).FirstOrDefault());
        return mResults;
    }


    public void RSolve(decimal goal, decimal currentSum, decimal[] elements, decimal toAdd)
    {
        if(currentSum >= goal)
            return;

        currentSum += toAdd;
        mResults.Add(toAdd);

        var remainder = goal - currentSum;


        var nextToAdd = elements.Where(e => e <= remainder).OrderByDescending(e => e).FirstOrDefault();

        if(nextToAdd == 0)
            nextToAdd = elements.OrderBy(e => e).FirstOrDefault();

        RSolve(goal, currentSum, elements, nextToAdd);

    }
}
kaya3
  • 47,440
  • 4
  • 68
  • 97
boruchsiper
  • 2,016
  • 9
  • 29
  • 53
  • 1
    Stackoverflow is not a code writing service and this is clearly a homework assingment. Show us what you have done so far and wich specific problem you got, that we can help you with. – Christopher Dec 18 '19 at 18:40
  • 1
    Also the solution is to add 15 until value + 15 would > 57. And then repeat with size 6. Decimal is the wrong type, those should clearly be integers. – Christopher Dec 18 '19 at 18:42
  • You can do it with 2 Loops. That is all you need. While you can often switch between loops and recursions, this seems a painfully simple loop case. – Christopher Dec 18 '19 at 18:44
  • Not getting it. Some example code in an answer would be great. – boruchsiper Dec 18 '19 at 18:55

1 Answers1

2

This is an instance of the change-making problem. It can be solved by dynamic programming; build an array where the value at index i is the largest coin that can be used in a solution totalling i, or -1 if no solution is possible. If you use larger units first then the solutions will satisfy the "highest unit of measure" requirement automatically; to satisfy the "least amount of overage" requirement, you can try to find a solution for 57, if that doesn't work try 58, and so on.

The running time is at most O((n + 1 - n₀)k) where n is the required sum, n₀ is the largest index in the cache, and k is the number of units of measure. In particular, after trying 57, it takes at most O(k) time to try 58, then at most O(k) time to try 59, and so on.

To build the output list for a sum n, initialize an empty list, then while n > 0 append the value in the cache at index n, and subtract that value from n.

kaya3
  • 47,440
  • 4
  • 68
  • 97
  • Some code in c-like language would be very helpful. – boruchsiper Dec 18 '19 at 18:58
  • @boruchsiper We will not provide code for Homework assignments. Writing that yourself is part of the learning. And it is realy incredibly trivial once you know where to start. It is two loops. Not quantum Physics. – Christopher Dec 18 '19 at 19:01
  • It is trivial for people who have already learned how to do it; for people who are currently learning, it is not trivial. But it is important that you try for yourself, anyway. – kaya3 Dec 18 '19 at 19:06
  • `initialize an empty list, then while n > 0 append the value in the cache at index n, and subtract that value from n.` What is `that value`? – boruchsiper Dec 18 '19 at 20:24
  • also, adding value at index n means at index 57 at start. Doesn't make sense to me – boruchsiper Dec 18 '19 at 20:30
  • *"build an array where the value at index i is the largest coin that can be used in a solution totalling i, or -1 if no solution is possible"*. You have to build it starting from index 0. *"That value"* is the one you read from the cache. – kaya3 Dec 18 '19 at 20:43