Matrix conversion in a particular cluster Structure - javascript

I am trying to convert the Distance Matrix I got after calculating Euclidean Distance and taking Matrix form of it, to a manual defined clustered pattern.
In my case, this is the matrix suppose which normal pattern
Suppose, this is the desired cluster order, I have to convert i.e. from 1 2 3 4 to 3 1 2 4, I want to have something like this. I do not want to do it manually since my matrix size is 40 X 40.
It is not clicking to my mind, I can code but algorithm is not coming to my mind. If you could help or someone has done something like this before. Please help me out with it.
I tried reading the data from csv with the help of d3.csv which gives the desired result of 1234 like this :
d3.csv("final.csv", function(loadeddata) {
mydata = loadeddata.map(function(d) {return [+d["1"], +d["2"] , +d["3"], +d["4"]] ;});
to
d3.csv("final.csv", function(loadeddata) {
mydata = loadeddata.map(function(d) {return [+d["3"], +d["1"] , +d["2"], +d["4"]] ;});
so that I can get the matrix in desired clustered format but it did not work coz it shifting whole column to the desired place but not shifting the element wise.
Here is another try I made
var iMax = 4;
var jMax = 4;
var newdata = new Array();
for (i=0;i<iMax;i++) {
newdata[i]=new Array();
for (j=0;j<jMax;j++) {
newdata[i][j]=0;
}
}
var arraycomb = [3,1,2,4];
for ( i = 0; i < 4; i++) {
for ( j = 0; j < 4; j++) {
newdata[arraycomb[i]][arraycomb[j]] = mydata[i][j];
}
}

Related

From an array of objects, I want to pick a random object from the array and set one of that object's variables

I have an array named grid. Stored in that array is an object, cell. I want to set one of cell's variables(isBomb) to true.
I know that this isn't quite how to do it, but here is my(nonfunctioning implementation).
When I try to run it, I get this error message: Main, line 32:Cannot set property '288' of undefined I assume that's because I formatted it wrong. Could anyone help?
for(var i in grid){
for(var j=0; j<bombAmount; j++){
this.isBomb[floor(random(grid.length))]=true;
}
This is in javascript, with the p5.js library.
Openprocessing link
You can use Math.random() to achieve this. For example:
const grid = [{
cellId: 1
}, {
cellId: 2
}, {
cellId: 3
}, {
cellId: 4
}, {
cellId: 5
}, {
cellId: 6
}, {
cellId: 7
}, {
cellId: 8
}, {
cellId: 9
}, {
cellId: 10
}];
function pickRandomCell() {
return grid[Math.floor(Math.random() * grid.length)];
}
for (let i = 0; i < 50; i++) {
console.dir(pickRandomCell());
}
As the answer above, do Math.random() and update the cell like this:
// Do a loop to apply each bomb to a cell
for (let i = 0; i < bombAmount; i++) {
const randomPosition = Math.round(Math.random() * (grid.length -1));
// Select random cell from grid, and update the "isBomb" to true
grid[randomPosition].isBomb = true;
}
There are quite a few issues with the code that this question doesn't address.
I will start with the simplest question from the title: picking a random object from the an array. The existings answers already address this. I wanted to point out that random() in p5 can also take an array as an argument and returns a random item from that array, as you can see in the reference example:
function setup(){
let words = ['apple', 'bear', 'cat', 'dog'];
let word = random(words); // select random word
console.log(word);
createCanvas(100, 100);
text(word, 10, 50);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.3.1/p5.min.js"></script>
Back to the snippet you posted:
for(var i in grid){
for(var j=0; j<bombAmount; j++){
this.isBomb[floor(random(grid.length))]=true;
}
}
In the context above this will not point to an individual cell.
You might be looking at something like grid[i].isBomb = true instead.
isBomb is a boolean property of Cell hence the errors when trying to access it via array access notation.
The connection between bombAmount and isBomb is unclear.
Perhaps you meant to use something like the bombsFound array returned by checkArea() somehow ?
If you want to pick a random cell to have a bomb or not you could something like:
for(let i = 0; i < grid.length; i++){
grid[i].isBomb = random(0.0, 1.0) > 0.5;
}
the example above sets a psuedo random chance of 50/50 that a cell will be a bomb or not.
The Cell constructor actually accepts isBomb as it's last argument:
function Cell(x, y, bombNum, clicked, isBomb)
Therefore you could skip the loop completely and simply randomly assign isBomb when populating grid:
for (var y = 0; y < rows; y++) {
for (var x = 0; x < cols; x++) {
var cell = new Cell(x, y, index(x, y), false, random(0.0, 1.0) > 0.5);
grid.push(cell);
}
}
Currently it looks like you're not passing the expected arguments to the Cell constructor:
var cell = new Cell(x, y, false);
These are just a few of the issues and points out that you may not fully understand the code you're trying to modify. I recommend slowing down, stepping back for a second and with pen an paper figure out what you're trying to achieve. With the clear goals, break them down into very simple individual steps, solve one step at a time, then start integrating the tested individual steps into the larger program.
Update based on the clarification in the comment bellow you could easily do something like:
for(let i = 0; i < bombAmount; i++){
grid[i].isBomb = random(0.0, 1.0) > 0.5;
}
However this won't guarantee 20 bombs, but a 50-50 chance that the 1st 20 cells might have bombs.
If you want to guarantee 20 bombs at random locations you could use a temporary array to pick a random from, but remove that randomly selected item so it won't be selected on the next iteration.
Here's a snippet to illustrate the idea:
// make a new array that will hold references to the original cells
let selection = grid.map(cell => cell);
// for the bomb amount...
for(let i = 0 ; i < bombAmount; i++){
// pick a random index
let randomIndex = floor(random(selection.length));
// retrieve the cell at that index and remove it from the selection list
let cell = selection.splice(randomIndex, 1);
// set that cell as a bomb
cell.isBomb = true
}

Get the minimum value in the chart rendered for flot.js

Is it possible to get the lowest value in the chart itself assuming that the data is dynamic?Take a look at this example Fiddle.
$(function () {
var d1 = [];
for (var i = 0; i < 14; i += 0.5)
d1.push([i, Math.sin(i)]);
$.plot($("#placeholder"), [ d1]);
});
How can I get the lowest value in this line chart?
Update: It seems my earlier example didn't quite make sense please take a look at this link: https://abtw.alliancebernstein.com.tw/APAC/TW/Funds/American-Income.htm?ShareClassId=60006908 make sure to turn off Flash plugin so that Flotchart will render. Now looking at the area chart I want to get the lowest value base on the chart rendered. Is this possible?
If you save your plot object like so
var plot = $.plot($("#placeholder"), [ d1]);
you can get the minimum value from it with
var minimum = plot.getData()[0].yaxis.datamin;
The same is possible for maximum value (datamax), for the xaxis and for other data series (the index behind getData()).
http://jsfiddle.net/fenderistic/Sf5Yr/
Simply keep a lowest variable, and check throughout the for-loop to see if the value lower, if so, replace the current lowest value with it.
$(function () {
var d1 = [];
//Assuming you're always starting at zero
var lowest = Math.sin(0);
for (var i = 0; i < 14; i += 0.5) {
d1.push([i, Math.sin(i)]);
if (Math.sin(i) < lowest) {
lowest = Math.sin(i);
}
}
alert(lowest)
$.plot($("#placeholder"), [d1]);
});

Algorithm to remove extreme outliers in array

I've got an array which I use for the x-axis in a D3 graph, and it blows up because the chart size is too small for the size of the array. I had a look at data and there are extreme outliers in the data. See chart below.
The data around 0 (its not totally zero, its 0.00972 etc).
The data starts getting interesting around 70, then massive spikes about 100. the data then continues and then the same sort of thing on the other side about 200.
Can anyone help me with some algo that removes the extreme outliers? e.g. give me 95% or 90% percentiles and remove the contiguous elements (e.g. not just one element from the middle but x number of elements from the start of the array and the end of the array, where x depends on working out where best to do it based on the data? In Javascript as well please!
thanks!
ps you'll need to save the image to view it properly
Assuming the data is like
var data[] = {0.00972, 70, 70, ...};
first sort
data.sort(function(a,b){return a-b});
then take off the bottom 2.5% and top 2.5%
var l = data.length;
var low = Math.round(l * 0.025);
var high = l - low;
var data2 = data.slice(low,high);
An alternative would be to only show data within 3 standard deviations of the mean. If you data is normally distributed 99.7% will fall in this range.
var sum=0; // stores sum of elements
var sumsq = 0; // stores sum of squares
for(var i=0;i<data.length;++i) {
sum+=data[i];
sumsq+=data[i]*data[i];
}
var mean = sum/l;
var varience = sumsq / l - mean*mean;
var sd = Math.sqrt(varience);
var data3 = new Array(); // uses for data which is 3 standard deviations from the mean
for(var i=0;i<data.length;++i) {
if(data[i]> mean - 3 *sd && data[i] < mean + 3 *sd)
data3.push(data[i]);
}
Or similar using some multiple of the Inter-quartile range
var median = data[Math.round(l/2)];
var LQ = data[Math.round(l/4)];
var UQ = data[Math.round(3*l/4)];
var IQR = UQ-LQ;
var data4 = new Array();
for(var i=0;i<data.length;++i) {
if(data[i]> median - 2 * IQR && data[i] < mean + 2 * IQR)
data4.push(data[i]);
}

Implementing A-Star algorithm. Help please?

I am trying to implement an A* algorithm for my pathfinding robot in JavaScript. The only problem is that I do not understand what does it mean to find all adjacent squares. I am using the Manhattan Distance formula as I cannot let my bot go diagonally. Here is my code (for now):
var open = new Array();
var closed = new Array();
start = [9,18]; //do not take this literally
goal = [1,0]; //again don't
open.push(start);
while (open.length != 0) {
for(var x = 0; x < open.length; x++) {
heuristicValue[x] = computeHeuristicV(maplayout, start[0], start[1], open[x][0], open[x][1], goal[0], goal[1]);
}
minimum = Math.min(100000,heuristicValue[0]);
for(var x = 1; x < open.length; x++) {
minimum = Math.min(minimum, heuristicValue[x]);
}
for(var x = 0; x < open.length; x++) {
if (minimum == heuristicValue[x]) {
current = [open[x][0], open[x][1]];
}
}
closed.push(current);
//INCOMPLETE
}
The computeHeuristicV function computes the heuristic value in the code above.
"All adjacent squares" means every possible next hop on the path.
A* is a great algorithm to master and use. The two key elements are finding neighbors and the heuristic. A heuristic is used to estimate the distance between your current location, and the end. Also, the statement "find all adjacent squares" is referencing a neighbors function. For example, you might have the following:
var heuristic = function(state) {
var endLocation = MyGame.getEndLocation();
return Math.abs(state.x - endLocation.x) + Math.abs(state.y - endLocation.y)
}
var neighbors = function(state){
var neighborStates = [];
MyGame.setPlayer({
x: state.x,
y: state.y
});
neighborStates.push(MyGame.moveUp.getState());
neighborStates.push(MyGame.moveRight.getState());
neighborStates.push(MyGame.moveDown.getState());
neighborStates.push(MyGame.moveLeft.getState());
return neighborStates;
}
So, getting the "adjacent squares" is just asking you for the neighboring states or options. Personal plug: I just authored a simple a-star algorithm here: https://github.com/tssweeney/async-astar. Reading the description might help you to better understand the problem.

How could I generate random locations with distances between each other in javascript?

I want to design a function that can generate a 'map' of sorts.
For example:
Location A is created, it is located at some position X
Location B is created, it is located at some position Y, we know the distance between X, Y
Location C is created, we know the distance from C to B, how do we calculate C to A?
Using a triangle method, I suppose I could also assign a random angle and calculate the third side, but what would I do if I added a Location D, E, F randomly? Would I be calculating multiple triangles that get exponentially worse with every addition?
Say you want to generate a list of locations L[1..n], you just randomly pick next location and scan over the L to guarantee the distance is over a threshold, otherwise, pick again.
Then, push this into your list L. So the total run time of generating a n elements list is O(n^2). When n < 1000, this is fast enough. The following method is guaranteed to terminate, which is designed for a relatively small read-to-pick list, say up to 1,000,000.
function generateList(orgList, numberToOutput) {
if (orgList.length < numberToOutput)
return false;
var orgListClone = orgList.slice(0);
var L = [];
while (L.length < numberToOutput && orgListClone.length > 0) {
var n = parseInt(Math.random() * orgListClone.length);
// Assume we pick n-th element in the list.
var ok = true;
for (var j = 0; j < L.length; j++)
if (distance(orgListClone[n], L[j]) < kThreshold) {
// n is not an option, swap orgListClone[n] with the last element and pop it out.
orgListClone[n] = orgListClone[orgListClone.length - 1];
orgListClone.pop();
ok = false;
break;
}
if (ok) {
// All tests passed
L.push(orgListClone[n]);
orgListClone[n] = orgListClone[orgListClone.length - 1];
orgListClone.pop();
}
}
if (L.length == numberToOutput)
return L;
// Failed to find the list
return null;
}
Another solution is to calcuate distances between each of the locations ahead, and make a list of too close locations for each location.
So that after each pick, just merge the too close locations to the current set, which takes O(n). And then pick another location which is not included in this set. This method only works when the read-to-pick list is large enough, so that the probability (1 - |too close list| / |read-to-pick list|) of choosing a location not included in the set is large. This will take up to O(nm) in total, where m is the average |too close list|.
function generateList(orgList, numberToOutput) {
if (orgList.length < numberToOutput)
return false;
var tooCloseSet = {};
var L = [];
var lastLengthOfL = 0;
var repickCount = 0;
for (L.length < numberToOutput) {
if (l.length == lastLengthOfL) {
if (++repickCount > 10)
return false;
} else {
lastLengthOfL = l.length;
repickCount = 0;
}
var n = parseInt(Math.random() * orgList.length);
if (n in tooCloseSet)
continue;
L.push(orgList[n]);
mergeSet(tooCloseSet, orgList[n].tooCloseList);
}
return L;
}
You could try something like this, I haven't tested it, so it's just conceptual at this point.
You could just generate an array of randomly placed points, and each point could hold it's own array of distances, calculated using basic trigonometry.
function Point(x, y) {
return {
x: x,
y:y,
addRelative: function(pt) {
this.realtivePoints[pt] = abs(sqrt(pow((this.x-pt.x),2) + pow((this.y-pt.y),2)));
},
relativePoints: {}
};
var randPoints = []; // Lets assume this has a collection of random Point objects
for(var i=0; i<randPoints.length; i++) {
for(var j=0; j<randPoints.length; j++) {
randPoint[i].addRelative(randPoints[j]);
}
}
randPoints[0].relativePoints[randPoints[1]]; // Dist from first to second point.
Yes, it gets geometrically more complicated with each point you add.
The problem is that even if you know the lengths of all three sides of a triangle, you still don't know the orientation. To illustrate your example:
You're defining ABC by specifying distances dAB and dBC (which gives you dAC). But you actually have two possible triangles, ABC and ABC'. Which means if you add a fourth point, D, by specifying it's distance to one of the points on ABC (e.g. dCD), you've added a 2nd triangle, which can also have one of two orientations, making for a total of four possible solutions. As you can see, orientation doesn't matter for determining distance between two points on the same triangle, but for determining distances between points on different triangles, it does.

Categories