I would like to operate with quite big number of data - with elements and periodic table.
At first let the program return the atomic weight of given element. How would you perfrom that?
By manually creating a table with 118 elements and searching for given element in tab1[element][] and then passing the tab1[][atomic_weight] by iterating up to 118 times?
Or maybe instead of creating in program table create a file with the data? Languages are C++ and JS (in browser-JS you can't deal with local files, but only with server ones by using e.g. AJAX, yes?).
Later it will have to perform more advanced calculations. Of course databases would be helpful, but without using it?
Here are your steps to make this happen:
Decide the targets you want your application to run on (The web, local machine...)
Learn C++ OR Javascript depending on #1 (Buy a book)
Come back to this question on Stack Overflow
Realize this is not a good question for Stack Overflow
Tips when you get to a point where you can answer your own question:
Use a single dimension array with Objects you have designed. This is one reason why Object Oriented Programming is so great. It can be expanded easily later.
Why the single dimension array?
118 Elements is chump change for a computer even if you went through every element. You have to touch on each one anyways, so why make it more complex than a single dimension array.
You KNOW how large the data structure will be, and it won't change
You could access elements anywhere on the table in O(1) time based on its atomic number
Groups and periods can be deduced by simple math, and therefore also deduced in constant time.
The jist:
You aren't fooling me. You have a long way to go. Learn to program first.
I recommend placing all the element information into a structure.
For example:
struct Element_Attributes
{
const char * symbol;
unsigned int weight;
};
The data structure to contain the elements varies, depending on how you want to access them.
Since there are columns and rows on the Periodic Table of the Elements, a matrix would be appropriate. There are blank areas in the matrix, so your program would have to handle the {wasted} blank space in the matrix.
Another idea is to have row and column links. The row links would point to the next element in the row. The column link would point to the next element in the column. This would have slower access time than a matrix, but would not have empty slots (links).
Also, don't worry about your program's performance unless somebody (a user) says it is too slow. Other entities are usually slower than executing loops. Some of those entities are file I/O and User I/O.
Edit 1 - Implementation
There are 33 columns to the table and 7 rows:
#define MAX_ROWS 7
#define MAX_COLUMNS 33
Element_Attributes Periodic_Table[MAX_ROWS][MAX_COLUMNS];
Manually, an element can be created and added to the table:
Element_Attributes hydrogen = {"H", 1};
Periodic_Table[0][0] = hydrogen;
The table can also be defined statically (when it is declared). This is left as an exercise for the reader.
Searching:
bool element_found = false;
for (unsigned int row = 0; row < MAX_ROWS; ++row)
{
for (unsigned int column = 0; column < MAX_COLUMNS; ++column)
{
const std::string element_symbol = Periodic_Table[row][column].symbol;
if (element_symbol == "K") // Search for Potassium
{
element_found = true;
break;
}
}
if (element_found)
{
break;
}
}
Related
I'm doing a project on natural selection for cells for fun. Each code has "dna" which is just a set of instructions. The dna can either have REMOVE WASTE, DIGEST FOOD, or REPAIR WALL. I won't really go into detail what they do, because that would take too long. But the only reason evolution really happens is through genetic mutations. I'm wondering if this is possible in javascript, and how to do it. For example, the starting cell has 5 dna strands. But if it reproduces, the child can have 4, or 6. And some of the dna strands can be altered. This is my code so far:
var strands = ["DIGEST FOOD", "REPAIR WALL", "REMOVE WASTE"];
var dna = [];
for (let i = 0; i < 5; i++) {
if (parent) {
// something about the parents dna, and the mutation chance
}
else {
dna.push(strands[Math.floor(Math.random() * 3)]); // if cell doesn't have parent
}
}
I'm just wondering if this is possible in javascript, and how to succesfully do it. Sorry if the question isn't too clear.
Edit: Let me rephrase a little. What I'm trying to achieve is a genetic mutation in the new cell. Like:
if (parent) {
dna.push(parent);
if (Math.random() < 0.5) {
changeStrand(num);
}
if (Math.random() < 0.5) {
addStrand(num);
}
if (Math.random() < 0.5) {
removeStrand(num);
}
}
function changeStrand() {
// change the strand
}
function newStrand(num) {
// add random strands
}
function removeStrand(num) {
// remove random strands
}
or something like that
For a genetic algorithm, you basically want to take two slices from each parent and stitch them together, whilst ensuring the end result is still a valid dna strand.
For a fixed sized DNA sequence (such a N queens positions), the technique would be to pick a random slice point (1-3 | 4-8) and then combine these slices from the parents to create a child.
For your usecase, you need two random slices who sum of sizes adds upto 4-6. So possibly two slices of size 2-3. You could potentially take one from the front, and the other from the back. Else you could first pick a random output size, and then fill it will two random sequences for either parent.
Array.slice() and Array.splice() are probably the functions you want to use.
You can also add in a random mutation to the end result. Viruses at the speed limit of viable genetic evolution have an average of 1 mutation per transcription. Which means some transcriptions won’t have mutations, which is equivalent to allowing some of the parents in the parent generation to survive.
You can also experiment with different variations. Implement these as feature flags, and see what works best in practice.
Also compare with Beam Search, which essentially keeps a copy of the N best results from each generation. You may or may not want to keep the best from the parent generation to survive unmutated.
Another idea is to compute a distance metric between individuals, and add a cost for being too close to an existing member of the population, and this will select for genetic diversity.
In the standard model, variation occurs both by point mutations in the letter sequence and by “crossover” (in which the DNA of an offspring is generated by combining long sections of DNA from each parent).
The analogy to local search algorithms has already been described; the principal difference between stochastic beam search and evolution is the use of sexual reproduction, wherein successors are generated from multiple organisms rather than just one. The actual mechanisms of evolution are, however, far richer than most genetic algorithms allow. For example, mutations can involve reversals, duplications, and movement of large chunks of DNA; some viruses borrow DNA from one organism and insert it in another, and there are transposable genes that do nothing but copy themselves many thousands of times within the genome. There are even genes that poison cells from potential mates that do not carry the gene, thereby increasing their own chances of replication. Most important is the fact that the genes themselves encode the mechanisms whereby the genome is reproduced and translated into an organism. In genetic algorithms, those mechanisms are a separate program that is not represented within the strings being manipulated.
Artificial Intelligence: A Modern Approach. (Third edition) by Stuart Russell and Peter Norvig.
If you want to have random numbers you can use Math.random() for that. In the linked page there are also some examples for getting values between x and y for example:
// Source https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}
I am not sure this is what you try to achieve - since you already make use of the Math.random() function.
A few months ago I made a small terrain generator, like Minecraft, for a school project.
The way I did this was by using multiple chunks. Each chunk contained a 3-dimensional array that stored the blocks.
Every position in this array corresponded with the position of the block it contained.
blocks[x, y, z] = new Block();
Now I would like to add different sizes if blocks. However, I can't do that with the way I am storing the blocks right now, because bigger blocks would have to be spread over multiple positions in the 3-dimensional array.
An example of a game with different sizes of blocks (and different shapes) is LEGO Worlds. How does a game like this store all these little blocks?
I hope someone can help me with this.
The language I am using is Javascript in combination with WebGL.
Thanks in advance!
In my experience there are a few different ways of tackling an issue like this, but the one I'd recommend would depend on the amount of time you have to work on this and the scope (how big) you wanted to make this game.
Your Current Approach
At the moment I think your using what most people would consider the most straightforward approach by storing the voxels in a 3D grid
[Source].
But two problems you seem to be having is that there isn't an obvious way to create blocks that are bigger then 1x1 and that a 3D grid for a world space is fairly inefficient in terms of memory usage (As for an array you have to have memory allocated for every cell, including empty space. JavaScript is no different).
An Alternative Approach
An alternative to using a 3D array would be to instead use a different data structure, the full name being a sparse voxel octree.
This to put it simply is a tree data structure that works by subdividing an area of space until everything has been stored.
The 2D form of this where a square sub divides into four smaller quadrants is called a quad tree and likewise a 3D equivalent divides into eight quadrants, called an octree. This approach is generally preferable when possible as its much more efficient because the trees only occupy more memory when its absolutely essential and they can also be packed into a 1D array (Technically a 3D array can be too).
A common tactic used with quad/octrees in some block based games is to take a region of the same kind of voxel that fit into one larger quadrant of the tree is to simply stop sub division there, as there's no reason to go deeper if all the data is the same.
The other optimization they can make is called sparse where regions of empty space (air) are simply deleted since empty space doesn't do anything special and its location can be inferred.
[SVO Source]
[Z Order Curve Source]
Recommended Approach
Unless you have a few months to complete your game and you're at university I seriously wouldn't recommend an SVO (Though reading up about could impress any teachers you have). Instead I'd recommend taking the same approach that Minecraft appears to visibly has. E.G. A door is 1X2 but blocks can only be 1x1, then just make it two blocks.
In the example of a door you would have four unique blocks in total, two for the upper and lower half, and two variations of each being opened or closed.
E.G.
var cubeProgram; // shader program
var cubeVBO; // vertex buffer (I recommend combining vertex & UV coords)
var gl; // rendering context
// Preset list of block ID's
var BLOCK_TYPES = {
DOOR_LOWER_OPEN: 0,
DOOR_UPPER_OPEN: 1,
DOOR_LOWER_CLOSED: 2,
DOOR_UPPER_CLOSED: 3,
}
var BLOCK_MESHES = {
GENERIC_VBO: null,
DOOR_UPPER_VBO: null
DOOR_LOWER_VBO: null
}
// Declare a Door class using ES6 syntax
class Door {
// Assume X & Y are the lower half of the door
constructor(x,y,map) {
if (y - 1 > -1) {
console.error("Error: Top half of the door goes outside the map");
return;
}
this.x = x;
this.y = y;
map[x][y ] = BLOCK_TYPES.DOOR_LOWER_OPEN;
map[x][y-1] = BLOCK_TYPES.DOOR_UPPER_OPEN;
}
}
I've been reading up a bit on using data types in javascript, specifically CData. I have a specific use case with a numeric string I'm running a regex pattern on. It's already fairly performant for what I'm doing, but I'm interested in possibly making it more performant for larger applications.
I am representing multi-dimensional models as a single string of integers (doesn't have to be integers, but that's worked for me so far). I represent empty space with 0, occupied space as 1, and each successive dimensional divide with an integer, beggining with 2 for 2-dimensions.
3 1D:
000
3x3 2D:
00020002000
3x3x3 3D:
00020002000300020002000300020002000
There's a bunch of stuff involved with making the regex pattern, but essentially it looks like this for 2D (this is a super-dumbed-down version for ease):
var gridWidth = //total width of our grid
var columns = //width of our object to place in grid
var rows = //height of our object to place in grid
var grid = 00020002000;
// (0{number of columns})+(([0-2]{difference in width of grid and object})(0{number of columns again)).repeat(number of rows)
var reg = RegExp(("(0{" + columns + "})" + ("([0-2]{" + (gridWidth + 1 - columns) + "})(0{"+columns+"})").repeat(rows-1)) + "");
grid = grid.replace(reg, function(){
//the last 2 argument's aren't part of our grouping
var l = arguments.length - 2;
r = "";
for (var i = 1; i<l; ++i){
if (i%2){
r+= "1".repeat(columns); //repeat prototyped, just repeats string x times
} else {
r+= arguments[i];
}
}
return r;
});
CData integers seem to be somehow more performant than javascript strings from what I'm reading, though I'm not experienced with C or the finer points of higher-level programming. I'm a javascript code monkey - feel free to tell me I'm WAY off base with my train of thought.
So my question is, is it possible to take my grid (which is essentially an integer), turn it into/store it as CData, and run my regex pattern against it somehow in an effort to increase performance processing large numbers of object in a very large grid space?
(side note: I have been able to place 10000 objects of random sizes between 1x1 and 4x4 in a grid using divs in an average of about 14000ms in chrome, so it's performant for basic grid layouts [registers as 0ms sometimes with only a few dozen objects on a small grid.] Handling placing objects more efficiently may inspire greater uses)
"More performant" is all relative to what you're trying to accomplish.
The CData spec you were reading from is a draft. In the meantime, keep it simple - try arrays. The regex seems like a novel idea, but also seems to me that it would be quite difficult to maintain.
Trying to create a random (0/1) boolean operation. I have a multidimensional array set up. So far, everything works. Am I on the right path? I currently use recursion; is there a more efficient way to do this?
function randomMove(){
var cs=b.length,
cr=Math.floor((Math.random()*cs)+1)-1,
cc=Math.floor((Math.random()*cs)+1)-1;
if(b[cr][cc]===""){ // THIS IS DEPENDENT ON EXISTING CODE. VIEW FIDDLE. //
// DO STUFF //
} else { randomMove(); }
}
Is this considered a good way to create a random move for 2 players? Or is recursion the wrong process here?
Fiddle
Select the cells that can possibly be selected, then choose a random one by index.
http://jsfiddle.net/Ehqka/1/
$.fn.random = function(){
return this.eq(Math.floor(Math.random()*this.length));
};
function randomMove(){
$("#board td").not(".o,.comp").random().addClass('comp');
testWin();
}
It selects all cells in the board, drops the ones that have a class of o or comp from the selection, generates a random number between 0 and the number of remaining cells, then selects the cell at that index to add a class to.
Note, however, your method will be "faster" than the above on the first move due to the fact that on the first move, every move is a valid one therefore it will never iterate past the first time. Mine can be slightly optimized to be more efficient on the first by removing the .not(), but your's should still be "faster" because it doesn't have to go to the DOM.
"faster" is relative, my method will grow less efficient as the table grows than yours will on the first move. As more and more moves happen, your method will become less and less efficient since more and more of the possible moves are invalid.
I have an multi dimensional array as
[
{"EventDate":"20110421221932","LONGITUDE":"-75.61481666666670","LATITUDE":"38.35916666666670","BothConnectionsDown":false},
{"EventDate":"20110421222228","LONGITUDE":"-75.61456666666670","LATITUDE":"38.35946666666670","BothConnectionsDown":false}
]
Is there any plugin available to search for combination of LONGITUDE,LATITUDE?
Thanks in advance
for (var i in VehCommLost) {
var item = VehCommLost[i];
if (item.LONGITUDE == 1 && item.LATITUDE == 2) {
//gotcha
break;
}
}
this is json string..which programming language u r using with js??
by the way try with parseJSON
Are the latitudes and longitudes completely random? or are they points along a path, so there is some notion of sequence?
If there is some ordering of the points in the array, perhaps a search algorithm could be faster.
For example:
if the inner array is up to 10,000 elements, test item 5000
if that value is too high, focus on 1-4999;
if too low, focus on 5001-10000, else 5000 is the right anwser
repeat until the range shrinks to the vicinity, making a straight loop through the remaining values quick enough.
After sleeping on it, it seems to me most likely that the solution to your problem lies in recasting the problem.
Since it is a requirement of the system that you are able to find a point quickly, I'd suggest that a large array is the wrong data structure to support that requirement. It maybe necessary to have an array, but perhaps there could also be another mechanism to make the search rapid.
As I understand it you are trying to locate points near a known lat-long.
What if, in addition to the array, you had a hash keyed on lat-long, with the value being an array of indexes into the huge array?
Latitude and Longitude can be expressed at different degrees of precision, such as 141.438754 or 141.4
The precision relates to the size of the grid square.
With some knowledge of the business domain, it should be possible to select a reasonably-sized grid such that several points fit inside but not too many to search.
So the hash is keyed on lat-long coords such as '141.4#23.2' with the value being a smaller array of indexes [3456,3478,4579,6344] using the indexes we can easily access the items in the large array.
Suppose we need to find 141.438754#23.2i7643 : we can reduce the precision to '141.4#23.2' and see if there is an array for that grid square.
If not, widen the search to the (3*3-1=) 8 adjacent grids (plus or minus one unit).
If not, widen to the (=5*5-9) 16 grid squares one unit away. And so on...
Depending on how the original data is stored and processed, it may be possible to generate the hash server-side, which would be preferable. If you needed to generate the hash client-side, it might be worth doing if you reused it for many searches, but would be kind of pointless if you used the data only once.
Could you comment on the possibility of recasting the problem in a different way, perhaps along these lines?