簡體   English   中英

在拋出“std::invalid_argument”實例后調用終止 what(): stof

[英]Terminate called after throwing an instance of 'std::invalid_argument' what(): stof

正如我在另一篇文章中寫的那樣,我正在嘗試用 C++ 實現 K-means 算法。 調試時,我沒有得到任何錯誤,但是在嘗試運行程序時,我得到了標題中提到的錯誤:

在拋出“std:invalid_argument” what():stof 實例后調用終止

我知道當文件無法轉換為浮動時會出現此錯誤。 然后,我想問的是,我應該在代碼中更改某些內容,還是使用另一種文件格式作為輸入而不是 *.csv 文件會更好? (顯然,我假設程序無法從文件中讀取某些內容。我不知道這是否是正確的推理。)謝謝大家!

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>

using namespace std;

//Inizializzare il punto

struct Point {
    double x, y; // Coordinate del punto
    int cluster; // Cluster di default
    double minDist; // Distanza minima

    Point()
        : x(0.0)
        , y(0.0)
        , cluster(-1)
        , minDist(__DBL_MAX__)
    {
    }

    Point(double x, double y)
        : x(x)
        , y(y)
        , cluster(-1)
        , minDist(__DBL_MAX__)
    {
    }

    double distance(Point p)

    {
        return (p.x - x) * (p.x - x) + (p.y - y) * (p.y - y);
    }
};

vector<Point> readcsv()
{
    vector<Point> points;
    string line;
    ifstream file("Mall_Customers.csv");

    while (getline(file, line)) {
        stringstream lineStream(line);
        string bit;
        double x, y;
        getline(lineStream, bit, ',');
        x = stof(bit);
        getline(lineStream, bit, '\n');
        y = stof(bit);

        points.push_back(Point(x, y));
    }
    return points;
}

vector<Point> points = readcsv();

void kMeansClustering(vector<Point>* points, int epochs, int k)
{

    int n = points->size();

    vector<Point> centroids;
    srand(time(0));

    for (int i = 0; i < k; ++i) {
        centroids.push_back(points->at(rand() % n));
    }

    for (vector<Point>::iterator c = begin(centroids); c != end(centroids); ++c) {
        int clusterId = c - begin(centroids);
        {
            for (vector<Point>::iterator it = points->begin(); it != points->end(); ++it) {
                Point p = *it;
                double dist = c->distance(p);
                if (dist < p.minDist) {

                    p.minDist = dist;
                    p.cluster = clusterId;
                }
                *it = p;
            }
        }
    }

    vector<int> nPoints;
    vector<double> sumX, sumY;

    for (int j = 0; j < k; j++) {
        nPoints.push_back(0.0);
        sumX.push_back(0.0);
        sumY.push_back(0.0);
    }

    for (vector<Point>::iterator it = points->begin(); it != points->end(); ++it) {
        int clusterId = it->cluster;
        nPoints[clusterId] += 1;
        sumX[clusterId] += it->x;
        sumY[clusterId] += it->y;

        it->minDist = __DBL_MAX__; // reset distance
    }

    // Compute the new centroids
    for (vector<Point>::iterator c = begin(centroids); c != end(centroids); ++c) {
        int clusterId = c - begin(centroids);
        c->x = sumX[clusterId] / nPoints[clusterId];
        c->y = sumY[clusterId] / nPoints[clusterId];
    }
    // Write to csv
    ofstream myfile;
    myfile.open("output.csv");
    myfile << "x,y,c" << endl;

    for (vector<Point>::iterator it = points->begin(); it != points->end();
         ++it) {
        myfile << it->x << "," << it->y << "," << it->cluster << endl;
    }
    myfile.close();
}

int main()
{
    vector<Point> points = readcsv();

    // Run k-means with 100 iterations and for 5 clusters
    kMeansClustering(&points, 100, 5);
}

現在似乎可以了,謝謝大家對我的幫助,特別是 @Yksisarvinen 和 @molbdnilo :問題在於我盲目地導入了程序中的所有 csv 文件,但我應該只導入兩個列:一欄是收入,另一欄是支出欄。

雖然現在我必須弄清楚為什么它向我顯示最終結果,而不是像人們期望從算法中那樣以“氣泡”的形式,而是以點聚集在一條直線上的形式。

在此處輸入圖片說明

嘗試打開原始文件(原始數據集)時,出現下圖所示的錯誤。

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM