I'm coding a Q-Learning implementation for a game and the Q-Learning state requires a 7-dimensional array because I have everything about the game on it (player x, player y, monsters, treasures, possible moves, etc...)
Everything adds up to more than 1 billion states and the memory can't handle a static matrix of this size, I'm pretty sure the algorithm won't need a lot of these states, so how can I do that using a dynamic structure?
My first thought was to use something like:
ArrayList<ArrayList<ArrayList<ArrayList<ArrayList<ArrayList<ArrayList<Double>>>>>>> qList;
But I'm not sure this is a reasonable solution and I'm not sure how to allocate all of these ArrayLists.
What would be the best way to create a dynamic data structure to store a 7 dimensional matrix?
Related
So I'm making a game similar to Age of Empires 2. So far, what I've been doing is using an Applet and making an array of tiles (grid) to contain units and buildings. I feel that in the long run this is going to be inefficient. I'm sure there is a better way to do this, perhaps using GUI, but I'm not a very experienced programmer yet so I've resorted to this more primitive method. Is there a better, more efficient way to have tiles that contain characters and buildings on the map?
Thanks.
This is pretty much how I want it to look like:
An array of tiles should be fine - this is what is usually used to represent the map in a 2D game.
Note that you will probably want to distinguish between:
Map terrain tiles, where each square contains just one tile
Units / buildings / other game objects, where each square might contain multiple objects
For the terrain a single array is fine, with one tile in each position.
For the other objects, you need a way to store multiple objects in each square. An array with an ArrayList in each square can work - though you will probably want to leave nulls in all the squares that don't have any contents to avoid creating a lot of empty ArrayLists.
It's also useful to create a global collection of game objects so that you can iterate over all game objects and/or find a speciifc object quickly without searching the whole map. I typically use something like a HashMap for this, where the integer key is a unique ID for each game object.
It depends on what you consider to be the 'inefficient' part. If most of the array elements are going to be containing data, and you need to be able to look up that data quickly and easily, than arrays are certainly the best way to go. They're easy to understand, and the logic mikera described for storing data is a very good way to get started.
There are data structures that very big tile based games use for storing data. Most of those are optimized for 'sparse' graphs at the like. A sparse graph is one where most of the locations are empty, but a few of them have content. Very big world maps often have this qualit. If you're curious about these scenarios, then you should google "quad tree tiling".
But in general, if you're still learning development, stick to the array. Premature optimization is the root of all evil. :)
Firstly I did my homework,
I've checked this:
How to store 2D Array coordinates in a list in java
I have created my own Vector2 class (like XNA).
I think if i use list and access the list every frame, it might slow my game down:S
I need to access this array every frame, so I really want to know if i can create them in a high efficiency way (not using list or class,just some basic type like int[]).
thx in advance!
Edit:
just access this array(the array will be created on init), because i need to search this array's element every frame in my game. I did want to try Vector2[].. buy the efficiency y'konw ^^
Edit*2:eh,I'm really new to JAVA. the "map" you mean use map to store Vector2?
In Java, arrays are (mostly) objects. That is why you can do stuff like
int[] b = { 2, 4, 5 };
System.out.println(b.length);
I know you are concerned with speed; however, attempting to program in a non-object-oriented manner in Java doesn't speed up your program. The JVM is optimized heavily to make object-oriented code run fast.
Concentrate more on your algorithms. If you can keep a list of "to be updated" items instead of iterating over a list of all items, you will dramatically speed up your program regardless of the data structure. Only go shopping for better implementations of data structures after you have determined that the data structure is the slow part.
Premature optimization means you start writing your code to be fast (which normally means you make large concessions to reduce readability) before you have determined that the section of code is impacting the speed of your program. You don't want to make a section of critical code unreadable before you realize it's only 5% of the problem that is making your code slow.
Semi-recent benchmarking puts a correctly sized ArrayList within 3% of the speed of a raw array. If you are wrapping your raw array in an object, odds are good the stock implementation of the ArrayList around its embedded array is much faster.
I am making a game for Android. I am kind of trying to keep the game a secret so I cannot reveal too much about it, so bear with me. Basically it runs in real-time (so I will be implementing a thread to update objects' coordinates) and its style is kind of like Duck Hunt; you have to hit objects that move around on the screen.However, the game has been lagging slightly from time to time (running on a Samsung Galaxy S, which is one of the higher-end devices) so I believe I need to use a better data structure.
Basically I am storing these objects in a doubly linked list instead of in an array because I wanted the maximum number of objects on the screen to be dynamic. In other words, I have a reference to the head and tail objects and all the game objects are connected just as a typical linked list would. This provides the following problems:
Searching if an object intersects with a given coordinate (by touching the screen) takes O(n) time (worst case scenario) because I have to traverse from head to tail and check the hitbox of each object.
Collision checking between two objects takes O(n^2) time (again, worst case scenario) because for every object I have to check if its hitbox intersects with that of all other objects in the linked list.
Another reason why I chose linked list is because I basically have two linked lists: one for active objects (i.e. objects that are on the screen) and one for inactive objects. So let's say that there will be at most 8 objects on the game screen, if the active linked lists would have 5 objects, the inactive list will have 3 objects. Using two linked list makes it so that whenever an object becomes inactive, I can simply append it to the inactive linked list instead of dereferencing it and waiting for the garbage collector to reclaim memory. Also, if I need a new object, I can simply take an object from the inactive linked list and use it in the active linked list instead of having to allocate more memory to create a new object.
I have considered using a multi-dimensional array. This method involves dividing up the screen into "cells" in which an object can lie. For example, on a 480x800 screen, if the object's height and width are both 80 pixels, I would divide the screens into a 6x10 grid, or in the context of Java code, I would make GameObject[6][10]. I could simply divide the coordinates (on the screen) of an object by 80 to get its index (on the grid), which could also provide an O(1) insertion. This could also make searching by coordinate O(1) as I could do the same thing with the touch coordinates to check the appropriate index.
Collision checking might still take O(n^2) time because I still have to go through every cell in the grid (although this way I only have to compare with at most 8 cells that are adjacent to the cell I am examining currently).
However, the grid idea poses its own problems:
What if the screen has a resolution other than 480x800? Also, what if the grid cannot be evenly divided into 6x10? This might make the program more error prone.
Is using a grid of game objects expensive in terms of memory? Considering that I am developing for a mobile device, I need to take this into consideration.
So the ultimate question is: should I use linked list, multi-dimensional array, or something else that I haven't considered?
Below is an idea of how I am implementing collision:
private void checkForAllCollisions() {
GameObject obj1 = mHead;
while (obj1 != null) {
GameObject obj2 = obj1.getNext();
while (obj2 != null) {
//getHitBox() returns a Rect object that encompasses the object
Rect.intersects(obj1.getHitBox(), obj2.getHitBox());
//Some collision logic
}
obj1 = obj1.getNext();
}
}
Common data structures for better collision-detection performance are quadtrees (in 2 dimensions) and octrees (3 dimensions).
If you want to stick with a list - is there a reason you're using LinkedList and not ArrayList? I hope you are currently using the built-in linked list implementation...
A Samsung Galaxy S has 512 MB of RAM - don't worry about taking up too much memory with a single data structure (yet). You'd have to have a relatively high number of relatively heavy objects before this data structure starts sucking significant amounts of RAM. Even if you have 1000 GameObject instances, and each instance in the data structure (including the associated weight of storing an instance in said data structure) was 10,000 bytes (which is pretty honking big) that's still only 9.5 megabytes of memory.
So I definitely think that there's something we need to firstly consider.
1.) LL vs. Array
You said that you used a LL instead of an array because of the dynamic property the LL gives you. However, I would like to say that you can make using an array dynamic enough by doubling the size of it after it has filled up, which will give you O(1) runtime of insert amortized (given that the array is being unkept/unsorted). However, there will be a scenario where every now and then an insert can take O(n) since you must copy the data appropriately. So, for live games such as this, I believe the LL was a good choice.
2.) Your consideration of memory in terms of game objects.
This depends heavily on the structure of each GameObject, which you have not provided enough detailed information about. If each GameObject only contains a couple of ints or primitive types, chances are that you can afford the memory. If each GameObject is very memory costly and you are using a very large grid, then it will definitely cost tons of memory, but it will depend on both the memory usage of each GameObject as well as the size of the grid.
3.) If the resolution is different than 480x800, don't worry. If you are using a 6x10 grid for everything, consider using a density multiplier like so:
float scale = getContext().getResources().getDisplayMetrics().density;
and then getWidth() and getHeight() should be multiplied by this scale to get the exact width and height of the device that's using your app. You can then divide these numbers by the 6 and 10. However, note that some grids may look ugly on some devices, even if they are scaled correctly this way.
4.) Collision Handling
You mentioned that you were doing collision handling. Although I cannot say which is the best way to handle this in your situation (I'm still kind of confused how you're actually doing this based on your question), please keep in mind these alternatives:
a.) Linear Probing
b.) Separate Chaining
c.) Double Hashing
which are all admittedly hash collision handling strategies, but may be implementable given your game (which, again, you would know more about since you have kept some info back). However, I will say that if you use a grid, you may want to do something along the lines of linear probing or create 2 hash tables all together (if appropriate, but this seems to take away the grid-layout you're trying to achieve, so, again, your discretion). Also note that you may use a tree of some sort (like a quadtree) to get faster collision detection. If you don't know about quadtrees, check them out here. A good way to think of one is dividing a square picture into separate pixels at the leaves and storing the average colors at the parent nodes for pruning. Just a way to help you think of quadtrees meaningfully.
Hoped that helped. Again, maybe I'm misunderstanding something because of the vague nature of your question, so let me know. I'd be happy to help.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I'm a first year computer engineering student and I'm quite new here. I have been learning Java for the past three and a half months, and C++ for six months before that. My knowledge of Java is limited to defining and using own methods, absolute basics of object-oriented programming like use of static data members and member visibility.
This afternoon, my computer programming prof taught us about multi-dimensional arrays in Java. About multi-dimensional arrays being simply arrays of arrays and so on. He mentioned that in nominal, educational programming, arrays beyond 2 dimensions are almost never used. Even 3D arrays are used only where absolutely essential, like carrying out scientific functions. This leaves next to zero use for 4D arrays as using them shows that "you're using the wrong datatype" in my prof's words.
However, I'd like to write a program in which the use of a 4D array, of any data type, primitive or otherwise, is justified. The program must not be as trivial as printing the elements of the array.
I have no idea where to begin, this is why I am posting this here. I'd like your suggestions. Relevant problem statements, algorithms, and bits and pieces of code are also welcome.
Thank you.
Edit: Forgot to mention, I have absolutely no idea about working with GUIs in Java, so please do not post ideas that implement GUIs.
Ideas:
- Matrix multiplication and it's applications like finding shortest path in graphs
- Solving of systems of equations
- Cryptography -- many cryptoprotocols represent data or keys or theirs internal structures in a form of matrices.
- Any algo on graphs represented as matrices
I must have been having some kind of fixation on matrices, sorry :)
For 4D arrays one obvious thing I can think of is the representation of 3D environment changing in time, so 4th dimension represents time scale. Or any representation of 3D which have additional associated property placed in 4th dimension of array.
You could create a Sodoku hypercube with 4 dimensions and stores the numbers the user enters into a 4dimensional int array.
One use could be applying dynamic programming to a function that takes 4 integer parameters f(int x,int y,int z,int w). To avoid calling this expensive function over and over again, you can cache the results in a 4D array, results[x][y][z][w]=f(x,y,z,w);.
Now you just have to find an expensive integer function with arity of 4, oh, and a need for calculating it often...
Just to back him up,..your prof is quite right. I'm afraid I might be physically violent to anyone using a 4D+ array in production code.
It's kinda cool to be able to go into greater than 3 dimensions as an educational exercise but for real work it makes things way too complicated because we don't really have much comprehension of structures with greater than 3 dimensions.
The reason it's difficult to come up with a practical use for 4D+ arrays is because there is (almost) nothing that complicated in the real world to model.
You could look into modelling something like a tesseract , which is (in layman's terms ) a 4D cube or as Victor suggests use the 4th dimension to model constant time.
HTH
There are many possible uses. As others have said, you can model a hypercube or something that makes use of a hypercube as well as modeling a change over time. However, there are many other possible uses.
For example, one of the theoretical simulation models of our universe uses 11th dimensional physics. You can write a program to model what these assumed physics would look like. The user would only be able to see a 3-dimensional space which definitely limits usability, but the 4th dimensional coordinate could act like the changing of a channel allowing the user to change their perspective. If a 4th dimensional explosion occurs, for example, you might even want a 5th dimensional array so that you can model what it looks like in each connected 3-dimensional space as well as how it looks in each frame of time.
To take a step away from the scientific, think about an MMORPG. Today many of those games uses "instanced" locations which means that a copy of a given zone is created exclusively for the use of a given group of players so to prevent lag. If this "instanced" concept was given a 4th dimensional coordinate and it allows players to shift their position across instances it could effectively allow all server worlds to be merged together while allowing the players a great deal of control over where they go while decreasing cost.
Of course, your question wants to know about ideas without using a GUI. That's a bit more difficult because you are working in a 2D environment. One real application would be Calculus. We have 3D graphing calculators, but for higher dimensions you pretty much have to do it by hand. A pogram that aims to solve these calculations for you might not be able to properly display the information, but you can certainly calculate it. Also, when hologaphic interfaces become a widespread reality it may be possible to represent a hypercube graph in 3D making such a program useful.
You might be able to write a text based board game where the position of pieces is represented with text. You can add dimensions and game rules to use them.
The simplest idea I could give you is a save state system. At each interval the program in memory is copied and stored into a file. It's coordinate is it's position in time. At face value you may not need a 4D array to handle this, but suppose the program you were saving states of used a 3D array. You could set it up to represent each saved state as a position in time that you can make use of and then view the change in time.
I'm not sure what specifically you could do with this, because I just started thinking about it. But you could possibly use a 4D array for some sort of basic physics simulation, like modeling a projectile flight involving some wind values and what not. That just came to mind because the term 4D always brings to mind that the "position" of any object is 4 values, with time as the 4th.
Being a physics student we have only 3 dimension of space but we have a 4th dimension which is time. So thinking in that way we can think of an array of any dimension(1D or 2D or 3D) whose values differ with time or an array which keeps the record of every array whose values changed with time.
It seems to be quite known to us. For example the "ATTENDANCE REGISTER" which we usually have in our classroom.
This is my view to it.
That's it.
Enjoy :-)
To give a concrete example for the Ishtar's answer: Four-string alignment. To compute optimal two-string alignment, you write one string along one (say, horizontal) axis of a 2D-array (a matrix!) and the other one along the other array. The array is filled with edit costs, and the optimal alignment of the two strings is the one which produces the lowest cost, associated with a path through the matrix. A common way of finding such a path is by the above mentioned dynamic programming. You can look up 'Levenshtein distance' or 'edit distance' for technical details.
The basic idea can be expanded to any number of strings. For four strings you'd need a four-dimensional array, to write each string along one of the dimensions.
In practice, however, multiple string alignment is not done this way, for at least two reasons:
Lack of flexibility: Why would you need to align exactly four strings??? In computational molecular biology, for example, you might wish to align many strings (think of DNA sequences), and their number is not known in advance, but it is seldom four. You program would be useful for a very limited class of problems.
Computational complexity, in space and time. The requirements are exponential in the number of dimensions, making the approach impractical for most real-world purposes. Besides, most of the entries in such multi-dimensional array would lie on such suboptimal paths, which are never even touched, so that storing them would be simply waste of space.
So, for all practical purposes, I believe your professor was right.
I'm currently creating a tile based game, where elements of the games are placed in four different vectors (since there are multiple game objects with different properties, hence stored in different vectors).
These game elements themselves contain x and y coordinates similar to how they are stored in a two dimensional array. i was wondering if there was a way to access these vector elements similar to two dimensional array access (currently i am implementing an for loop to cycle the elements while comparing its coordinates).
This kinda sucks when i need to refresh my display at every game cycle (since the large number of comparisons and loops).
I'm implementing this in java btw.
My recommendation would be to think "object-oriented": create a class named Board or Grid or whatever fits that encapsulates that implementation detail of choosing between 2D array or Vector of Vectors. Add a method that lets you return a board token for a given (i, j) index into the board.
Don't use Vector, use ArrayList.
If you have very large datas, see perhaps buffers, for instance IntBuffer.
Three Ideas:
You could use a HashMap with the coordinates as key and your elements as value. This is faster than cycling through the vector and lightweight for memory.
You could store null instead of elements at empty coordinates. This way you can access each stored memory by its coordinates.Fastest but memory intensive way.
A speed up for what you currently do: Sort your elements by their coordinates once and then use binary search to find them in the vector.