Okay I am new to Java, and I'm asking this question because I'm sure there is a better simple way to deal with this and the more experienced folk out there may be able to give me some pointers.
I have a graph of cities with lengths of paths between them. I am trying to construct an algorithm using Java to go from a start city to a destination city, finding the shortest path. Each city will have a name and map coordinates. More specifically I will be using the A* algorithm, but that is (probably) not important to my question.
My issue is I am trying to figure out a good way to represent the nodes and the paths between them with the length.
The easiest way I could think of was to create a huge 2 dimensional square array with each city represented by an index, where the connecting cities can be represented by where they intersect in the array. I assigned an index # to each city. In the array values, 0's would go where there is no connection, and the distance would go where there is a connection.
I will also have a city subclass with an "index" attribute, with the value of its index in the array. The downside to this is to figure out which cities have connections, there have to be extra steps to lookup what the city's index is in the array, and also having to lookup which connecting city has the connecting index.
Is there a better way to represent this?
An alternative way would be having a Node structure that store all the pointers to the adjacent nodes.
E.g.
if you have something like this in your data structure
A B C
A / 0 1
B 0 / 1
C 1 1 /
in the new structure it would be
A: [C]
B: [C]
C: [AB]
Compare to your 2D array approach, this way takes longer time to check if two nodes are connected, but uses smaller space
Consider...
class Node {
List<Link> link;
String cityName;
}
class Link {
Node destinationCity;
Long distance;
}
Related
I'm attempting to write a program which can identify all nodes in a graph that don't share any common neighbors, and in which all vertices are contained within the various subsystems in the graph. Assume all nodes are numerically labeled for simplicity.
For example, in a graph of a cube, the furthest corners share no common nodes and are part of subsystems that together contain all vertices.
I'm looking to write a program that compares each potential subsystem against all other potential subsystems, regardless of the graph, number of nodes or sides, and finds groups of subsystems whose central nodes don't share common neighbors. For simplicity's sake, assume the graphs aren't usually symmetrical, unlike the cube example, as this introduces functionally equivalent systems. However, the number of nodes in a subsystem, or elements in an array, can vary.
The goal for the program is to find a set of central nodes whose neighbors are each unique to the subsystem, that is no neighbor appears in another subsystem. This would also mean that the total number of nodes in all subsystems, central nodes and neighbors together, would equal the total number of vertices in the graph.
My original plan was to use a 2d array, where rows act as stand-ins for the subsystems. It would compare individual elements in an array against all other elements in all other arrays. If two arrays contain no similar elements, then index the compared array and its central node is recorded, otherwise it is discarded for this iteration. After the program has finished iterating through the 2d array against the first row, it adds up the number of elements from all recorded rows to see if all nodes in the graph are represented. So if a graph contains x nodes, and the number of elements in the recorded rows is less than x, then the program iterates down one row to the next subsystem and compares all values in the row against all other values like before.
Eventually, this system should print out which nodes can make up a group of subsystems that encompass all vertices and whose central nodes share no common neighbors.
My limited exposure to CS makes a task like this daunting, as it's just my way of solving puzzles presented by my professor. I'd find the systems by hand through guess-and-check methods, but with a 60+ node array...
Thanks for any help, and simply pointers in the right direction would be very much appreciated.
I don't have a good solution (and maybe there exists none; it sounds very close to vertex cover). So you may need to resort backtracking. The idea is the following:
Keep a list of uncovered vertices and a list of potential central node candidates. Both lists initially contain all vertices. Then start placing a random central node from the candidate list. This will erase the node and its one-ring from the uncovered list and the node plus its one-ring and two-ring from the candidate list. Do this until the uncovered list is empty or you run out of candidates. If you make a mistake, revert the last step (and possibly more).
In pseudo-code, this looks as follows:
findSolution(uncoveredVertices : list, centralNodeCandidates : list, centralNodes : list)
if uncoveredVertices is empty
return centralNodes //we have found a valid partitioning
if centralNodeCandidates is empty
return [failure] //we cannot place more central nodes
for every n in centralNodeCandidates
newUncoveredVertices <- uncoveredVertices \ { n } \ one-ring of n
newCentralNodeCandidates <- centralNodeCandidates \ { n } \ one-ring of n \ two-ring of n
newCentralNodes = centralNodes u { n }
subProblemSolution = findSolution(newUncoveredVertices, newCentralNodeCandidates, newCentralNodes)
if subProblemSolution is not [failure]
return subProblemSolution
next
return [failure] //none of the possible routes to go yielded a valid solution
Here, \ is the set minus operator and u is set union.
There are several possible optimizations:
If you know the maximum number of nodes, you can represent the lists as bitmaps (for a maximum of 64 nodes, this even fits into a 64 bit integer).
You may end up checking the same state multiple times. To avoid this, you may want to cache the states that resulted in failures. This is in the spirit of dynamic programming.
I need to implement a graph in Java. I cannot use the collection classes. I can readily create a graph using an Adjacency Matrix or an Adjacency List, but I need to create a directed graph using a linked structure.
I might be given the adjacency matrix form:
4 // square matrix size -- all would be square -- square only
0 1 1 0
1 1 1 1
1 0 0 0
1 1 0 1
NOTE: This is supposed to a a 4x4 matrix, but I cannot format correctly for StackOverflow. I do not know how to enter hard return.
Continuing my question, I found a similar question on StackOverflow:
Questions regarding Implementation of graph in c++
Where in the best accepted answer, pmr wrote:
1.) Yes, you can also implement it explicitly using pointers to other nodes.
This answer by pmr is the form of solution I need. This is where I am having trouble. I simply cannot picture this solution in my head. One of the problems is how do I allow for a number of child nodes that is read from a file so that I can refer to them for a search ? One adjacency list implementation would allow me to create an array of linked lists, but I cannot use that.
Is this a multi-graph ? Is this a problem that multi-graphs solve ?
Alternate: I have also envisioned a tree structure with multiple child nodes per parent.
How would I go about implementing this in Java ?
One possible solution:
Create a class representing each graph node.
class GraphNode {
LinkedList<GraphNode> children;
}
Each line of data you read in will represent a GraphNode. Each '1' in that line represents a link to the GraphNode at the same index as that '1'.
Create a GraphNode for each line and add it to a list/array of GraphNodes (maybe call it 'allNodes'). For each 1 or 0 on a line, increment a counter. If it is a 1, add the Node in allNodes at that index (use counter as the index) to the children of the current node.
Now you will have a list of GraphNodes, each with its own list of the GraphNodes it is connected to.
Hope that makes sense.
I've found many resources online, discussing this and related topics, but I haven't found anything that really helps me know where to start with implementing this solution.
To clarify, starting from city 0, I need to visit every other city once, and return back to city 0.
I have an array such as this one:
0 1129 1417 1240 1951
1129 0 1100 800 2237
1417 1100 0 1890 3046
1240 800 1890 0 1558
1951 2237 3046 1558 0
Along with finding the optimal route, I need to also find the optimal partial routes along the way. For example, I'd start with routes of length 2, and end up printing out something like this:
S = {0,1}
C({0,1},1) = 1129
S = {0,2}
C({0,2},2) = 1417
S = {0,3}
C({0,3},3) = 1240
S = {0,4}
C({0,4},4) = 1951
Then I'd go to routes of length 3, and print something like this:
S = {0,1,2}
C({0,1,2},1) = 2517
C({0,1,2},2) = 2229
and so on...
To make this a dynamic programming solution, I assume I should be saving the shortest distance between any n nodes, and the best way I've thought to do that is with a Hashmap, where the key would be an integer value of every node included in that path, in ascending order (A path going from nodes 0>1>3>4 or 0>1>4>3 could be stored as '134'), and each key would hold a pair that could store the path order as a List, and the total distance as an integer.
At this point I would think I'd want to calculate all paths of distance 2, then all of distance 3, and then take the smallest few and use the hashmap to find the shortest path back for each, and compare.
Does this seem like it could work? Or am I completely on the wrong track?
You're sort of on track. Dynamic programming isn't the way to calculate a TSP. What you're sort of close to is calculating a minimum spanning tree. This is a tree that connects all nodes using the shortest possible sum of edges. There are two algorithms that are frequently used: Primm's, and Kruskal's. They produce something similar to your optimal partial routes list. I'd recommend you look at Primm's algorithm: https://en.wikipedia.org/wiki/Prim%27s_algorithm
The easiest way of solving TSP is by finding the minimum spanning tree, and then doing a pre-order tree walk over the tree. This gives you an approximate travelling salesman solution, and is known as the Triangle Inequality Approximation. It's guaranteed to be no more than twice as long as an optimal TSP, but it can be calculated much faster. This web page explains it fairly well http://www.personal.kent.edu/~rmuhamma/Algorithms/MyAlgorithms/AproxAlgor/TSP/tsp.htm
If you want a more optimal solution, you'll need to look at Christofide's method, which is more complicated.
You are on the right track.
I think you're getting at the fact that the DP recursion itself only tells you the optimal cost for each S and j, not the node that attained that cost. The classical way to handle this is through "backtracking": once you found out that, for example, C({0,1,2,3,4},-) = 10000, you figure out which node attained that cost; let's say it's 3. Then you figure out which node attained C({0,1,2,3,4},3); let's say it's 1. Then you figure out which node attained C({0,1,2,4},1); let's say it's 2, ... and so on. This is the classical way and it avoids having to store a lot of intermediate data. For DPs with a small state space, it's easier just to store all those optimizers along the way. In your case you have an exponentially large state space so it might be expensive to store all of those optimizers, but you already have to store an equally large data structure (C), so most likely you can store the optimizers as well. Your intermediate solution of storing a few of the best could work -- then if the backtracking routine turns out to need one you didn't store you can just calculate it the classical way -- seems reasonable, but I'm not sure it's worth the extra coding vs. a pure backtracking approach.
One clarification: You don't actually want to "calculate all paths of distance 2, then all of distance 3, ...", but rather you want to enumerate all sets of size 2, then all sets of size 3, etc. Still exponential, but not as bad as enumerating all paths.
Hi I am new to Java so please using basic and simple Java methods that will help me quickly understand your idea.
Problem: I have n cities (each city has a unique names) and they are all connected to each other so that there is a distance between any 2 cities.
What is the best way to store those distances so later if I use name of 2 cities (since name is unique) I can retrieve distance between them?
I was thinking about using 2-D array but it doesn't seem like a good idea (possible duplication distance between A - B and B - A, also can't using city names) does it?
Why did somebody give thumb-downs to this question?
Two possibilities to add to your own Idea
HashMap of HashMap - heavier than 2D arrays, but provide ease of use, by city names directly.
Alternatively, make an enum with the names of the cities, and use the enum to index into the 2D array.
2DArray of variable dimension (non rectangular) - Each row can have a different size, store only half of the full matrix and derive the other half as needed. eg of creating a non rectangular array
If the distance between two cities is just the geometric distance, you only need to store the coordinates of each city.
Otherwise, store the distances in a N*N matrix, and keep an String[N] with the names.
Look in to the concept of collections in java. This should help you implement what you are looking for:
http://docs.oracle.com/javase/tutorial/collections/index.html
I have a binary tree that looks like this
the object that represents it looks like this (java)
public class node {
private String value = "";
private TreeNode aChild;
private TreeNode bChild;
....
}
I want to read the data and build the tree from a string.
So I wrote some small method to serialize it and I have it like this
(parent-left-right)
0,null,O#1,left,A#2,left,C#3,left,D#4,left,E#4,right,F#1,right,B#
Then I read it and I have it as a list - objects in this order O,A,C,D,E,F,B
And now my question is - how to I build the tree?
iterating and putting it on a stack, queue ?
should I serialize on a different order ?
(basically I want to learn the best practices for building a tree from string data)
can you refer me to a link on that subject ?
Given your second string representation, there is no way to retrieve the original tree. So unless any tree with that sequence is acceptable, you'll have to include mor information in your string. One possible way would be representing null references in some fashion. Another would be using parentheses or similar.
Given your first representation, restoring the data is still possible. One algorithm expliting the level information would be the following:
Maintain a reference x to the current position in your tree
For every node n you want to add, move that reference x up in your tree as long as the level of x is no less than the level of n
Check that now the level of x is exactly one less than the level of n
Make x the parent of n, and n the next child of x
Move x to now point at n
This works if you have parent links in your nodes. If you don't, then you can maintain a list of the most recent node for every level. x would then correspond to the last element of that list, and moving x up the tree would mean removing the last element from the list. The level of x would be the length of the list.
Your serialization is not well explained, especially regarding how you represent missing nodes. There are several ways, such as representing the tree structure with ()s or by using the binary tree in an array technique. Both of these can be serialized easily. Take a look at Efficient Array Storage for Binary Tree for further explanations.