Advertisement
mamamaria

Untitled

Apr 28th, 2022
973
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.35 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.  
  170.     double di = 0, dj = 0;
  171.     ReductionDi(result, di);
  172.     ReductionDj(result, dj);
  173.  
  174.     return result;
  175. }
  176. double LittleWayCounter(const TreeNode &node, const Graph &graph) {
  177.     double sum = 0;
  178.     for (int i = 0; i < node.way.size(); i++) {
  179.         sum += graph[i][node.way[i]];
  180.     }
  181.     return sum;
  182. }
  183.  
  184. void Handle(const TreeNode& node, const Graph& originalGraph) {
  185.     TreeNode yesNode = node, noNode = node;
  186.  
  187.     double maxAssessment; double di = 0, dj = 0;
  188.     Graph graph = ConstructGraph(originalGraph, node.history);
  189.  
  190.     Direction zeroMaxAssessment = MaxCostForRejection(graph, maxAssessment);
  191.     CrossOut(graph, zeroMaxAssessment);
  192.     ReductionDi(graph, di);
  193.     ReductionDj(graph, dj);
  194.     yesNode.cost = di + dj + yesNode.cost;
  195.     yesNode.way[zeroMaxAssessment.first] = zeroMaxAssessment.second;
  196.     yesNode.waysCounter++;
  197.     yesNode.history.emplace_back(zeroMaxAssessment, true);
  198.     Nodes.push(yesNode);
  199.  
  200.     //maxAssessment = Assessment(graph, zeroMaxAssessment.first, zeroMaxAssessment.second);
  201.     noNode.cost = maxAssessment + noNode.cost;
  202.     noNode.history.emplace_back(zeroMaxAssessment, false);
  203.     Nodes.push(noNode);
  204.  
  205.  
  206. }
  207.  
  208. void GraphReader(Graph& graph, int& N, const string strr) {
  209.     ifstream gin(strr);
  210.     gin >> N;
  211.     graph.resize(N);
  212.     for (int i = 0; i < N; i++) {
  213.         graph[i].resize(N);
  214.     }
  215.     double dub;
  216.     for (int i = 0; i < N; i++) {
  217.         for (int j = 0; j < N; j++) {
  218.             gin >> dub;
  219.             if (i == j) dub = INFINITY;
  220.             graph[i][j] = dub;
  221.         }
  222.     }
  223.     gin.close();
  224. }
  225. int main()
  226. {
  227.  
  228.  
  229.     ofstream filetime("newTSPBAB_time-N.txt");
  230.     ofstream filelongway("newTSPBAB_longway-N.txt");
  231.     for (int NUMBER = 5; NUMBER <= 100; NUMBER += 5) {
  232.         double averagelong = 0;
  233.         double averagetime = 0;
  234.         for (int graphforN = 0; graphforN < 20; graphforN++) {
  235.             cout << "N: " << NUMBER << " graph number: " << graphforN << endl;
  236.             double di = 0, dj = 0;
  237.             auto BABstart = high_resolution_clock::now();
  238.             string strr = mainstr + to_string(NUMBER) + "_" + to_string(graphforN) + ".txt";
  239.             Graph graph;
  240.             GraphReader(graph, N, strr);
  241.             ReductionDi(graph, di);
  242.             ReductionDj(graph, dj);
  243.             double lowerBound = di + dj;
  244.             Nodes.emplace(N, lowerBound);
  245.  
  246.             TreeNode temporaryNode;
  247.             while (!Nodes.empty()) {
  248.                 temporaryNode = Nodes.top();
  249.                 if (temporaryNode.waysCounter == N)
  250.                     break;
  251.                 Nodes.pop();
  252.                 Handle(temporaryNode, graph);
  253.             }
  254.             Nodes = priority_queue<TreeNode>();
  255.             /*cout << temporaryNode.cost;
  256.             cout << endl;way
  257.             for (int i = 0; i < N; i++) {
  258.                 cout << temporaryNode.way[i] << "   ";
  259.             }*/
  260.  
  261.             auto BABfinish = high_resolution_clock::now();
  262.  
  263.             averagelong += LittleWayCounter(temporaryNode, graph);
  264.             averagetime += duration_cast<milliseconds>(BABfinish - BABstart).count();
  265.         }
  266.         filelongway << "N: " << NUMBER << " waylong: " << averagelong / 20 << endl;
  267.         filetime << "N: " << NUMBER << " timelong: " << averagetime / 20 << endl;
  268.  
  269.     }
  270.     filetime.close();
  271.     filelongway.close();
  272. }
  273.  
  274.  
  275.  
  276.  
  277.  
  278.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement