Index: mythmusic/playlist.h
===================================================================
--- mythmusic/playlist.h	(revision 22065)
+++ mythmusic/playlist.h	(working copy)
@@ -147,6 +147,14 @@
 
   private:
     QString             removeDuplicateTracks(const QString &new_songlist);
+    void    computeIntelliOrder(QList<Track*>&          songs,
+                                std::map<int,uint32_t>& order,
+                                int                     playcountMin,
+                                int                     playcountMax,
+                                double                  lastplayMin,
+                                double                  lastplayMax);
+
+  private:
     int                 playlistid;
     QString             name;
     QString             raw_songlist;
Index: mythmusic/playlist.cpp
===================================================================
--- mythmusic/playlist.cpp	(revision 22065)
+++ mythmusic/playlist.cpp	(working copy)
@@ -1,3 +1,6 @@
+#include "playlist.h"
+
+#include <assert.h>
 #include <unistd.h>
 #include <inttypes.h>
 #include <cstdlib>
@@ -11,7 +14,6 @@
 #include <QFileInfo>
 #include <q3process.h>
 
-#include "playlist.h"
 #include "playlistcontainer.h"
 #include "smartplaylist.h"
 
@@ -847,6 +849,102 @@
     return songlist;
 }
 
+void Playlist::computeIntelliOrder(QList<Track*>&          songs,
+                                   std::map<int,uint32_t>& order,
+                                   int                     playcountMin,
+                                   int                     playcountMax,
+                                   double                  lastplayMin,
+                                   double                  lastplayMax)
+{
+    assert(order.empty());
+
+    int RatingWeight = 2;
+    int PlayCountWeight = 2;
+    int LastPlayWeight = 2;
+    int RandomWeight = 2;
+    parent->FillIntelliWeights(RatingWeight, PlayCountWeight, LastPlayWeight,
+                               RandomWeight);
+
+    // first we compute all the weights
+    std::map<int,double> weights;
+    std::map<int,int> ratings;
+    std::map<int,int> ratingCounts;
+    int TotalWeight = RatingWeight + PlayCountWeight + LastPlayWeight;
+    for (int trackItI = 0; trackItI < songs.size(); ++trackItI)
+    {
+    	Track *trackIt = songs[trackItI];
+        if (!trackIt->getCDFlag())
+        {
+            int songId = trackIt->getValue();
+            if (songId == 0)
+            {
+                VERBOSE(VB_IMPORTANT, "Song with ID of 0 in playlist, this "
+                                      "shouldn't happen.");
+            }
+            if (songId > 0)
+            {
+                Metadata *tmpdata = all_available_music->getMetadata(songId);
+                if (tmpdata && tmpdata->isVisible())
+                {
+                    int rating = tmpdata->Rating();
+                    int playcount = tmpdata->PlayCount();
+                    double lastplaydbl = tmpdata->LastPlay();
+                    double ratingValue = (double)(rating) / 10;
+                    double playcountValue, lastplayValue;
+
+                    if (playcountMax == playcountMin)
+                        playcountValue = 0;
+                    else
+                        playcountValue = ((playcountMin - (double)playcount) / (playcountMax - playcountMin) + 1);
+
+                    if (lastplayMax == lastplayMin)
+                        lastplayValue = 0;
+                    else
+                        lastplayValue = ((lastplayMin - lastplaydbl) / (lastplayMax - lastplayMin) + 1);
+
+                    double weight = (RatingWeight * ratingValue +
+                                     PlayCountWeight * playcountValue +
+                                     LastPlayWeight * lastplayValue) / TotalWeight;
+                    weights[songId] = weight;
+                    ratings[songId] = rating;
+                    ++ratingCounts[rating];
+                }
+            }
+        }
+    }
+
+    // then we divide weights with the number of songs in the rating class
+    // (more songs in a class ==> lower weight, without affecting other classes)
+    double totalWeights = 0;
+    std::map<int,double>::iterator weightsIt, weightsEnd = weights.end();
+    for(weightsIt = weights.begin() ; weightsIt != weightsEnd ; ++weightsIt)
+    {
+        weightsIt->second /= ratingCounts[ratings[weightsIt->first]];
+        totalWeights += weightsIt->second;
+    }
+
+    // then we get a random order, balanced with relative weights of remaining songs
+    uint32_t orderCpt = 1;
+    std::map<int,double>::iterator weightIt, weightEnd;
+    while(weights.size() > 0)
+    {
+        double hit = totalWeights * (double)rand() / (double)RAND_MAX;
+        weightEnd = weights.end();
+        weightIt = weights.begin();
+        double pos = 0;
+        while(weightIt != weightEnd)
+        {
+            pos += weightIt->second;
+            if(pos >= hit) break;
+            ++weightIt;
+        }
+        order[weightIt->first] = orderCpt;
+        totalWeights -= weightIt->second;
+        weights.erase(weightIt);
+        ++orderCpt;
+    }
+}
+
 int Playlist::writeTree(GenericTree *tree_to_write_to, int a_counter)
 {
     // compute max/min playcount,lastplay for this playlist
@@ -932,14 +1030,11 @@
         count++;
     }
 
-    int RatingWeight = 2;
-    int PlayCountWeight = 2;
-    int LastPlayWeight = 2;
-    int RandomWeight = 2;
+    std::map<int,uint32_t> intelliOrder;
+    computeIntelliOrder(songs, intelliOrder, 
+                        playcountMin, playcountMax, 
+                        lastplayMin, lastplayMax); 
 
-    parent->FillIntelliWeights(RatingWeight, PlayCountWeight, LastPlayWeight,
-                               RandomWeight);
-
     for (it = songs.begin(); it != songs.end(); ++it)
     {
         if (!(*it)->getCDFlag())
@@ -965,37 +1060,8 @@
                     added_node->setAttribute(1, a_counter); //  regular order
                     added_node->setAttribute(2, rand()); //  random order
 
-                    //
-                    //  Compute "intelligent" weighting
-                    //
-
-                    int rating = tmpdata->Rating();
-                    int playcount = tmpdata->PlayCount();
-                    double lastplaydbl = tmpdata->LastPlay();
-                    double ratingValue = (double)(rating) / 10;
-                    double playcountValue, lastplayValue;
-
-                    if (playcountMax == playcountMin)
-                        playcountValue = 0;
-                    else
-                        playcountValue = ((playcountMin - (double)playcount)
-                                         / (playcountMax - playcountMin) + 1);
-
-                    if (lastplayMax == lastplayMin)
-                        lastplayValue = 0;
-                    else
-                        lastplayValue = ((lastplayMin - lastplaydbl)
-                                        / (lastplayMax - lastplayMin) + 1);
-
-                    double rating_value =  (RatingWeight * ratingValue +
-                                            PlayCountWeight * playcountValue +
-                                            LastPlayWeight * lastplayValue +
-                                            RandomWeight * (double)rand() /
-                                            (RAND_MAX + 1.0));
-                    uint32_t integer_rating = (int) (4000001 -
-                                                     rating_value * 10000);
                     //  "intelligent" order
-                    added_node->setAttribute(3, integer_rating);
+                    added_node->setAttribute(3, intelliOrder[(*it)->getValue()]);
 
                     // "intellegent/album" order
                     uint32_t album_order;
