Reputation: 67
I've re-worded this search about as many times as I think I can and I've come up with nothing, so either this hasn't been asked before, or I don't know HOW to ask.
I am working on a personal project that boils down to trying to find the shortest path from a starting state to a finishing state.
There are too many (more than 2^64) states so I can't generate the entire graph. However, each state contains enough information to determine all the states adjacent to it. There are (infinitely) many paths from a state to another, and I am only interested in the shortest. This requires me to know if I've reached been to a state before, and also how I got there the first time.
My state object contains all the state information, as well as the depth of the path that lead me there, and the move I made to get there from the previous state in that path. If I get to the same state following a different path, the state information will be the same, but the depth and previous move fields will be different.
I want a data structure that will tell me if I have visited that state before, and if I have, retrieve the depth and previous state information from it.
The best solution I have come up with so far is to use a HashMap which maps a state to a state, and use the same state object as both the key and value, as in: myHashMap.put(myState, myState)
I've implemented hashCode() and equals() such that two states will be considered "equal" if their state information is the same (i.e. we've been in this room before) regardless of how I got there (i.e. which door I used to enter the room).
This seems rather silly but I can't think of another way (with fast storage/access) to store the information about whether I've been to a state and how I got there.
Does my plan make sense, or is there a better way?
Upvotes: 0
Views: 126
Reputation: 23349
If you see yourself storing key and value as the same value, then it is a Set
what you really need.
Set<State> set = new HashSet<>();
set.put(stat1);
And by the way your solution is not very far from that as HashSet
is backed by a HashMap
behind the scenes which means a HashSet has the performance characteristic as those of HashMap
and relies on equals
and hashCode
methods.
Upvotes: 1
Reputation: 786
You say that "I want a data structure that will tell me if I have visited that state before, and if I have, retrieve the depth and previous state information from it."
A Set (HashSet is likely better than a TreeSet for what you've described) will do the first part. Now, I see that you are trying to use a Map in order to do the second half which is retrieving the information. However, if you are already able to check if you've visited a state, that means you have a reference to the state. So, you don't need a map at all.
/* Marking a state as visited */
Set<State> visited = new HashSet<>();
visited.put(currentState);
/* Checking if visited/retrieving */
if (visited.contains(currentState)) {
// already visited
} else {
// do something with 'currentState'
}
Upvotes: 1