Advertisement
mamamaria

bhabha

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