I'm new here, but I have searched for solutions to this issue for a couple hours and even though I kinda found some answers, but none of them actually worked.
I have an Array List called "parents" (of a node in this case) of the type "State" (8 queens arranged in a chess board). I am declaring it like this:
ArrayList<State> parents = new ArrayList<State>(3);
Likewise, I have a "children" array of states declared like this:
ArrayList<State> children = new ArrayList<State>(7);
I have to rearrange the state of the board so I don't have any queens in position to attack each other, using the Beam Search method. To do this, I have to copy the state of the parents to the children, randomly rearrange the queens in the children and check if the number of attacks in their states has lowered, rinse and repeat until I get 0 attacks (or the algorithm has gone on long enough without finding a better state than the last).
Finally, after this "contextualization" of the problem, let's go to the Issue per se.
Whenever I change the position of a queen in a child state, it is also changed in the parent state, even though I tried a lot of workarounds to passing an object from an ArrayList to another without copying the references. Right now, I'm doing it like this:
ArrayList <State> buffer = new ArrayList<State>(parents);
children.add(buffer.get(m)); //the m here is just so I can choose in a for witch parent will be copied to the children array
And then I am changing the queen values like this (not exactly this, but the actual code would require more contextualization and I would digress from the issue even more:
children.get(k).board[queen]=k;//basically changing the "Y" position of the queen to a "k" value that comes from a loop.
When I change the value of the queen in the children state like this, the parent state is also changed, and this is what I can't for the life of me fix, and I did try using some answers found here before I made this post, like using the clone method, like this:
buffer=(ArrayList<State>) parents.clone();
or the Collections.copy method:
ArrayList<State> buffer = new ArrayList<State>(3);
Collections.copy(buffer, parents);//actually this one gives me an out of bounds error, stating that the source does not fit in the destiny
and some others, but all to no avail, the parent values still get modified.
Does anyone have an Idea of what can be done to fix this? Or am I approaching the problem in a way that it can't be fixed? I'm also kinda new to Java so it is possible that I missed something in one of the solutions I've previously found, so if anyone out there is really sure that one of those methods have to work in my case, by all means, explain it and I will try to use it again.
(also, I tried to "build" the post in the better possible way, if anyone have any suggestion on how to formulate my questions in the future, they are also welcome)
Cheers :)
Related
I have a load of vecmath Point objects (Point3d FWIM) which I would like to “group” based on the distance between them. I can probably write the code for this from scratch (I’ve done similar tasks in excel), but I like the idea of using existing libraries where possible. The problem is I can’t find any libraries like this.
I haven’t thought through the exact algorithm fully, but I hope I’ve done enough for the question not to be deleted. Please bear with me, I'm still new here at the time of this post.
I imagine the grouping would work as follows:
decide the distanceLimit
loop 1: for each Point, calculate the distance to each other Point
Make a "Set"
loop 2: for each Point
if the next Point is within the distanceLimit of any previously considered Points up to i, add it to current "Set"
Else make a new "Set".
Edit: ah the power of verbalising one's ideas. The above doesn't the capture the situation where points 1 and 2 are between one and two distanceLimits apart and initiate separate "sets", and point 3 crops up halfway between them meaning that all three should be in one set really. Need to think about this some more!
I’m also not sure yet what data structures I should really use for the input and output (ArrayLists? Sets?).
Ideally I am looking for an existing library that does this or similar; if you’re confident there isn’t one, then any suggestions for the algorithm or the actual code would be more than welcome.
After lots more googling, I found that:
what I was trying to do is called clustering;
this did exactly what I was trying to do; I was impressed with how well it worked for me.
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?
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'
}
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.
Lets say I have a graph and a starting node. Each note has a weight.
The problem is to find all paths from the starting node where the sum of weights of the nodes are, say, five.
A simple approach is to do a depth first search, and, on discovering the sum of the current path is five, you could simply copy the solution into a list of solutions.
This simply solution would require you to search the entire tree until there are no more possibilities. What if you only needed one solution? Or two? Or the best out of 100? Wouldn't this approach waste potentially a large amount of memory storing all solutions?
I imagine you could write some sort of Iterator, where .next() simply continues the search until it finds a new path. This way you waste no storage or computation time.
I figured I'd ask if such a known pattern, or solution, or algorithm exists before trying to reinvent the wheel.
Additionally:
My actual problem is a special Iterator which finds all trees matching a certain condition, but I assumed the answer to the more general path problem would lead me closer to the solution to my problem. Any information on this would also be very much appreciated.
You could simply pass around a count in your function and return when you've reached that count.
void dfs(List<...> solutions, int count, ...)
{
// check for solution and add to solutions
if (solutions.size() == count)
return;
...
dfs(solutions, count, ...);
if (solutions.size() == count)
return;
...
}
This is probably the solution requiring the least changes (C# has functionality that allows you to have "some sort of Iterator, where .next() simply continues the search until it finds a new path", but Java doesn't, to my knowledge).
Alternate solutions are:
Have multiple threads. Let one thread run your function, adding items to a global list. Let another thread access this list and presumably add some functionality to have the one running your function stop after adding an element to the list, and let the other thread resume it, or something like that.
If you're using a recursive function, convert this to an iterative one, and store the Stack in a class variable after generating a single solution, and return, allowing you to continue again.
There exists an algorithm used to solve exactly your problem.
It is called the Djikstra's Algorithm and is used to solve shortest path node problems.
You can find codes of it on the web, and probably learn more as well.
Wikilink
I have a program which has a structure like this.
Document which contains (up to 20)
Chapters which contain (up to 100)
Pages which contain (up to 20)
Elements
This structure is represented by JPanels in my program. Meaning this structure has to be visually represented, and I'd rather not make a whole complex of ArrayList (unless absolutely neccessary) since each JPanels have a ZOrder of component, and a getParent() method.
This structure is one-dimenisonal, meaning that the parent has an one-dimensional array (and when I say array, it's purely descriptive, I don't mean ArrayList or anything similar) of its children. Each individual element has an index which represents it's location in(on?) it's parent. Number of elements in a page, and pages in a chapter is inconsistent.
It's easy to get the child's index within it's parent, but what about it's grandparents?
Since the elements can be (and usually are) numbered, having a one numbered list per chapter, I'd have to know the index of element in the Chapter, so I can adjust the numbers when a new element is added to the list (it doesn't have to be added in the end).
This can be solved in two ways (that I know of, that is):
Have an ArrayList in each chapter that keeps all the elements. This would require me that, everytime I add a new element to any page, to add it to the chapter array too.
To accomplish that I'd have to go trough all the previous pages, add up all the elements on them and add index of the new element on the present page to that number, the result being the index of the new element in the chapter, and therfore, in the array. And do that each time I add a new element.
Recreate the arrayList each time I need to get the order of elements in the chapter. Which again means going trought each page and adding each element one after another until I reach the end of chapter. And I'd need it each time a new element is added.
So the question is, which of this two methods is better (more efficient memory or processor time wise)? Which is more in the spirit of Java and programming altogether? Is there a third option that I am unaware of??
Chapter example:
Page one {
1. something
2. more something
3. nothing
.
.
.
16. still nothing
}
Page two {
17. maybe something
18. nope, still nothing
.
.
.
21. giberish
}
etc.
The question is: Which way of doing it is better? If you have a better idea, you can tell me, but I want to know which way of the above two is better non the less.
You need to make a tree. For some reason, programmers want to flatten everything out into tabular structures. You are talking about a tree, you need to either use one or make one.
Sadly, there is nothing in the Java Collections for implementing Trees. You can make them fairly easily.
If you have things that are different contained in the tree, but that need to be treated similarly (as nodes), then do a simple implementation of the Composite Pattern. A good example is a filesystem tree: each node is either a Folder or a File. If you both have them implement an interface called FilesystemItem, then you can put them into their tree structure.
Since you are doing a Document, I would recommend Composite.
a while ago i wrote an editor for a navigation graph that represented the paths inside (and between) buildings. it was stored inside a Graph-class.
the edges, for example were stored in one collection per floor, plus one collection for the ones that were between floors.
to draw them (only the current floor) or save them to disk (all of them), i needed to get at them from the outside. for that i implemented methods like callWithAllEdges and callWithAllEdgesIn, the latter taking a parameter to specify a floor.
those methods took a functor (at least i called it that), that was then called with the edges.
this is what drawing the edges of one floor looked like:
graph.callWithAllEdgesIn(id, new Functor<Edge>() {
public void call(Edge e) {
drawEdge(g,e);
}
});
this is a bit long-winded, of course. might be a problem with java and not with my solution though, i dont know.
another way would have been to just make a method that puts references to all the needed edges into a new collection and then iterate over that, i guess. seemed kind of wrong to me though.
my question is: how could i have solved that better?
Your current design is perfectly reasonable. Another option is to provide an Iterable/Iterator. That way you don't need to copy everything into a new list, but can instead lazily step through your internal lists.