Related
I realise I've written this like a homework question, but that's because it's the simplest way for me to understand and try to relay the problem. It's something I want to solve for a personal project.
I have cards laid out in a grid, I am starting with a simple case of a 2x2 grid but want to be able to extrapolate to larger n×n grids eventually.
The cards are all face down, and printed on the faces of the cards are either a:
positive non-zero integer, representing the card's 'score'
or the black spot.
I am given the information of the sum of the scores of each row, the number of black spots in each row, and the sum of the scores of each column, and the number of black spots in each column.
So the top row must have a sum score of 1, and exactly one of the cards is a black spot.
The rightmost column must have a sum score of 2, and exactly one of the cards is a black spot.
Etc.
Of course we can see the above grid will "solve" to
Now I want to make a function that inputs the given information and produces the grid of cards that satisfies those constraints.
I am thinking I can use tuple-like arguments to the function.
And then every "cell" or card in the grid is itself a tuple, the first element of the tuple will be the score of the card there (or 0 if it is a black spot) and the second element will be a 1 if the card is a black spot or a 0 otherwise.
So the grid will have to resemble that ^^
I can find out what all the a, b, variables are by solving this system of equations:
(Knowing also that all of these numbers are integers which are ≥0).
I wanted to use this problem as a learning exercise in prolog, I think it seems like a problem Prolog will solve elegantly.
Have I made a good decision or is Prolog not a good choice?
I wonder how I can implement this in Prolog.
Prolog is very good for this kind of problems. Have a look clp(fd), that is Constraint Logic Programming in Finite Domains.
This snippet shows a primitive way how to solve your initial 2x2 example in SWI Prolog:
:- use_module(library(clpfd)).
test(Vars) :-
Vars = [TopLeft, TopRight, BottomLeft, BottomRight],
global_cardinality([TopLeft, TopRight], [0-1,1-_,2-_]), TopLeft + TopRight #= 1,
global_cardinality([TopLeft, BottomLeft], [0-1,1-_,2-_]), TopLeft + BottomLeft #= 1,
global_cardinality([BottomLeft, BottomRight], [0-1,1-_,2-_]), BottomLeft + BottomRight #= 2,
global_cardinality([TopRight, BottomRight], [0-1,1-_,2-_]), TopRight + BottomRight #= 2,
label(Vars).
Query:
?- test(Vars).
Vars = [1, 0, 0, 2].
You can take this as a starting point and generalize. Note that the black dot is represented as 0, because clp(fd) deals only with integers.
Here is the documentation: http://www.swi-prolog.org/man/clpfd.html
I'm currently stuck on a challenge our lecturer gave us over at our university. We've been looking at the most popular pathfinding algorithms such as Dijkstra and A*. Although, I think this challenge exercise requires something else and it has me stumped.
A visual representation of the maze that needs solving:
Color legend
Blue = starting node
Gray = path
Green = destination node
The way it's supposed to be solved is that when movement is done, it has to be done until it collides with either the edge of the maze or an obstacle (the black borders). It would also need to be solved in the least amount of row-movements possible (in this case 7)
My question: Could someone push me in the right direction on what algorithm to look at? I think Dijkstra/A* is not the way to go, considering the shortest path is not always the correct path given the assignment.
It is still solvable with Dijkstra / A*, what needs to be changed is the configuration of neighbors.
A little background, first:
Dijkstra and A* are general path finding algorithms formulated on graphs. When, instead of a graph, we have a character moving on a grid, it might not be that obvious where the graph is. But it's still there, and one way to construct a graph would be the following:
the nodes of the graph correspond to the cells of the grid
there are edges between nodes corresponding to neighboring cells.
Actually, in most problems involving some configurations and transitions between them, it is possible to construct a corresponding graph, and apply Dijkstra/A*. Thus, it is also possible to tackle problems such as sliding puzzle, rubik's cube, etc., which apparently differ significantly from a character moving on a grid. But they have states, and transitions between states, thus it is possible to try graph search methods (these methods, especially the uninformed ones such as Dijkstra's algorithm, might not always be feasible due to the large search space, but in principle it's possible to apply them).
In the problem that you mentioned, the graph would not differ much from the one with typical character movements:
the nodes can still be the cells of the grid
there will now be edges from a node to nodes corresponding to valid movements (ending near a border or an obstacle), which, in this case, will not always coincide with the four spatial immediate neighbors of the grid cell.
As pointed by Tamas Hegedus in the comments section, it's not obvious what heuristic function should be chosen if A* is used.
The standard heuristics based on Manhattan or Euclidean distance would not be valid here, as they might over-estimate the distance to the target.
One valid heuristic would be id(row != destination_row) + id(col != destination_col), where id is the identity function, with id(false) = 0 and id(true) = 1.
Dijkstra/A* are fine. What you need is to carefully think about what you consider graph nodes and graph edges.
Standing in the blue cell (lets call it 5,5), you have three valid moves:
move one cell to the right (to 6,5)
move four cells to the left (to 1,5)
move five cells up (to 5,1)
Note that you can't go from 5,5 to 4,5 or 5,4. Apply the same reasoning to new nodes (eg from 5,1 you can go to 1,1, 10,1 and 5,5) and you will get a graph on which you run your Dijkstra/A*.
You need to evaluate every possible move and take the move that results with the minimum distance. Something like the following:
int minDistance(int x, int y, int prevX, int prevY, int distance) {
if (CollionWithBorder(x, y) // can't take this path
return int.MAX_VALUE;
if (NoCollionWithBorder(x, y) // it's OK to take this path
{
// update the distance only when there is a long change in direction
if (LongDirectionChange(x, y, prevX, prevY))
distance = distance + 1;
)
if (ReachedDestination(x, y) // we're done
return distance;
// find the path with the minimum distance
return min(minDistance(x, y + 1, x, y, distance), // go right
minDistance(x + 1, y, x, y, distance), // go up
minDistance(x - 1, y, x, y, distance), // go down
minDistance(x, y - 1, x, y, distance)); // go left
}
bool LongDirectionChange(x, y, prevX, prevY) {
if (y-2 == prevY && x == prevX) ||(y == prevY && x-2 == prevX)
return true;
return false;
}
This is assuming diagonal moves are not allowed. If they are, add them to the min() call:
minDistance(x + 1, y + 1, distance), // go up diagonally to right
minDistance(x - 1, y - 1, distance), // go down diagonally to left
minDistance(x + 1, y - 1, distance), // go up diagonally to left
minDistance(x - 1, y + 1, distance), // go down diagonally to right
Problem Statement: To find the nearest GRID ID of each of the particles using Octree.
Fig[1]:
Fig[2]:
I have a system of particles(~6k, movable) for which I need to check which grid point (rigid; in picture) is nearest to. Somebody have suggested me to go for Octree as it is fast(est) for 3D Grids.
Is this the correct Algorithm for recursive Octree to get the nearest grid point of the grid?
Get a input as point P Start coordinate C (first time it [0,0,0])
Start Size = [Sx, Sy, Sz]
Get all 8 mid point Mi = {M1,..,M8} get minimum distance of Mi and P
Say M get start position of M as Cn set size Sn = [Sx/8, Sy/8, Sz/8]
if distance of M and P is less than 2 * (Grid Space G):
5.1. Iterate all the grid points from Cn to Sn
5.2. Print least as result
else
6.1. set Start coordinate as Cn
6.2. set Size as Sn
6.3. Goto 1
Problem: The last iteration eat all speed if the particle is out or nearly on the border as it checks all A x B x C.
Please suggest if you have a better way to solve this problem.
There is no need to use an octree here. Octree is useful for the reverse problem (given a grid point, find the nearest particule) but completely useless here.
Assuming the size of a grid cell is (a, b, c), then the nearest grid point from (x, y, z) is (a*floor(x/a+0.5), b*floor(y/b+0.5), c*floor(z/c+0.5)).
Generally we traverse the array by row or column but here I want to traverse it in an angle.
I will try and explain what I mean,
So lets say if the angle is 45 degree then rather than row by col it would search as (0,0) then (0,1) (1,0) then (0,2) , (1,1) ,(2,0) and so on.. .(sorry could not upload an image as I am new user and not allowed to do so, may be try and imagine/draw an array that would help get what I am trying to say)
But what will happen if the user inputs an angle like 20 degree how can we determine how to search the array.
i just wanted to know if there is any algorithm which does something similar to this? Programming language is not an issue i guess the issue is more of algoritham sort.
Any ideas would be welcome.
Please feel free to ask if I am not able to explain clearly what I am looking for.
Thanks guys.
Easy. Take an angle (let's say 45). This corresponds to a vector v=(1, 1) in your case. (This can be normalized to a unitary vector (sqrt(2)/2, sqrt(2)/2), but this is not necessary)
For every single point in your array, you have their coordinates (x, y). Simply do the scalar product of these coordinates with the vector. Let's call f(x, y) = scalarProduct((x, y), v)
Sort the values of f(x, y) and you've got the "traversing" you're looking for!
A real example.
Your matrix is 3x3
The scalar products are :
(0,0).(1,1) = 0
(0,1).(1,1) = 1
(0,2).(1,1) = 2
(1,0).(1,1) = 1
(1,1).(1,1) = 2
(1,2).(1,1) = 3
(2,0).(1,1) = 2
(2,1).(1,1) = 3
(2,2).(1,1) = 4
If you order these scalar products by ascending order, you obtain the ordering (0,0), (1,0), (1,0), (2,0), (1,1), (0,2), (2,1)...
And if you want to do it with the angle 20, replace all occurences of v=(1, 1) with v=(cos(20), sin(20))
Here's an illustration of a geometrical interpretation. The scalar products correspond to the intersections of the vector v (in red) with the blue lines.
For every starting point (the leftmost point of every row), use trigonometry to determine an ending point for the given angle. The tan(angle) is defined as (height difference / width of the array), so your height differece is tan(angle)*(witdh of the array). You only have to calculate the height difference once. If y+height difference is greater than the height of the array, just subtract the height (or use the modulo operator).
Now that you have a starting point and an ending point you could use Bresenham's Algorithm to determine the points in between: http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
You want to look for a space-filling-curve for example a morton curve or z-curve. If you want to subdivide the array in 4 tiles you may want to look for a hilbert curve or a moore curve.
For this problem speed is pretty crucial. I've drawn a nice image to explain the problem better. The algorithm needs to calculate if edges of a rectangle continue within the confines of the canvas, will the edge intersect another rectangle?
We know:
The size of the canvas
The size of each rectangle
The position of each rectangle
The faster the solution is the better! I'm pretty stuck on this one and don't really know where to start.
alt text http://www.freeimagehosting.net/uploads/8a457f2925.gif
Cheers
Just create the set of intervals for each of the X and the Y axis. Then for each new rectangle, see if there are intersecting intervals in the X or the Y axis. See here for one way of implementing the interval sets.
In your first example, the interval set on the horizontal axis would be { [0-8], [0-8], [9-10] }, and on the vertical: { [0-3], [4-6], [0-4] }
This is only a sketch, I abstracted many details here (e.g. usually one would ask an interval set/tree "which intervals overlap this one", instead of "intersect this one", but nothing not doable).
Edit
Please watch this related MIT lecture (it's a bit long, but absolutely worths it).
Even if you find simpler solutions (than implementing an augmented red-black tree), it's good to know the ideas behind these things.
Lines that are not parallel to each other are going to intersect at some point. Calculate the slopes of each line and then determine what lines they won't intersect with.
Start with that, and then let's see how to optimize it. I'm not sure how your data is represented and I can't see your image.
Using slopes is a simple equality check which probably means you can take advantage of sorting the data. In fact, you can probably just create a set of distinct slopes. You'll have to figure out how to represent the data such that the two slopes of the same rectangle are not counted as intersecting.
EDIT: Wait.. how can two rectangles whose edges go to infinity not intersect? Rectangles are basically two lines that are perpendicular to each other. shouldn't that mean it always intersects with another if those lines are extended to infinity?
as long as you didn't mention the language you chose to solve the problem, i will use some kind of pseudo code
the idea is that if everything is ok, then a sorted collection of rectangle edges along one axis should be a sequence of non-overlapping intervals.
number all your rectangles, assigning them individual ids
create an empty binary tree collection (btc). this collection should have a method to insert an integer node with info btc::insert(key, value)
for all rectangles, do:
foreach rect in rects do
btc.insert(rect.top, rect.id)
btc.insert(rect.bottom, rect.id)
now iterate through the btc (this will give you a sorted order)
btc_item = btc.first()
do
id = btc_item.id
btc_item = btc.next()
if(id != btc_item.id)
then report_invalid_placement(id, btc_item.id)
btc_item = btc.next()
while btc_item is valid
5,7,8 - repeat steps 2,3,4 for rect.left and rect.right coordinates
I like this question. Here is my try to get on it:
If possible:
Create a polygon from each rectangle. Treat each edge as an line of maximum length that must be clipped. Use a clipping algorithm to check weather or not a line intersects with another. For example this one: Line Clipping
But keep in mind: If you find an intersection which is at the vertex position, its a valid one.
Here's an idea. Instead of creating each rectangle with (x, y, width, height), instantiate them with (x1, y1, x2, y2), or at least have it interpret these values given the width and height.
That way, you can check which rectangles have a similar x or y value and make sure the corresponding rectangle has the same secondary value.
Example:
The rectangles you have given have the following values:
Square 1: [0, 0, 8, 3]
Square 3: [0, 4, 8, 6]
Square 4: [9, 0, 10, 4]
First, we compare Square 1 to Square 3 (no collision):
Compare the x values
[0, 8] to [0, 8] These are exactly the same, so there's no crossover.
Compare the y values
[0, 4] to [3, 6] None of these numbers are similar, so they're not a factor
Next, we compare Square 3 to Square 4 (collision):
Compare the x values
[0, 8] to [9, 10] None of these numbers are similar, so they're not a factor
Compare the y values
[4, 6] to [0, 4] The rectangles have the number 4 in common, but 0 != 6, therefore, there is a collision
By know we know that a collision will occur, so the method will end, but lets evaluate Square 1 and Square 4 for some extra clarity.
Compare the x values
[0, 8] to [9, 10] None of these numbers are similar, so they're not a factor
Compare the y values
[0, 3] to [0, 4] The rectangles have the number 0 in common, but 3 != 4, therefore, there is a collision
Let me know if you need any extra details :)
Heh, taking the overlapping intervals answer to the extreme, you simply determine all distinct intervals along the x and y axis. For each cutting line, do an upper bound search along the axis it will cut based on the interval's starting value. If you don't find an interval or the interval does not intersect the line, then it's a valid line.
The slightly tricky part is to realize that valid cutting lines will not intersect a rectangle's bounds along an axis, so you can combine overlapping intervals into a single interval. You end up with a simple sorted array (which you fill in O(n) time) and a O(log n) search for each cutting line.