There have been a couple of questions very close to this topic, but none really helped me.
Ive been programming a graphing library, and I need an algorithm to vertically place labels without overlapping. I've been stuck on this for a couple of days now, and managed to distil it to the most basic function:
If given a series of label positions along the Y axis, say, 1 1 2 3 5 6 9, and an upper and a lower limits 10 and 0 respectively, I need a way to space out the values to output 1 2 3 4 5 6 9
333467 should be 234567 weighted to be close to the original coordinates.
This should also work backwards, if values are bunched up at the upper end of the scale, they should be spread as much as possible (before overflowing)
I'm not looking for a definitive answer, but I'd like some help on how to approach this problem. Im completely stuck.
Last train of thought was to scan all labels for possible collisions and position them as one big block, aligning to the centre of all the Y coordinates. But this will not work if there are multiple sets of collisions.
EDIT: To put this algorithm in a bigger context, have a look at these two google chart API pie charts:
1) Top stacked labels
2) Bottom Stacked Labels
The labels are almost springy, they avoid collisions by joining together and moving their entire mass to the center of their mass.
Make the set of labels unique by inserting into an ordered set. Divide the difference between the y-axis upper and lower bound by the number of elements in the set. This is your spacing increment. Iterate over the set in order and position one label every spacing increment.
You didn't say anything about needing to preserve a scale...
Well, After some thought and advice from other sources i came up with a solution:
Pseudocode:
foreach labels as label
if label->collidesWith(labels->lowerLimit)
label->moveAwayFrom(labels->lowerLimit)
if label->collidesWith(labels->upperLimit)
label->moveAwayFrom(labels->upperLimit)
if label->collidesWith(label->previous)
label->moveAwayFrom(label->previous)
label->previous->moveAwayFrom(label)
if label->collidesWith(label->next)
label->moveAwayFrom(label->next)
label->next->moveAwayFrom(label)
endforeach
MoveAwayFrom moves 1 pixel at a time. When this function is run multiple times it rejiggles the labels until none of them collide. (in reality im calling this loop 100 times, havent figured out a way to do it more inteligently)
Related
I have 4 years PHP and C# experience, but Math is not my better side.
I thnik that i need in this project use some math algorithms.
When page load I need randomly create 7 numbers, 6 are numbers that I can use to calculate given three digit number:
rand 1-9
rand 1-9
rand 1-9
rand 1-9
rand 10-100 //5 steps
rand 10-100 //5 steps
and given number to calculate is 100-999,
I can use this operations: +, -, /, *, (, )
What is best algorithm for this?
I probably need to try all possible combinations with this 6 numbers to calculate given number or closest number of calculations.
example:
let say that given three digit number is
350, and I need to calculate this number from this numbers:
3,6,9,5 10, 100
so formula for this is:
(100*3)+(5*10) = 350
if is not possible to calculate exact number, than calculate closest.
You don't need to solve this problem completely, you can introduce me to solve this problem by paste some pseudo, or describing how to do that.
I have no actual experience that might help you with this, though since you're asking for some insight, I'll share my thoughts on how to do this.
As I typed my answer, I realised that this is in fact a knapsack problem, which means you can solve it to optimality using any algorithm that solves the knapsack problem. I recommend using dynamic programming to make your program run faster.
What you need to do is construct all numbers you can generate by combining two numbers with an operator, so that after this you have a list containing the numbers you started with, and the numbers you generated.
Then you solve the knapsack problem using the numbers as items with their value as their weight, and the number as the weight you can store at most.
The only thing that is slightly different is that you have an extra constraint that says that you may only use a number once. So you need to add into your implementation that if you add a combination of numbers, that you must remove the option of storing another combination that is constructed with the same number.
You could enumerate all the solutions by building "Abstract syntax trees", binary trees with the following informations :
the leaves are the 6 numbers
the nodes are the operations, for example a node '+' with the leaf '7' for left son and another node for right son that is 'x' with '140' for left son and '8' for right son would represent (7+(140*8)). Additionally, at each node you store the numbers that you already used (the leaves used in the tree), and the total.
Let's say you store all the constructed trees in the associative map TreeSets, but indexed by the number of leaves you use. For example, the tree (7+(140*8)) would not be stored directly in TreeSets but in TreeSets[3] (TreeSets[3] contains several trees, it is also a set).
You store the most close score in BestScore and one solution of the BestScore in BestSolution.
You start by constructing the 6 leaves (that makes you 6 different trees consisting of only one leaf). You save the closer number in Bestscore and the corresponding leaf in BestSolution.
Then at each step, you try to construct the trees with i leaves, i from 2 to 6, and store them in TreeSets[i].
You take j from 1 to i-1, you take each tree in TreeSets[j] and each tree in TreeSets[i-j], you check that those two trees don't use the same leaves (you don't have to check at the bottom of the tree since you have stored the leaves used in the node), if so you build the four nodes '+', 'x', '/', '-' with the tree from TreeSets[j] as left son and the tree from TreeSets[i-j] and store all four of them in TreeSets[i]. While building a node, you take the total from both tree and apply the operation, you store the total, and you check if it is closer than BestScore (if so you update BestScore and BestSolution with this new total and with the new node). If the total is exactly the value you were looking for, you can stop here.
If you didn't stopped the program by finding an exact solution, there is no such solution, and the closer one is in BestSolution at the end.
Note : You don't have to build a complete tree each time, just build the node with two pointers on other trees.
P.S. : You may avoid to enumerate all the solutions by using the dynamic programming approach, as Glubus said. In this case, it would consist, at each step (i) to remove some solutions that are considered sub-optimal. But with this problem I'm not sure that is possible (except maybe remove the nodes with a total of 0).
i am developing a board game in php and now i have problems in writing an algorithm...
the game board is a multidimensional array ($board[10][10]) to define rows and columns of the board matrix or vector...
now i have to loop through the complete board but with a dynamic start point. for example the user selects cell [5,6] this is the start point for the loop. goal is to find all available board cells around the selected cell to find the target cells for a move method. i think i need a performant and efficient way to do this. does anyone know an algorithm to loop through a matrix/vector, only ones every field to find the available and used cells?
extra rule...
in the picture appended is a blue field selected (is a little bigger than the other). the available fields are only on the right side. the left side are available but not reachable from the current selected position... i think this is a extra information which makes the algorithm a little bit complicated....
big thx so far!
kind regards
not completely sure that I got the requirements right, so let me restate them:
You want an efficient algorithm to loop through all elements of an nxn matrix with n approximately 10, which starts at a given element (i,j) and is ordered by distance from (i,j)!?
I'd loop through a distance variable d from 0 to n/2
then for each value of d loop for l through -(2*d) to +(2*d)-1
pick the the cells (i+d, j+l), if i>=0 also pick (i+l,j-d),(i+l, j+d)
for each cell you have to apply a modulo n, to map negativ indexes back to the matrix.
This considers the matrix basically a torus, glueing upper and lower edge as well as left and right edge together.
If you don't like that you can let run d up to n and instead of a modulo operation just ignore values outside the matrix.
These aproaches give you the fields directly in the correct order. For small fields I do doubt any kind of optimization on this level has much of an effect in most situations, Nicholas approach might be just as good.
Update
I slightly modified the cells to pick in order to honor the rule 'only consider fields that are right from the current column or on the same column'
If your map is only 10x10, I'd loop through from [0][0], collecting all the possible spaces for the player to move, then grade the spaces by distance to current player position. N is small, so the fact that the algorithm has O(N^2) shouldn't affect your performance much.
Maybe someone with more background in algorithms has something up their sleeve.
I have a html table with a variable number of cells.
For the sake of this example i will say 20x20 (although it's quite bigger).
This is generated via php and the dataset to populate the table has been pulled from mysql.
Each one of these cells has a numeric value, and it needs to specifically be placed where is is. So if cell A(10,15) has a value of 100, that 100 needs to specifically be on 10,15-
And while the table is being generated i have no way to analyze the positioning.
Now, many of these cells, have other adjacent cells with the same value. Either horizontally or vertically.
What i need to do is merge adjacent cells of a this table that have the same value.
This could be horizontal, vertical, or both, but still keeping it a rectangle- Nothing too funky.
For example if i have
0 1 1 1 0
2 2 5 0 4
5 5 5 1 4
i need to modify the colspan and/or rowspan based on value-
To be noted is that upon generation i can actually define classes or ids for each one
of these cells. Also during generation i can identify wether there will be more than one in a series in a row, but i have no way of knowing wether there will be one on the row below.
ps: i did do a bit a research and found this thread.
Complex table merging javascript & jquery algorithm
modified the jsfiddle example to affect both colspan and rowspan of the cell but it seems to flip out when it needs to merge more that two cells-
What could be a suggested approach on the matter?
Thank you in advance
Do it in two passes (O(n2)), first traverse your array in the width and detect the number of adjacent cells (and set zero for a cell after the same one) :
0(1) 1(3) 1(0) 1(0) 0(1)
2(2) 2(0) 5(1) 0(1) 4(1)
5(3) 5(0) 5(0) 1(1) 4(1)
Then, traverse it vertically, and find cells where both numbers are the same (and the count > 0), you'll get :
0(1,1) 1(3,1) 1(0,0) 1(0,0) 0(1,1)
2(2,1) 2(0,0) 5(1,0) 0(1,1) 4(1,2)
5(3,1) 5(0,0) 5(0,0) 1(1,1) 4(1,0)
Now, the first number of the pair is the colspan, the second is the rowspan. If one of the number is 0, don't output it.
0 1---- 0
2-- 5 0 4
5---- 1 |
This is prob more of a geometry question, but
I have an array of 4 points (from user input), that could be in any order.
I'm trying to work out a procedure that would return what each point is likely to be, i.e.
top left,
top right,
bottom left,
bottom Right
I'm working in PHP now, but any help in any language is fine.
{'Ill add what i've got so far in PHP shortly}
Would this question be better asked on another stackexchange, math maybe?
You could sort the points by their x coordinates ascending and if there's a tie, the y coordinate ascending.
The first two points are the "left" side - the one with the greater y is the "top" and the other is "bottom".
The last two points are the "right" side, same deal.
This won't work for a diamond though! (But what's "top-left" on a diamond anyway?)
In general, for a convex set of points, you can calculate the centroid (x value is the average of all x values, y value is the average of all y values).
Then, you can calculate the argument (i.e. angle) of the line between the centroid and the point, being arctan2 of (y_pt-y_centroid,x_pt-x_centroid).
If you then sort the points by their arguments, they'll be in anticlockwise order, with -pi being the West point of the compass, 0 being the East, wrapping around again to +pi being the west point.
You could sort the points first vertically and call the top 2 points top points and the bottom 2 bottom points. Then sort the points horizontally and call the two right-most points right and the other two left. Now you have one of each.
The two-points with the lowest x-values make up the left-side, the other two make up the right.
Same goes for y and top/bottom.
I'm trying to write a function in PHP that gets all permutations of all possible sizes. I think an example would be the best way to start off:
$my_array = array(1,1,2,3);
Possible permutations of varying size:
1
1 // * See Note
2
3
1,1
1,2
1,3
// And so forth, for all the sets of size 2
1,1,2
1,1,3
1,2,1
// And so forth, for all the sets of size 3
1,1,2,3
1,1,3,2
// And so forth, for all the sets of size 4
Note: I don't care if there's a duplicate or not. For the purposes of this example, all future duplicates have been omitted.
What I have so far in PHP:
function getPermutations($my_array){
$permutation_length = 1;
$keep_going = true;
while($keep_going){
while($there_are_still_permutations_with_this_length){
// Generate the next permutation and return it into an array
// Of course, the actual important part of the code is what I'm having trouble with.
}
$permutation_length++;
if($permutation_length>count($my_array)){
$keep_going = false;
}
else{
$keep_going = true;
}
}
return $return_array;
}
The closest thing I can think of is shuffling the array, picking the first n elements, seeing if it's already in the results array, and if it's not, add it in, and then stop when there are mathematically no more possible permutations for that length. But it's ugly and resource-inefficient.
Any pseudocode algorithms would be greatly appreciated.
Also, for super-duper (worthless) bonus points, is there a way to get just 1 permutation with the function but make it so that it doesn't have to recalculate all previous permutations to get the next?
For example, I pass it a parameter 3, which means it's already done 3 permutations, and it just generates number 4 without redoing the previous 3? (Passing it the parameter is not necessary, it could keep track in a global or static).
The reason I ask this is because as the array grows, so does the number of possible combinations. Suffice it to say that one small data set with only a dozen elements grows quickly into the trillions of possible combinations and I don't want to task PHP with holding trillions of permutations in its memory at once.
Sorry no php code, but I can give you an algorithm.
It can be done with small amounts of memory and since you don't care about dupes, the code will be simple too.
First: Generate all possible subsets.
If you view the subset as a bit vector, you can see that there is a 1-1 correspondence to a set and a binary number.
So if your array had 12 elements, you will have 2^12 subsets (including empty set).
So to generate a subset, you start with 0 and keep incrementing till you reach 2^12. At each stage you read the set bits in the number to get the appropriate subset from the array.
Once you get one subset, you can now run through its permutations.
The next permutation (of the array indices, not the elements themselves) can be generated in lexicographic order like here: http://www.de-brauwer.be/wiki/wikka.php?wakka=Permutations and can be done with minimal memory.
You should be able to combine these two to give your-self a next_permutation function. Instead of passing in numbers, you could pass in an array of 12 elements which contains the previous permutation, plus possibly some more info (little memory again) of whether you need to go to the next subset etc.
You should actually be able to find very fast algorithms which use minimal memory, provide a next_permutation type feature and do not generate dupes: Search the web for multiset permutation/combination generation.
Hope that helps. Good luck!
The best set of functions I've come up with was the one provided by some user at the comments of the shuffle function on php.net Here is the link It works pretty good.
Hope it's useful.
The problem seems to be trying to give an index to every permutation and having a constant access time. I cannot think of a constant time algorithm, but maybe you can improve this one to be so. This algorithm has a time complexity of O(n) where n is the length of your set. The space complexity should be reducible to O(1).
Assume our set is 1,1,2,3 and we want the 10th permutation. Also, note that we will index each element of the set from 0 to 3. Going by your order, this means the single element permutations come first, then the two element, and so on. We are going to subtract from the number 10 until we can completely determine the 10th permutation.
First up are the single element permutations. There are 4 of those, so we can view this as subtracting one four times from 10. We are left with 6, so clearly we need to start considering the two element permutations. There are 12 of these, and we can view this as subtracting three up to four times from 6. We discover that the second time we subtract 3, we are left with 0. This means the indexes of our permutation must be 2 (because we subtracted 3 twice) and 0, because 0 is the remainder. Therefore, our permutation must be 2,1.
Division and modulus may help you.
If we were looking for the 12th permutation, we would run into the case where we have a remainder of 2. Depending on your desired behavior, the permutation 2,2 might not be valid. Getting around this is very simple, however, as we can trivially detect that the indexes 2 and 2 (not to be confused with the element) are the same, so the second one should be bumped to 3. Thus the 12th permutation can trivially be calculated as 2,3.
The biggest confusion right now is that the indexes and the element values happen to match up. I hope my algorithm explanation is not too confusing because of that. If it is, I will use a set other than your example and reword things.
Inputs: Permutation index k, indexed set S.
Pseudocode:
L = {S_1}
for i = 2 to |S| do
Insert S_i before L_{k % i}
k <- k / i
loop
return L
This algorithm can also be easily modified to work with duplicates.