Find combination of products for max profit - algorithm

I have a problem where I have to find out the best combination of products which can yield maximum profit.
Suppose I have 3 products (A,B and C). The Unit cost of each product respectively is ($a, $b and $c). The inflation rate for A,B and C is (p%, q% and r%) i.e. every time user purchase a product, its unit cost increases by the said inflation rate. User can only purchase the product in lot of (l,m and n) quantities respectively. Each product gives a profit of $x, $y and $z respectively per unit.
So for a single round of purchase, for product A,
Total Cost = l*$a
Total Profit = l*$x
Unit price after purchase = ((p/100)*$a)+$a
How can I find the right combination of purchase of A,B and C, which will give me maximum profit.
I referred internet and found something called "Optimal Product Mix" problem given here...
http://www.technicalcommunicationcenter.com/2013/03/29/how-to-calculate-optimal-product-mix-with-ms-excel-2010-solver-to-maximize-profits/
However, somehow I am not able to relate it which my problem statement.
Can someone suggest me a way to solve this?
Thanks

If your budget is significantly larger than the price of a single lot, a greedy algorithm should get you close to an optimal solution - iteratively select the lot that you can afford that gives you the most profit right now until all options are no longer profitable.
If your budget is not significantly larger than a single lot, or you must solve for the globally optimal solution, this reduces to the knapsack problem.
If your budget is unlimited, simply buy enough lots of each item to make the profit go negative, then stop - the greedy algorithm will lead to the same result.

Related

How to order a set of tasks where each has a starting cost and reward

Assume you start with T amount of money, you want to find internships but because you have no experience you can't get into any, so you decided to buy into paid internships.
You are given a set of internships each with a buying cost C_b to get you in first, and once you are in you get paid back some money C_p. C_b can be either greater or smaller or the same than C_p so the net gain can be either positive or negative or 0.
Edit :The goal is to do all the internships.
Is there an algorithm to find out the order to do all the internships (in O(n^2))? And it can find out if there's no way to order e.g(The money left if not enough to buy you into any remaining internships). Thanks!
I'm really confused as to where to even start.
To restate the question: How can you find the most effective order to do buy-in internships in, that maximizes the number of internships you can do.
Given:
A set of internships, each with a buy-in cost (C_b) and payback amount (C_p)
C_b may be greater than or less than C_p
You have some amount of money that cannot go into the negative
The Algorithm
Sort the internships by net gain in descending order
Loop through this sorted set of internships
If money - C_b >= 0
then do the internship and money = money + net gain
Repeat step 2, looping over the skipped internships, until you complete a loop without doing another internship.
With this algorithm you will do the internships that pay you the most first, which increases your ability to buy in to more internships.
EDIT
I believe a more efficient algorithm would be, upon finding a suitable internship at step 2, to start the loop back at from the beginning (in case you're now able to do one of the skipped higher net gain internships).

Sorting algorithm using divide and conquer

This is like a stock marketing problem, I am confused that the question is asking about how to get everyday's maximum profit? I only know that the algorithm's time complexity can be O(n) or O(n log2 n).
The input is A, an array of stock prices. For day i, the best trade is the maximum profit that can be achieved by buying at day i and selling on a subsequent day. For convenience, you can define the best trade for the last day to simply be −A[n] (because if you buy on the last day, you cannot sell and you lost all your money).
Give the pseudocode of an algorithm that returns an array containing the maximum profit for every day in A.
Update: I understand how to get the maximum profit now, and I can use the similar algorithm as the merge sort that divide and conquer to find this maximum profit. My question is what's another method (algorithm) that use time complexity O(n) to find the maximum profit or how can I approach in this way?
One way you can think of this problem is using one for loop since it's O(n), I can give you some hints:
for i from 0 to n:
if (A[i] < A[min]) // find the minimum value of stock
min = i;
profit = A[i] - A[min] // get the profit
if (profit > maxProfit) { // compares the profits
maxProfit = profit // always update the max profit
If you buy on day i, the maximum profit you can make is Amax(i) - A[i],
where Amax(i) is the highest price that occurs after day i.
My reading of the algorithm's specification is that you are to construct and return the array M whose entries are defined by M[i] = Amax(i) - A[i].
The highest price that occurs after day i is the greater of
A[i+i] and the highest price that occurs after day i + 1.
The last paragraph gives you a recursive relationship, except that unlike
the "typical" recursion you might see, the ith value depends on the
i + 1st value rather than the other way around.
But fortunately for you, you already know that the nth value and
every later value is 0, that is, after day n you will get 0 for your stock.
So you only need to figure out the values for days
1, 2, ..., n - 1, which you can do in O(n) time.
And each time you find one of these values, Amax(i), you can set one of the entries of M using M[i] = Amax(i) - A[i].
If you want to find the maximum profit that can be made by buying one share of stock on any single day and selling on any subsequent day, one time
(though this is not required by the problem statement, as far as I can see), you just have to find the maximum value in M, which you can do in O(n) time.
If your goal is to make the maximum profit possible by a series of actions, buying and selling stock, the best you can do is to buy as many shares as you can afford whenever the stock is at a local minimum (assuming infinite price before the first day) and sell everything whenever it reaches a local maximum price. You can identify all the local minimums and maximums in O(n) time, scanning A in either direction, and given a starting amount of money, you can compute the maximum overall profit in O(n) time using the list of local minimums and maximums of A. (But this does not use the array that the original problem statement asked you to construct, because that array does not account for the number of shares bought nor the possibility of multiple transactions.)
Remember that if each pass of a two-pass algorithm takes O(n) time, the algorithm as a whole takes O(n) time.

How do I calculate the most profit-dense combination in the most efficient way?

I have a combinations problem that's bothering me. I'd like someone to give me their thoughts and point out if I'm missing some obvious solution that I may have overlooked.
Let's say that there is a shop that buys all of its supplies from one supplier. The supplier has a list of items for sale. Each item has the following attributes:
size, cost, quantity, m, b
m and b are constants in the following equation:
sales = m * (price) + b
This line slopes downward. The equation tells me how many of that item I will be able to sell if I charge that particular price. Each item has its own m and b values.
Let's say that the shop has limited storage space, and limited funds. The shop wants to fill its warehouse with the most profit-dense items possible.
(By the way, profit density = profit/size. I'm defining that profit density be only with regard to the items size. I could work with the density with regard to size and cost, but to do that I'd have to know the cost of warehouse space. That's not a number I know currently, so I'm just going to use size.)
The profit density of items drops the more you buy (see below.)
If I flip the line equation, I can see what price I'd have to charge to sell some given amount of the item in some given period of time.
price = (sales-b)/m
So if I buy n items and wanted to sell all of them, I'd have to charge
price = (n-b)/m
The revenue from this would be
price*n = n*(n-b)/m
The profit would be
price*n-n*cost = n*(n-b)/m - n*cost
and the profit-density would be
(n*(n-b)/m - n*cost)/(n*size)
or, equivalently
((n-b)/m - cost)/size
So let's say I have a table containing every available item, and each item's profit-density.
The question is, how many of each item do I buy in order to maximise the amount of money that the shop makes?
One possibility is to generate every possible combination of items within the bounds of cost and space, and choose the combo with the highest profitability. In a list of 1000 items, this takes too long. (I tried this and it took 17 seconds for a list of 1000. Horrible.)
Another option I tried (on paper) was to take the top two most profitable items on the list. Let's call the most profitable item A, the 2nd-most profitable item B, and the 3rd-most profitable item C. I buy as many of item A as I can until it's less profitable than item B. Then I repeat this process using B and C, for every item in the list.
It might be the case however, that after buying item B, item A is again the most profitable item, more so than C. So this would involve hopping from the current most profitable item to the next until the resources are exhausted. I could do this, but it seems like an ugly way to do it.
I considered dynamic programming, but since the profit-densities of the items change depending on the amount you buy, I couldn't come up with a resolution for this.
I've considered multiple-linear regression, and by 'consider' I mean I've said to myself "is multi-linear regression an option?" and then done nothing with it.
My spidey-sense tells me that there's a far more obvious method staring me in the face, but I'm not seeing it. Please help me kick myself and facepalm at the same time.
If you treat this as a simple exercise in multivariate optimization, where the controllable variables are the quantities bought, then you are optimizing a quadratic function subject to a linear constraint.
If you use a Lagrange multiplier and differentiate then you get a linear equation for each quantity variable involving itself and the Lagrange multiplier as the only unknowns, and the constraint gives you a single linear equation involving all of the quantities. So write each quantity as a linear function of the Lagrange multiplier and substitute into the constraint equation to get a linear equation in the Lagrange multiplier. Solve this and then plug the Lagrange multiplier into the simpler equations to get the quantities.
This gives you a solution if you are allowed to buy fractional and negative quantities of things if required. Clearly you are not, but you might hope that nothing is very negative and you can round the non-integer quantities to get a reasonable answer. If this isn't good enough for you, you could use it as a basis for branch and bound. If you make an assumption on the value of one of the quantities and solve for the others in this way, you get an upper bound on the possible best answer - the profit predicted neglecting real world constraints on non-negativity and integer values will always be at least the profit earned if you have to comply with these constraints.
You can treat this as a dynamic programming exercise, to make the best use of a limited resource.
As a simple example, consider just satisfying the constraint on space and ignoring that on cost. Then you want to find the items that generate the most profit for the available space. Choose units so that expressing the space used as an integer is reasonable, and then, for i = 1 to number of items, work out, for each integer value of space up to the limit, the selection of the first i items that gives the most return for that amount of space. As usual, you can work out the answers for i+1 from the answers for i: for each value from 0 up to the limit on space just consider all possible quantities of the i+1th item up to that amount of space, and work out the combined return from using that quantity of the item and then using the remaining space according to the answers you have already worked out for the first i items. When i reaches the total number of items you will be working out the best possible return for the problem you actually want to solve.
If you have constraints for both space and cost, then the state of the dynamic program is not the single variable (space) but a pair of variables (space, cost) but you can still solve it, although with more work. Consider all possible values of (space, cost) from (0, 0) up to the actual constraints - you have a 2-dimensional table of returns to compute instead of a single set of values from 0 to max-space. But you can still work from i=1 to N, computing the highest possible return for the first i items for each limit of (space, cost) and using the answers for i to compute the answers for i+1.

If you know the future prices of a stock, what's the best time to buy and sell?

Interview Question by a financial software company for a Programmer position
Q1) Say you have an array for which the ith element is the price of a given stock on
day i.
If you were only permitted to buy one share of the stock and sell one share
of the stock, design an algorithm to find the best times to buy and sell.
My Solution :
My solution was to make an array of the differences in stock prices between day i and day i+1 for arraysize-1 days and then use Kadane Algorithm to return the sum of the largest continuous sub array.I would then buy at the start of the largest continuous array and sell at the end of the largest
continous array.
I am wondering if my solution is correct and are there any better solutions out there???
Upon answering i was asked a follow up question, which i answered exactly the same
Q2) Given that you know the future closing price of Company x for the next 10 days ,
Design a algorithm to to determine if you should BUY,SELL or HOLD for every
single day ( You are allowed to only make 1 decision every day ) with the aim of
of maximizing profit
Eg: Day 1 closing price :2.24
Day 2 closing price :2.11
...
Day 10 closing price : 3.00
My Solution: Same as above
I would like to know what if theres any better algorithm out there to maximise profit given
that i can make a decision every single day
Q1 If you were only permitted to buy one share of the stock and sell one share of the stock, design an algorithm to find the best times to buy and sell.
In a single pass through the array, determine the index i with the lowest price and the index j with the highest price. You buy at i and sell at j (selling before you buy, by borrowing stock, is in general allowed in finance, so it is okay if j < i). If all prices are the same you don't do anything.
Q2 Given that you know the future closing price of Company x for the next 10 days , Design a algorithm to to determine if you should BUY,SELL or HOLD for every single day ( You are allowed to only make 1 decision every day ) with the aim of of maximizing profit
There are only 10 days, and hence there are only 3^10 = 59049 different possibilities. Hence it is perfectly possible to use brute force. I.e., try every possibility and simply select the one which gives the greatest profit. (Even if a more efficient algorithm were found, this would remain a useful way to test the more efficient algorithm.)
Some of the solutions produced by the brute force approach may be invalid, e.g. it might not be possible to own (or owe) more than one share at once. Moreover, do you need to end up owning 0 stocks at the end of the 10 days, or are any positions automatically liquidated at the end of the 10 days? Also, I would want to clarify the assumption that I made in Q1, namely that it is possible to sell before buying to take advantage of falls in stock prices. Finally, there may be trading fees to be taken into consideration, including payments to be made if you borrow a stock in order to sell it before you buy it.
Once these assumptions are clarified it could well be possible to take design a more efficient algorithm. E.g., in the simplest case if you can only own one share and you have to buy before you sell, then you would have a "buy" at the first minimum in the series, a "sell" at the last maximum, and buys and sells at any minima and maxima inbetween.
The more I think about it, the more I think these interview questions are as much about seeing how and whether a candidate clarifies a problem as they are about the solution to the problem.
Here are some alternative answers:
Q1) Work from left to right in the array provided. Keep track of the lowest price seen so far. When you see an element of the array note down the difference between the price there and the lowest price so far, update the lowest price so far, and keep track of the highest difference seen. My answer is to make the amount of profit given at the highest difference by selling then, after having bought at the price of the lowest price seen at that time.
Q2) Treat this as a dynamic programming problem, where the state at any point in time is whether you own a share or not. Work from left to right again. At each point find the highest possible profit, given that own a share at the end of that point in time, and given that you do not own a share at the end of that point in time. You can work this out from the result of the calculations of the previous time step: In one case compare the options of buying a share and subtracting this from the profit given that you did not own at the end of the previous point or holding a share that you did own at the previous point. In the other case compare the options of selling a share to add to the profit given that you owned at the previous time, or staying pat with the profit given that you did not own at the previous time. As is standard with dynamic programming you keep the decisions made at each point in time and recover the correct list of decisions at the end by working backwards.
Your answer to question 1 was correct.
Your answer to question 2 was not correct. To solve this problem you work backwards from the end, choosing the best option at each step. For example, given the sequence { 1, 3, 5, 4, 6 }, since 4 < 6 your last move is to sell. Since 5 > 4, the previous move to that is buy. Since 3 < 5, the move on 5 is sell. Continuing in the same way, the move on 3 is to hold and the move on 1 is to buy.
Your solution for first problem is Correct. Kadane's Algorithm runtime complexity is O(n) is a optimal solution for maximum subarray problem. And benefit of using this algorithm is that it is easy to implement.
Your solution for second problem is wrong according to me. What you can do is to store the left and right index of maximum sum subarray you find. Once you find have maximum sum subarray and its left and right index. You can call this function again on the left part i.e 0 to left -1 and on right part i.e. right + 1 to Array.size - 1. So, this is a recursion process basically and you can further design the structure of this recursion with base case to solve this problem. And by following this process you can maximize profit.
Suppose the prices are the array P = [p_1, p_2, ..., p_n]
Construct a new array A = [p_1, p_2 - p_1, p_3 - p_2, ..., p_n - p_{n-1}]
i.e A[i] = p_{i+1} - p_i, taking p_0 = 0.
Now go find the maximum sum sub-array in this.
OR
Find a different algorithm, and solve the maximum sub-array problem!
The problems are equivalent.

Shopping cart minimization algorithm

I have a list of products, which consists of list of shops, which sold it.
{
'Book A': [ShopA, ShopB, ShopC],
'Book B': [ShopC, ShopD],
'Movie C': [ShopA, ShopB, ShopD, ShopE],
...
}
(Price differs between the shops)
Each shop is also has a shipping cost. It's a "per-order" shipping cost, it doesn't matter how many items are in my cart. And it differs between the shops too.
Ex: if I buy "Book A" from ShopA, "Book B" from ShopC and "Movie C" from ShopA, the resulting price is: Book A price in ShopA + Book B price in ShopC + Movie C price in ShopA + ShopC shipping cost + ShopA shipping cost
If the shipping cost was zero or it was on per-item basis and constant, than I would just sort the offer lists by price+shipping field and fetch the first result from each set.
I need to buy all the items once and find the minimal price and the resulting set.
I'm not very good with optimization algorithms and dynamic programming so I need a solution or just a nod into the right direction.
This problem is NP Hard.
We will show a reduction from the Hitting Set problem.
Hitting Set problem: Given sets S1,S2,...,Sn and a number k: chose set S of size k, such that for every Si there is an element s in S such that s is in Si. [alternative definition: the intersection between each Si and S is not empty].
Reduction:
Given an instance of hitting set, in the form of (S1,...,Sn,k) create an instance of this problem:
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.
proof:
Hitting Set -> This problem: Assume there is a minimal hitting set in (S1,...,Sn) of size k. Let this hitting set be S. By buying from each store in S, we can buy all our books at cost k, since the books cost nothing [in our construction], and we bought all books, and we paid for the ordering from stores exactly k, thus the total price was k.
This problem -> Hitting set: Assume there is a pricing of k for the problem at the question. Then, from the building of the problem, and since the books cost nothing, we need to buy in k different stores to get all books. Let these stores be S. From the construction of the problem, S is a hitting set for (S1,...,Sn)
Q.E.D.
Conclusion:
Thus, this problem is "not easier then" Hitting Set Problem, and there is no known polynomial solution for this problem, so - your best shot, if you want optimal solution, is probably an exponential one, such as backtracking [Check all possibilities, and return the minimal solution].
With so little items I have a solution. It is dynamic.
We will process every shop iteratively. At every step we store the current best price with which we can cover all subsets of items. In the beginning all of them are infinity in price except for the empty subset which is 0 of price. Note that all subsets are 2^Num_products in count but in your case these are only about 1000.
Now how do we process the next to follow shop: Consider you cover every possible subset of the products with this shop (i mean subset that the shop can actually provide) and all the rest of the products being covered by shops you already observed, thus improving the minimal costs of covering every subset. This step takes 2^Num_products*2^Num_products=4^Num_products, still about a million which is bareable. You do this for every shop and at the end the answer is the cost of covering all the elements. The whole complexity of the proposed solution is 4^Num_products * num_shops which is about 50 million which is good to go.
Note that this is still exponential and this is not surprising. Thank you to amit for his incredible proof of NP hard.
EDIT Adding further explanation of the algorithm in pseudocode:
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]
Note that here I use sets as index - this is because I actually use the bitmask representation of the subsets e.g 1101 is a subset containing the 1st, 2nd and the forth element. Thus an iteration of all sets is for (int i = 0; i < (1 << n); i++).
There is also one more thing: if you want to cycle all the subsets of a subset S you can actually do it faster than iterating all the subsets of the initial set and checking whether the subset is subset of S. If S is also represented with bitmask bit_mask this for loop does the job: for(int i = bit_mask; i > 0; i = (i - 1) & bitmask). Using this approach you decrease the complexity of the algorithm to 3^Num_products * num_shops. However, this is a bit harder to understand and you will probably need to write by hand one example to make sure the loop I wrote actually cycles all the subsets of S. About the complexity - just trust me.
EDIT2 Edited the break condition. also let me elaborate on the set remaining and its calculation: as dmzkrsk pointed out the pseudocode mentions removal from the set, but you can actually just assign remaining = set ^ covered_set (again bit operation) in case of using bitmasks to represent the subsets.
I have dealt with this exact problem once. I didn't come up with any other solution than just testing every possible combination of shops but there is an easy way to filter out many of the shops in every product.
1. Calculate the lowest price (shipping cost included) of every product, let's call it best_price.
2. In every product, retain only the shops where price of the shop (without shipping cost) <= best_price (with shipping cost)
3. Test every possible combination of shops for the cheapest.
A good heuristic can be the ant colony optimization. I use it to solve the travel salesman problem. You can find a working example from google tsp solver. It's a javascript library that uses also a brute force and a dynamic programming solution. The AOC is used when you have more cities to compute then the current limit of 20 cities. I believe you can use the library to solve your problem and it just need a little rewrite. With 20 cities the program has to check 20! posibilites. In your case it's a bit lighter but maybe only a magnitude.

Resources