从文本文件读取数字矩阵(不包括方括号中的数据)到CPLEX IloNumArray2失败

Fail to read numeric matrix (without including data in square brackets) from a text file to CPLEX IloNumArray2

本文关键字:数据 失败 IloNumArray2 CPLEX 方括号 不包括 读取 文件 文本 数字      更新时间:2023-10-16

我正在使用CPLEX c++协调库来建模一些混合整数问题。当涉及到从外部文本文件读取数据。我一直使用模板操作符>>从[x, y, z,…]格式的文本文件中读取数值。同样地,[x1, y1, c1,…], [x2, y2, c2,…]),…[2D病例])。这条路很好。然而,为了使我的代码更通用,我想写一个函数,可以读取一个数字矩阵没有格式化使用方括号(即纯数字矩阵,见下面的例子)从文本文件直接到IloNumArray2。

下面是我使用的示例数据文本文件,名为"test.txt":

0.51 3.71 0.23
0.90 3.71 0.24
1.30 3.71 0.24
1.45 3.34 0.18
2.15 3.77 0.15

注意,这个矩阵可以有任意数量的列(通常是2或3),您可以提前知道总行数。假设我们知道总行数。我在main.cpp中给出了我的读取数据函数和部分代码,其中我调用了读取数据函数,如下所示。

void readToIloNumArray(IloEnv env, const char* fileName, IloNumArray2& iloNum2dArray)
    {
        std::ifstream inFile(fileName); 
        if(!inFile) 
        {
            std::cerr << "ERROR: could not open data file '" << fileName <<endl;
            exit(1);
        }
        IloNumArray rowData(env);  // to store each line of data 
        std::string line; 
        int i = 0; 
        while(std::getline(inFile, line))  // read a line of data as a string
        {
            std::istringstream iss(line); 
            double number; 
            rowData.clear();    // to clear the 1-d array before reading new data to it
            while(iss >> number)  // extract numbers from line
            {
                rowData.add(number); 
            }
            // This is how I add each rowData (an IloNumArray) to the final iloNum2dArray (an IloNumArray2) 
            iloNum2dArray[i] = rowData;
            // output iloNum2dArray[i] to make sure it contains the correct data
            cout << iloNum2dArray[i] << endl;  // yes, results is correct
            // by changing the index i, I ensure that the next line of data is stored as a new row in iloNum2Array 
            i++; 
        }
        // make sure that the number of lines read from the text file is actually equal to its known actual size
        cout << "i = " << i << endl;  // YES
        // SOMEHOW, each row of iloNum2dArray just simply repeats the last row of the input text file
        cout << iloNum2dArray << endl; 
        cout << "Successfully read file " << fileName << "!" << endl;
        inFile.close();
    }
#include <ilcplex/ilocplex.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
int main(int argc, char **argv)
{ 
    IloEnv env;
    IloNumArray2 IloMatrix(env, n);
    // call the reading data function defined above
    readToIloNumArray(env, "test.txt", IloMatrix); 
    // output IloMatrix to see if it contains the original matrix in the test.txt
    cout << "IloMatrix = " << IloMatrix << endl;  // NO, IloMatrix repeats the last line for n times        // do other process 
    ...
}

我的问题是为什么最终的ilommatrix不包含test.txt文件中指定的原始矩阵,而是重复test.txt的最后一行数据n次?(如下图所示)

2.15 3.77 0.15
2.15 3.77 0.15
2.15 3.77 0.15
2.15 3.77 0.15
2.15 3.77 0.15

我想出了一个变通方法,它首先使用一个2D矢量来存储从文本文件读取的矩阵。然后,简单地将2D向量复制(赋值)到IloNumArray2。修改后的读取数据功能代码如下:

void readToIloNumArray(IloEnv env, const char* fileName, IloNumArray2& iloNum2dArray)
{
    ifstream inFile(fileName); 
    if(!inFile) 
    {
        cerr << "ERROR: could not open data file '" << fileName <<endl;
        exit(1);
    }
    vector<vector<double> > vectorMatrix;
    string line; 
    while(getline(inFile, line))  // read a line 
    {
        vector<double> rowData;
        istringstream iss(line); 
        double number; 
        while(iss >> number)  // extract numbers from line
        {
            rowData.push_back(number); 
        }
        vectorMatrix.push_back(rowData); 
    }
    // Now assign  values (copy) vectorMatrix to IloNumArray2
    for(int i = 0; i < vectorMatrix.size(); i++)
    {
        iloNum2dArray.add(IloNumArray(env)); 
        for(int j = 0; j < vectorMatrix[0].size(); j++)
        {
            iloNum2dArray[i].add(vectorMatrix[i][j]);
        }
    }
    /// for debug
    //cout << "IloNum2dArray:" << iloNum2dArray << endl; 
    cout << "Successfully read file " << fileName << "!" << endl;
    inFile.close();
}