What is a good algorithm to solve a non boolean puzzle? - algorithm

and thanks for taking your time considering this question.
My problem is the solving of a non boolean puzzle that has no perfect solution.
In a regular puzzle, two pieces either match and can be placed next to each other, or don't match.
In a non boolean puzzle, any piece can be put next to any other one, but a matching score can be established for every junction between two pieces, between 0 and 1.
Here, let's say the best "solution" is the one that maximises the average score of all the junctions in the solved puzzle.
As with big puzzles it becomes impossible to test all solutions, I want an algorithm that gives a solution that is "relatively good".
In reality, I'm not dealing with a puzzle, but with a tiled image where the tiles are shuffled. We get the matching score of a tile junction by comparing their edge pixels.
An image with shuffeled tiles looks like this:
In my cases, the additional rules apply:
- No two pieces are the same. Two pieces might have the same edges however.
- The tiles doesn't have to get in a specific shape when solved. I want it to be roughly square/rectangle shaped however.
- It is possible to leave blank tiles with no pieces inside.
What I want is an algorithm idea that could give a decent solution is reasonable time (few minutes is totally ok).
If you think the definition of a good solution (currently: get the highest junction score in average in the final image) is wrong, feel free to change it to match your algorithm.
A problem I have with that solution is that currently, you can just place two tiles together to get a score of 1, and separate every single other tile with blank space to prevent them from getting a lower score. That technicly gives a perfect average score of 1, but the final image will contain moslty blank spaces, that's not what I want.
For comprehension sake, here is an answer I would find very good for the problem above:
Obviously I would be surprised to have that good of an output, but I would like at least that similar tiles get close to each other in the final image.
Thanks for your time, and remember any idea is welcome, even weird ones.

Related

Number of ways to fill a n*m piece matrix with L-shaped three piece tiles using recursive programming

I'm looking for an approach to this problem where you have to fill a n*m (n, m <=8) piece matrix with L-shaped three piece tiles. The tiles can't be placed on top of each other in any way.
I'm not necessarily looking for the whole answer, just a hint on how to approach it.
Source: https://cses.fi/dt/task/336
I solved this graph problem using a recursive backtracking algorithm plus memoization. My solution is not particularly fast and takes a minute or so to solve a 9x12 grid, but it should be sufficient for the 8x8 grid in your question (it takes about a second on a 9x9). There are no solutions for 7x7 and 8x8 grids because they are not divisible by the triomino size, 3.
The strategy is to start in a corner of the grid and move through it cell by cell, trying to place each block whenever it is legal to do so and thereby exploring the solution space methodically.
If placement of a block is legal but creates an unfillable air pocket in the grid, remove the block; we know ahead of time there will be no solutions to this state and can abandon exploring its children. For example, on a 3x6 grid,
abb.c.
aabcc.
......
is hopelessly unsolvable.
Once a state is reached where all cells have been filled, we can report a count of 1 solution to its parent state. Here's an example of a solved 3x6 grid:
aaccee
abcdef
bbddff
If every possible block has been placed at a position, backtrack, reporting the solution count to parent states along the way and exploring any states that are as yet unexplored.
In terms of memoization, call any two grid states equivalent if there is some arrangement of tiles such that they cover the exact same coordinates. For example:
aacc..
abdc..
bbdd..
and
aacc..
bacd..
bbdd..
are considered to be equivalent even though the two states were reached through different tile placements. Both states have the same substructure, so counting the number of solutions to one state is enough; add this to the memo, and if we reach the state again, we can simply report the number of solutions from the memo rather than re-computing everything.
My program reports 8 solutions on a 3x6 grid:
As I mentioned, my Python solution isn't fast or optimized. It's possible to solve a 9x12 grid less than a second. Large optimizations aside, there are basic things I neglected in my implementation. For example, I copied the entire grid for each tile placement; adding/removing tiles on a single grid would have been an easy improvement. I also did not check for unsolvable gaps in the grid, which can be seen in the animation.
After you solve the the problem, be sure to hunt around for some of the mind-blowing solutions people have come up with. I don't want to give away much more than this!
There's a trick that's applicable to a lot of recursive enumeration problems. In whichever way you like, define a deterministic procedure for removing one piece from a nonempty partial solution. Then the recursive enumeration works in the opposite direction, building the possible solutions from the empty solution, but each time it places a piece, that same piece has to be the one that would be removed by the deterministic procedure.
If you verify that the board size is divisible by three before beginning the enumeration, you shouldn't have any problem with the time limit.

Procedural Maze Algorithm With Cells Determined Independently of Neighbors

I was thinking about maze algorithms recently (mostly because I'm working on a game, but I felt this is a more general question than game development related). In simple terms, I was wondering if there is a sort of maze algorithm that can generate (a possibly infinite number of) cells without any information specifically about the cell's neighbors. I imagine, if such a thing were possible, it would rely heavily upon noise functions such as Perlin or Simplex.
Each cell has four walls, these are used when actually rendering the maze so that corridors and walls are not the same thickness.
Let's say, for example, I'd like a cell at (32, 15) to generate its walls.
I know of algorithms like Ellers (which requires a limited number of columns, but infinite rows) and the Virtual fractal Mazes algorithm (which needs to know previous cells in order to build upon them infinitely in both x and y directions).
Does anyone know of any algorithm I could look into for this specific request? If not, are there any algorithms that are good for chunk-based mazes that you know of?
(Note: I did search around for a bit through StackOverflow to see if there were any questions with similar requests to mine, but I did not come across any. If you happen to know of one, a link would be greatly appreciated :D)
Thank you in advance.
Seeeeeecreeeets. My preeeeciooouss secretts. But yeah I can understand the frustration so I'll throw this one to you OP/SO. Feel free to update the PCG Wiki if you're not as lazy as me :3
There are actually many ways to do this. Some of the best techniques for procgen are:
Asking what you really want.
Design backwards. Play in reverse. Result is forwards.
Look at a random sampling of your target goal and try to see overall patterns.
But to get back to the question, there are two simple ways and they both start from asking what your really want. I'll give those first.
The first is to create 2 layers. Both are random noise. You connect the top and the bottom so they're fully connected. No isolated portions. This is asking what you really want which is connected-ness. And then guaranteeing it in a local clean-up step. (tbh I forget the function applied to layer 2 that guarantees connected-ness. I can't find the code atm.... But I remember it was a really simple local function... XOR, Curl, or something similar. Maybe you can figure it out before I fix this).
The second way is using the properties of your functions. As long as your random function is smooth enough you can take the gradient and assign a tile to it. The way you assign the tiles changes the maze structure but you can guarantee connectivity by clever selection of tiles for each gradient (b/c similar or opposite gradients are more likely to be near each other on a smooth gradient function). From here your smooth random can be any form of Perlin Noise, etc. Once again a asking what you want technique.
For backwards-reversed you unfortunately have an NP problem (I'm not sure if it's hard, complete, or whatever it's been a while since I've worked on this...). So while you could generate a random map of distances down a maze path. And then from there generate the actual obstacles... it's not really advisable. There's also a ton of consideration on different cases even for small mazes...
012
123
234
Is simple. There's a column in the lower right corner of 0 and the middle 2 has an _| shaped wall.
042
123
234
This one makes less sense. You still are required to have the same basic walls as before on all the non-changed squares... But you can't have that 4. It needs to be within 1 of at least a single neighbor. (I mean you could have a +3 cost for that square by having something like a conveyor belt or something, but then we're out of the maze problem) Okay so....
032
123
234
Makes more sense but the 2 in the corner is nonsense once again. Flipping that from a trough to a peak would give.
034
123
234
Which makes sense. At any rate. If you can get to this point then looking at local neighbors will give you walls if it's +/-1 then no wall. Otherwise wall. Also note that you can break the rules for the distance map in a consistent way and make a maze just fine. (Like instead of allowing a column picking a wall and throwing it up. This is just loop splitting at this point and should be safe)
For random sampling as the final one that I'm going to look at... Certain maze generation algorithms in the limit take on some interesting properties either as an average configuration or after millions of steps. Some form Voronoi regions. Some form concentric circles with a randomly flipped wall to allow a connection between loops. Etc. The loop one is good example to work off of. Create a set of loops. Flip a random wall on each loop. One will delete a wall which will create access to the next loop. One will split a path and offer a dead-end and a continuation. For a random flip to be a failure there has to be an opening and a split made right next to each other (unless you allow diagonals then we're good). So make loops. Generate random noise per loop. Xor together. Replace local failures with a fixed path if no diagonals are allowed.
So how do we get random noise per loop? Or how do we get better loops than just squares? Just take a random function. Separate divergence and now you have a loop map. If you have the differential equations for the source random function you can pick one random per loop. A simpler way might be to generate concentric circular walls and pick a random point at each radius to flip. Then distort the final result. You have to be careful your distortion doesn't violate any of your path-connected-ness conditions at that point though.

How to find neighboring solutions in simulated annealing?

I'm working on an optimization problem and attempting to use simulated annealing as a heuristic. My goal is to optimize placement of k objects given some cost function. Solutions take the form of a set of k ordered pairs representing points in an M*N grid. I'm not sure how to best find a neighboring solution given a current solution. I've considered shifting each point by 1 or 0 units in a random direction. What might be a good approach to finding a neighboring solution given a current set of points?
Since I'm also trying to learn more about SA, what makes a good neighbor-finding algorithm and how close to the current solution should the neighbor be? Also, if randomness is involved, why is choosing a "neighbor" better than generating a random solution?
I would split your question into several smaller:
Also, if randomness is involved, why is choosing a "neighbor" better than generating a random solution?
Usually, you pick multiple points from a neighborhood, and you can explore all of them. For example, you generate 10 points randomly and choose the best one. By doing so you can efficiently explore more possible solutions.
Why is it better than a random guess? Good solutions tend to have a lot in common (e.g. they are close to each other in a search space). So by introducing small incremental changes, you would be able to find a good solution, while random guess could send you to completely different part of a search space and you'll never find an appropriate solution. And because of the curse of dimensionality random jumps are not better than brute force - there will be too many places to jump.
What might be a good approach to finding a neighboring solution given a current set of points?
I regret to tell you, that this question seems to be unsolvable in general. :( It's a mix between art and science. Choosing a right way to explore a search space is too problem specific. Even for solving a placement problem under varying constraints different heuristics may lead to completely different results.
You can try following:
Random shifts by fixed amount of steps (1,2...). That's your approach
Swapping two points
You can memorize bad moves for some time (something similar to tabu search), so you will use only 'good' ones next 100 steps
Use a greedy approach to generate a suboptimal placement, then improve it with methods above.
Try random restarts. At some stage, drop all of your progress so far (except for the best solution so far), raise a temperature and start again from a random initial point. You can do this each 10000 steps or something similar
Fix some points. Put an object at point (x,y) and do not move it at all, try searching for the best possible solution under this constraint.
Prohibit some combinations of objects, e.g. "distance between p1 and p2 must be larger than D".
Mix all steps above in different ways
Try to understand your problem in all tiniest details. You can derive some useful information/constraints/insights from your problem description. Assume that you can't solve placement problem in general, so try to reduce it to a more specific (== simpler, == with smaller search space) problem.
I would say that the last bullet is the most important. Look closely to your problem, consider its practical aspects only. For example, a size of your problems might allow you to enumerate something, or, maybe, some placements are not possible for you and so on and so forth. THere is no way for SA to derive such domain-specific knowledge by itself, so help it!
How to understand that your heuristic is a good one? Only by practical evaluation. Prepare a decent set of tests with obvious/well-known answers and try different approaches. Use well-known benchmarks if there are any of them.
I hope that this is helpful. :)

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

Calculating a cutting list with the least amount of off cut waste

I am working on a project where I produce an aluminium extrusion cutting list.
The aluminium extrusions come in lengths of 5m.
I have a list of smaller lengths that need to be cut from the 5m lengths of aluminium extrusions.
The smaller lengths need to be cut in the order that produces the least amount of off cut waste from the 5m lengths of aluminium extrusions.
Currently I order the cutting list in such a way that generally the longest of the smaller lengths gets cut first and the shortest of smaller lengths gets cut last. The exception to this rule is whenever a shorter length will not fit in what is left of the 5m length of aluminium extrusion, I use the longest shorter length that will fit.
This seems to produce a very efficient (very little off cut waste) cutting list and doesn't take long to calculate. I imagine, however, that even though the cutting list is very efficient, it is not necessarily the most efficient.
Does anyone know of a way to calculate the most efficient cutting list which can be calculated in a reasonable amount of time?
EDIT: Thanks for the answers, I'll continue to use the "greedy" approach as it seems to be doing a very good job (out performs any human attempts to create an efficient cutting list) and is very fast.
This is a classic, difficult problem to solve efficiently. The algorithm you describe sounds like a Greedy Algorithm. Take a look at this Wikipedia article for more information: The Cutting Stock Problem
No specific ideas on this problem, I'm afraid - but you could look into a 'genetic algorithm' (which would go something like this)...
Place the lengths to cut in a random order and give that order a score based on how good a match it is to your ideal solution (0% waste, presumably).
Then, iteratively make random alterations to the order and re-score it. If the score is higher, ditch the result. If the score is lower, keep it and use it as the basis for your next calculation. Keep going until you get your score within acceptable limits.
What you described is indeed classified as a Cutting Stock problem, as Wheelie mentioned, and not a Bin Packing problem because you try to minimize the waste (sum of leftovers) rather than the number of extrusions used.
Both of those problems can be very hard to solve, but the 'best fit' algorithm you mentioned (using the longest 'small length' that fits the current extrusion) is likely to give you very good answers with a very low complexity.
Actually, since the size of material is fixed, but the requests are not, it's a bin packing problem.
Again, wikipedia to the rescue!
(Something I might have to look into for work too, so yay!)
That's an interesting problem because I suppose it depends on the quantity of each length you're producing. If they are all the same quantity and you can get Each different length onto one 5m extrusion then you have the optimum soloution.
However if they don't all fit onto one extrusion then you have a greater problem. To keep the same amount of cuts for each length you need to calculate how many lengths (not necessarily in order) can fit on one extrusion and then go in an order through each extrusion.
I've been struggling with this exact ( the lenght for my problem is 6 m) problem here too.
The solution I'm working on is a bit ugly, but I don't settle for your solution. Let me explain:
Stock size 5 m
Needs to cut in sizes(1 of each):
**3,5
1
1,5**
Your solution:
3,5 | 1 with a waste of 0,5
1,5 with a left over of 3,5
See the problem?
The solution I'm working on -> Brute force
1 - Test every possible solution
2 - Order the solutuion by their waste
3 - Choose the best solution
4 - Remove the items in the solution from the "Universe"
5 - Goto 1
I know it's time consuming (but I take 1h30 m to lunch... so... :) )
I really need the optimum solution (I do an almoust optimum solution by hand (+-) in excel) not just because I'm obsecive but also the product isn't cheap.
If anyone has an easy better solution I'd love it
The Column generation algorithm will quickly find a solution with the minimum possible waste.
To summarize, it works well because it doesn't generate all possible combinations of cuts that can fit on a raw material length. Instead, it iteratively solves for combinations that would improve the overall solution, until it reaches an optimum solution.
If anyone needs a working version of this, I've implemented it with python and posted it on GitHub: LengthNestPro

Resources