Note that there are some explanatory texts on larger screens.

plurals
  1. POReading a Matrix txt file and storing as an array
    text
    copied!<p>I'm currently writing a Simulated Annealing code to solve a traveling salesman problem and have run into difficulties with storing and using my read data from a txt file. Each row &amp; column in the file represents each city, with the distance between two different cities stored as a 15 x 15 matrix:</p> <pre><code>0.0 5.0 5.0 6.0 7.0 2.0 5.0 2.0 1.0 5.0 5.0 1.0 2.0 7.1 5.0 5.0 0.0 5.0 5.0 5.0 2.0 5.0 1.0 5.0 6.0 6.0 6.0 6.0 1.0 7.1 5.0 5.0 0.0 6.0 1.0 6.0 5.0 5.0 1.0 6.0 5.0 7.0 1.0 5.0 6.0 6.0 5.0 6.0 0.0 5.0 2.0 1.0 6.0 5.0 6.0 2.0 1.0 2.0 1.0 5.0 7.0 5.0 1.0 5.0 0.0 7.0 1.0 1.0 2.0 1.0 5.0 6.0 2.0 2.0 5.0 2.0 2.0 6.0 2.0 7.0 0.0 5.0 5.0 6.0 5.0 2.0 5.0 1.0 2.0 5.0 5.0 5.0 5.0 1.0 1.0 5.0 0.0 2.0 6.0 1.0 5.0 7.0 5.0 1.0 6.0 2.0 1.0 5.0 6.0 1.0 5.0 2.0 0.0 7.0 6.0 2.0 1.0 1.0 5.0 2.0 1.0 5.0 1.0 5.0 2.0 6.0 6.0 7.0 0.0 5.0 5.0 5.0 1.0 6.0 6.0 5.0 6.0 6.0 6.0 1.0 5.0 1.0 6.0 5.0 0.0 7.0 1.0 2.0 5.0 2.0 5.0 6.0 5.0 2.0 5.0 2.0 5.0 2.0 5.0 7.0 0.0 2.0 1.0 2.0 1.0 1.0 6.0 7.0 1.0 6.0 5.0 7.0 1.0 5.0 1.0 2.0 0.0 5.0 6.0 5.0 2.0 6.0 1.0 2.0 2.0 1.0 5.0 1.0 1.0 2.0 1.0 5.0 0.0 7.0 6.0 7.0 1.0 5.0 1.0 2.0 2.0 1.0 5.0 6.0 5.0 2.0 6.0 7.0 0.0 5.0 5.0 7.0 6.0 5.0 5.0 5.0 6.0 2.0 6.0 2.0 1.0 5.0 6.0 5.0 0.0 </code></pre> <p>To read this I have a LoadCities() function as shown below:</p> <pre><code>#include "iostream" #include "fstream" #include "string" using namespace std; double distances [15][15]; void LoadCities() { ifstream CityFile; if (!CityFile.is_open()) //check is file has been opened { CityFile.open ("Cities.txt", ios::in | ios::out); if (!CityFile) { cerr &lt;&lt; "Failed to open " &lt;&lt; CityFile &lt;&lt; endl; exit(EXIT_FAILURE); //abort program } } int length; char * buffer; string cities; CityFile.seekg(0, ios::end); length = CityFile.tellg(); CityFile.seekg (0, ios::beg); buffer = new char [length]; cities = CityFile.read (buffer,length); string rows = strtok(cities, "\n"); distances = new double[rows.length()][rows.length()]; for (int i = 0; i &lt; (string) rows.length(); i++) { string distance = strtok(rows[i], " "); for (int j = 0; j &lt; distance.length(); j++) { distances[i][j] = (double) Parse(distance[j]); } } CityFile.close(); } </code></pre> <p>I've attempted an alternative istreambuf_iterator method to get to the point of manipulating the read material into arrays, however I always seem to run into complications:</p> <pre><code>ifstream CityFile("Cities.txt"); string theString((std::istreambuf_iterator&lt;char&gt;(CityFile)), std::istreambuf_iterator&lt;char&gt;()); </code></pre> <p>Any help would be much appriciated. Been bashing my head against this with little success!</p> ################ EDIT / Update <p>@ SoapBox - Some Detail of the SA code, functions and main(). This is not clean, efficient, tidy and isn't ment to be at this stage, just needs to work for the moment. This version (below) works and is setup to solve polynomials (simplest problems). What needs to be done to convert it to a Traveling Salesman Problem is to:</p> <ol> <li><p>Write the LoadCities() function to gather the distance data. (Current)</p></li> <li><p>Change Initialise() to get the Total of the distances involved</p></li> <li><p>Change E() to the TSP function (e.g. Calculate distance of a random route)</p></li> </ol> <p>The latter two I know I can do, however I require LoadCities() to do it. Nothing else needs to be changed in the following script.</p> <pre><code>#include "math.h" #include "iostream" #include "fstream" #include "time.h" // Define time() #include "stdio.h" // Define printf() #include "randomc.h" // Define classes for random number generators #include "mersenne.cpp" // Include code for the chosen random number generator using namespace std; // For the use of text generation in application double T; double T_initial; double S; double S_initial; double S_current; double S_trial; double E_current; int N_step; // Number of Iterations for State Search per Temperature int N_max; //Number of Iterations for Temperature int Write; const double EXP = 2.718281828; //------------------------------------------------------------------------------ //Problem Function of Primary Variable (Debugged 17/02/09 - Works as intended) double E(double x) //ORIGNINAL { double y = x*x - 6*x + 2; return y; } //------------------------------------------------------------------------------ //Random Number Generation Function (Mod 19/02/09 - Generated integers only &amp; fixed sequence) double Random_Number_Generator(double nHigh, double nLow) { int seed = (int)time(0); // Random seed CRandomMersenne RanGen(seed); // Make instance of random number generator double fr; // Random floating point number fr = ((RanGen.Random() * (nHigh - nLow)) + nLow); // Generatres Random Interger between nLow &amp; nHigh return fr; } //------------------------------------------------------------------------------ //Initializing Function (Temp 17/02/09) void Initialize() //E.g. Getting total Distance between Cities { S_initial = Random_Number_Generator(10, -10); cout &lt;&lt; "S_Initial: " &lt;&lt; S_initial &lt;&lt; endl; } //------------------------------------------------------------------------------ //Cooling Schedule Function (make variables) (Completed 16/02/09) double Schedule(double Temp, int i) // Need to find cooling schedule { double CoolingRate = 0.9999; return Temp *= CoolingRate; } //------------------------------------------------------------------------------ //Next State Function (Mod 18/02/09) double Next_State(double T_current, int i) { S_trial = Random_Number_Generator(pow(3, 0.5), pow(3, 0.5)*-1); S_trial += S_current; double E_t = E(S_trial); double E_c = E(S_current); double deltaE = E_t - E_c; //Defines gradient of movement if ( deltaE &lt;= 0 ) //Downhill { S_current = S_trial; E_current = E_t; } else //Uphill { double R = Random_Number_Generator(1,0); //pseudo random number generated double Ratio = 1-(float)i/(float)N_max; //Control Parameter Convergence to 0 double ctrl_pram = pow(EXP, (-deltaE / T_current)); //Control Parameter if (R &lt; ctrl_pram*Ratio) //Checking { S_current = S_trial; //Expresses probability of uphill acceptance E_current = E_t; } else E_current = E_c; } return S_current; } //------------------------------------------------------------------------------ //Metropolis Function (Mod 18/02/09) double Metropolis(double S_start, double T_current, int N_Steps, int N_temperatures) { S_current = S_start; //Initialised S_initial equated to S_current for ( int i=1; i &lt;= N_step; i++ ) //Iteration of neighbour states S_current = Next_State(T_current, N_temperatures); //Determines acceptance of new states return S_current; } //------------------------------------------------------------------------------ //Write Results to Notepad (Completed 18/02/09) void WriteResults(double i, double T, double x, double y) { //This function opens a results file (if not already opened) //and stores results for one time step static ofstream OutputFile; const int MAXLENGTH = 80; if (!OutputFile.is_open()) //check is file has been opened { //no it hasn't. Get a file name and open it. char FileName[MAXLENGTH]; //read file name cout &lt;&lt; "Enter file name: "; do { cin.getline(FileName, MAXLENGTH); } while (strlen(FileName) &lt;= 0); //try again if length of string is 0 //open file OutputFile.open(FileName); // check if file was opened successfully if (!OutputFile) { cerr &lt;&lt; "Failed to open " &lt;&lt; FileName &lt;&lt; endl; exit(EXIT_FAILURE); //abort program } OutputFile &lt;&lt; "Iterations" &lt;&lt; '\t' &lt;&lt; "Temperatures" &lt;&lt; '\t' &lt;&lt; "X-Value" &lt;&lt; '\t' &lt;&lt; "Y-Value" &lt;&lt; endl; OutputFile &lt;&lt; endl; } //OutputFile.width(10); OutputFile &lt;&lt; i &lt;&lt; '\t' &lt;&lt; T &lt;&lt; '\t' &lt;&lt; x &lt;&lt; '\t' &lt;&lt; y &lt;&lt; endl; if (i == N_max) { OutputFile &lt;&lt; endl &lt;&lt; "Settings: " &lt;&lt; endl &lt;&lt; "Initial Temperature: " &lt;&lt; T_initial &lt;&lt; endl &lt;&lt; "Temperature Iterations: " &lt;&lt; N_max &lt;&lt; endl &lt;&lt; "Step Iterations: " &lt;&lt; N_step &lt;&lt; endl &lt;&lt; endl &lt;&lt; "Results: " &lt;&lt; endl &lt;&lt; "Final Temperature: " &lt;&lt; T &lt;&lt; endl &lt;&lt; "Minimum: " &lt;&lt; S &lt;&lt; endl; OutputFile.close(); } } //------------------------------------------------------------------------------ //Main SA Function (Mod 17/02/09) void SA(int W) { S = S_initial; T = T_initial; for ( int N_temperatures = 1 ; N_temperatures &lt;= N_max ; N_temperatures++ ) { S = Metropolis( S, T, N_step, N_temperatures); T = Schedule(T, N_temperatures); if (W == 1) WriteResults(N_temperatures, T, S, E_current); } cout &lt;&lt; "Result" &lt;&lt; endl &lt;&lt; "Y-value&gt; " &lt;&lt; S &lt;&lt; endl &lt;&lt; "Temperature&gt; " &lt;&lt; T &lt;&lt; endl; } //------------------------------------------------------------------------------ //Execution of Traveling Salesman Problem (Progress 18/02/09) int main() { cout &lt;&lt; "Quadratic Function" &lt;&lt; endl &lt;&lt; "Solving method: Simulated Annealing" &lt;&lt; endl; cout &lt;&lt; "" &lt;&lt; endl; cout &lt;&lt; "Select desired Initial Temperature:" &lt;&lt; endl &lt;&lt; "&gt; "; cin &gt;&gt; T_initial; cout &lt;&lt; "Select desired number of Temperature Iterations:" &lt;&lt; endl &lt;&lt; "&gt; "; cin &gt;&gt; N_max; cout &lt;&lt; "Select desired number of step Iterations:" &lt;&lt; endl &lt;&lt; "&gt; "; cin &gt;&gt; N_step; Initialize(); cout &lt;&lt; "Write to file: (1 / 0) " &lt;&lt; endl &lt;&lt; "&gt; "; cin &gt;&gt; Write; SA(Write); system ("PAUSE"); return 0; } </code></pre> <p>@ strager - I know its bad code, but unfortunatly with the time constraints involved for my project and the consiquental learning curve, results are what are needed! :) It'll be tidied up at latter stages.</p> <p>@ dirkgently - That was the initial reason for doing it this way, and hence why my first attempt is to go at it like so.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload