I have an interesting (or maybe its plain simple) problem to solve.
There are different size blocks (say any real numbers like 0.5 or 50) to allocate among buckets. Bucket size is always 64.
The problem to solve is to allocate the blocks in such a way that least amount of space in buckets is wasted.
Going for naive solution one can just iterate over buckets and push nth element into first bucket that the block can fit into. If there are no buckets that can fit the element - new bucket is created.
Is there any better way to do that or is the naive solution also an optimal solution?
This is a mathematically complex question called the Bin Packing Problem.
You probably won't find an easy way to implement the optimal soloution. This page mentions one solution, to always put the block in the fullest bucket that can fit it.
I think analyzing the entire dataset beforehand is the key to an optimal solution, but it doesn't seem like it will be easy to implement.
You can keep the buckets sorted by available space (e.g. from the max space available till the least space available. Your algorithm would be:
Initially the list is empty.
Create the first block for the new coming block.
The next one one is coming. Check if it fits into the first bucket. If doesn't, create a new one and check for available. If the new one has more available space than the first one, place it in front of the list, otherwise append to the end.
Essentially the problem narrows down to performing a binary search to find which of the buckets will fit the new element and finding a new place for the element you've updated at the current step.
Related
Here's the fiddle for it: https://jsfiddle.net/rujbra6y/3/
I'm already logging the speed so make any changes and just re-run it a couple times to see if the performance increased at all.
Been working on it for a couple hours and I can't think of anything else I can change to make it faster. I'd like it to be as fast as possible because currently there is a small delay when the user uses floodfill and for proper user experience, I'd like that delay to be as short as possible.
Are there any more optimizations or hacks I can use to increase the speed?
There are a couple of things you could do at a brief glance:
Replaced Uint8ClampedArray with Uint32Array. This will save you from unnecessary shifting and ANDing ops
Replace push/pop with a stack pointer, this way you just update instances
You could define a typed array (Int16Array) for the stack using a fixed size (be sure to make it large enough)
The only thing you need to be aware of for Uint32Array is the byte-order is little-endian, which mean you need to provide the target color in 0xAABBGGRR format (or do an initial bit-shift giving r,g,b as separate values).
With these changes (except the last) the code went down from about 69-75ms to 58-61ms on my computer (i5 at the moment).
Updated fiddle
I'll leave the typed array for stack as an exercise. :-)
I using JasonDavies's Word Cloud for my project, but there is a problem that I using Persian[Farsi] Strings and my problem here that words have overlapping in Svg.
This is my project's output:
What happened to the Farsi words?
As explained on the About page for the project, the generator needs to retrieve the shape of a glyph to be able to compute where it is "safe" to put other words. The about page explains the process in much more detail, but here's what we care for:
Glyphs are rendered individually to a hidden <canvas> element.
Pixel data is retrieved
Bounding boxes are derived
The word cloud is generated.
Now, the critical insight is that in Western (and many other) scripts, glyphs don't change shape based on context often. Yes, there are such things as ligatures, but they are generally rare, and definitely not necessary for the script.
In Persian, however, the glyph shape will change based on context. For non-Persian readers, look at ی and س which, when combined, become یس. Yes, that last one is two glyphs!
The algorithm actually has no problem dealing with Persian characters, as you can see by hacking the demo on the about page, putting a breakpoint just after the d.code is generated, to be able to modify it:
Replacing it with 1740, which is the charCode for the first Persian glyph above, and letting the algorithm run, shows beautiful and perfectly correct bounding boxes around the glyph:
The issue is that when the word cloud is actually rendered, the glyph is placed in context and... changes shape. The generator doesn't know this, though, and continues to use the old bounding data to place other words, thus creating the overlapping you witnessed. In addition, there is probably also an issue around right-to-left handling of text, which certainly would not help.
I would encourage you to take this up the author of the generator directly. The project has a GitHub page: https://github.com/jasondavies/d3-cloud so opening an issue there (and maybe referring back to this answer) would help!
I will describe my problem using the attached image :
The green block is the starting position of my game entity. Next I'd like to move it to the position marked by the orange square. But at the same time, I assume that levitation is not possible or/& this block is a wall. In either case going there is not possible. So I need to figure out a way of finding the first available place (as close to the orange square as possible) for my entity to move (in this case it would be either the top of the grey column or point two rows beneath the orange square).
I have a 2d array describing the grid, where 1 is a wall and 0 is empty space.
data = [
[1,1,1,1,...],
[1,0,0,0,0,...],
[1,0,0,...],
...
]
I was thinking about solution in this way (where for example I can check at 1. if beneath my cell is floor and end the algo, or continue if not to cell 2.) but I can't think of a way of doing this efficiently (and easily).
Does anyone has any ideas how to tackle this ? I'm not really sure what algo should I ask google for :)
You are looking for Q-learning algorithms. This is a form of reinforcement learning. Here's one http://en.wikipedia.org/wiki/SARSA
Basically you run the simulation between source and destination multiple times and each time it gets close and closer to discovering the goal.
I think you can use Cellular Automata for your case, if it is worth the trouble. It is not AI per se, easy to implement and you can replace A* as well as the final position finding problem using one logic.
Consider the eight neighbourhood cells around the game entity. Each cell can be free or blocked (0 or 1). There will be 2^8 combinations of the neighbourhood, but you may or may not have to use that many rules for the CA.
Try looking into this: http://www.cs.sun.ac.za/rw711/2012term1/documents/CABehringPathPlanning.pdf
they implemented CA for path planning in robotics, you can tweak it to suit your need.
The advantage is, with proper rule set, your CA will terminate only when the game entity has reached the appropriate position around the goal (closest to the goal and not levitating).
You can also implement multiple rule sets on the system, thereby making it more robust.
I'm trying to create a simple "human-powered prioritizer" program in Javascript, and I'd like to find a way to sort a list of items according to user input.
I think it would be best to implement this using an algorithm that makes as few comparisons as possible (so that the user will be presented with as few prompts as possible.)
I'd like to sort the following items by importance (where the relative importance of each pair of items is decided by the user.):
1) Finish Haxe project
2) Finish Java project
3) Fix car
I'd like to present the items to the user in pairs, and then ask them to decide which item is the most important. Which sorting algorithm would be best suited to this task (where the comparison of items would be made by the user?)
Here's an example of an automatic prioritizer that uses user input: http://luhman.org/prioritizer-scheduler
Update: I've written a script that does exactly this: here it is. http://jsfiddle.net/fq3sy/1/
JavaScript arrays offer the sort method, which allows passing in a callback function to do custom sorting of non-strings. If you can perform a "blocking" user input collection in such a callback function, you could fully sort the list with exactly the set of "which one is more important" questions needed (perhaps a window.confirm() with a question like "Is A more important than B?"). This would be ugly in terms of beautiful-UI, but could be practical and work.
To avoid the question-answering occurring during execution of the sort, you could at least assign the list an order to start, perform the sort and record which pairs of items were asked for, then present all those pairs in a list. Any change of which of 2 items was more important would trigger a resort and then the user would be asked to answer only those items that were new (and hadn't already been asked).
Tad's idea to allow the user to drag-and-drop to sort the list could be good (though it sounds like you want the "which is more important" flow instead), though I recommend jQuery and its Sortable plugin.
To address which sort algorithm is the best to use, that may be difficult. No one algorithm will reliably sort the list in the fewest number of steps, because the number of steps required always depends on the initial position of the items. Some sort algorithms are indeed more efficient, but they still can be costly if the list starts out sorted completely in reverse or in another way hostile to that algorithm. No matter what scheme you use, there will be ways that it is inefficient. Some are better than others, however.
To get a handle on the issue, start by reviewing popular sorting algorithms. Each sort has a best-case, average, and worst-case scenario. In the question you linked in your comment, the questioner said his data had sort keys that were repeated many times, thus an answerer suggested maybe using the insertion sort whose best-case occurs when the input is already sorted. In the case of the list being exactly in reverse, though, it has a very bad worst-case performance of O(n2). For arbitrary comparisons, pretty much the best you can achieve is O(n log n).
I do have one idea to cut down on the number of questions, though: start by presenting the whole list of items with a set of H M L (high medium low) buttons for the user to assign an overall priority to each. This can be done very quickly by the user. When done, sort each list individually. This is basically doing a distribution sort, and will cut down on the number of "which is more important" questions by a huge amount. My instinct says that sorting three lists of 10 items each is quite a bit less expensive than sorting one list of 30.
Your best bet is probably a merge sort or a heap sort. But you need to examine the algorithms yourself. Perhaps you would use one sort at the beginning when everything is out of order, then for later sorts use a method that performs best when the inputs are close to in order already.
In any case, my idea of breaking the list into H M L categories should substantially reduce the number of steps with any sort method.
After some more thought, it seems to me that having the user perform what amounts to an insertion sort may be a reasonable method. To implement it, instead of making the user compare an unsorted item one at a time to each already-sorted item, simply ask the user to place the new item at the correct place in the already-sorted items. Ask the user to pick one item to start with. It can be the most important, least important, or somewhere in the middle--it doesn't matter. Then, display the list of one item (with plenty of room for more) and then one at a time, have him drag into place (or otherwise choose) where in the list each unsorted item belongs. When done, the list will be sorted. This gains efficiencies because the user will not have to read (and compare) every single item in his list one at a time at each step--he'll know whether his item belongs near the top, in the middle, or at the bottom of the in-process, already-organized portion of the list simply by familiarity with it. He'll be able to scan quickly through the obvious non-matching-priority areas and then zero in on the few items he has to carefully weigh to determine proper order. At any time, if he changes his mind about the order of already-placed items, he can rearrange them.
As one final comment, I would like to suggest that you look into the Getting Things Done model, which has some advantages over the "do things in order of priority" model. At the very least, the concepts of having a trusted computer system, scheduling things and forgetting them, and avoiding the repetition of the same work seem invaluable for any system to help users get things done.
Sounds like a drag & drop sortable list using Javascript
http://tool-man.org/ToolManDHTML/sorting.html
You can sort the Example: A Basic List and click the inspect button on the right to get the current order. Should be pretty easy to adapt to what you want.
Note: I don't have any affiliation with the site - just the first one I found quickly in google.
Ok I need to be able to position a bunch of random sized absolutely positioned words on a page but I don't want any of the elements to overlap.
The end goal is to have a fluid word cloud that responds to user interaction (remember the Google Balls Doodle?). I would really like to build this from scratch to develop my understanding of this type of development. Any help in this department would also be appreciated :)
I'm not sure if you also want to position the words randomly inside a container, but i've written a fiddle that does just that. You can modify the code to position one word right after the other if you want to though. I think the key part is the method to check if there's a collision.
see http://jsfiddle.net/fZtdt/13/
EDIT: Be aware that this is very simple and unoptimized code. If for example you would add to many words, chances are that the script won't be able to fit all words inside the container, and get into an endless loop.
I have forked Jules' script to add this improvement : the search for a non-overlapping region is bounded (otherwise the original script will loop I believe), and the best region (the one with the smallest overlap) is selected.
see http://jsfiddle.net/Vnyvc/21/
play with the maxSearchIterations variable and/or the size of the whole region, it really makes a difference.