- Timestamp:
- Dec 16, 2009, 11:22:05 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/mainwindow.cpp
r71 r74 302 302 { 303 303 //! \todo TODO: Normal about window :-) 304 QString about = QString::fromUtf8("TSPSG: TSP Solver and Generator\n"); 305 about += QString::fromUtf8(" Version: "BUILD_VERSION"\n"); 306 about += QString::fromUtf8(" Copyright (C) 2007-%1 Lёppa <contacts[at]oleksii[dot]name>\n").arg(QDate::currentDate().toString("yyyy")); 307 about += QString::fromUtf8("Target OS: %1\n").arg(OS); 308 about += "Qt library:\n"; 309 about += QString::fromUtf8(" Compile time: %1\n").arg(QT_VERSION_STR); 310 about += QString::fromUtf8(" Runtime: %1\n").arg(qVersion()); 311 about += QString::fromUtf8("Built on %1 at %2\n").arg(__DATE__).arg(__TIME__); 312 about += QString::fromUtf8(VERSIONID"\n\n"); 313 about += QString::fromUtf8("Algorithm: %1\n").arg(CTSPSolver::getVersionId()); 314 about += "\n"; 315 about += "TSPSG is licensed under the terms of the GNU General Public License. You should have received a copy of the GNU General Public License along with TSPSG."; 316 QMessageBox(QMessageBox::Information,"About",about,QMessageBox::Ok,this).exec(); 304 QString about = QString::fromUtf8("<b>TSPSG: TSP Solver and Generator</b><br>"); 305 about += QString::fromUtf8(" Version: <b>"BUILD_VERSION"</b><br>"); 306 about += QString::fromUtf8(" Copyright: <b>© 2007-%1 Lёppa</b><br>").arg(QDate::currentDate().toString("yyyy")); 307 about += QString::fromUtf8(" <b><a href=\"http://tspsg.sourceforge.net/\">http://tspsg.sourceforge.net/</a></b><br>"); 308 about += "<br>"; 309 about += QString::fromUtf8("Target OS: <b>%1</b><br>").arg(OS); 310 about += "Qt library:<br>"; 311 about += QString::fromUtf8(" Build time: <b>%1</b><br>").arg(QT_VERSION_STR); 312 about += QString::fromUtf8(" Runtime: <b>%1</b><br>").arg(qVersion()); 313 about += QString::fromUtf8("Built on <b>%1</b> at <b>%2</b><br>").arg(__DATE__).arg(__TIME__); 314 about += QString::fromUtf8("Id: <b>"VERSIONID"</b><br>"); 315 about += QString::fromUtf8("Algorithm: <b>%1</b><br>").arg(CTSPSolver::getVersionId()); 316 about += "<br>"; 317 about += "TSPSG is free software: you can redistribute it and/or modify it<br>" 318 "under the terms of the GNU General Public License as published<br>" 319 "by the Free Software Foundation, either version 3 of the License,<br>" 320 "or (at your option) any later version.<br>" 321 "<br>" 322 "TSPSG is distributed in the hope that it will be useful, but<br>" 323 "WITHOUT ANY WARRANTY; without even the implied warranty of<br>" 324 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br>" 325 "GNU General Public License for more details.<br>" 326 "<br>" 327 "You should have received a copy of the GNU General Public License<br>" 328 "along with TSPSG. If not, see <a href=\"http://www.gnu.org/licenses/\">http://www.gnu.org/licenses/</a>."; 329 330 QDialog *dlg = new QDialog(this); 331 QLabel *lblIcon = new QLabel(dlg); 332 QTextBrowser *txtAbout = new QTextBrowser(dlg); 333 QVBoxLayout *vb1 = new QVBoxLayout(), 334 *vb2 = new QVBoxLayout(); 335 QHBoxLayout *hb = new QHBoxLayout(); 336 QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok, Qt::Horizontal, dlg); 337 338 lblIcon->setPixmap(QPixmap(":/images/tspsg.png").scaledToWidth(64, Qt::SmoothTransformation)); 339 340 vb1->addWidget(lblIcon); 341 vb1->addStretch(); 342 343 // txtAbout->setTextInteractionFlags(txtAbout->textInteractionFlags() ^ Qt::TextEditable); 344 txtAbout->setWordWrapMode(QTextOption::NoWrap); 345 txtAbout->setOpenExternalLinks(true); 346 txtAbout->setHtml(about); 347 txtAbout->moveCursor(QTextCursor::Start); 348 349 hb->addLayout(vb1); 350 hb->addWidget(txtAbout); 351 352 vb2->addLayout(hb); 353 vb2->addWidget(bb); 354 355 dlg->setWindowTitle(trUtf8("About TSPSG")); 356 dlg->setLayout(vb2); 357 358 connect(bb, SIGNAL(accepted()), dlg, SLOT(accept())); 359 360 dlg->resize(475, 350); 361 dlg->exec(); 362 363 delete dlg; 317 364 } 318 365 … … 331 378 void MainWindow::buttonSolveClicked() 332 379 { 333 tMatrix matrix;380 TMatrix matrix; 334 381 QList<double> row; 335 382 int n = spinCities->value(); … … 347 394 } 348 395 CTSPSolver solver; 349 sStep *root = solver.solve(n,matrix,this);396 SStep *root = solver.solve(n,matrix,this); 350 397 if (!root) 351 398 return; … … 358 405 output.append("<hr>"); 359 406 output.append("<p>" + trUtf8("Solution of Variant #%1 task").arg(spinVariant->value()) + "</p>"); 360 sStep *step = root;407 SStep *step = root; 361 408 n = 1; 362 409 while (n <= spinCities->value()) { 363 if (step->prNode->prNode != NULL || ( step->prNode->prNode == NULL && step->plNode->prNode == NULL)) {410 if (step->prNode->prNode != NULL || ((step->prNode->prNode == NULL) && (step->plNode->prNode == NULL))) { 364 411 if (n != spinCities->value()) { 365 412 output.append("<p>" + trUtf8("Step #%1").arg(n++) + "</p>"); 366 outputMatrix(step->matrix,output,step->candidate.nRow,step->candidate.nCol); 367 if (step->alts) 368 output.append("<p class=\"hasalts\">" + trUtf8("This step has alternate candidates for branching.") + "</p>"); 413 outputMatrix(*step, output); 414 output.append("<p>" + trUtf8("Selected candidate for branching: %1.").arg(trUtf8("(%1;%2)").arg(step->candidate.nRow + 1).arg(step->candidate.nCol + 1)) + "</p>"); 415 if (!step->alts.empty()) { 416 TCandidate cand; 417 QString alts; 418 foreach(cand, step->alts) { 419 if (!alts.isEmpty()) 420 alts += ", "; 421 alts += trUtf8("(%1;%2)").arg(cand.nRow + 1).arg(cand.nCol + 1); 422 } 423 output.append("<p class=\"hasalts\">" + trUtf8("%n alternate candidate(s) for branching: %1.","",step->alts.count()).arg(alts) + "</p>"); 424 } 369 425 output.append("<p> </p>"); 370 426 } … … 392 448 393 449 // Scrolling to the end of text. 394 QTextCursor cursor(solutionText->textCursor()); 395 cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor); 396 solutionText->setTextCursor(cursor); 450 solutionText->moveCursor(QTextCursor::End); 397 451 398 452 enableSolutionActions(); … … 536 590 qtTranslator = NULL; 537 591 } 538 qtTranslator = new QTranslator();539 592 static QTranslator *translator; // Application translator 540 593 if (translator) { … … 543 596 } 544 597 translator = new QTranslator(); 545 if ( lng.compare("en") && !lng.startsWith("en_")) {598 if ((lng.compare("en") != 0) && !lng.startsWith("en_")) { 546 599 // Trying to load system Qt library translation... 600 qtTranslator = new QTranslator(); 547 601 if (qtTranslator->load("qt_" + lng,QLibraryInfo::location(QLibraryInfo::TranslationsPath))) 548 602 qApp->installTranslator(qtTranslator); 549 else 550 // No luck. Let's try to load bundled one.603 else { 604 // No luck. Let's try to load a bundled one. 551 605 if (qtTranslator->load("qt_" + lng,PATH_I18N)) 552 606 qApp->installTranslator(qtTranslator); … … 556 610 qtTranslator = NULL; 557 611 } 558 // Now let's load application translation. 559 if (translator->load(lng,PATH_I18N)) 560 qApp->installTranslator(translator); 561 else { 612 } 613 } 614 // Now let's load application translation. 615 if (translator->load(lng,PATH_I18N)) 616 qApp->installTranslator(translator); 617 else { 618 delete translator; 619 translator = NULL; 620 if ((lng.compare("en") != 0) && !lng.startsWith("en_")) { 562 621 if (!ad) 563 622 QMessageBox(QMessageBox::Warning,trUtf8("Language Change"),trUtf8("Unable to load translation language."),QMessageBox::Ok,this).exec(); 564 delete translator;565 translator = NULL;566 623 return false; 567 624 } … … 583 640 } 584 641 585 void MainWindow::outputMatrix(const tMatrix &matrix, QStringList &output, int nRow, int nCol)642 void MainWindow::outputMatrix(const TMatrix &matrix, QStringList &output) 586 643 { 587 644 int n = spinCities->value(); … … 593 650 if (matrix.at(r).at(c) == INFINITY) 594 651 line += "<td align=\"center\">"INFSTR"</td>"; 595 else if ((r == nRow) && (c == nCol))596 line += "<td align=\"center\" class=\"selected\">" + QVariant(matrix.at(r).at(c)).toString() + "</td>";597 652 else 598 653 line += "<td align=\"center\">" + QVariant(matrix.at(r).at(c)).toString() + "</td>"; 654 } 655 line += "</tr>"; 656 output.append(line); 657 } 658 output.append("</table>"); 659 } 660 661 void MainWindow::outputMatrix(const SStep &step, QStringList &output) 662 { 663 int n = spinCities->value(); 664 QString line=""; 665 output.append("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">"); 666 for (int r = 0; r < n; r++) { 667 line = "<tr>"; 668 for (int c = 0; c < n; c++) { 669 if (step.matrix.at(r).at(c) == INFINITY) 670 line += "<td align=\"center\">"INFSTR"</td>"; 671 else if ((r == step.candidate.nRow) && (c == step.candidate.nCol)) 672 line += "<td align=\"center\" class=\"selected\">" + QVariant(step.matrix.at(r).at(c)).toString() + "</td>"; 673 else { 674 TCandidate cand; 675 cand.nRow = r; 676 cand.nCol = c; 677 if (step.alts.contains(cand)) 678 line += "<td align=\"center\" class=\"alternate\">" + QVariant(step.matrix.at(r).at(c)).toString() + "</td>"; 679 else 680 line += "<td align=\"center\">" + QVariant(step.matrix.at(r).at(c)).toString() + "</td>"; 681 } 599 682 } 600 683 line += "</tr>"; -
trunk/src/mainwindow.h
r71 r74 92 92 bool loadLanguage(const QString &lang = QString()); 93 93 bool maybeSave(); 94 void outputMatrix(const tMatrix &matrix, QStringList &output, int nRow = -1, int nCol = -1); 94 void outputMatrix(const TMatrix &matrix, QStringList &output); 95 void outputMatrix(const SStep &step, QStringList &output); 95 96 bool saveTask(); 96 97 void setFileName(const QString &fileName = trUtf8("Untitled") + ".tspt"); -
trunk/src/tspsolver.cpp
r71 r74 26 26 //! Class constructor 27 27 CTSPSolver::CTSPSolver() 28 : nCities(0) 28 : nCities(0), root(NULL) 29 29 { 30 30 } … … 80 80 * \todo TODO: Comment the algorithm. 81 81 */ 82 sStep *CTSPSolver::solve(int numCities, tMatrix task, QWidget *parent)82 SStep *CTSPSolver::solve(int numCities, TMatrix task, QWidget *parent) 83 83 { 84 84 if (numCities <= 1) … … 98 98 pd.setValue(0); 99 99 100 sStep *step = new sStep();100 SStep *step = new SStep(); 101 101 step->matrix = task; 102 102 step->price = align(step->matrix); 103 103 root = step; 104 104 105 sStep *left, *right;105 SStep *left, *right; 106 106 int nRow, nCol; 107 107 bool firstStep = true; … … 117 117 } 118 118 if ((nRow == -1) || (nCol == -1) || pd.wasCanceled()) { 119 root = NULL;119 cleanup(); 120 120 break; 121 121 } 122 122 123 123 // Route with (nRow,nCol) path 124 right = new sStep();124 right = new SStep(); 125 125 right->matrix = step->matrix; 126 126 for (int k = 0; k < nCities; k++) { … … 136 136 137 137 // Route without (nRow,nCol) path 138 left = new sStep();138 left = new SStep(); 139 139 left->matrix = step->matrix; 140 140 left->matrix[nRow][nCol] = INFINITY; … … 180 180 } 181 181 182 CTSPSolver::~CTSPSolver() 183 { 184 if (root != NULL) 185 deleteNode(root); 186 } 187 182 188 /* Privates **********************************************************/ 183 189 184 double CTSPSolver::align( tMatrix &matrix)190 double CTSPSolver::align(TMatrix &matrix) 185 191 { 186 192 double r = 0; … … 207 213 route.clear(); 208 214 mayNotBeOptimal = false; 209 } 210 211 bool CTSPSolver::findCandidate(const tMatrix &matrix, int &nRow, int &nCol) const 215 if (root != NULL) 216 deleteNode(root); 217 } 218 219 void CTSPSolver::deleteNode(SStep *node) 220 { 221 if (node->plNode != NULL) 222 deleteNode(node->plNode); 223 if (node->prNode != NULL) 224 deleteNode(node->prNode); 225 delete node; 226 node = NULL; 227 } 228 229 QList<TCandidate> CTSPSolver::findCandidate(const TMatrix &matrix, int &nRow, int &nCol) const 212 230 { 213 231 nRow = -1; 214 232 nCol = -1; 215 bool alts = false; 233 QList<TCandidate> alts; 234 TCandidate cand; 216 235 double h = -1; 217 236 double sum; … … 225 244 nRow = r; 226 245 nCol = c; 227 alts = false; 228 } else if ((sum == h) && !hasSubCycles(r,c)) 229 alts = true; 246 alts.clear(); 247 } else if ((sum == h) && !hasSubCycles(r,c)) { 248 cand.nRow = r; 249 cand.nCol = c; 250 alts.append(cand); 251 } 230 252 } 231 253 return alts; 232 254 } 233 255 234 double CTSPSolver::findMinInCol(int nCol, const tMatrix &matrix, int exr) const256 double CTSPSolver::findMinInCol(int nCol, const TMatrix &matrix, int exr) const 235 257 { 236 258 double min = INFINITY; … … 241 263 } 242 264 243 double CTSPSolver::findMinInRow(int nRow, const tMatrix &matrix, int exc) const265 double CTSPSolver::findMinInRow(int nRow, const TMatrix &matrix, int exc) const 244 266 { 245 267 double min = INFINITY; … … 264 286 } 265 287 266 void CTSPSolver::subCol( tMatrix &matrix, int nCol, double val)288 void CTSPSolver::subCol(TMatrix &matrix, int nCol, double val) 267 289 { 268 290 for (int k = 0; k < nCities; k++) … … 271 293 } 272 294 273 void CTSPSolver::subRow( tMatrix &matrix, int nRow, double val)295 void CTSPSolver::subRow(TMatrix &matrix, int nRow, double val) 274 296 { 275 297 for (int k = 0; k < nCities; k++) -
trunk/src/tspsolver.h
r71 r74 34 34 35 35 //! A matrix of city-to-city travel costs. 36 typedef QList<QList<double> > tMatrix; 36 typedef QList<QList<double> > TMatrix; 37 38 /*! 39 * \brief A structure that represents a candidate for branching. 40 */ 41 struct TCandidate { 42 int nRow; //!< A zero-based row number of the candidate 43 int nCol; //!< A zero-based column number of the candidate 44 45 //! Assigns default values 46 TCandidate() { 47 nCol = nRow = -1; 48 } 49 //! An operator == implementation 50 bool operator ==(const TCandidate &cand) const { 51 return ((cand.nRow == nRow) && (cand.nCol == nCol)); 52 } 53 }; 37 54 38 55 /*! … … 41 58 * A tree of such elements will represent the solving process. 42 59 */ 43 //! \todo TODO: List alternative candidates. 44 struct sStep { 45 tMatrix matrix; //!< This step's matrix 60 struct SStep { 61 TMatrix matrix; //!< This step's matrix 46 62 double price; //!< The price of travel to this step 47 struct { 48 int nRow; //!< A zero-based row number of the candidate 49 int nCol; //!< A zero-based column number of the candidate 50 } candidate; //!< A candiadate for branching in the current matrix 51 bool alts; //!< Indicates whether or not matrix has alternative candidates 52 sStep *plNode; //!< Pointer to the left branch step 53 sStep *prNode; //!< Pointer to the right branch step 63 TCandidate candidate; //!< A candiadate for branching in the current matrix 64 QList<TCandidate> alts; //!< A list of alternative branching candidates 65 SStep *plNode; //!< Pointer to the left branch step 66 SStep *prNode; //!< Pointer to the right branch step 54 67 55 68 //! Assigns default values 56 sStep() { 57 price = candidate.nRow = candidate.nCol = -1; 58 alts = false; 69 SStep() { 70 price = -1; 59 71 plNode = prNode = NULL; 60 72 } … … 76 88 static QString getVersionId(); 77 89 bool isOptimal() const; 78 sStep *solve(int numCities, tMatrix task, QWidget *parent = 0); 90 SStep *solve(int numCities, TMatrix task, QWidget *parent = 0); 91 ~CTSPSolver(); 79 92 80 93 private: 81 94 bool mayNotBeOptimal; 82 95 int nCities; 83 sStep *root;96 SStep *root; 84 97 QHash<int,int> route; 85 98 // QHash<int,int> forbidden; 86 99 87 double align( tMatrix &matrix);100 double align(TMatrix &matrix); 88 101 void cleanup(); 89 bool findCandidate(const tMatrix &matrix, int &nRow, int &nCol) const; 90 double findMinInCol(int nCol, const tMatrix &matrix, int exr = -1) const; 91 double findMinInRow(int nRow, const tMatrix &matrix, int exc = -1) const; 102 void deleteNode(SStep *node); 103 QList<TCandidate> findCandidate(const TMatrix &matrix, int &nRow, int &nCol) const; 104 double findMinInCol(int nCol, const TMatrix &matrix, int exr = -1) const; 105 double findMinInRow(int nRow, const TMatrix &matrix, int exc = -1) const; 92 106 bool hasSubCycles(int nRow, int nCol) const; 93 void subCol( tMatrix &matrix, int nCol, double val);94 void subRow( tMatrix &matrix, int nRow, double val);107 void subCol(TMatrix &matrix, int nCol, double val); 108 void subRow(TMatrix &matrix, int nRow, double val); 95 109 }; 96 110 -
trunk/ui/mainwindow.ui
r73 r74 525 525 </property> 526 526 <property name="text"> 527 <string>&About ...</string>528 </property> 529 <property name="iconText"> 530 <string>About ...</string>527 <string>&About TSPSG...</string> 528 </property> 529 <property name="iconText"> 530 <string>About TSPSG...</string> 531 531 </property> 532 532 <property name="statusTip">
Note: See TracChangeset
for help on using the changeset viewer.