vector< vector<u32> > kmeans_pp(const vector< vector<f64> >& points, u32 k, algo::iLCG& lcg, vector< vector<f64> >& centers) { if (points.size() == 0) throw eInvalidArgument("There must be points to cluster!"); if (points[0].size() == 0) throw eInvalidArgument("There must be at least one dimension!"); for (size_t i = 1; i < points.size(); i++) if (points[i].size() != points[0].size()) throw eInvalidArgument("All data points must have the same dimensionality."); if (k == 0) throw eInvalidArgument("Clustering into zero clusters makes no sense."); centers.resize(k); centers[0] = points[lcg.next() % points.size()]; for (u32 i = 1; i < k; i++) { vector<f64> cumDists(points.size()); for (size_t d = 0; d < cumDists.size(); d++) { f64 mind = s_distanceSquared(points[d], centers[0]); for (u32 j = 1; j < i; j++) mind = std::min(mind, s_distanceSquared(points[d], centers[j])); cumDists[d] = (d == 0) ? (mind) : (cumDists[d-1]+mind); } f64 ran = ((f64)lcg.next()) / ((f64)lcg.randMax()) * cumDists.back(); size_t d; for (d = 0; ran > cumDists[d]; d++) { } centers[i] = points[d]; } return kmeans(points, k, centers); }
static vector<u8> s_genMessage(algo::iLCG& lcg) { u32 len = (lcg.next() % kMaxMessageLen) + 1; vector<u8> mess(len); for (u32 i = 0; i < len; i++) mess[i] = (lcg.next() % 256); return mess; }
static vector<f64> s_randPoint(algo::iLCG& lcg, f64 rmin, f64 rmax, u32 dimensions) { vector<f64> v(dimensions); for (u32 i = 0; i < dimensions; i++) { v[i] = ((f64)lcg.next()) / ((f64)lcg.randMax()); // [0.0, 1.0] v[i] *= rmax-rmin; // [0.0, rmax-rmin] v[i] += rmin; // [rmin, rmax] } return v; }