Quickest Algorithm to write for this? - algorithm

Given a 20x30 'sheet of graph paper' mark any even n number of cells so that every cell has an odd number of marked neighboring cells and so that all the cells connect making one 'piece'
Neighboring cells are defined as immediately adjacent cells. (All surrounding cells excluding diagonal cells).
I'm having a problem coming up with a clean algorithm. I currently have one and it's very messy and confusing and I just know there has to be a much better way to do it, I'm just not sure how. I'm looking for a quickly implemented algorithm because I don't have much time left to do the program and we have to code it in Ada which isn't a strength of mine.
I currently am making use of I made like so,
CanMark(cell); -- Checks if the cell can be marked.
HasProblem(cell); -- Checks if the cell has an even number of surrounding marked cells.
HasFix(cell); -- Checks if there is a sequence of cells that can be marked to eliminate currently existing problem.
I don't have the code with me at the moment but I will post when I get home.
Any help would be greatly appreciated.
Sorry for being unclear. I am just asking for a direction not for you to do my problem for me. I feel like this could be done using a graph related algorithm but don't know enough to know for sure. I don't have my code with me right at the moment, but I will certainly post it when I am able to.

I would start small, and build up. The smallest (n=1) is simply:
*
that clearly doesn't work since there are 0 neighbors (and even number). So no solution exists for n=1. Next, try n=2. Only one choice:
**
This works.
Now what about n=3? Doesn't work, no solution for n=3.
Now, how can you add to it to make n=4? n=6? Can you form a pattern?

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.

Defining a special case of a subset-sum with complications

I have a problem that I have a number of questions about. First, I'm mostly looking for help describing and understanding the problem at hand. Solutions are always welcome, but most importantly I could use some advice from someone more experienced than I. Now, to the problem at hand:
I have a set of orders that each require some number of items. I also have several groupings of items that each contain some number of some items (call them groups). The goal is to find a subset of the orders that can be fulfilled using as few groups as possible and where the total number of items contained within the orders is between n and N.
Edit: The constraints on the number of items contained in the orders (n and N) are chosen independently.
To me at least, that's a really complicated way of saying the problem so I've been trying to re-phrase it as a knapsack problem (I suspect this might reduce to a subset-sum). To help my conceptual understanding of this I've started using the following definitions:
First, lets say that a dimension exists for each possible item, and somethings 'length' in that dimension is the number of that particular type of item it either has or requires.
From this, an order becomes an 'n-dimensional object' where its value in each dimension corresponds to the number of that item that it requires.
In addition, a group can be seen as an 'n-dimensional box' that has space in each dimension corresponding to the number of items it provides.
An objects value is equal to the sum of its length in all dimensions.
Boxes can be combined.
Given the above I've rephrased the problem to this:
What is the smallest combination of boxes that can hold a combination of items with value between n and N.
Question #1: Is this a correct/useful way to express the problem? Does it seem like I've missed anything obvious?
As I see it, since there are two combinations that I'm looking for I need to break the problem into two parts. So far I think breaking the problem up like this is a good step:
How many objects can box (or combination of boxes) X hold?
Check all (or preferably some small subset of) the possible combinations of boxes and pick the 'best'.
That makes it a little more manageable, but I'm still struggling with the details.
Question #2: Solved To solve the first part I think it's appropriate to say that the cost of an object is equal to the sum of its length in all dimensions, so is it's value. That places me into a subset-sum problem, right? Obviously it's a special case, but does this problem have a name?
Question #3: Solved I've been looking into subset-sum solutions a lot, but I don't understand how to apply them to something like this in multiple dimensions. I assume it's been done before, but I'm unsure where to start my research. Could someone either describe the principles at work or point me in a research direction?
Edit: After looking at everyone's feedback and digging into the terms I think I've found a good algorithm I can implement to solve part 1. Since I will have a very large number of dimensions compared to the number of items it looks like using a 'primal effective capacity heuristic (PECH)' will be a good fit. I'd be interested in hearing someones thoughts about it if they have experience with such an algorithm.
Question #4: For the second part, performance is a concern and I doubt it will be realistic to brute force it. So I intend to treat all combinations of boxes as a really big tree of solutions. The idea is to compute part 1 for all combinations of M-1 boxes where M is the total number of boxes. Somehow determine the 'best' couple box combinations from that set and do the same to their child nodes on the tree. Does this sound like it would help me arrive at something close to optimal? How would I choose the 'best' box combinations?
Thanks for reading! Suggestions for edits and clarifications are welcome.

CuFrog solving using CLPFD

Ok, so I have this puzzle that is called the CuFrog, that consists in filling a 3x3x3 cube with a number in each position but leaping over a position when going from one to the other. For instance, considering a flattened cube, the valid position to the right of (1,1) on side 1 would be (3,1) on side 1.
So I'm using Constraints in Prolog to do this and I've given the domain of each variable (1 to 54), I've said they must all be different and that, for each position, one of the positions in the set right-left-down-up has to be the current value of such position + 1.
Also, I've given an entry point to the puzzle, which means I placed the number 1 already on the first position.
Thing is, SICStus is not finding me an answer when I'm labelling the variables. :( It seems I must be missing a restriction somewhere or maybe I'm doing something wrong. Can anyone help?
Thanks.
So you say the CLP(FD) doesn't find a solution. Do you
mean it terminates with "no" or do you mean it doesn't
terminate?
The problem looks like a Hamiltonian path problem. It
could be that the search needs exponential time, and simply
doesn't terminate in practical time.
In this particular case, giving restrictions like symmetry
breaking heuristics, could in fact reduce the search time!
For example from your starting point, you could fix the search
in 2 directions, the other directions can be derived later.
So if the answer is "No", this means too many restrictions.
If the answer is that it doesn't terminate, this means not
enough restrictions or impossible to practically solve.
Despite all the brute force you put into searching a path,
it might later turn out that a solution is systematic. Or
you might get the idea by yourself.
Bye

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.

N-Puzzle with 5x5 grid, theory question

I'm writing a program which solves a 24-puzzle (5x5 grid) using two heuristic. The first uses how many blocks the incorrect place and the second uses the Manhattan distance between the blocks current place and desired place.
I have different functions in the program which use each heuristic with an A* and a greedy search and compares the results (so 4 different parts in total).
I'm curious whether my program is wrong or whether it's a limitation of the puzzle. The puzzle is generated randomly with pieces being moved around a few times and most of the time (~70%) a solution is found with most searches, but sometimes they fail.
I can understand why greedy would fail, as it's not complete, but seeing as A* is complete this leads me to believe that there's an error in my code.
So could someone please tell me whether this is an error in my thinking or a limitation of the puzzle? Sorry if this is badly worded, I'll rephrase if necessary.
Thanks
EDIT:
So I"m fairly sure it's something I'm doing wrong. Here's a step-by-step list of how I'm doing the searches, is anything wrong here?
Create a new list for the fringe, sorted by whichever heuristic is being used
Create a set to store visited nodes
Add the initial state of the puzzle to the fringe
while the fringe isn't empty..
pop the first element from the fringe
if the node has been visited before, skip it
if node is the goal, return it
add the node to our visited set
expand the node and add all descendants back to the fringe
If you mean that sliding puzzle: This is solvable if you exchange two pieces from a working solution - so if you don't find a solution this doesn't tell anything about the correctness of your algorithm.
It's just your seed is flawed.
Edit: If you start with the solution and make (random) legal moves, then a correct algorithm would find a solution (as reversing the order is a solution).
It is not completely clear who invented it, but Sam Loyd popularized the 14-15 puzzle, during the late 19th Century, which is the 4x4 version of your 5x5.
From the Wikipedia article, a parity argument proved that half of the possible configurations are unsolvable. You are probably running into something similar when your search fails.
I'm going to assume your code is correct, and you implemented all the algorithms and heuristics correctly.
This leaves us with the "generated randomly" part of your puzzle initialization. Are you sure you are generating correct states of the puzzle? If you generate an illegal state, obviously there will be no solution.
While the steps you have listed seem a little incomplete, you have listed enough to ensure that your A* will reach a solution if there is one (albeit not optimal as long as you are just simply skipping nodes).
It sounds like either your puzzle generation is flawed or your algorithm isn't implemented correctly. To easily verify your puzzle generation, store the steps used to generate the puzzle, and run it in reverse and check if the result is a solution state before allowing the puzzle to be sent to the search routines. If you ever generate an invalid puzzle, dump the puzzle, and expected steps and see where the problem is. If the puzzle passes and the algorithm fails, you have at least narrowed down where the problem is.
If it turns out to be your algorithm, post a more detailed explanation of the steps you have actually implemented (not just how A* works, we all know that), like for instance when you run the evaluation function, and where you resort the list that acts as your queue. That will make it easier to determine a problem within your implementation.

Resources