代码源自:http://www.cppblog.com/unixfy/archive/2012/02/13/165487.html,记录,有部分修改,测试。 #include <iostream> #include <vector> #include <cassert> #include <cmath> using namespace std; double dotProduct(const vector<double>& v1, const vector<double>& v2) { assert(v1.size() == v2.size()); double ret = 0.0; for (vector<double>::size_type i = 0; i != v1.size(); i++) { ret += v1[i] * v2[i]; } return ret; } double module(const vector<double>& v) { double ret = 0.0; for (vector<double>::size_type i = 0; i != v.size(); i++) { ret += v[i] * v[i]; } return sqrt(ret); } double cosine(const vector<double>& v1, const vector<double>& v2) { assert(v1.size() == v2.size()); return dotProduct(v1, v2) / (module(v1) * module(v2)); } double mean(const vector<double>& v) { assert(v.size() != 0); double ret = 0.0; for (vector<double>::size_type i = 0; i != v.size(); ++i) { ret += v[i]; } return ret / v.size(); } double cov(const vector<double>& v1, const vector<double>& v2) { assert(v1.size() == v2.size() && v1.size() > 1); double ret = 0.0; double v1a = mean(v1), v2a = mean(v2); for (vector<double>::size_type i = 0; i != v1.size(); ++i) { ret += (v1[i] - v1a) * (v2[i] - v2a); } return ret / (v1.size() - 1); } // 相关系数 double coefficient(const vector<double>& v1, const vector<double>& v2) { assert(v1.size() == v2.size()); return cov(v1, v2) / sqrt(cov(v1, v1) * cov(v2, v2)); } // Dice 系数 double dice(const vector<double>& v1, const vector<double>& v2) { assert(v1.size() == v2.size()); return 2.0 * dotProduct(v1, v2) / (dotProduct(v1, v1) + dotProduct(v2, v2)); } // Jaccard 系数 double jaccard(const vector<double>& v1, const vector<double>& v2) { assert(v1.size() == v2.size()); return dotProduct(v1, v2) / (dotProduct(v1, v1) + dotProduct(v2, v2) - dotProduct(v1, v2)); } // Minkowsky 距离 double minkowsky(const vector<double>& v1, const vector<double>& v2, double m) { assert(v1.size() == v2.size()); double ret = 0.0; for (vector<double>::size_type i = 0; i != v1.size(); ++i) { ret += pow(abs(v1[i] - v2[i]), m); } return pow(ret, 1.0 / m); } // Euclidean 距离 double euclidean(const vector<double>& v1, const vector<double>& v2) { assert(v1.size() == v2.size()); return minkowsky(v1, v2, 2.0); } // Manhattan 距离 double manhattan(const vector<double>& v1, const vector<double>& v2) { assert(v1.size() == v2.size()); return minkowsky(v1, v2, 1.0); } // Jffreys & Matusita 距离 double jffreysMatusita(const vector<double>& v1, const vector<double>& v2) { assert(v1.size() == v2.size()); double ret = 0.0; for (vector<double>::size_type i = 0; i != v1.size(); ++i) { ret += (sqrt(v1[i]) - sqrt(v2[i])) * (sqrt(v1[i]) - sqrt(v2[i])); } return sqrt(ret); } // Camberra 距离(Lance 距离,Williams 距离) double camberra(const vector<double>& v1, const vector<double>& v2) { assert(v1.size() == v2.size()); double ret = 0.0; for (vector<double>::size_type i = 0; i != v1.size(); ++i) { ret += abs(v1[i] - v2[i]) / abs(v1[i] + v2[i]); } return ret; } int main() { float a[] = {1, 2, 3, 4, 5}; float b[] = {4, 3, 2, 1, 0}; vector<double> v1(a, a + sizeof (a) / sizeof (*a)), v2(b, b + sizeof (b) / sizeof (*b)); cout << "cosine = "<<cosine(v1, v2) << endl; cout << "coefficient = "<<coefficient(v1, v2) << endl; cout << "dice = "<<dice(v1, v2) << endl; cout << "jaccard = "<<jaccard(v1, v2) << endl; // cout << "minkowsky = "<<minkowsky(v1, v2, 5.0) << endl; cout << "euclidean = "<<euclidean(v1, v2) << endl; cout << "manhattan = "<<manhattan(v1, v2) << endl; cout << "jffreysMatusita = "<<jffreysMatusita(v1, v2) << endl; cout << "camberra = "<<camberra(v1, v2) << endl; return 0; }