Reducing unused space/arrow length for cytoscape js layouts - javascript

I am using the cytoscape js library for displaying a hierarchy of images. I followed the example on http://jsbin.com/gist/aedff159b0df05ccfaa5?js,output and found that the breadthfirst layout is what I need.
However, I find the rendered result unsatisfactory due to too much unused space. The arrows are too long. Even the example (http://jsbin.com/gist/aedff159b0df05ccfaa5?js,output) has this issue. For this example, I tried the following
Increase the "height/width" in .selector('node') .css({
Muck around with the distanceX and distanceY (node spacing) variables in layout.breadthfirst.js (line 352).
I am unable to reduce the unused space or reduce the length of the arrows.

Ticket to follow: https://github.com/cytoscape/cytoscape.js/issues/737
If you want a new feature in future, please file a ticket.

For rushing Devs, try this layout option:
spacingFactor: 0
The manual says :
spacingFactor: 1.75, // positive spacing factor,
// larger => more space between nodes (N.B. n/a if causes overlap)
That's the result of the ticket https://github.com/cytoscape/cytoscape.js/issues/737 reported by maxkfranz.

Related

Organizing felt tip pens: optimizing the arrangement of items in a 2D grid by similarity of adjacent items, using JS [updated]

UPD: the question has been updated with specifics and code, see below.
Warning: This question is about optimizing an arrangement of items in a matrix. It is not about comparing colors. Initially, I have decided that providing context about my problem would help. I now regret this decision because the result was the opposite: too much irrelevant talk about colors and almost nothing about actual algorithms. 😔
I've got a box of 80 felt tip pens for my kid, and it annoys me so much that they are not sorted.
I used to play a game called Blendoku on Android where you need to do just that: arrange colors in such a way that they form gradients, with nearby colors being the most similar:
It is easy and fun to organize colors in intersecting lines like a crossword. But with these sketch markers, I've got a full-fledged 2D grid. What makes it even worse, colors are not extracted from a uniform gradient.
This makes me unable to sort felt tip pens by intuition. I need to do it algorithmically!
Here's what I've got:
Solid knowledge of JavaScript
A flat array of color values of all pens
A function distance(color1, color2) that shows how similar a color pair is. It returns a float between 0 and 100 where 0 means that colors are identical.
All I'm lacking is an algorithm.
A factorial of 80 is a number with 118 digits, which rules out brute forcing.
There might be ways to make brute forcing feasible:
fix the position of a few pens (e. g. in corners) to reduce the number of possible combinations;
drop branches that contain at least one pair of very dissimilar neighbours;
stop after finding first satisfactory arrangement.
But I'm still lacking an actual algorithm even for than, not to mention a non-brute-forcey one.
PS Homework:
Sorting a matrix by similarity -- no answers.
Algorithm for optimal 2D color palette arrangement -- very similar question, no answers.
How to sort colors in two dimensions? -- more than 50% of cells already contain correctly organized colors; unfamiliar programming language; the actual sorting solution is not explained.
Sort Colour / Color Values -- single flat array.
Update
Goal
Arrange a predefined set of 80 colors in a 8×10 grid in such a way that colors form nice gradients without tearing.
For reasons described below, there is no definitive solution to this question, possible solution are prone to imperfect result and subjectiveness. This is expected.
Note that I already have a function that compares two colors and tells how similar they are.
Color space is 3D
Human eye has three types of receptors to distinguish colors. Human color space is three-dimensional (trichromatic).
There are different models for describing colors and they all are three-dimensional: RGB, HSL, HSV, XYZ, LAB, CMY (note that "K" in CMYK is only required because colored ink is not fully opaque and expensive).
For example, this palette:
...uses polar coordinates with hue on the angle and saturation on the radius. Without the third dimension (lightness), this palete is missing all the bright and dark colors: white, black, all the greys (except 50% grey in the center), and tinted greys.
This palette is only a thin slice of the HSL/HSV color space:
It is impossible to lay out all colors on a 2D grid in a gradient without tearing in the gradient.
For example, here are all the 32-bit RGB colors, enumerated in lexicographic order into a 2D grid. You can see that the gradient has a lot of tearing:
Thus, my goal is to find an arbitrary, "good enough" arrangment where neighbors are more or less similar. I'd rather sacrifice a bit of similarity than have a few very similar clusters with tearing between them.
This question is about optimizing the grid in JavaScript, not about comparing colors!
I have already picked a function to determine the similarity of colors: Delta E 2000. This function is specifically designed to reflect the subjective human perception of color similarity. Here is a whitepaper describing how it works.
This question is about optimizing the arrangement of items in a 2D grid in such a way that the similarity of each pair of adjacent items (vertical and horizontal) is as low as it gets.
The word "optimizing" is used not in a sense of making an algorithm run faster. It is in a sense of Mathematical optimization:
In the simplest case, an optimization problem consists of maximizing or minimizing a real function by systematically choosing input values from within an allowed set and computing the value of the function.
In my case:
"The function" here means running the DeltaE.getDeltaE00(color1, color2) function for all adjacent items, the output is a bunch of numbers (142 of them... I think) reflecting how dissimilar all the adjacent pairs are.
"Maximizing or minimizing" — the goal is to minimize the output of "the function".
"An input value" — is a specific arrangement of 80 predefined items in the 8×10 grid. There are a total of 80! input values, which makes the task impossible to brute force on a home computer.
Note that I don't have a clear definition for the minimization criteria of "the function". If we simply use the smallest sum of all numbers, then the winning result might be a case where the sum is the lowest, but a few adjacent item pairs are very dissimilar.
Thus, "the function" should maybe take into account not only the sum of all comparisons, but also ensure that no comparisons are way off.
Possible paths for solving the issue
From my previous bounty attempt on this question, I've learned the following paths:
genetic algorithm
optimizer/solver library
manual sorting with a some algorithmic help
something else?
The optimizer/solver library solution is what I initially was hoping for. But the mature libraries such as CPLEX and Gurobi are not in JS. There are some JS libraries but they are not well documented and have no newbie tutorials.
The genetic algorithm approach is very exciting. But it requires concieving algorithms of mutating and mating specimen (grid arrangements). Mutating seems trivial: simply swap adjacent items. But I have no idea about mating. And I have little understanding of the whole thing in general.
Manual sorting suggestions seem promising at the first glance, but fall short when looking into them in depth. They also assume using algorithms to solve certain steps without providing actual algorithms.
Code boilerplate and color samples
I have prepared a code boilerplate in JS: https://codepen.io/lolmaus/pen/oNxGmqz?editors=0010
Note: the code takes a while to run. To make working with it easier, do the following:
Login/sign up for CodePen in order to be able to fork the boilerplate.
Fork the boilerplate.
Go to Settings/Behavior and make sure automatic update is disabled.
Resize panes to maximize the JS pane and minimize other panes.
Go to Change view/Debug mode to open the result in a separate tab. This enables console.log(). Also, if code execution freezes, you can kill the render tab without losing access the coding tab.
After making changes to code, hit save in the code tab, then refresh the render tab and wait.
In order to include JS libraries, go to Settings/JS. I use this CDN to link to code from GitHub: https://www.jsdelivr.com/?docs=gh
Source data:
const data = [
{index: 1, id: "1", name: "Wine Red", rgb: "#A35A6E"},
{index: 2, id: "3", name: "Rose Red", rgb: "#F3595F"},
{index: 3, id: "4", name: "Vivid Red", rgb: "#F4565F"},
// ...
];
Index is one-based numbering of colors, in the order they appear in the box, when sorted by id. It is unused in code.
Id is the number of the color from pen manufacturer. Since some numbers are in form of WG3, ids are strings.
Color class.
This class provides some abstractions to work with individual colors. It makes it easy to compare a given color with another color.
index;
id;
name;
rgbStr;
collection;
constructor({index, id, name, rgb}, collection) {
this.index = index;
this.id = id;
this.name = name;
this.rgbStr = rgb;
this.collection = collection;
}
// Representation of RGB color stirng in a format consumable by the `rgb2lab` function
#memoized
get rgbArr() {
return [
parseInt(this.rgbStr.slice(1,3), 16),
parseInt(this.rgbStr.slice(3,5), 16),
parseInt(this.rgbStr.slice(5,7), 16)
];
}
// LAB value of the color in a format consumable by the DeltaE function
#memoized
get labObj() {
const [L, A, B] = rgb2lab(this.rgbArr);
return {L, A, B};
}
// object where distances from current color to all other colors are calculated
// {id: {distance, color}}
#memoized
get distancesObj() {
return this.collection.colors.reduce((result, color) => {
if (color !== this) {
result[color.id] = {
distance: this.compare(color),
color,
};
}
return result;
}, {});
}
// array of distances from current color to all other colors
// [{distance, color}]
#memoized
get distancesArr() {
return Object.values(this.distancesObj);
}
// Number reprtesenting sum of distances from this color to all other colors
#memoized
get totalDistance() {
return this.distancesArr.reduce((result, {distance}) => {
return result + distance;
}, 0);
}
// Accepts another color instance. Returns a number indicating distance between two numbers.
// Lower number means more similarity.
compare(color) {
return DeltaE.getDeltaE00(this.labObj, color.labObj);
}
}
Collection: a class to store all the colors and sort them.
class Collection {
// Source data goes here. Do not mutate after setting in the constructor!
data;
constructor(data) {
this.data = data;
}
// Instantiates all colors
#memoized
get colors() {
const colors = [];
data.forEach((datum) => {
const color = new Color(datum, this);
colors.push(color);
});
return colors;
}
// Copy of the colors array, sorted by total distance
#memoized
get colorsSortedByTotalDistance() {
return this.colors.slice().sort((a, b) => a.totalDistance - b.totalDistance);
}
// Copy of the colors array, arranged by similarity of adjacent items
#memoized
get colorsLinear() {
// Create copy of colors array to manipualte with
const colors = this.colors.slice();
// Pick starting color
const startingColor = colors.find((color) => color.id === "138");
// Remove starting color
const startingColorIndex = colors.indexOf(startingColor);
colors.splice(startingColorIndex, 1);
// Start populating ordered array
const result = [startingColor];
let i = 0;
while (colors.length) {
if (i >= 81) throw new Error('Too many iterations');
const color = result[result.length - 1];
colors.sort((a, b) => a.distancesObj[color.id].distance - b.distancesObj[color.id].distance);
const nextColor = colors.shift();
result.push(nextColor);
}
return result;
}
// Accepts name of a property containing a flat array of colors.
// Renders those colors into HTML. CSS makes color wrap into 8 rows, with 10 colors in every row.
render(propertyName) {
const html =
this[propertyName]
.map((color) => {
return `
<div
class="color"
style="--color: ${color.rgbStr};"
title="${color.name}\n${color.rgbStr}"
>
<span class="color-name">
${color.id}
</span>
</div>
`;
})
.join("\n\n");
document.querySelector('#box').innerHTML = html;
document.querySelector('#title').innerHTML = propertyName;
}
}
Usage:
const collection = new Collection(data);
console.log(collection);
collection.render("colorsLinear"); // Implement your own getter on Collection and use its name here
Sample output:
I managed to find a solution with objective value 1861.54 by stapling a couple ideas together.
Form unordered color clusters of size 8 by finding a min-cost matching and joining matched subclusters, repeated three times. We use d(C1, C2) = ∑c1 in C1 ∑c2 in C2 d(c1, c2) as the distance function for subclusters C1 and C2.
Find the optimal 2 × 5 arrangement of clusters according to the above distance function. This involves brute forcing 10! permutations (really 10!/4 if one exploits symmetry, which I didn't bother with).
Considering each cluster separately, find the optimal 4 × 2 arrangement by brute forcing 8! permutations. (More symmetry breaking possible, I didn't bother.)
Brute force the 410 possible ways to flip the clusters. (Even more symmetry breaking possible, I didn't bother.)
Improve this arrangement with local search. I interleaved two kinds of rounds: a 2-opt round where each pair of positions is considered for a swap, and a large-neighborhood round where we choose a random maximal independent set and reassign optimally using the Hungarian method (this problem is easy when none of the things we're trying to move can be next to each other).
The output looks like this:
Python implementation at https://github.com/eisenstatdavid/felt-tip-pens
The trick for this is to stop thinking about it as an array for a moment and anchor yourself to the corners.
First, you need to define what problem you are trying to solve. Normal colors have three dimensions: hue, saturation, and value (darkness), so you're not going to be able to consider all three dimensions on a two dimensional grid. However, you can get close.
If you want to arrange from white->black and red->purple, you can define your distance function to treat differences in darkness as distance, as well as differences in hue value (no warping!). This will give you a set, four-corner-compatible sorting for your colors.
Now, anchor each of your colors to the four corners, like so, defining (0:0) as black, (1:1) as white, (0,1) as red (0 hue), and (1:0) as purple-red (350+ hue). Like so (let's say purple-red is purple for simplicity):
Now, you have two metrics of extremes: darkness and hue. But wait... if we rotate the box by 45 degrees...
Do you see it? No? The X and Y axes have aligned with our two metrics! Now all we need to do is divide each color's distance from white with the distance of black from white, and each color's distance from purple with the distance of red from purple, and we get our Y and X coordinates, respectively!
Let's add us a few more pens:
Now iterate over all the pens with O(n)^2, finding the closest distance between any pen and a final pen position, distributed uniformly through the rotated grid. We can keep a mapping of these distances, replacing any distances if the respective pen position has been taken. This will allow us to stick pens into their closest positions in polynomial time O(n)^3.
However, we're not done yet. HSV is 3 dimensional, and we can and should weigh the third dimension into our model too! To do this, we extend the previous algorithm by introducing a third dimension into our model before calculating closest distances. We put our 2d plane into a 3d space by intersecting it with the two color extremes and the horizontal line between white and black. This can be done simply by finding the midpoint of the two color extremes and nudging darkness slightly. Then, generate our pen slots fitted uniformly onto this plane. We can place our pens directly in this 3D space based off their HSV values - H being X, V being Y, and S being Z.
Now that we have the 3d representation of the pens with saturation included, we can once again iterate over the position of pens, finding the closest one for each in polynomial time.
There we go! Nicely sorted pens. If you want the result in an array, just generate the coordinates for each array index uniformly again and use those in order!
Now stop sorting pens and start making code!
As it was pointed out to you in some of the comments, you seem to be interested in finding one of the global minima of a discrete optimization problem. You might need to read up on that if you don't know much about it already.
Imagine that you have an error (objective) function that is simply the sum of distance(c1, c2) for all (c1, c2) pairs of adjacent pens. An optimal solution (arrangement of pens) is one whose error function is minimal. There might be multiple optimal solutions. Be aware that different error functions may give different solutions, and you might not be satisfied with the results provided by the simplistic error function I just introduced.
You could use an off-the-shelf optimizer (such as CPLEX or Gurobi) and just feed it a valid formulation of your problem. It might find an optimal solution. However, even if it does not, it may still provide a sub-optimal solution that is quite good for your eyes.
You could also write your own heuristic algorithm (such as a specialized genetic algorithm) and get a solution that is better than what the solver could find for you within the time and space limit it had. Given that your weapons seem to be input data, a function to measure color dissimilarity, and JavaScript, implementing a heuristic algorithm is probably the path that will feel most familiar to you.
My answer originally had no code with it because, as is the case with most real-world problems, there is no simple copy-and-paste solution for this question.
Doing this sort of computation using JavaScript is weird, and doing it on the browser is even weirder. However, because the author explicitly asked for it, here is a JavaScript implementation of a simple evolutionary algorithm hosted on CodePen.
Because of the larger input size than the 5x5 I originally demonstrated this algorithm with, how many generations the algorithm goes on for, and how slow code execution is, it takes a while to finish. I updated the mutation code to prevent mutations from causing the solution cost to be recomputed, but the iterations still take quite some time. The following solution took about 45 minutes to run in my browser through CodePen's debug mode.
Its objective function is slightly less than 2060 and was produced with the following parameters.
const SelectionSize = 100;
const MutationsFromSolution = 50;
const MutationCount = 5;
const MaximumGenerationsWithoutImprovement = 5;
It's worth pointing out that small tweaks to parameters can have a substantial impact on the algorithm's results. Increasing the number of mutations or the selection size will both increase the running time of the program significantly, but may also lead to better results. You can (and should) experiment with the parameters in order to find better solutions, but they will likely take even more compute time.
In many cases, the best improvements come from algorithmic changes rather than just more computing power, so clever ideas about how to perform mutations and recombinations will often be the way to get better solutions while still using a genetic algorithm.
Using an explicitly seeded and reproducible PRNG (rather than Math.random()) is great, as it will allow you to replay your program as many times as necessary for debugging and reproducibility proofs.
You might also want to set up a visualization for the algorithm (rather than just console.log(), as you hinted to) so that you can see its progress and not just its final result.
Additionally, allowing for human interaction (so that you can propose mutations to the algorithm and guide the search with your own perception of color similarity) may also help you to get the results you want. This will lead you to an Interactive Genetic Algorithm (IGA). The article J. C. Quiroz, S. J. Louis, A. Shankar and S. M. Dascalu, "Interactive Genetic Algorithms for User Interface Design," 2007 IEEE Congress on Evolutionary Computation, Singapore, 2007, pp. 1366-1373, doi: 10.1109/CEC.2007.4424630. is a good example of such approach.
If you could define a total ordering function between two colors that tell you which one is the 'darker' color, you can sort the array of colors using this total ordering function from dark to light (or light to dark).
You start at the top left with the first color in the sorted array, keep going diagonally across the grid and fill the grid with the subsequent elements. You will get a gradient filled rectangular grid where adjacent colors would be similar.
Do you think that would meet your objective?
You can change the look by changing the behavior of the total ordering function. For example, if the colors are arranged by similarity using a color map as shown below, you can define the total ordering as a traversal of the map from one cell to the next. By changing which cell gets picked next in the traversal, you can get different color-similar gradient grid fills.
I think there might be a simple approximate solution to this problem based on placing each color where it is the approximate average of the sorrounding colors. Something like:
C[j] ~ sum_{i=1...8}(C[i])/8
Which is the discrete Laplace operator i.e., solving this equation is equivalent to define a discrete harmonic function over the color vector space i.e., Harmonic functions have the mean-value property which states that the average value of the function in a neighborhood is equal to its value at the center.
In order to find a particular solution we need to setup boundary conditions i.e., we must fix at least two colors in the grid. In our case it looks convinient to pick 4 extrema colors and fix them to the corners of the grid.
One simple way to solve the Laplace's equation is the relaxation method (this amounts to solve a linear system of equations). The relaxation method is an iterative algorithm that solves one linear equation at a time. Of course in this case we cannot use a relaxation method (e.g., Gauss Seidel) directly because it is really a combinatorial problem more than a numercal problem. But still we can try to use relaxation to solve it.
The idea is the following. Start fixing the 4 corner colors (we will discuss about those colors later) and fill the grid with the bilinear interpolation of those colors. Then pick a random color C_j and compute the corresponding Laplacian color L_j i.e., the average color of sorrounding neighbors. Find the color closest to L_j from the set of input colors. If that color is different to C_j then replace C_j with it. Repeat the process until all colors C_j have been searched and no color replacements are needed (convergence critetia).
The function that find the closest color from input set must obey some rules in order to avoid trivial solutions (like having the same color in all neighbors and thus also in the center).
First, the color to find must be the closest to L_j in terms of Euclidian metric. Second, that color cannot be the same as any neighbor color i.e., exclude neighbors from search. You can see this match as a projection operator into the input set of colors.
It is expected that covergence won't be reached in the strict sense. So limiting the number of iterations to a large number is acceptable (like 10 times the number of cells in the grid). Since colors C_j are picked randomly, there might be colors in the input that were never placed in the grid (which corresponds to discontinuities in the harmonic function). Also there might be colors in the grid which are not from input (i.e., colors from initial interpolation guess) and there might be repeated colors in the grid as well (if the function is not a bijection).
Those cases must be addressed as special cases (as they are singularities). So we must replace colors from initial guess and repeated colors with that were not placed in the grid. That is a search sub-problem for which I don't have a clear euristic to follow beyond using distance function to guess the replacements.
Now, how to pick the first 2 or 4 corner colors. One possible way is to pick the most distinct colors based on Euclidean metric. If you treat colors as points in a vector space then you can perform regular PCA (Principal Component Analysis) on the point cloud. That amounts to compute the eigenvectors and corresponding eigenvalues of the covariance matrix. The eigenvector corresponding to the largest eigenvalue is a unit vector that points towards direction of greatest color variance. The other two eigenvectors are pointing in the second and third direction of greatest color variance in that order. The eigenvectors are orthogonal to each other and eigenvalues are like the "length" of those vectors in a sense. Those vectors and lengths can be used to determine an ellipsoid (egg shape surface) that approximately sorround the point cloud (let alone outliers). So we can pick 4 colors in the extrema of that ellipsoid as the boundary conditions of the harmonic function.
I haven't tested the approach, but my intuition ia that it should give you a good approximate solution if the input colors vary smoothly (the colors corresponds to a smooth surface in color vector space) otherwise the solution will have "singularities" which mean that some colors will jump abruptly from neighbors.
EDIT:
I have (partially) implemented my approach, the visual comparison is in the image below. My handling of singularities is quite bad, as you can see in the jumps and outliers. I haven't used your JS plumbing (my code is in C++), if you find the result useful I will try to write it in JS.
I would define a concept of color regions, that is, a group of colors where distance(P1, P2) <= tolerance. In the middle of such a region you would find the point which is closest to all others by average.
Now, you start with a presumably unordered grid of colors. The first thing my algorithm would do is to identify items which would fit together as color regions. By definition each region would fit well together, so we arrive to the second problem of interregion compatibility. Due to the very ordered manner of a region and the fact that into its middle we put the middle color, its edges will be "sharp", that is, varied. So, region1 and region2 might be much more compatible, if they are placed together from one side than the other side. So, we need to identify which side the regions are desirably glued together and if for some reason "connecting" those sides is impossible (for example region1 should be "above" region2, but, due to the boundaries and the planned positions of other regions), then one could "rotate" one (or both) the regions.
The third step is to check the boundaries between regions after the necessary rotations were made. Some repositioning of the items on the boundaries might still be needed.

Get RGB color of coordinates: Adobe Illustrator

I'm using ExtendScript to work on JavaScript for Adobe Illustrator 2015. Is there any way I could get RGB values from a coordinate in the code below?
// declares a document
var doc = app.activeDocument;
// sets x and y coordinates to get color from
var xPosition = 70.0;
var yPosition = 64.0;
This is what needs work:
// gets rgb values
double redValue = doc.getRGBColor(xPosition, yPosition).red;
double greenValue = doc.getRGBColor(xPosition, yPosition).red;
double blueValue = doc.getRGBColor(xPosition, yPosition).red;
I've googled quite a bit and found this.
It doesn't work, though, either because it was posted in 2009, or because it was meant to be in photoshop.
A solution to the problem or translation of that post would be greatly appreciated.
[EDIT: My apologies for giving essentially an AppleScript answer to your ExtendScript question. I was just looking over AS questions and forgot I went to a different section. I can only hope that you are on a Mac. If not, I guess I'll just eat my downvotes and weep.]
There is a workaround. The advantage of it (and part of the workaround nature of it) is that it works in all apps. The downside is that it requires python (which should be on your Mac anyway - fairly easy to install if not), and two pieces of third party software (both free), "checkModifierKeys" and "cliclick". I've been using a script that appears in my script menu for years.
The python part is described here: http://thechrisgreen.blogspot.com/2013/04/python-script-for-getting-pixel-color.html
This script can be saved, made executable and invoked using the AS do shell script command.
and the rest of it, for selecting a point on the screen and for waiting for the control key to be pressed (that's how mine works) is pretty simple.
The basic checkModifierKeys part (which waits until the Control key is pressed) is:
set controlIsDown to false
repeat until (controlIsDown)
set initialCheck to ((do shell script "/usr/local/bin/checkModifierKeys control"))
if initialCheck = "1" then set controlIsDown to true
end repeat
The cliclick part (which gets the coordinates) is:
set xyGrabbed to do shell script "/usr/local/bin/cliclick p"
It may seem like a long way to go for it, but it works great. My version converts the rgb value to hex with this handler, which is useful for my purposes:
to makeHex(theNumber) --was anInteger
--Converts an unsigned integer to a two-digit hexadecimal value
set theResult to ""
repeat with theIndex from 1 to 0 by -1
set theBase to (16 ^ theIndex) as integer
if theNumber is greater than or equal to theBase then
set theMultiplier to ((theNumber - (theNumber mod theBase)) / theBase) as integer
set theResult to theResult & item theMultiplier of ¬
{1, 2, 3, 4, 5, 6, 7, 8, 9, "A", "B", "C", "D", "E", "F"}
set theNumber to (theNumber - theBase * theMultiplier)
else
set theResult to (theResult & "0")
end if
end repeat
theResult
end makeHex
Yes, this solution doesn't work, because in vector editors such as Illustrator, color is applied to vector item (path) on the whole not to separate pixels. Even if you work with pixel image in illistrator there are no scripting functions to get pixel color.
I think it could be achieved via the rather monstrous solution:
Rasterize the artrboard.
Create Object Mosaic (where one tile ~> one pixel).
Figure out which one of the tiles lies underneath the given coordinates and pick its color.

How to optimize threshold in pocketsphinx.js

In original folder of pocketsphinx.js, where should I add the threshold code? I added to recognizer.js but didnt work. Here is the code that i found:
["-kws_threshold", '2']
I added like this (into recognizer.js):
function initialize(data, clbId) {
var config = new Module.Config();
config.push_back(["-kws_threshold", '300']);
And this is README of pocketsphinx..
Thank you
You need to optimize it on desktop with a prerecorded audio file, see details from the tutorial
Threshold must be specified for every keyphrase. For shorter keyphrase you can use smaller thresholds like 1e-1, for longer threshold must be bigger, up to 1e-50. If your keyphrase is very long, larger than 10 syllables, it is recommended to split it and spot for parts separately. For the best accuracy it is better to have keyphrase with 3-4 syllables. Too short phrases are easily confused.
Threshold must be tuned to balance between false alarms and missed detections, the best way to tune threshold is to use a prerecorded audio file. Tuning process is the following:
Take a long recording with few occurrences of your keywords and some
other sounds. You can take a movie sound or something else. The
length of the audio should be approximately 1 hour
Run keyword
spotting on that file with different thresholds for every keyword
Use the following command:
pocketsphinx_continuous -infile <your_file.wav> -keyphrase <"your keyphrase"> -kws_threshold <your_threshold> -time yes
It will print many lines, some of them are keywords with detection times and confidences. You can also disable extra logs with -logfn your_file.log option to avoid clutter.
From keyword spotting results count how many false alarms and missed
detections you've encountered Select the threshold with smallest
amount of false alarms and missed detections

highcharts positioning and colour

I have a few things I can't see to fix with my chart in highcharts-ng, see this http://jsfiddle.net/mcneela86/DJVP2/ for reference:
As a background, the chart will display a comparison of before and after values for horse power and torque in cars, after parts have been added.
1: I have grouped the data into 'before' and 'after', can I have the 'before' gourp coloured differently than the 'after' group. the colour of the 'after' group is correct, the 'before group' needs to be shades of grey?
2: I need to make the columns wider (while keeping them responsive). I thought the way to do this would be reducing the padding around the columns (see below) - but this won't work for me?
groupPadding: 0,
3; The third button (Stage 4 (new engine)) contains data with zero/null values, is it possible to have the data that remain spread across the whole graph? (so it doesn't look like there is something missing)
{
"after_hp":1000,
"after_torque":900,
"before_hp": null,
"before_torque":null,
"name":"Stage 4 (new engine)"
}
the 'null' values above can be null or '0' - I can control the data.
I have spent days trying to fix these issues and would really appreciate any help.
EDIT:
I found a solution for the first question above:
See this jsfiddle - http://jsfiddle.net/mcneela86/6caPj/ I used a workaround of targeting the data with css, while this works for my case it me not be ideal for larger data sets.
Hope this helps someone.
2) You can manipulate only groupPadding/pointPadding/pointWidth, but you have also ability to catch $(window).resize() or load.redraw() and update serie with new paraemters, described abo
3) You can try to call setExtremes() skipping 0, i.e as 1,1. or set min value as 1, on xAxis.
http://api.highcharts.com/highcharts#Axis.setExtremes

Solver for TSP-like Puzzle, perhaps in Javascript

I have created a puzzle which is a derivative of the travelling salesman problem, which I call Trace Perfect.
It is essentially an undirected graph with weighted edges. The goal is to traverse every edge at least once in any direction using minimal weight (unlike classical TSP where the goal is to visit every vertex using minimal weight).
As a final twist, an edge is assigned two weights, one for each direction of traversal.
I create a new puzzle instance everyday and publish it through a JSON interface.
Now I know TSP is NP-hard. But my puzzles typically have only a good handful of edges and vertices. After all they need to be humanly solvable. So a brute force with basic optimization might be good enough.
I would like to develop some (Javascript?) code that retrieves the puzzle from the server, and solves with an algorithm in a reasonable amount of time. Additionally, it may even post the solution to the server to be registered in the leader board.
I have written a basic brute force solver for it in Java using my back-end Java model on the server, but the code is too fat and runs out of heap-space quick, as expected.
Is a Javascript solver possible and feasible?
The JSON API is simple. You can find it at: http://service.traceperfect.com/api/stov?pdate=20110218 where pdate is the date for the puzzle in yyyyMMdd format.
Basically a puzzle has many lines. Each line has two vertices (A and B). Each line has two weights (timeA for when traversing A -> B, and timeB for when traversing B -> A). And this should be all you need to construct a graph data structure. All other properties in the JSON objects are for visual purposes.
If you want to become familiar with the puzzle, you can play it through a flash client at http://www.TracePerfect.com/
If anyone is interested in implementing a solver for themselves, then I will post detail about the API for submitting the solution to the server, which is also very simple.
Thank you for reading this longish post. I look forward to hear your thoughts about this one.
If you are running out of heap space in Java, then you are solving it wrong.
The standard way to solve something like this is to do a breadth-first search, and filter out duplicates. For that you need three data structures. The first is your graph. The next is a queue named todo of "states" for work you have left to do. And the last is a hash that maps the possible "state" you are in to the pair (cost, last state).
In this case a "state" is the pair (current node, set of edges already traversed).
Assuming that you have those data structures, here is pseudocode for a full algorithm that should solve this problem fairly efficiently.
foreach possible starting_point:
new_state = state(starting_point, {no edges visited})
todo.add(new_state)
seen[new_state] = (0, null)
while todo.workleft():
this_state = todo.get()
(cost, edges) = seen[this_state]
foreach directed_edge in graph.directededges(this_state.current_node()):
new_cost = cost + directed_edge.cost()
new_visited = directed_edge.to()
new_edges = edges + directed_edge.edge()
new_state = state(new_visited, new_edges)
if not exists seen[new_state] or new_cost < seen[new_state][0]:
seen[new_state] = (new_cost, this_state)
queue.add(new_state)
best_cost = infinity
full_edges = {all possible edges}
best_state
foreach possible location:
end_state = (location, full_edges)
(cost, last_move) = seen[end_state]
if cost < best_cost:
best_state = end_state
best_cost = cost
# Now trace back the final answer.
path_in_reverse = []
current_state = best_state
while current_state[1] is not empty:
previous_state = seen[current_state][1]
path_in_reverse.push(edge from previous_state[0] to current_state[0])
current_state = previous_state
And now reverse(path_in_reverse) gives you your optimal path.
Note that the hash seen is critical. It is what prevents you from getting into endless loops.
Looking at today's puzzle, this algorithm will have a maximum of a million or so states that you need to figure out. (There are 2**16 possible sets of edges, and 14 possible nodes you could be at.) That is likely to fit into RAM. But most of your nodes only have 2 edges connected. I would strongly advise collapsing those. This will reduce you to 4 nodes and 6 edges, for an upper limit of 256 states. (Not all are possible, and note that multiple edges now connect two nodes.) This should be able to run very quickly with little use of memory.
For most parts of graph you can apply http://en.wikipedia.org/wiki/Seven_Bridges_of_K%C3%B6nigsberg.
This way you can obtain number of lines that you should repeat in order to solve.
At beginning you should not start at nodes which has short vertices over which you should travel two times.
If I summarize:
start at node whit odd number of edges.
do not travel over lines which sit on even node more than once.
use shortest path to travel from one odd node to another.
Simple recursive brute force solver whit this heuristic might be good way to start.
Or another way.
Try to find shortest vertices that if you remove them from graph remining graph will have only two odd numbered nodes and will be considered solvable as Koningsberg bridge. Solution is solving graph without picking up pencil on this reduced graph and once you hit node whit "removed" edge you just go back and forward.
On your java backend you might be able to use this TSP code (work in progress) which uses Drools Planner (open source, java).

Categories