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

时间:2015-07-22 19:28:13

标签: c++ cplex

我正在使用CPLEX C ++ Concert库来模拟一些混合整数问题。说到从外部文本文件中读取数据。我一直在使用模板运算符>>以[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 
    ...
}

我的问题是为什么最终的IloMatrix不包含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

1 个答案:

答案 0 :(得分:0)

我想出了一种变通方法,它首先使用2D向量来存储从文本文件中读取的矩阵。然后,只需将该2​​D矢量复制(赋值)给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();
}