mamamaria

Untitled

Apr 21st, 2022 (edited)
787
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.14 KB | None | 0 0
  1. // BranchAndBound.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
  2. //
  3.  
  4. #include <iostream>
  5. #include <vector>
  6. #include <queue>
  7. #include <ctime>
  8. #include <random>
  9. #include <fstream>
  10. #include <chrono>
  11. #include <string>
  12. using namespace std;
  13. using namespace chrono;
  14. string mainstr = "C:\\Users\\asus\\Desktop\\petya\\Coursework\\Coursework\\graphs\\";
  15. default_random_engine eng(time(0));
  16.  
  17. using Graph = vector<vector<double>>;
  18. using Way = vector<int>;
  19. using Direction = pair<int, int>;
  20. int N; // количество городов
  21.  
  22. struct HistoryNode {
  23.     int from;
  24.     int to;
  25.     bool accepted;
  26.     HistoryNode(Direction dir, bool accepted) : from(dir.first), to(dir.second), accepted(accepted) {}
  27. };
  28. using History = vector<HistoryNode>;
  29.  
  30. struct TreeNode {
  31.     History history;
  32.     Way way;
  33.     int waysCounter;
  34.     double cost;
  35.     bool operator<(const TreeNode& tn) const
  36.     {
  37.         return cost > tn.cost;
  38.     }
  39.     TreeNode() : history(), way(), waysCounter(0), cost(0) {}
  40.     TreeNode(int N, double cost) : history(), way(N, -1), waysCounter(0), cost(cost) {}
  41. };
  42.  
  43. priority_queue<TreeNode> Nodes;
  44.  
  45. /*Graph GraphGenerator() {
  46.     Graph graph(N);
  47.     for (int i = 0; i < N; i++) {
  48.         graph[i].resize(N);
  49.     }
  50.     uniform_real_distribution<double> distr(1, 10);
  51.     for (int i = 0; i < N; i++) {
  52.         for (int j = 0; j <= i; j++) {
  53.             if (i == j) {
  54.                 graph[i][j] = INFINITY;
  55.                 graph[j][i] = INFINITY;
  56.                 continue;
  57.             }
  58.             graph[i][j] = distr(eng);
  59.             graph[j][i] = distr(eng);
  60.         }
  61.     }
  62.     return graph;
  63. }*/
  64. //Graph GraphGenerator() {
  65. //  Graph graph;
  66. //  graph.push_back({ INFINITY,20,18,12,8 });
  67. //  graph.push_back({ 5,INFINITY,14,7,11 });
  68. //  graph.push_back({ 12,18,INFINITY,6,11 });
  69. //  graph.push_back({ 11,17,11,INFINITY,12 });
  70. //  graph.push_back({ 5,5,5,5,INFINITY });
  71. //  return graph;
  72. //  }
  73.  
  74. void ReductionDi(Graph& graph, double& di) {
  75.     double min = INFINITY;
  76.     for (int i = 0; i < N; i++) {
  77.         min = INFINITY;
  78.         for (int j = 0; j < N; j++) {
  79.             if (graph[i][j] < min)
  80.                 min = graph[i][j];
  81.         }
  82.         if (min != 0 && min != INFINITY) {
  83.             di += min;
  84.             for (int j = 0; j < N; j++) {
  85.                 graph[i][j] -= min;
  86.             }
  87.         }
  88.     }
  89. }
  90.  
  91. void ReductionDj(Graph& graph, double& dj) {
  92.     double min = INFINITY;
  93.     for (int j = 0; j < N; j++) {
  94.         min = INFINITY;
  95.         for (int i = 0; i < N; i++) {
  96.             if (graph[i][j] < min)
  97.                 min = graph[i][j];
  98.         }
  99.         if (min != 0 && min != INFINITY) {
  100.             dj += min;
  101.             for (int i = 0; i < N; i++) {
  102.                 graph[i][j] -= min;
  103.             }
  104.         }
  105.     }
  106. }
  107.  
  108. double Assessment(const Graph& graph, const int i, const int j) {
  109.     double min = INFINITY, sum = 0;
  110.     for (int pj = 0; pj < N; pj++) {
  111.         if (graph[i][pj] < min && pj != j)
  112.             min = graph[i][pj];
  113.     }
  114.     sum += min;
  115.     min = INFINITY;
  116.     for (int pi = 0; pi < N; pi++) {
  117.         if (graph[pi][j] < min && pi != i)
  118.             min = graph[pi][j];
  119.     }
  120.     sum += min;
  121.     return sum;
  122. }
  123. Direction MaxCostForRejection(const Graph& graph, double& maxAssessment) { //выбрали в матрице нулевую клетку с наибольшей стоимостью
  124.     maxAssessment = 0; int maxi, maxj; double assessment; Direction direction;
  125.     for (int i = 0; i < N; i++) {
  126.         for (int j = 0; j < N; j++) {
  127.             if (graph[i][j] == 0) {
  128.                 assessment = Assessment(graph, i, j);
  129.                 if (assessment == INFINITY) {
  130.                     direction.first = i; direction.second = j;
  131.                     maxAssessment = INFINITY;
  132.                     return direction;
  133.                 }
  134.                 if (assessment > maxAssessment) {
  135.                     maxAssessment = assessment;
  136.                     maxi = i;
  137.                     maxj = j;
  138.                 }
  139.             }
  140.         }
  141.     }
  142.     direction.first = maxi; direction.second = maxj;
  143.     return direction;
  144. }
  145.  
  146. void CrossOut(Graph& graph, const Direction& direction) {
  147.     graph[direction.first][direction.second] = INFINITY;
  148.     graph[direction.second][direction.first] = INFINITY;
  149.     for (int k = 0; k < N; k++) {
  150.         graph[k][direction.second] = INFINITY;
  151.         graph[direction.first][k] = INFINITY;
  152.     }
  153.  
  154. }
  155. //непонятно делать ли infinity когда не берем
  156. //непонятно нужно ли делать пометку в том, идем ли по этому ребру или нет
  157. //и как ее делать
  158.  
  159. Graph ConstructGraph(const Graph& graph, const History& history) {
  160.     Graph result = graph;
  161.     for (const auto& historyNode : history) {
  162.         if (historyNode.accepted) {
  163.             CrossOut(result, make_pair(historyNode.from, historyNode.to));
  164.         }
  165.         else {
  166.             result[historyNode.from][historyNode.to] = INFINITY;
  167.         }
  168.  
  169.         double di = 0, dj = 0;
  170.         ReductionDi(result, di);
  171.         ReductionDj(result, dj);
  172.     }
  173.     return result;
  174. }
  175.  
  176. void Handle(const TreeNode& node, const Graph& originalGraph) {
  177.     TreeNode yesNode = node, noNode = node;
  178.  
  179.     double maxAssessment; double di = 0, dj = 0;
  180.     Graph graph = ConstructGraph(originalGraph, node.history);
  181.  
  182.     Direction zeroMaxAssessment = MaxCostForRejection(graph, maxAssessment);
  183.     CrossOut(graph, zeroMaxAssessment);
  184.     ReductionDi(graph, di);
  185.     ReductionDj(graph, dj);
  186.     yesNode.cost = di + dj + yesNode.cost;
  187.     yesNode.way[zeroMaxAssessment.first] = zeroMaxAssessment.second;
  188.     yesNode.waysCounter++;
  189.     yesNode.history.emplace_back(zeroMaxAssessment, true);
  190.     Nodes.push(yesNode);
  191.  
  192.     //maxAssessment = Assessment(graph, zeroMaxAssessment.first, zeroMaxAssessment.second);
  193.     noNode.cost = maxAssessment + noNode.cost;
  194.     noNode.history.emplace_back(zeroMaxAssessment, false);
  195.     Nodes.push(noNode);
  196.  
  197.  
  198. }
  199.  
  200. void GraphReader(Graph& graph, int& N, const string strr) {
  201.     ifstream gin(strr);
  202.     gin >> N;
  203.     graph.resize(N);
  204.     for (int i = 0; i < N; i++) {
  205.         graph[i].resize(N);
  206.     }
  207.     double dub;
  208.     for (int i = 0; i < N; i++) {
  209.         for (int j = 0; j < N; j++) {
  210.             gin >> dub;
  211.             if (i == j) dub = INFINITY;
  212.             graph[i][j] = dub;
  213.         }
  214.     }
  215.     gin.close();
  216. }
  217. int main()
  218. {
  219.  
  220.  
  221.     ofstream filetime("TSPBAB_time-N.txt");
  222.     ofstream filelongway("TSPBAB_longway-N.txt");
  223.     for (int NUMBER = 40; NUMBER <= 100; NUMBER += 5) {
  224.         double averagelong = 0;
  225.         double averagetime = 0;
  226.         for (int graphforN = 0; graphforN < 20; graphforN++) {
  227.             cout << "N: " << NUMBER << " graph number: " << graphforN << endl;
  228.             double di = 0, dj = 0;
  229.             auto BABstart = high_resolution_clock::now();
  230.             string strr = mainstr + to_string(NUMBER) + "_" + to_string(graphforN) + ".txt";
  231.             Graph graph;
  232.             GraphReader(graph, N, strr);
  233.             ReductionDi(graph, di);
  234.             ReductionDj(graph, dj);
  235.             double lowerBound = di + dj;
  236.             Nodes.emplace(N, lowerBound);
  237.  
  238.             TreeNode temporaryNode;
  239.             while (!Nodes.empty()) {
  240.                 temporaryNode = Nodes.top();
  241.                 if (temporaryNode.waysCounter == N)
  242.                     break;
  243.                 Nodes.pop();
  244.                 Handle(temporaryNode, graph);
  245.             }
  246.             Nodes = priority_queue<TreeNode>();
  247.             /*cout << temporaryNode.cost;
  248.             cout << endl;
  249.             for (int i = 0; i < N; i++) {
  250.                 cout << temporaryNode.way[i] << "   ";
  251.             }*/
  252.  
  253.             auto BABfinish = high_resolution_clock::now();
  254.  
  255.             averagelong += temporaryNode.cost;
  256.             averagetime += duration_cast<milliseconds>(BABfinish - BABstart).count();
  257.         }
  258.         filelongway << "N: " << NUMBER << " waylong: " << averagelong / 20 << endl;
  259.         filetime << "N: " << NUMBER << " timelong: " << averagetime / 20 << endl;
  260.  
  261.     }
  262.     filetime.close();
  263.     filelongway.close();
  264. }
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
Advertisement
Add Comment
Please, Sign In to add comment