Say I have p nodes on a n by m pixel 2D surface, I want the nodes to be attracted to each other such that the further they are apart the strong the attraction. But if the distance between two nodes, say d(A,B) is less than some threshold say k then they start to repel. Could anyone get me started on some code on how to update the co-ordinates of the nodes over time.
I have something a little like the code below which is start to do the attraction, but looking for some advice. (P.S. I can not use an existing library to do this).
public class node{
float posX;
float posY;
}
public class mySimulator{
ArrayList<node> myNodes = new ArrayList<node>();
// Imagine I add a load of nodes to myNodes
myNodes.add(.....
// Now image this is the updating routine that is called at every fixed time increment
public void updateLocations(){
for(int i =0; i <= myNodes.size(); i++){
for(int i =0; i <= myNodes.size(); i++){
myNodes.get(i).posX = myNodes.get(i).posX + "some constant"*(myNodes.get(j).posX -myNodes.get(i).posX);
myNodes.get(i).posY = myNodes.get(i).posY + "some constant"*(myNodes.get(j).posY -myNodes.get(i).posY);
}
}
}
}
}
This kinetic model of elastic collisions is completely unrelated to magnetism, but the design might give you some ideas on modeling an ensemble of interacting particles.
Say I have p nodes on a n by m pixel 2D surface, I want the nodes to be attracted to each other such that the further they are apart the strong the attraction. But if the distance between two nodes, say d(A,B) is less than some threshold say k then they start to repel.
You realize, of course, that this is not how the physics of magnetism work?
Could anyone get me started on some code on how to update the co-ordinates of the nodes over time.
Nobody will be able to give you code to do this easily, because it's actually a difficult problem.
You can numerically integrate the ordinary differential equations for each particle over time. Given initial conditions for position, velocity, and acceleration vectors in 2D, you'll take a time step, integrate the equations to get the values at the end of the time step, update the values by adding the increment, and then doing it again.
It requires some knowledge of 2D vectors, numerical integration, ordinary differential equations, linear algebra, and physics. Do you know anything about those?
Even if you "make up" your own physical laws governing the interactions between your particles, you'll still have to integrate that set of equations.
I'd recommend looking at Runge-Kutta for systems of ODEs. "Numerical Recipes" has a nice chapter on it, even if you go elsewhere for the implementation.
"NR" is now in its third edition. It's a bit controversial, but the prose is very good.
Related
So I have a fairly large array that contains xyz coordinates, where array[0] = x0, array[1] = y0, array[2] = z0, array[3] = x1, array[4] = y1... and so on.
I'm running an algorithm on this array that is taking longer than I would like it to, and I want to split the work amongst threads. I have my threads set up, but I am not sure how to divide this array properly so I can distribute this work across 3 threads.
Even though I have an array length that is divisible by 3, this won't work, because splitting into 3 can split an xyz coordinate (for instance, if my array was size 15, dividing it by 3 will give me arrays of size 5, which means I'm splitting an XYZ coordinate.
How can I split this array (it doesn't have to necessarily be equal in size) so that I can distribute the work? (for instance, in the previous example, I would like to have two arrays of size 6 and one of size 3).
Note: The size of the array is variable, but is always divisible by 3.
EDIT: Sorry, should have mentioned that I'm working in Java. My algorithm iterates through a collection of coordinates and determines which coordinates lie inside of a particular 3d shape (such as an ellipsoid). It saves these coordinates and I perform other tasks with these coordinates (I'm working on a computer graphics app).
EDIT2: I'm going to elaborate on the algorithm a bit more.
Basically, I am working in Android OpenGL-ES-3.0. I have complex 3D-object with somewhere around 230000 vertices and close to a million triangles.
In the app, the user moves either a ellipsoid or box (they choose which one) to a location close to or on the object. After moving it, they click a button, which runs my algorithm.
The purpose of the algorithm is to determine which points from my object lie inside of the ellipsoid or box. These points are subsequently changed to a different color. To add to the complexity, however, is the fact that I have transformation matrices applied to both the points of the object and the points of the ellipsoid/box.
My current algorithm begins by iterating through all the points of the object. For those of you unclear on my iteration, this is my loop.
for(int i = 0; i < numberOfVertices*3;)
{
pointX = vertices[i];
i++;
pointY = vertices[i];
i++;
pointZ = vertices[i];
i++;
//consider transformations, then run algorithm
}
I perform the necessary steps to consider all my transformations, and after that is finished, I have a point from my object and the location of my ellipsoid/box centroid.
Then, depending on the shape, one of the following algorithms is used:
Ellipsoid: I use the centroid of the ellipse and apply the formula
(x−c)T RT A R(x−c) (sorry I don't know how to format that, I'll explain the formula). x is a column vector describing the xyz point from my object that I am on in my iteration. c is a column vector describing the xyz point of my centroid. T is supposed to mean transpose. R is my rotation matrix. A is a diagonal matrix with entries with entries (1/a^2, 1/b^2, 1/c^2), and I have values for a b and c. If this formula is > 1, then x lies outside of my ellipsoid and is not a valid point. If it is <=1, then I save x.
Box: I simply check if the point falls within a range. If the point of the object lies a certain distance in the X-direction, Y-direction, and Z-direction from the centroid, I save it.
These algorithms are accurate, and work as intended. The issue, is obviously efficiency. I don't seem to have a good understanding of what makes my app strain and what doesn't. I thought multi-threading would work, and I tried some of the techniques described but they didn't have a significant improvement on performance. If anyone has ideas on filtering out my search so I'm not iterating through all these points, it would help.
May I suggest a slightly different way to handle it. I know this isn't a direct answer to your question, but please consider it.
This could be easier to see if you implemented it as coordinate Objects, each with x, y and z values. Your "array" would now be 1/3 as long. You might think this would be less efficient--and you might be right--but you'd be surprised at how well java can optimize things. Often Java optimizes for the cases people use the most and your manually manipulating this array as you suggest is possibly even slower than using objects. Until you've proven the most readable design too slow you shouldn't optimize it.
Now you have a collection of coordinate objects. Java has queues that multiple threads can pull from efficiently. Dump all your objects into a queue and have each of your threads pull one and work on it by processing it and putting it in a "Completed" queue. Note that this gives you the ability to add or remove threads easily, without effecting your code except for 1 number. How would you take the array based solution to 4 or 6 threads?
Good luck
Here is a demo of the work explained below.
Observations
Each coordinate is 3 indexes.
You have 3 threads.
Let's say you have 17 coordinates, that's 51 indexes. You want to split the 17 coordinates among your 3 threads.
var arraySize = 51;
var numberOfThreads = 3;
var numberOfIndexesPerCoordinate = 3;
var numberOfCoordinates = arraySize / numberOfIndexesPerCoordinate; //17 coordinates
Now split that 17 coordinates among your threads.
var coordinatesPerThread = numberOfCoordinates / numberOfThreads; //5.6667
This isn't an even number, so you need to distribute unevenly. We can use Math.floor and modulo to distribute.
var floored = Math.floor(coordinatesPerThread); //5 - every thread gets at least 5.
var modulod = numberOfCoordinates % floored; // 2 - there will be 2 left that need to be placed sequentially into your thread pool
This should give you all the information you need. Without knowing what language you are using, I don't want to give any real code samples.
I see you edited your question to specify Java as your language. I'm not going to do the threading work for you, but I'll give a rough idea.
float[] coordinates = new float[17 * 3]; //17 coordinates with 3 indexes each.
int numberOfThreads = 3;
int numberOfIndexesPerCoordinate = 3;
int numberOfCoordinates = coordinates.length / numberOfIndexesPerCoordinate ; //coordinates * 3 indexes each = 17
//Every thread has this many coordinates
int coordinatesPerThread = Math.floor(numberOfCoordinates / numberOfThreads);
//This is the number of coordinates remaining that couldn't evenly be split.
int remainingCoordinates = numberOfCoordinates % coordinatesPerThread
//To make things easier, I'm just going to track the offset in the original array. It could probably be computed instead, but its just an int.
int offset = 0;
for (int i = 0; i < numberOfThreads; i++) {
int numberOfIndexes = coordinatesPerThread * numberOfIndexesPerCoordinate;
//If this index is one of the remainders, then increase by 1 coordinate (3 indexes).
if (i < remainingCoordinates)
numberOfIndexes += numberOfIndexesPerCoordinate ;
float[] dest = new float[numberOfIndexes];
System.arraycopy(coordinates, offset, dest, 0, numberOfIndexes);
offset += numberOfIndexes;
//Put the dest array of indexes into your threads.
}
Another, potentially better option would be to use a Concurrent Deque that has all of your coordinates, and have each thread pull from it as they need a new coordinate to work with. For this solution, you'd need to create Coordinate objects.
Declare a Coordinate object
public static class Coordinate {
protected float x;
protected float y;
protected float z;
public Coordinate(float x, float y, float z) {
this.x = x;
this.y = y;
this.z = z;
}
}
Declare a task to do your work, and pass it your concurrent deque.
public static class CoordinateTask implements Runnable {
private final Deque<Coordinate> deque;
public CoordinateTask(Deque<Coordinate> deque) {
this.deque = deque;
}
public void run() {
Coordinate coordinate;
while ((coordinate = this.deque.poll()) != null) {
//Do your processing here.
System.out.println(String.format("Proccessing coordinate <%f, %f, %f>.",
coordinate.x,
coordinate.y,
coordinate.z));
}
}
}
Here's the main method showing the example in action
public static void main(String []args){
Coordinate[] coordinates = new Coordinate[17];
for (int i = 0; i < coordinates.length; i++)
coordinates[i] = new Coordinate(i, i + 1, i + 2);
final Deque<Coordinate> deque = new ConcurrentLinkedDeque<Coordinate>(Arrays.asList(coordinates));
Thread t1 = new Thread(new CoordinateTask(deque));
Thread t2 = new Thread(new CoordinateTask(deque));
Thread t3 = new Thread(new CoordinateTask(deque));
t1.start();
t2.start();
t3.start();
}
See this demo.
Before trying to optimize with concurrency, try to minimize the amount of points you need to test, and minimize the cost of those tests, by using the most efficient collision detection methods at your disposal.
Some general suggestions:
Consider normalizing everything to a common frame of reference before running through your calculations. For example, instead of applying transformations to each point, transform the selection box/ellipsoid into the shape's coordinate system so you can perform your collision detection without the transformations within each iteration.
You may also be able to combine some or all of your transformations (rotation, translation, etc.) into a single matrix calculation, but that won't gain you much unless you're performing a lot of transformations, which you should try to avoid.
Generally speaking it's beneficial to keep the transformation pipeline as streamlined as possible, and keep all coordinate calculations in the same space to avoid transformations as much as possible.
Try to minimize the number of points you need to perform your slowest calculations on. The most accurate collision test should only be necessary for points that you can't rule out as being inside the shape by faster means, using an approximation of the shape, such as a collection of spheres, or the shape's convex hull. Simplifying the shape allows you to limit the slowest calculations to only those points that lie very close to your shape's actual bounds.
In my own 2D work in the past I found that even calculating the convex hulls for hundreds of complex animated shapes in real time was faster than doing collision detection directly without using their convex hulls, because they enable much faster collision calculations.
Consider calculating/storing additional information about the shape, such as an inner and outer collision sphere (one sphere inside all points, and one outside all points) which you can use as a fast initial filter. Anything inside the smaller sphere is guaranteed to be inside your shape, anything outside the outer sphere is known to be outside your shape. You might even want to store a simplified version of your shape, (or its convex hull), which you could calculate in advance and use to aid collision detection.
Similarly, consider using one or more spheres to approximate your ellipsoid in initial calculations, to minimize which points you need to test for collision.
Instead of calculating actual distances, calculate the squared distances and use those for comparison. However, prefer using faster tests for collision if possible. For example, for convex polygons you can use the Separating Axis Theorem, which projects vertices onto a common axis/plane to permit very quick overlap calculations.
I would like to use Simulated Annealing to find local minimum of single variable Polynomial function, within some predefined interval. I would also like to try and find Global minimum of Quadratic function.
Derivative-free algorithm such as this is not the best way to tackle the problem, so this is only for study purposes.
While the algorithm itself is pretty straight-forward, i am not sure how to efficiently select neighbor in single or n-dimensional space.
Lets say that i am looking for local minimum of function: 2*x^3+x+1 over interval [-0.5, 30], and assume that interval is reduced to tenths of each number, e.g {1.1, 1.2 ,1.3 , ..., 29.9, 30}.
What i would like to achieve is balance between random walk and speed of convergence from starting point to points with lower energy.
If i simply select random number form the given interval every time, then there is no random walk and the algorithm might circle around. If, on the contrary, next point is selected by simply adding or subtracting 0.1 with the equal probability, then the algorithm might turn into exhaustive search - based on the starting point.
How should i efficiently balance Simulated Annealing neighbor search in single dimensional and n-dimensional space ?
So you are trying to find an n-dimensional point P' that is "randomly" near another n-dimensional point P; for example, at distance T. (Since this is simulated annealing, I assume that you will be decrementing T once in a while).
This could work:
double[] displacement(double t, int dimension, Random r) {
double[] d = new double[dimension];
for (int i=0; i<dimension; i++) d[i] = r.nextGaussian()*t;
return d;
}
The output is randomly distributed in all directions and centred on the origin (notice that r.nextDouble() would favour 45º angles and be centred at 0.5). You can vary the displacement by increasing t as needed; 95% of results will be within 2*t of the origin.
EDIT:
To generate a displaced point near a given one, you could modify it as
double[] displaced(double t, double[] p, Random r) {
double[] d = new double[p.length];
for (int i=0; i<p.length; i++) d[i] = p[i] + r.nextGaussian()*t;
return d;
}
You should use the same r for all calls (because if you create a new Random() for each you will keep getting the same displacements over and over).
In "Numerical Recepies in C++" there is a chapter titled "Continuous Minimization by Simulated Annealing". In it we have
A generator of random changes is inefficient if, when local downhill moves exist, it nevertheless almost always proposes an uphill move. A good generator, we think, should not become inefficient in narrow valleys; nor should it become more and more inefficient as convergence to a minimum is approached.
They then proceed to discuss a "downhill simplex method".
I've created a text based game which automatically generates a map with 10x10 rooms, a few of the rooms are blocked by various debris and I couldn't work out the most efficient way to check if a player can still reach a key and get to the exit without them being cut off from the map.
Currently there's a low chance needed rooms are cut off from the rest of the map, making the level impossible, I thought about checking each adjacent square to the start position, and then repeat and repeat until all of the squares that are accessible are set to 'accessible' in a variable and then if the three objects aren't reachable just regen'ing the map again until they are.
This may be slow if it regens a few times though.
Does anyone have any thoughts on the repetitive part to keep it fast, or a better way of achieving this?
Here's an image of a generated map: #'s are blocked rooms.
http://postimg.org/image/8oo88jxgb/
You can use the Dijkstra's algorithm, or some other pathfinding algorithm, to check if there is a way from the room entrance to each object and then discard the invalid rooms. This would probably be a bit slow though, specially if the rooms get bigger or you add more objects.
A better option would be to guarantee by construction that each part of the room can be reached. This can be achieved using Binary Space Partioning (BSP). It can be used to create random dungeons while assuring that all the rooms are connected. You can find more information in this tutorial.
There is a lot of material about procedurally generated dungeons around. You can check another interesting tutorial here.
The real problem is that programmers have spent far too much time
worrying about efficiency in the wrong places and at the wrong times;
premature optimization is the root of all evil (or at least most of
it) in programming.
Donald Knuth (1974 Turing Award Lecture, Communications of the ACM 17 (12), (December 1974), pp. 667–673)
Taking Knuth's advice, I recommend implementing the simplest solution that comes to mind (as outlined in the question, for example) and only looking for a more efficient algorithm if that approach turns out to be a bottleneck in the program. If he was right for computers with the performance they had in 1974, he's much more right now ...
You could represent your board as a graph holding a coordinate value as the key and a set of coordinates as the values representing each coordinates neighbors..example Map<Coordinate, HashSet<Coordinate> = new Hashmap<Coordinate, HashSet<Coordinate>();.
Then populate the graph with each coordinate value as a key with their respective neighbors as their values.
Whenever a blocked off room appears, simply remove that coordinate from each of the coordinates neighbors that surround it.
So if you have coordinate (5,5) as a blocked room, you would removed (5,5) from (4,5)s neighbor set, (5,4)s neighbor set, (6,5)s neighbor set, and (5,6)s neighbor set. This would basically not allow you to move through this path any more.
To populate the graph you could use two loops:
for(int r = 0; r <= 10; r++){
for(int c = 0; c <= 10; c++){
HashSet<Coordinate> neighbors = new HashSet<Coordinate>();
if(r > 0){
neighbors.add(new Coordinate(r - 1, c));
}
if(r < 8){
neighbors.add(new Coordinate(r + 1, c));
}
if(c > 0){
neighbors.add(new Coordinate(r, c - 1));
}
if(c < 8){
neighbors.add(new Coordinate(r, c + 1));
}
graph.put((new Coordinate(r,c)), neighbors);
}
}
I hope this is what you were asking for.
Make an array A with a row for each room and a column for each room.
Put a 1 in each i, j (row,column) position if the two rooms are connected.
This matrix( A ) is the numeric representation of the graph that is your game, the nodes of the graph are rooms and the edges are doors.
Now take a vector with a length corresponding to the number of rooms you have and fill it with zeros except for a one in the position corresponding to the room you start in. This vector( P ) is the number of ways you can get to a given room after 0 transitions. To check if it is possible to get to a given room in ( n )transitions simply multiply P A^n and look for a non zero value in the position in the vector that represents the given room.
this is a generalization of maths described well here https://en.wikipedia.org/wiki/Markov_chain
I'm doing some video processing, for each frame I need to get a gradient of a bi-variate function.
The function is represented as a two dimensional array of doubles. Where the domain is the rows and columns indices and the range is the double value of the corresponding indices values. Or more simply put, the function f is defined for double[][] matrix as such:
f(x,y)=matrix[x][y]
I'm trying to use the Apache Commons Math library for it:
SmoothingPolynomialBicubicSplineInterpolator iterpolator = new SmoothingPolynomialBicubicSplineInterpolator();
BicubicSplineInterpolatingFunction f = iterpolator.interpolate(xs, ys, matrix.getData());
for (int i = 0; i < ans.length; i++) {
for (int j = 0; j < ans[0].length; j++) {
ans[i][j] = f.partialDerivativeY(i, j);
}
}
with xs, as a sorted array of the x indices (0,1,...,matrix.getRowDimension() - 1)
ys the same on the columns dimension (0,1,...,matrix.getColumnDimension() - 1)
The problem is that for a typical matrix in the size of 150X80 it takes as much as 1.4 seconds to run, which renders it completely irrelevant for my needs. So, as a novice user of this library, and programmatic numeric analysis in general, I want to know:
Am I doing something wrong?
Is there another, faster, way I can accomplish this task with?
Is there another open source library (preferably maven-friendly) that offers a solution?
Numerical differentiation is an entire topic unto itself, a simple google should bring up enough material for you to work with (just the wiki might be sufficient). There are parameters of your problem that I cannot know, so I can only speak broadly here, but there are direct methods of determining the gradient at a given point, i.e. ones that don't require an interpolation. See the wikipedia for the formulae (ranging from the simple f(x+1)-f(x), which is where h=1, to the higher order ones). Calculating the partial derivatives is then a simple O(NM) loop with an uber easy formula inside (no interpolation required).
The specifics can get gritty:
The higher order formulae need to be reduced for the edges, or
discarded altogether.
Your precise speed requirements might render more complex formulae useless (depending on the platform sometimes the lookup times for higher order formulae make them too slow; again, it depends on the cache etc.). This is easy to test, the formulae are simple; code them and benchmark.
The specific implementation is also dependent on your error requirements. The theory provides error bounds, so that will play a role in what formula you need; but again, there's a trade-off with speed requirements. The in turn can be practically lowered if you know specifics about the types of matrices you'll be processing, if such a thing is known.
The implementation can be made even easier (and maybe faster) if you have existing convolution tools, since this method is really just a convolution of the matrix (note; technically it's called a cross-correlation).
I want to solve a 3-dimesional knapsack problem.
I got a number of boxes with a different width, height, length and value. I got a specified space and I want to put the boxes into that space, such that I will get the optimal profit. I would like to do it with using bruteforce.
I'm programming in Java.
I tried to do it with recursion, so:
public void solveBruteforce(double freeX, double freeY, double freeZ) {
for(int i = 0; i < numOfBoxes; i++) {
for(int j = 0; j < BoxObject.numOfVariations; j++) {
if(possible to place box) {
place(box);
add(value);
solveBruteforce(newX, newY, newZ);
}
}
}
remove(box);
remove(value);
}
But I will get the problem that each line has a different free x, y and z.
Could someone help me to find another way to do it?
First thing is, use an octree to keep track of where things are in the space. Occupancy tree is a 3D 4-out-degree tree, with occupancy flags at every node, dividing your space into a place that is efficient to search over. This would be useful if you want to use some kind of heuristic search to place the boxes, and even if you are trying all possibilities. It can shortcut the forbidden (crowded) placements.
Brute force will take a long time. But if that's what you want you need to define an ordering for trying out permutations of placements.
Since you will need many iterations, recursion is not so great since you will get a stack overflow.
A first-draft alternative would involve a greedy algorithm. Take the box that maximizes your profit (say, the largest), place that, then take the next largest box, and find the best fit for that, and so on.
But, say you wanted to try all possible combinations:
def maximize_profit(boxes,space):
max_profit = 0
best_fits = list()
while(Arranger.hasNext()):
a_fit,a_profit = Arranger.next(boxes,space)
if (a_profit == max_profit):
best_fits.append(a_fit)
elif (a_profit > max_profit):
max_profit = a_profit
best_fits = [ a_profit ]
return best_fits, max_profit
For ideas on how to define the Arranger, think about choosing #{box} slots from #{space} possibilities, respecting arrangements that are identical w.r.t. symmetry. Alternately maybe a "flood fill" method will give you ideas.