I have a list of 500 elements each with 2 values x (float value from 0-Infinity) and a y (float value from 0-1). I need to find the cheapest (lowest sum(x)) combination of 10 of these elements that achieve an average y value less than a given n. I think this is some kind of knapsack problem but I'm unsure of how to fit solutions online to my exact problem and fear that it may be too complicated.
All I have tried so far is trying a solution from ChatGPT but I believe that its complexity is too high. I'm looking for a solution that hopefully can be completed with a high number of elements <1000.
def find_cheapest_combination(elements, k, target_avg):
def backtrack(start, combo):
if len(combo) == k:
# Calculate the average float value for the current combination
avg_float = sum(element[1] for element in combo) / k
if avg_float <= target_avg:
nonlocal best_combo, lowest_avg
best_combo = combo[:]
lowest_avg = avg_float
return
for i in range(start, len(elements)):
if len(elements) - i < k - len(combo):
# Not enough elements remaining to form a valid combination
break
combo.append(elements[i])
backtrack(i + 1, combo)
combo.pop()
elements.sort(key=lambda x: x[0]) # Sort by price in ascending order
best_combo = []
lowest_avg = float('inf')
backtrack(0, [])
return best_combo
elements = [(x, y) for x, y in items]
k = 10
target_avg = 0.07
cheapest_combination = find_cheapest_combination(elements, k, target_avg)
print(cheapest_combination)
You can try this:
This function takes as its arguments arrays
xandyof x- and y-values, respectively.nis the number of elements to be selected, andmis the value that bounds the mean of selected y-values from above. If a solution to the problem exists, the function returns a dictionary of the formIt a solution cannot be found (i.e. no selection of elements gives small enough mean of y-values), the function returns
None.For example:
gives:
Explanation. Let
x = [a_1,…,a_k],y=[b_1,…,b_k]. The problem of selecting some elements ofxwith the smallest sum is equivalent to finding a minimum of the functiona_1*x_1 + … + a_k*x_kwhere the value of each variablex_ican be either 1 (which means thata_iis selected) or 0. The variablesx_imust satisfy a couple constraints. First,x_1 + … + x_k = n, since we want to select exactlynelements. Second,b_1*x_1 + … + b_k*x_k <= n*m. This condition means that the average of selectedb_i’s does not exceedm. In this form, the problem becomes an integer linear program. The code usesscipy.optimize.milpto compute its solution.