Reputation: 41
I want to create a sorting algorithm for a specific game inventory.
Each item has an ID and a size (1-3). The size reflects how many slots it occupies in the inventory, vertically.
I want to create a sorting algorithm using its size mainly so the largest items are first and that would be very simple. However the inventory has multiple pages, each page having 5 columns of 10 rows. This is where the problem appears. Logically you will fill up the first inventory with 3 sized items, however that means that in the last row there wont be any items. So the algorithm has to fill the first 6 rows with 3 size items, and the second 4 with 2 size items. The number of items is dynamic so that may not be the case every time. Can anyone point me in the right direction? I am using python. Thank you very much!
Upvotes: 2
Views: 101
Reputation: 5703
If your goal is to:
You may apply a 0-1 knapsack algorithm: maximize the "cost" up to 10
Below a solution dumbly copy-pasted and adaptated from a previous answer of mine
long story short:
from collections import namedtuple
def pick_items (values):
S = 10
Candidate = namedtuple('Candidate', ['sum', 'lastIndex', 'path'])
tuples = [Candidate(0, -1, [])]
best_fallback = tuples[0]
while len(tuples):
next = []
for (sum, i, path) in tuples:
for j in range(i + 1, len(values)):
v = values[j]
if v + sum <= S:
candidate = Candidate(sum = v + sum, lastIndex = j, path = path + [v])
if candidate[0] > best_fallback[0]:
best_fallback = candidate
next.append(candidate)
if v + sum == S:
return path + [v]
tuples = next
return best_fallback[2]
print(pick_items([3,3,3,1])) #finds the trivial sum [3, 3, 3, 1]
print(pick_items([1,3,3,1])) #returns the closest to goal [1, 3, 3, 1]
print(pick_items([2,2,2,2,2,1,3,3,1])) #returns the shortest set [2, 2, 3, 3]
print(pick_items([3,3,2,2,3])) #returns an exact count [3, 3, 2, 2]
print(pick_items([3,1,1,1,2,2,2,2])) #shortest set as well [3, 1, 2, 2, 2]
PS: regarding the set [2,2,2,2,2,3,1,3,1]
(where there are two solutions of equal size: (3,1, 3,1, 2)
and (2,2, 2,2 ,2)
we may force the order in which the solutions are explored by prefixing values=sorted(values, reverse=True)
at the begininning:
def pick_items (values):
# force biggest items solution to be explored first
values = sorted(values, reverse=True)
S = 10
Upvotes: 1