Java TSP Permute Points - java

Doing a project for school where we implement the Nearest Neighbor heuristic (which I have already done), and the Traveling Salesperson Problem where we do an exhaustive search (we then analyze the algorithms, their time complexity, etc). Our teacher said to look around for code to use (or modify) for the exhaustive search part instead of programming the whole thing as in the Nearest Neighbor portion. I have looked around, put only found stuff that does not pertain to how we were instructed to do our program.
As opposed to the typical problem where you use integers, we are using points (x, y).
My goal would be to calculate the shortest permutation and be able to know what that permutation was. So I'm thinking to have an array of array's (which contains the permutations).
If someone could help me out with the exhaustive search that would be nice.
Here is some excerpts from my code (member variables, function to calculate distance between two points, and where all the points are stored):
private int x;
private int y;
private boolean visited;
public double dist( point pt ){
int xdist = this.getX() - pt.getX();
int ydist = this.getY() - pt.getY();
double xsr = xdist*xdist;
double ysr = ydist*ydist;
return Math.sqrt( xsr + ysr );
}
point[] points = new point[n];
Any help is greatly appreciated.

A single TSP possible solution is essentially just an array of cities which represents the order in which to visit them, without the starting city.
So, presume n (the number of cities) = 5. Then a single possible solution is represented as an array of length 4. Now, how many ways can you order the cities [B, C, D, E]?
BCDE, BCED, BDCE, BDEC, ... That's 4! or 24 combinations. So for n cities you got (n-1)! combinations. For 10 cities that makes 362880 combinations. For 20 cities or 10^17 combinations you 'll run out of memory if you want to keep them all into memory.
An additional problem is that you 'll need n nested for loops, but it's impossible to just write those for loops, because there are n. (You can just start writing for() for() for() ....
So, your implementation will probably need some sort of walker approach, where you have a single loop that ticks through all combinations, much like a digital clock with each digit representing 1 index in the array.

You don't need (extra) memory for generating all permutations/solutions for a given instance. You can just write them on the screen...
Take a look at this implementation https://github.com/stardog-union/pellet/blob/master/core/src/main/java/org/mindswap/pellet/utils/PermutationGenerator.java.
It generates at each call of getNext() a new solution.
public void PermGen() {
int[] tour;
PermutationGenerator x = new PermutationGenerator(N);
System.out.println(x.getTotal());
while (x.hasMore()) {
tour = x.getNext();
System.out.println(Arrays.toString(tour));
}
}
The Java code above prints all TSP instance solutions...
But You can of course save them (in file(s) for example) but you'll need hundred of Terabytes to do it.

Related

Is there a way to reduce complexity when modelling interactions between nodes in a simulation engine?

I am building a simulation in Java w/JavaFX UI.
The idea is that I can create many Person objects (in an array) which will contain (x,y) co-ordinates to denote positioning for rendering on the screen. At each step in time I will iterate through the array and apply some to the Person objects to calculate their next position (based on current velocity etc). So far so good...
However, I also want to model interactions between Person objects (make sure that they can't overlap for instance and would just bounce off each other). The only way that I can see to do this is by iterating over the array for each Person to compare their x,y values against every other person e.g.
Person [] population = initialisePopulationArray(); //Helper function to just set initial values
//A step in time occurs just before I render the new positions on screen
void step(){
//Do basic initial calculation on positions O(n)
for(Person person: population){
updatePosition(person); //Based on trajectory etc
}
//Determine if new positions mean that people are overlapping and resolve O(n ^ 2)
for(int i=0; i<population.length; i++){ //For every person
Person person = population[i];
for(int x=i+1; i<population.length-(i+1); i++){ //Compare against every other person
compareAndResolve(person, population[x]; // Some function to compare and resolve any issues
}
}
}
As you can see this gives exponential complexity - is this just the way it has to be in a simulation like this or is there a better way that I have missed?
Any help would be greatly appreciated!!!
If two people don't interact as long as they are farther apart than some distance d, then you can divide your world into squares of size d x d. Then you only have check each person against other people in the same or adjacent squares.
In Java you could use, for example, a Hashmap<java.awt.Point, List<Person>> to keep track of which people are in each square.

Nearest Neighbour using KDtree

I know how to construct a kd tree .But the problem that i am facing is how to find nearest neighbour using KD Tree.I have searched on google but not able to find code for finding nearest neighbour,though algos are given . But I am facing difficulty in converting that algo into code because of Language.
Can you please provide me understandable code for NNSearch in java?
Here is pseudocode that assumes the target point is not stored in the tree. (If it is, just add logic to ignore it):
nearest_point = NULL
nearest_distance = INFINITE;
target_point = <set to the target point>
void nn_search(KD_NODE node) {
FLOAT d = node->point.distance_to(target_point);
if (d < nearest_distance) {
nearest_distance = d;
nearest_point = node->point;
}
BOX left_bb = node->left.bounding_box();
BOX right_bb = node->right.bounding_box();
if (left_bb.contains(target)) {
search_children(node->left, node->right, right_bb);
else { // right_bb must contain target
search_children(node->right, node->left, left_bb);
}
}
void search_children(KD_NODE a, KD_NODE b, BOX b_bb) {
nn_search(a);
// This condition makes the search expected O(log n) time rather than O(n).
// Skip searching the other child unless it might improve the answer.
if (b_bb.contains_point_closer_than(target, nearest_distance)) {
nn_search(b);
}
}
After this has run, nearest_point contains the nearest point to the target. Note that it's simple to compute the bounding boxes as parameters of nn_search rather than storing them inside the nodes, which this code appears to do. In production code you'd want to do that to save the space of 4 floats per node. I've omitted the parameters for simplicity.
The predicate contains_point_closer_than returns true if there exists any point in the bounding box that's closer to the target than the given distance. Happily it's enough to consider only one point in the box. E.g if the current node splits the search space into left and right halves at X, then you only need to consider the point (X, Y_target) and its distance to the target. That distance is just abs(X - X_target)! I'll let you convince yourself of this without further discussion
I know two Java kd-tree implementations that support kNN search, here and here. Theirs performance appears to be roughly equivalent.

Finding Rectangle which contains a Point

In Java SE 7, I'm trying to solve a problem where I have a series of Rectangles. Through some user interaction, I get a Point. What I need to do is find the (first) Rectangle which contains the Point (if any).
Currently, I'm doing this via the very naieve solution of just storing the Rectangles in an ArrayList, and searching for the containing Rectangle by iterating over the list and using contains(). The problem is that, because this needs to be interactive for the user, this technique starts to be too slow for even a relatively small number of Rectangles (say, 200).
My current code looks something like this:
// Given rects is an ArrayList<Rectangle>, and p is a Point:
for(Rectangle r : rects)
{
if(r.contains(p))
{
return r;
}
}
return null;
Is there a more clever way to solve this problem (namely, in O(log n) instead of O(n), and/or with fewer calls to contains() by eliminating obviously bad candidates early)?
Yes, there is. Build 2 interval trees which will tell you if there is a rectangle between x1 to x2 and between y1 and y2. Then, when you have the co-ordinates of the point, perform O(log n) searches in both the trees.
That'll tell you if there are possibly rectangles around the point of interest. You still need to check if there is a common rectangle given by the two trees.

Fast way to sort really big vector

I have a really big vector that stores 100000 different values,ranging from 0 to 50000.
They represent the cylinders on a hard disk,and I want to sort this vector according to three different algorithms used for disk scheduling.
So far,I read those 100000 values from a file,store them into a vector and then sort them according to the desired algorithm(FCFS,SCAN,SSTF).The problem is,it takes too long,because I'm doing it in the least creative way possible:
public static Vector<Integer> sortSSTF(Vector<Integer> array){
Vector<Integer> positions = new Vector<Integer>(array);
Vector<Integer> return_array = new Vector<Integer>();
int current_pos = 0,minimum,final_pos;
while(positions.size() > 0){
minimum = 999999;
final_pos = current_pos;
for(int i=0 ; i < positions.size() ; i++){
//do some math
}
}
return_array.add(final_pos);
current_pos = final_pos;
positions.removeElement(final_pos);
}
return return_array;
}
My function takes a vector as a parameter,makes a copy of it,does some math to find the desired element from the copied array and store him in the other array,that should be ordered according to the selected algorithm.But in a array with N elements,it is taking N! iterations to complete,which is way too much,since the code should do that at least 10 times.
My question is, how can I make this sorting more efficient?
Java already has built-in methods to sort a List very quickly; see Collections.sort.
Vector is old and incurs a performance penalty due to its synchronization overhead. Use a List implementation (for example, ArrayList) instead.
That said, based on the content of your question, it sounds like you're instead having difficulty implementing the Shortest Seek Time First algorithm.
See related question Shortest seek time first algorithm using Comparator.
I don't think you can implement the SSTF or SCAN algorithm if you don't also supply the current position of the head as an argument to your sorting method. Assuming the initial value of current_postion is always 0 will just give you a list sorted in ascending order, in which case your method would look like this:
public static List<Integer> sortSSTF(List<Integer> cylinders) {
List<Integer> result = new ArrayList<Integer>(cylinders);
Collections.sort(result);
return result;
}
But that won't necessarily be a correct Shortest Seek Time First ordering if it's ever possible for current_pos > 0 when you first enter the method. Your algorithm will then probably look something like this:
Collections.sort(positions);
find the indices in positions that contain the nextLowest and nextHighest positions relative to current_pos (or currentPos, if following Java naming conventions)
whichever position is closer, remove that position from positions and add it to return_array (If it was nextLowest, also decrement nextLowestIndex. If it was nextHighest, increment nextHighestIndex)
repeat step 3 until positions is empty
return return_array.
Of course, you'll also need to check for nextLowestIndex < 0 and nextHighestIndex >= positions.size() in step 3.
Note that you don't need the for loop inside of your while loop--but you would use that loop in step 2, before you enter the while loop.

Finding neighbors to Points in an ArrayList

I've recently started learning Java and though doing a "Conway's Game of Life" style program would be a good thing to start out with. Everything works fine but I'm having some serious performance issues with this part:
static List<Point> coordList = new ArrayList<Point>();
public int neighbors(int x, int y){
int n = 0;
Point[] tempArray = { new Point(x-1, y-1), new Point(x, y-1), new Point(x+1, y-1),
new Point(x-1, y ), new Point(x+1, y ),
new Point(x-1, y+1), new Point(x, y+1), new Point(x+1, y+1)};
for (Point p : tempArray) {
if (coordList.contains(p))
n++;
}
return n;
}
The method is used when iterating the ArrayList coordList filled with Points and checking every element how many neighbors they have. When the list size gets to about 10000 Points every cycle takes about 1 seconds and for 20000 Points it takes 7 seconds.
My question is, what would be a more effective way to do this? I know there are several other programs of this kind with source code available too look at, but I wan't do do as much as I can by my self since the point of the project is me learning Java. Also, I don't want to use a regular array because of the limitations.
If your points are unique, you could store them in a HashSet instead of an ArrayList. The contains method will then become an O(1) operation vs. O(n) in your current setup. That should speed up that section significantly.
Apart from the declaration, your code should remain mostly unchanged as both implement the Collection interface, unless you call List-specific method such as get(i) for example.
Performance-wise, I think your best bet is to have a plain numeric (effectively Boolean) array representing the grid. Since this is a learning exercise, I'd start with a simple one-element-per-cell array, and then perhaps progress to packing eight adjacent cells into a single byte.
It is not entirely clear what you mean by "the limitations".
The following has some interesting pointers: Optimizing Conway's 'Game of Life'
Your current code scales in a quadratic manner O(n^2). You have only given part of the program. If you look at your whole program there will be a loop that calls neighbors() and you will see that neighbors() is called n times. Also the operation contains() is linear in n, so the time is proportional to their product n*n.
Quadratic scaling is a common problem but can often be reduced to linear by using indexed data structures such as HashSet.

Categories

Resources