space (slots) optimization algorithm - algorithm

I'll start directly with the example:
In a game, there is a bag that players will use to store their items (items has variable sizes) and the bag has a variable size also.
In a bag of 8x15 slots, I need to insert an item that occupies 2x2 slots, I can search space to actually check if there's enough space for this item to be stored - this is easy, but, what if I don't have enough space to store the requested item? This is the real problem.
I'm trying to find a way to actually rearranging all the current items in the current bag in order to release space for the new item.
Is there any algorithm that will help me doing that?
EDIT
Rules:
I cannot remove any of the current items in the bag, just rearrange them in order to store a new one if there's not enough space.

I think this unfortunately is an NP-hard problem, but you can use a greedy approximation algorithm. The approximation algorithm could work as follows:
Sort all items by item volume, descending.
Iterate trough the list and try to place the current item anywhere
If at any point the current item can't be fitted anywhere, decide that the item can't be picked up.
If all pieces are fitted, decide that the item can be picked up.
This is based on the intuitive thought that larger pieces are 'harder' to place than smaller pieces. Another thing you could do, if most items are 1x1, is a brute-force solution, which is quite feasible in such a small inventory. This would work as follows:
Try every single position for the current piece, where it still fits and for every such position:
Do this with the next unpositioned piece.
This will always solve your problem, but is way slower (though more accurate). This algorithm can be inproved by leaving out every 1x1 piece, placing them afterwards.

Related

Auto align elements in table

I need to make an algorithm which will align elements in table by using smallest possible number of rows.
Elements that need to bee sorted should keep the horizontal position/alignment
Like this:
[
I hope someone already did this.
Thanks!
To clarify: I assume that you mean that each item must fit on one row, and one row only (it cannot break up into the next row), but that they can move horizontally.
Heuristically/naively, I would do it like this:
Sort the elements by length.
Try to fill the first free row by naively picking (from longest to shortest) items until the row is full or no more matching elements can be found.
Repeat until all elements are done.
This will finish (relatively) quickly (somewhere between O(nlogn) and O(n^2) depending on heuristic "shortcuts") but leave more holes than necessary and turn up otherwise non-optimal solutions.
I'd wager this problem is equivalent to one of the classical NP-complete problems https://en.wikipedia.org/wiki/Karp%27s_21_NP-complete_problems , so you likely will not find a good practical non-heuristic solution.

Shuffle polyominos in a grid

I have a 2d array that contains polyominos of lengths 1 to 4, i want to shuffle their position AND rotation.
For example:
[0,0,1,0,0,0,0,0,0,0]
[0,0,1,0,0,0,0,0,0,0]
[0,0,1,1,0,0,0,0,0,0]
[0,0,0,0,0,0,0,0,0,0]
[0,0,X,0,0,0,0,3,0,0]
[0,0,0,0,0,0,0,0,0,0]
[0,0,0,2,2,0,0,0,0,0]
[0,0,0,2,0,0,0,X,0,0]
[0,0,0,0,0,0,0,0,0,0]
[0,0,0,0,0,0,0,0,0,0]
First, 0s are empty spaces, and numbers are polyominos. There are four of them: one tetromino "L" made by 1s, one tromino "L" made of 2s, and one monomino made by one 3. I want to shuffle this grid, changing their position and rotation without loosing their structure.
Second, though 0s are available spaces, Xs aren't and cant be shuffled.
I'd be happy if someone can help me solve the first part of the problem, but if there is anyone smart (or bored) enough to solve also the second part, it'll really appreciated because this stuff gets way over my head.
Edit:
The problem can also be seen as placing N polyominos in a 2d grid of fixed size.
I think that rather than having a board the way you have it, you should actually store a list of pieces, and their rotation and position on your board. The way you are storing it right now, it is much more difficult to manipulate because you have essentially finalized the data onto the board as a single data set.
If you like, you can store the board with a set of booleans (simply to take up less space in memory) where a true correlates to your "X" and a false correlates to an un-utilized space.
Then I would randomly choose a rotation for each piece before placement.
After you know the finalized randomized rotation, you can move through your LIST of pieces, generate a list of all placement locations possible, and simply choose one of those locations randomly. You will have to generate this potential placement list separately for each piece, as once a piece is placed, you will not be able to place another piece on top of it!
The trick here is to separate your board data from your pieces data so that you can manipulate the pieces more easily.

Simple k-nearest-neighbor algorithm for euclidean data with variable density?

An elaboration on this question, but with more constraints.
The idea is the same, to find a simple, fast algorithm for k-nearest-neighbors in 2 euclidean dimensions. The bucketing grid seems to work nicely if you can find a grid size that will suitably partition your data. However, what if the data is not uniformly distributed, but has areas with both very high and very low density (for example, the US population), so that no fixed grid size could guarantee both enough neighbors and efficiency? Can this method still be salvaged?
If not, other suggestions would be helpful, though I hope for answers less complex than moving to kd-trees, etc.
If you don't have too many elements, just compare each with all the others. This can be a lot faster than you'd think; today's machines are fast. Unfortunately, the square factor will catch you sooner or later; I figure a linear search of a million objects won't take tooo long, so you may be okay with up to 1000 elements. Using a grid, or even stripes, might boost that number substantially.
But I think you're stuck with a quadtree (a specific form of k-d tree). Your whole map is one block, which can contain four subblocks (upper left, upper right, lower left, lower right). When a block fills up with more elements than you want to do a linear search on, break it into smaller ones and transfer the elements. (Only leaf nodes have elements.) It's easy to search within a given radius of a given point. Start at the top and if a part of a block is within range of the point, check out it's subblocks the same way if it has them. If it doesn't, check its elements.
(When searching for "closest", take care. The square grid means a nearer object might be in a farther block. You have to get everything within a given radius, then check 'em all. If you want the 10 closest and your radius of 20 only picked up 5, you need to try a larger radius. You may have a rejected item that proved to be 30 away and think you should grab it and a few others to make up your 10. However, there may be a few items at 25 away whose whole blocks were rejected, and you want them instead. There ought to be a better solution for this, but I haven't figured it out yet. I just make a guess at the radius and double it till I get enough.)
Quadtrees are fun. If you can set up your data and then access it, it's easy. The problems come when your mapped elements appear, disappear, and move while you are trying to figure out who's near what.
Have you looked at this?
http://www.cs.sunysb.edu/~algorith/major_section/1.4.shtml
kd-trees are quite simple to implement, there are standard java/c implementations.
Also:
You may want to post your question here:
https://cstheory.stackexchange.com/?as=1

3x3 grid puzzle solving (JS)

I have an image separated into a 3x3 grid. The grid is represented by an array. Each column or row can be rotated through. E.g, the top row [1,2,3] could become [3,1,2] etc.
The array needs to end up as:
[1,2,3]
[4,5,6]
[7,8,9]
And would start from something like:
[5,3,9]
[7,1,4]
[8,6,2]
It will always be solvable, so this doesn't need to be checked.
I've tried a long handed approach of looking for '1' and moving left then up to its correct place, and so on for 2, 3,... but end up going round in circles for ever.
Any help would be appreciated, even if you can just give me a starting point/reference... I can't seem to think through this one.
your problem is that the moves to shift one value will mess up others. i suspect with enough set theory you can work out an exact solution, but here's a heuristic that has more chance of working.
first, note that if every number in a row belongs to that row then it's either trivial to solve, or some values are swapped. [2,3,1] is trivial, while [3,2,1] is swapped, for example.
so an "easier" target than placing 1 top left is to get all rows into that state. how might we do that? let's look at the columns...
if the column contains one number from each row, then we are in a similar state to above (it's either trivial to shift so numbers are in the correct rows, or it's swapped).
so, what i would suggest is:
for column in columns:
if column is not one value from each row:
pick a value from column that is from a duplicate row
rotate that row
for column in columns:
as well as possible, shift until each value is in correct row
for row in rows:
as well as possible, shift until each value is in correct column
now, that is not guaranteed to work, although it will tend to get close, and can solve some set of "almost right" arrangements.
so what i would then do is put that in a loop and, on each run, record a "hash" of the state (for example, a string containing the values read row by row). and then on each invocation if i detect (by checking if the hash was one we had seen already) that the state has already occurred (so we are repeating ourselves) i would invoke a "random shuffle" that mixes things up.
so the idea is that we have something that has a chance of working once we are close, and a shuffle that we resort to when that gets stuck in a loop.
as i said, i am sure there are smarter ways to do this, but if i were desperate and couldn't find anything on google, that's the kind of heuristic i would try... i am not even sure the above is right, but the more general tactic is:
identify something that will solve very close solutions (in a sense, find out where the puzzle is "linear")
try repeating that
shuffle if it repeats
and that's really all i am saying here.
Since the grid is 3x3, you can not only find the solution, but find the smallest number of moves to solve the problem.
You would need to use Breadth First Search for this purpose.
Represent each configuration as a linear array of 9 elements. After each move, you reach a different configuration. Since the array is essentially a permutation of numbers between 1-9, there would be only 9! = 362,880 different configurations possible.
If we consider each configuration as a node, and making each move is considered as taking an edge, we can explore the entire graph in O(n), where n is the number of configurations. We need to make sure, that we do not re-solve a configuration which we have already seen before, so you would need a visited array, which marks each configuration visited as it sees it.
When you reach the 'solved' configuration, you can trace back the moves taken by using a 'parent' array, which stores the configuration you came from.
Also note, if it had been a 4x4 grid, the problem would have been quite intractable, since n would equal (4x4)! = 16! = 2.09227899 × 10^13. But for smaller problems like this, you can find the solution pretty fast.
Edit:
TL;DR:
Guaranteed to work, and pretty fast at that. 362,880 is a pretty small number for today's computers
It will find the shortest sequence of moves.

Writing Simulated Annealing algorithm for 0-1 knapsack in C#

I'm in the process of learning about simulated annealing algorithms and have a few questions on how I would modify an example algorithm to solve a 0-1 knapsack problem.
I found this great code on CP:
http://www.codeproject.com/KB/recipes/simulatedAnnealingTSP.aspx
I'm pretty sure I understand how it all works now (except the whole Bolzman condition, as far as I'm concerned is black magic, though I understand about escaping local optimums and apparently this does exactly that). I'd like to re-design this to solve a 0-1 knapsack-"ish" problem. Basically I'm putting one of 5,000 objects in 10 sacks and need to optimize for the least unused space. The actual "score" I assign to a solution is a bit more complex, but not related to the algorithm.
This seems easy enough. This means the Anneal() function would be basically the same. I'd have to implement the GetNextArrangement() function to fit my needs. In the TSM problem, he just swaps two random nodes along the path (ie, he makes a very small change each iteration).
For my problem, on the first iteration, I'd pick 10 random objects and look at the leftover space. For the next iteration, would I just pick 10 new random objects? Or am I best only swapping out a few of the objects, like half of them or only even one of them? Or maybe the number of objects I swap out should be relative to the temperature? Any of these seem doable to me, I'm just wondering if someone has some advice on the best approach (though I can mess around with improvements once I have the code working).
Thanks!
Mike
With simulated annealing, you want to make neighbour states as close in energy as possible. If the neighbours have significantly greater energy, then it will just never jump to them without a very high temperature -- high enough that it will never make progress. On the other hand, if you can come up with heuristics that exploit lower-energy states, then exploit them.
For the TSP, this means swapping adjacent cities. For your problem, I'd suggest a conditional neighbour selection algorithm as follows:
If there are objects that fit in the empty space, then it always puts the biggest one in.
If no objects fit in the empty space, then pick an object to swap out -- but prefer to swap objects of similar sizes.
That is, objects have a probability inverse to the difference in their sizes. You might want to use something like roulette selection here, with the slice size being something like (1 / (size1 - size2)^2).
Ah, I think I found my answer on Wikipedia.. It suggests moving to a "neighbor" state, which usually implies changing as little as possible (like swapping two cities in a TSM problem)..
From: http://en.wikipedia.org/wiki/Simulated_annealing
"The neighbours of a state are new states of the problem that are produced after altering the given state in some particular way. For example, in the traveling salesman problem, each state is typically defined as a particular permutation of the cities to be visited. The neighbours of some particular permutation are the permutations that are produced for example by interchanging a pair of adjacent cities. The action taken to alter the solution in order to find neighbouring solutions is called "move" and different "moves" give different neighbours. These moves usually result in minimal alterations of the solution, as the previous example depicts, in order to help an algorithm to optimize the solution to the maximum extent and also to retain the already optimum parts of the solution and affect only the suboptimum parts. In the previous example, the parts of the solution are the parts of the tour."
So I believe my GetNextArrangement function would want to swap out a random item with an item unused in the set..

Resources