2015-01-03 116 views
-1

我已经从文件中读取了一个RGB值的数据集,我试图编码K means算法,所以我需要找到数据集中最接近三个数字的值(3个值),可以你帮我告诉我如何做到这一点?找到最接近的值C++

我小白编程所以请温柔与滥用:L

谢谢您的时间

下面这段代码在文件中写道:

#include "stdafx.h" 
#include <iostream>; 
#include <fstream>; 
#include <string>; 
#include <cstdlib>; 

using namespace std; 

class rgb { 

public: 

    int r; 
    int g; 
    int b; 

}; 



int _tmain(int argc, _TCHAR* argv[]) 
{ 

    char filename[2000]; 

    ifstream infile; 
    infile.open("file.txt"); 

    if (infile.fail()) { 

     cerr << "something went wrong :(" << endl; 
     system("pause"); 
     exit(1); 

    } 

    rgb array[500]; 

    cout << "reading in file: " << endl; 

    for (int i = 0; i < 500; i++) 
    { 
     infile >> array[i].r >> array[i].g >> array[i].b; 

     cout << "r: " << array[i].r << " "; 
     cout << "g: " << array[i].g << " "; 
     cout << "b: " << array[i].b << " " << endl; 
    }  

那么这个代码查找数据集中最接近一个值(value1)的值,但继续阅读,您将看到底部真正需要的内容。此代码实际上可能是更好的方法:L

int num = 180; // random value assigned at 180 
    int centroid1x; 
    int distance = 400; 
    for (int i = 0; i < 500; i++) 
    { 


     if (abs(num - array[i].r) <= distance) 
     { 
      distance = abs(num - array[i].r); 
      centroid1x = array[i].r; 
     } 


     cout << centroid1x << " " ; 

    } 
    cout << endl << endl; 

    int centroid1y; 
    distance = 400; 
    for (int i = 0; i < 500; i++) 
    { 


     if (abs(num - array[i].g) <= distance) 
     { 
      distance = abs(num - array[i].g); 
      centroid1y = array[i].g; 
     } 

     cout << centroid1y << " " ; 

    } 
    cout << endl << endl; 

    int centroid1z; 
    distance = 400; 
    for (int i = 0; i < 500; i++) 
    { 


     if (abs(num - array[i].b) <= distance) 
     { 
      distance = abs(num - array[i].b); 
      centroid1z = array[i].b; 
     } 

     cout << centroid1z << " " ; 

    } 
    cout << endl << endl; 

    cout << "The closest x axis of centroid one is: " << centroid1x << endl; 
    cout << "The closest y axis of centroid one is: " << centroid1y << endl; 
    cout << "The closest z axis of centroid one is: " << centroid1z << endl << endl; 

    cout << "The closest point to centroid one is " << centroid1x << "." << centroid1y << "." << centroid1z << endl; 





    system("pause"); 

    return 0; 
} 

我需要的是代码,找出所有都接近180号码,以及所有那些更接近40的数字和所有那些更接近100

+0

你的代码有什么问题。您不需要在这里编写所有的代码,而是为您的问题提供[SSCCE](http://www.sscce.org)。 – Werner

+0

我想学习一种方法,使程序找到数据集(文件)中的哪些数字更接近180,40和100 – ceefax

+0

是的,但你有一个代码,有什么不工作呢?你能否隔离那些工作不正常的问题部分? – Werner

回答

0

你的问题ISN号码”很清楚,这可能不是你想要的,但我会试试它。

我认为你有一个RBG值和一些质心,也许三个,这也是RGB值的数组。对于阵列中的每个RBG值,您想知道哪个质心最接近。这将有效地将你的数组分割成与质心一样多的子数组。

您可以为每个质心创建单独的数组。我已经看到你使用C++,尽管有很多C习语。例如,您正在使用固定大小的数组而不是std::vector

我保持我的解决方案接近。我没有提供额外的数组,而是扩展了rgb类,以便它对最接近的质心采取整数引用。 split函数分配这个值。

RGB值之间的距离测量为空间距离,好像红色,绿色和蓝色值是三维空间中的x,y,z值。

下面的代码使用了12个RGB值的预定义数组,并且为了简洁起见,省略了从文件中读取列表。质心是纯红色,绿色和蓝色,但它们理论上可以在任何地方。

#include <iostream> 

struct rgb { 
    int r; 
    int g; 
    int b; 
    int ref; // reference index of closest centroid 
}; 

char hexdigit(int x) 
{ 
    if (x < 0) return '?'; 
    if (x < 10) return '0' + x; 
    if (x < 16) return 'a' + x - 10; 
    return '?'; 
} 

std::ostream &operator <<(std::ostream &os, rgb const &x) 
{ 
    return os << '#' 
     << hexdigit(x.r/16) << hexdigit(x.r % 16) 
     << hexdigit(x.g/16) << hexdigit(x.g % 16) 
     << hexdigit(x.b/16) << hexdigit(x.b % 16); 
} 

void split(rgb pool[], size_t npool, rgb const cent[], size_t ncent) 
{ 
    for (size_t i = 0; i < npool; i++) { 
     rgb *p = pool + i; 
     int dmin = 4*255*255; 

     for (size_t j = 0; j < ncent; j++) { 
      rgb const *c = cent + j; 
      int rr = p->r - c->r; 
      int gg = p->g - c->g; 
      int bb = p->b - c->b; 
      int dd = rr*rr + gg*gg + bb*bb; 

      if (dd < dmin) { 
       p->ref = j; 
       dmin = dd; 
      } 
     } 
    } 
} 

int main(int argc, char* argv[]) 
{ 
    rgb data[12] = { 
     {106, 92, 69}, 
     {135, 16, 137}, 
     {208, 204, 220}, 
     { 11, 52, 120}, 
     { 33, 57, 81}, 
     {196, 199, 192}, 
     {236, 237, 85}, 
     { 89, 27, 225}, 
     {173, 74, 158}, 
     {220, 2, 66}, 
     {171, 145, 204}, 
     {221, 60, 235} 
    }; 

    rgb cent[3] = { 
     {255, 0, 0}, 
     {0, 255, 0}, 
     {0, 0, 255} 
    }; 

    split(data, 12, cent, 3); 

    for (int i = 0; i < 12; i++) { 
     std::cout << data[i] << " " << cent[data[i].ref] << std::endl; 
    } 

    return 0; 
} 
+0

这是非常感谢你,我会尝试和重写这个,以便我可以学习它,然后实施我的版本到我的代码:) – ceefax

+0

我会投它,但我不够高的排名:( – ceefax