1

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/

Community
  • 1
  • 1
Anderson Green
  • 30,230
  • 67
  • 195
  • 328
  • I hope this question won't be closed as "too broad" or "too vague" - I'm trying to solve a simple and concrete problem here. – Anderson Green Nov 27 '12 at 01:55
  • Perhaps I could use a Javascript "prompt" function for user input in this case. I think it would be possible to adapt an algorithm such as quicksort for this purpose (using the Javascript "prompt" function for comparison, asking the user which item is more important to them). – Anderson Green Nov 27 '12 at 01:59
  • What about binary insertsort? Easy to implement, natural to the user (user always classifies a specific task => less "cache miss"es, linearithmic in the number of comparisons) – John Dvorak Nov 27 '12 at 02:06
  • Hint: if you're only looking for a strategy, don't include the language tag. I'm thinking about `language-agnostic` or `algorithm`. – John Dvorak Nov 27 '12 at 02:08
  • Hint2: if you're also looking for implementation details, then this _is_ too broad. – John Dvorak Nov 27 '12 at 02:08
  • @JanDvorak I gave the question a more specific title - I think it's now narrow enough to be given a specific answer. – Anderson Green Nov 27 '12 at 02:12
  • Also, if you're looking for a nice GUI, don't use the `prompt` even if synchronous user interaction simplifies coding. – John Dvorak Nov 27 '12 at 02:13
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/20141/discussion-between-anderson-green-and-jan-dvorak) – Anderson Green Nov 27 '12 at 02:13

2 Answers2

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.

Community
  • 1
  • 1
ErikE
  • 48,881
  • 23
  • 151
  • 196
  • On average, which sorting algorithm uses the least number of comparisons: the Javascript sort method, or insert-sort? According to this answer, insert-sort would most likely involve the fewest comparisons: http://stackoverflow.com/questions/13092548/which-sorting-algorithm-uses-the-fewest-comparisons – Anderson Green Nov 27 '12 at 02:41
  • Choosing the "most important" of a list of items is only one potential use case for an "assisted sorting" program: you could sort items by other subjective criteria (like "which photograph do you like the most?" or "which website is your favorite?"), while comparing just two or three items at a time. – Anderson Green Nov 27 '12 at 21:19
  • @AndersonGreen Fair enough! I wasn't trying to assume exactly what you're doing, it just occurred to me to add the "getting things done" info since it seemed related and could be helpful, depending on what your purpose is. – ErikE Nov 27 '12 at 21:48
  • Also, I have used the "Getting Things Done" methodology before, and I've found that it can be a bit overwhelming sometimes. I can spend hours making lists of things to do, and then get overwhelmed by the amount of work that I've created for myself. Trying to prioritize a long list of to-do items can be an overwhelming task, and that's why I wrote this script in the first place. – Anderson Green Dec 31 '12 at 00:44
0

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.

Tad
  • 934
  • 6
  • 10
  • I want to prompt the user to sort the items in pairs (using as few comparisons as possible) - is there any way to do this using the drag and drop list? I'd prefer to use a sorting algorithm that uses as few comparisons as possible (where the comparisons are made by the user.) – Anderson Green Nov 27 '12 at 02:28
  • Also, does this plugin present options to the user in pairs of two items, and then ask the user to choose the better of the two items? That's what I was trying to implement, and I don't see how it's relevant to a drag and drop sortable list. – Anderson Green Dec 16 '12 at 03:11