Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 比较“的数组”;相似性;?_Algorithm_Dataset - Fatal编程技术网

Algorithm 比较“的数组”;相似性;?

Algorithm 比较“的数组”;相似性;?,algorithm,dataset,Algorithm,Dataset,我试图比较相同大小的数组 给定以下数组: 我正在寻找一种算法来告诉我与输入最“相似”的数组。我知道“相似”这个词不是很具体,但我不知道如何更具体 例如,以下内容与输入非常相似 下面是一些类似的情况 以下是非常不同的 您可以对数组应用平滑内核,然后在其上计算L2范数(欧几里德距离) 这通常用于比较神经尖峰序列或其他连续信号 你没有指定语言…我碰巧有C++代码(可能不是最有效的)。 首先,根据所需的内核宽度对向量进行平滑处理,并根据“模糊”的比例/所需数量对其进行参数化。。例如: 以下代码的

我试图比较相同大小的数组

给定以下数组:

我正在寻找一种算法来告诉我与输入最“相似”的数组。我知道“相似”这个词不是很具体,但我不知道如何更具体

例如,以下内容与输入非常相似

下面是一些类似的情况

以下是非常不同的


您可以对数组应用平滑内核,然后在其上计算L2范数(欧几里德距离)

这通常用于比较神经尖峰序列或其他连续信号

你没有指定语言…我碰巧有C++代码(可能不是最有效的)。 首先,根据所需的内核宽度对向量进行平滑处理,并根据“模糊”的比例/所需数量对其进行参数化。。例如:

以下代码的输出(行为符合预期):

和代码(test.cpp):

#包括
#包括
#包括
#包括
双高斯核函数(常数大小与源时间,常数大小与此时间)
{
const double tauval=5.0;//内核的宽度
double dist=((sourcetime thisttime)/tauval);//向量中各点之间的距离
double retval=exp(-1*dist*dist);//远离该点中心的指数衰减,平方。。。。
返回返回;
}
标准::矢量卷积高斯(常数标准::矢量和v1)
{
标准::向量卷积(v1.size(),0.0);

对于(size_t=0;t根据您关心的向量的“特征”,您可能需要进行一些预处理。例如,如果您只关心“形状”,而不关心比例,您可以预先在内部规范化所有向量。在项目的某个时候,您必须定义“相似”的内容实际上是指。它是峰的数量吗?它是峰的位置吗?它是平均值吗?它是曲线的平滑度吗?有很多可能的标准。只要你对此不确定,讨论代码就没有多大意义。
riveale@rv-mba:~/tmpdir$ g++ -std=c++11 test.cpp -o test.exe
riveale@rv-mba:~/tmpdir$ ./test.exe
Distance [1] to [2]: [31.488026] (should be far)
Distance [2] to [3]: [26.591297] (should be far)
Distance [1] to [3]: [12.468342] (should be closer)
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <cmath>

double gauss_kernel_funct(const size_t& sourcetime, const size_t& thistime)
{
  const double tauval = 5.0; //width of kernel

  double dist = ((sourcetime-thistime)/tauval); //distance between the points in the vector
  double retval = exp(-1 * dist*dist); //exponential decay away from center of that point, squared....
  return retval;
}

std::vector<double> convolvegauss( const std::vector<double>& v1)
{
  std::vector<double> convolved( v1.size(), 0.0 );
  for(size_t t=0; t<v1.size(); ++t)
    {
      for(size_t u=0; u<v1.size(); ++u)
      {
        double coeff = gauss_kernel_funct(u, t);
        convolved[t]+=v1[u] * coeff;
      }
    }
  return (convolved);
}

double eucliddist( const std::vector<double>& v1, const std::vector<double>& v2 )
{
  if(v1.size() != v2.size()) { fprintf(stderr, "ERROR v1!=v2 sizes\n"); exit(1); }
  double sum=0.0;
  for(size_t x=0; x<v1.size(); ++x)
    {
      double tmp = (v1[x] - v2[x]);
      sum += tmp*tmp; //sum += distance of this dimension squared
    }
  return (sqrt( sum ));
}

double vectdist( const std::vector<double>& v1, const std::vector<double>& v2 )
{
   std::vector<double> convolved1 = convolvegauss( v1 );
   std::vector<double> convolved2 = convolvegauss( v2 );
   return (eucliddist( convolved1, convolved2 ));
}

int main()
{

  //Original 3 vectors. (1 and 3) are closer than (1 and 2) or (2 and 3)...like your example.
  std::vector<double> myvector1 = {1.0, 32.0, 10.0,  5.0, 2.0};
  std::vector<double> myvector2 = {2.0,  3.0, 10.0, 22.0, 2.0};
  std::vector<double> myvector3 = {2.0, 20.0, 17.0,  1.0, 2.0};


  //Now run the vectdist on each, which convolves each vector with the gaussian kernel, and takes the euclid distance between the convovled vectors)
  fprintf(stdout, "Distance [%d] to [%d]: [%lf] (should be far)\n", 1, 2, vectdist(myvector1, myvector2) );
  fprintf(stdout, "Distance [%d] to [%d]: [%lf] (should be far)\n", 2, 3, vectdist(myvector2, myvector3) );
  fprintf(stdout, "Distance [%d] to [%d]: [%lf] (should be closer)\n", 1, 3, vectdist(myvector1, myvector3) );
  return 0;
}