Algorithm for high level planning in artificial intelligence - algorithm

I am currently working on an artificial intelligence project in which an agents needs to push and pull boxes from their original position to a certain goal position. The project will then be expanded to include multiple agents, so we have a supervisor that takes care of creating "high-level" goals, while the agents take care of the actual implementations.
In practice, for the moment, the supervisor should decide the order in which the boxes should be put on goal position. In fact, it could happen that putting a box in its goal position could block the path to another goal.
Our first approach to solve this problem is trying to consider "cut-positions". A certain position is a cut position if it divides the walkable space into two subsets, in which one of those we have the agent, and in the other we have one or more goals. For example, consider the following level in which "x" is the agent, "A" and "B" are boxes and "a" and "b" are the respective goal positions:
+++++++++++++++++++++++++++++++++++++++++
x a b+
+++++ +++++++++++++++++++++++++++++++++
+AB +
+++++
In this case the position of goal "a" is a cut position, because if a box is put there, then the agent will not be able to reach goal "b".
Can you suggest a fast algorithm to compute the cut positions, and that maybe returns the number of goals that each cut position is blocking?

What you call a cut position for your grid word is called a cut vertex or articulation point in general graphs. From Wikipedia:
Specifically, a cut vertex is any vertex whose removal increases the number of connected components.
And a bit further down in the same article:
The classic sequential algorithm for computing biconnected components in a connected undirected graph due to John Hopcroft and Robert Tarjan (1973) [1] runs in linear time, and is based on depth-first search. This algorithm is also outlined as Problem 22-2 of Introduction to Algorithms (both 2nd and 3rd editions).
Having determined the biconnected components, it should be quite easy to determine the articulation points: All nodes which are contained in more than one bi-connected component are articulation points.

You could put the area into an undirected graph, where each node is a position of the map and two nodes are connected if the positions are adjacent to each other. Then you can mark those 'cut positions' on the graph and see all the paths that would be blocked by a box on a cut position.

Related

Quickest way to determine if a rectangular graph would be partitioned if a node is removed

I am working on an atmospheric simulation for a video game, and a problem I have stumbled into is that I need a cheap (in processing time) way to determine if a graph of nodes in a rectangular grid (each node is connected to up to four neighbours, NSEW) would become partitioned if I removed a particular node.
I have tried searching for ways of detecting if a graph is partitioned but so far I have not found anything that suits my problem. I have not taken advanced math courses and only have basic knowledge of graph theory so it is possible that I just have not been searching with the right terms.
If possible, it would be very very desirable to avoid having to search through the whole graph.
You can find articulation points using a modified depth first search - see http://en.wikipedia.org/wiki/Biconnected_component. An articulation point of a graph is a node that, if removed, disconnects the graph. Every graph can be split up at the articulation points into biconnected components. If you are lucky, you just need to know whether a point is an articulation point. If not, perhaps splitting the graph up into a tree of biconnected components and analysing them will help.

How to search through different parts of a graph?

Recently I met a coding problem that asks you on a given graph to find out how many different "closed" sub-graphs there are. And after you have found that out you need to search each sub-graph and find how many element are there in each sub-graph. So now to define sub-graph. Let's say we're given
.#####.
#.....#
#.E##.#
#.#.#.#
#.#####
#E..#E#
.#####.
Think of it like a maze where dots represents moving space, while the hashtags are walls and you can move horizontally or vertically. So let's say you are at one point in the graph. All the points you can reach by moving horizontally or vertically are part of a that particular "closed" sub-graph. So for the given example we have 3 "closed" sub-graphs
1#####1
#11111#
#11##1#
#1#2#1#
#1#####
#111#3#
1#####3
Also there are 2 elements in the first sub-graph, no elements in the second and one in the 3rd.
I guess it really doesn't matter what searching method you use, so I used BFS starting from the first entered dot in the line. So once I've reach all possible points starting from that particular point I have found one sub-graph and I have counted how many elements there are in the sub-graph. But the problem now is how to find the starting point of the next sub-graph. I can not think of another way than iterating through the graph until you find a non-visited point and the apply the BFS repeateadly until you have visited all the points. But this method proves to be too much time-consuming, so is there any way I can efficiently find the sub-graphs? For example is there a way to stack at least a point from each sub-graph in a queue, while you're entering the line?
Instead of iterating through the entire graph to find non-visited points you could try iterating though just the walls adjacent to your known sub-groups and look for non-visited points adjacent to those walls. You would be able to compile the list of walls during the bfs.
You can first iterate the graph and find all possible "starting point", hold these elements in a set data structure, and when you do a BFS - for each point you find - remove it from the set of entry points.
Now, at each iteration - all you have to do is choose a random entry point from the set (which is guaranteed to be unvisited yet), and do a new BFS.

How to find certain sized clusters of points

Given a list of points, I'd like to find all "clusters" of N points. My definition of cluster is loose and can be adjusted to whatever allows an easiest solution: it could be N points within a certain size circle or N points that are all within a distance of each other or something else that makes sense. Heuristics are acceptable.
Where N=2, and we're just looking for all point pairs that are close together, it's pretty easy to do ~efficiently with a k-d tree (e.g. recursively break the space into octants or something, where each area is a different branch on the tree and then for each point, compare it to other points with the same parent (if near the edge of an area, check up the appropriate number of levels as well)). I recognize that inductively with a solution for N=N', I can find solution for N=N'+1 by taking the intersections between different N' solutions, but that's super inefficient.
Anyone know a decent way to go about this?
You start by calculating the Euclidean minimum spanning tree, e.g CGAL can do this. From there the precise algorithm depends on your specific requirements, but it goes roughly like this: You sort the edges in that graph by length. Then delete edges, starting with the longest one. It's a singly connected graph, so with each deleted edge you split the graph into two sub-graphs. Check each created sub-graph if it forms a cluster according to your conditions. If not, continue deleting edges.

A* for finding shortest path and avoiding lines as obstacles

I have to get the (shortest)/(an optimal) distance between two points in 2D. I have to avoid shapes that are lines, that may be connected together. Any suggestion on how to represent the nodes I can travel on? I have thought of making a grid, but this doesn't sound very accurate or elegant. I would consider a node as unwalkable if any point of a line is inside a square (with the node being the center of the square).
An example would be going from point A to B.
Is the grid the recommended way to solve this? Thanks A LOT in advance!
I think this is essentially Larsmans' answer made a bit more algorithmic:
Nodes of the graph are the obstacle vertices. Each internal vertex actually represents two nodes: the concave and the convex side.
Push the start node onto the priority queue with a Euclidean heuristic distance.
Pop the top node from the priority queue.
Do a line intersection test from the node to the goal(possibly using ray-tracing data-structure techniques for speedup). If it fails,
Consider a ray from the current node to every other vertex. If there are no intersections between the current node the vertex under consideration, and the vertex is convex from the perspective of the current node, add the vertex to the priority queue, sorted using the accumulated distance in the current node plus the distance from the current node to the vertex plus the heuristic distance.
Return to 2.
You have to do extra pre-processing work if there are things like 'T' junctions in the obstacles and I wouldn't be surprised to discover that it breaks in a number of cases. You might be able to make things faster by only considering the vertices of the connected component that lies between the current node and the goal.
So in your example, after first attempting A,B, you'd push A,8, A,5, A,1, A,11, and A,2. The first nodes of consideration would be A,8, A,1, and A,5, but they can't get out and the nodes they can reach are already pushed on the queue with shorter accumulated distance. A,2 and A,11 will be considered and things will go from there.
I think you can solve this by an A* search on a graph defined as:
Vertices: origin, destination and all endpoints of obstacle edges.
Edges (successor function): any pair of the previous where the corresponding line does not cross any obstacle's edges. A naive implementation would just check for intersection between a potential edge and all obstacle edges. A faster implementation might use some kind of 2-d ray tracing algorithm.
I.e., it's not necessary to discretize the plane into a grid, but without it, the successor function becomes difficult to define.
A grid, and A* running through it is the way to go. All games i am aware of use A* or an adaptation of it for the global route and complement it with steering behaviour for local accuracy. Maybe you were not aware that using steering behaviour will resolve all your concerns about accuracy (search-engine it).
EDIT: i just remember a strategy game that uses flow-field. But it is not main-stream.
BTW: to get a feel for what steering behavior does for your objects take a look at the many youtube-videos about it. Some of them use the term path-finding in a more general sense: including the global algorithm (A*) as well as collision-avoidance, path-smoothing and object-inertia involved in steering-behavior.

Graph Algorithm To Find All Paths Between N Arbitrary Vertices

I have an graph with the following attributes:
Undirected
Not weighted
Each vertex has a minimum of 2 and maximum of 6 edges connected to it.
Vertex count will be < 100
Graph is static and no vertices/edges can be added/removed or edited.
I'm looking for paths between a random subset of the vertices (at least 2). The paths should simple paths that only go through any vertex once.
My end goal is to have a set of routes so that you can start at one of the subset vertices and reach any of the other subset vertices. Its not necessary to pass through all the subset nodes when following a route.
All of the algorithms I've found (Dijkstra,Depth first search etc.) seem to be dealing with paths between two vertices and shortest paths.
Is there a known algorithm that will give me all the paths (I suppose these are subgraphs) that connect these subset of vertices?
edit:
I've created a (warning! programmer art) animated gif to illustrate what i'm trying to achieve: http://imgur.com/mGVlX.gif
There are two stages pre-process and runtime.
pre-process
I have a graph and a subset of the vertices (blue nodes)
I generate all the possible routes that connect all the blue nodes
runtime
I can start at any blue node select any of the generated routes and travel along it to reach my destination blue node.
So my task is more about creating all of the subgraphs (routes) that connect all blue nodes, rather than creating a path from A->B.
There are so many ways to approach this and in order not confuse things, here's a separate answer that's addressing the description of your core problem:
Finding ALL possible subgraphs that connect your blue vertices is probably overkill if you're only going to use one at a time anyway. I would rather use an algorithm that finds a single one, but randomly (so not any shortest path algorithm or such, since it will always be the same).
If you want to save one of these subgraphs, you simply have to save the seed you used for the random number generator and you'll be able to produce the same subgraph again.
Also, if you really want to find a bunch of subgraphs, a randomized algorithm is still a good choice since you can run it several times with different seeds.
The only real downside is that you will never know if you've found every single one of the possible subgraphs, but it doesn't really sound like that's a requirement for your application.
So, on to the algorithm: Depending on the properties of your graph(s), the optimal algorithm might vary, but you could always start of with a simple random walk, starting from one blue node, walking to another blue one (while making sure you're not walking in your own old footsteps). Then choose a random node on that path and start walking to the next blue from there, and so on.
For certain graphs, this has very bad worst-case complexity but might suffice for your case. There are of course more intelligent ways to find random paths, but I'd start out easy and see if it's good enough. As they say, premature optimization is evil ;)
A simple breadth-first search will give you the shortest paths from one source vertex to all other vertices. So you can perform a BFS starting from each vertex in the subset you're interested in, to get the distances to all other vertices.
Note that in some places, BFS will be described as giving the path between a pair of vertices, but this is not necessary: You can keep running it until it has visited all nodes in the graph.
This algorithm is similar to Johnson's algorithm, but greatly simplified thanks to the fact that your graph is unweighted.
Time complexity: Since there is a constant number of edges per vertex, each BFS will take O(n), and the total will take O(kn), where n is the number of vertices and k is the size of the subset. As a comparison, the Floyd-Warshall algorithm will take O(n^3).
What you're searching for is (if I understand it correctly) not really all paths, but rather all spanning trees. Read the wikipedia article about spanning trees here to determine if those are what you're looking for. If it is, there is a paper you would probably want to read:
Gabow, Harold N.; Myers, Eugene W. (1978). "Finding All Spanning Trees of Directed and Undirected Graphs". SIAM J. Comput. 7 (280).

Resources