Aleks11

Untitled

May 6th, 2014
328
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 23.79 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <conio.h>
  3. #include <Windows.h>
  4.  
  5. #include <string>
  6. #include <locale>
  7.  
  8. #include <stack>
  9. #include <vector>
  10. #include <algorithm>
  11. #include <cctype>
  12.  
  13.  
  14. bool iswm(std::string const &_sMask, std::string const &_Text)
  15. {
  16.     std::string sMask;
  17.  
  18.     {
  19.         char cLast = 0;
  20.         size_t iLast = 0;
  21.  
  22.         for (size_t i = 0; i < _sMask.size(); i++)
  23.         {
  24.             char c = _sMask[i];
  25.             if (!(cLast == c && c == '*' || !isgraph(c)))
  26.             {
  27.                 sMask.push_back(_sMask[i]);
  28.                 iLast++;
  29.             }
  30.  
  31.             cLast = c;
  32.         }
  33.     }
  34.  
  35.     // вектор состояний, хранятся позиции состояния(т.е. символа)
  36.     std::vector<size_t> States(1, -1);
  37.  
  38.     // идём чётко по тексту
  39.     for (char cSource : _Text)
  40.     {
  41.         // быстрый выход по несоответствию
  42.         if (States.empty())
  43.             break;
  44.  
  45.         std::vector<size_t> NewStates;
  46.  
  47.         // но по маске не идём, проход по маске представляет НКА!
  48.         for (size_t iPos : States)
  49.         {
  50.             if (sMask[iPos + 1] == '?' || sMask[iPos + 1] == cSource)
  51.             {
  52.                 NewStates.push_back(iPos + 1);
  53.             }
  54.  
  55.             // если текущий переход *, то остаёмся тут и всё
  56.             if (iPos != -1 && sMask[iPos] == '*')
  57.             {
  58.                 NewStates.push_back(iPos);
  59.             }
  60.  
  61.             if (sMask[iPos + 1] == '*')
  62.             {
  63.                 NewStates.push_back(iPos + 1);
  64.  
  65.                 // * = 0
  66.                 if (iPos + 2 < sMask.size() && (sMask[iPos + 2] == '?' || sMask[iPos + 2] == cSource))
  67.                 {
  68.                     NewStates.push_back(iPos + 2);
  69.                 }
  70.             }
  71.         }
  72.  
  73.         States.assign(NewStates.begin(), NewStates.end());
  74.     }
  75.  
  76.  
  77.     // допускающее - последнее ) естессно
  78.     for (size_t i : States)
  79.     {
  80.         if (i == sMask.size() - 1)
  81.         {
  82.             return true;
  83.         }
  84.     }
  85.  
  86.     return false;
  87. }
  88.  
  89. enum class E_ERROR
  90. {
  91.     NONE = -1,
  92.     NOT_SETTED_TYPE,
  93.     WHERE_IS_FILE,
  94.     PARSING_ERROR,
  95.     BROKEN_DATA
  96. };
  97.  
  98. enum class E_GRAPHS_REPRES
  99. {
  100.     NONE = -1,
  101.     ADJ_LIST,
  102.     ADJ_MAT,
  103.     INC_MAT
  104. };
  105.  
  106. struct CEdge;
  107. struct CVertex
  108. {
  109.     CVertex()
  110.     {
  111.     }
  112.  
  113.     std::vector<CEdge *> Edges;
  114.  
  115.     bool bIsVisited = false;
  116.     bool bIsInGraph = false;
  117.  
  118.     DWORD dwID = -1;
  119.  
  120.     void *pMyData = nullptr;
  121. };
  122.  
  123. struct CEdge
  124. {
  125.     CEdge()
  126.     {
  127.     }
  128.  
  129.     DWORD dwID = -1;
  130.  
  131.     CVertex *pV1 = nullptr;
  132.     CVertex *pV2 = nullptr;
  133.  
  134.     float fWeight = 1.0f;
  135.  
  136.     bool bIsVisited = false;
  137.  
  138.     bool bIsInGraph = false;
  139.  
  140.     //void *pMyData = nullptr;
  141. };
  142.  
  143. class CGraph
  144. {
  145. public:
  146.     CGraph() :
  147.         m_eReprType(E_GRAPHS_REPRES::NONE), m_bIsLoaded(false), m_bIsParsing(false)
  148.     {
  149.     }
  150.  
  151.     CGraph(CGraph const &_Graph) :
  152.         m_bIsLoaded(false)
  153.     {
  154.         if (this != &_Graph)
  155.         {
  156.             for (auto iV : _Graph.m_Vertices)
  157.             {
  158.                 //CVertex *pNew = new CVertex(*iV);
  159.  
  160.                 //pNew->pMyData = iV->pMyData;
  161.  
  162.                 m_Vertices.push_back(iV);
  163.             }
  164.  
  165.             for (auto iE : _Graph.m_Edges)
  166.             {
  167.                 //m_Edges.push_back(new CEdge(*iE));
  168.                 m_Edges.push_back(iE);
  169.             }
  170.  
  171.             m_eReprType = _Graph.m_eReprType;
  172.             m_bIsOriented = _Graph.m_bIsOriented;
  173.             m_bIsWeighted = _Graph.m_bIsWeighted;
  174.             m_bIsLoaded = _Graph.m_bIsLoaded;
  175.             m_bIsParsing = _Graph.m_bIsParsing;
  176.         }
  177.     }
  178.  
  179.     CGraph(E_GRAPHS_REPRES const _Repr) :
  180.         m_eReprType(_Repr), m_bIsLoaded(false), m_bIsParsing(false)
  181.     {
  182.     }
  183.  
  184.     ~CGraph()
  185.     {
  186.  
  187.     };
  188.  
  189.     int GetEdgeID(int _nVertex1, int _nVertex2) const
  190.     {
  191.         if (!m_bIsLoaded && !m_bIsParsing)
  192.             return INT_MAX;
  193.  
  194.         CVertex *v = m_Vertices[_nVertex1];
  195.  
  196.         if (!v->bIsInGraph)
  197.             return INT_MAX;
  198.  
  199.         for (auto e : v->Edges)
  200.         {
  201.             if (!e->bIsInGraph)
  202.                 continue;
  203.  
  204.             if (e->pV1->dwID == _nVertex1 && e->pV2->dwID == _nVertex2)
  205.                 return e->dwID;
  206.  
  207.             if (e->pV1->dwID == _nVertex2 && e->pV2->dwID == _nVertex1)
  208.                 return e->dwID;
  209.         }
  210.  
  211.         return INT_MAX;
  212.     }
  213.  
  214.     /*
  215.     Format of file:
  216.  
  217.         repres_type(E_GRAPHS_STRUCT) is_oriented(0, 1) is_weighted(0, 1)
  218.         VertexCount EdgeCount
  219.  
  220.         representation:
  221.             adj_list:
  222.                 vert0 -> vert1(weight1), vert2(weight2)
  223.                 vert0 -> vert1, vert2
  224.  
  225.             adj_mat:
  226.                 vert to vert mat(weigth)
  227.                 vert to vert mat
  228.  
  229.             inc_mat:
  230.                 vert to edge mat
  231.  
  232.     */
  233.  
  234.     E_ERROR ParseFile(std::string const &_sFileName)
  235.     {
  236.         m_bIsLoaded = false;
  237.         m_bIsParsing = true;
  238.  
  239.         //if (m_eReprType == E_GRAPHS_REPRES::NONE)
  240.         //  return E_ERROR::NOT_SETTED_TYPE;
  241.  
  242.         if (_sFileName.empty())
  243.             return E_ERROR::WHERE_IS_FILE;
  244.  
  245.         FILE *pFile;
  246.  
  247.         fopen_s(&pFile, _sFileName.c_str(), "r");
  248.  
  249.         if (!pFile)
  250.             return E_ERROR::WHERE_IS_FILE;
  251.  
  252.         // read the type of graph
  253.         // mask: repres_type(E_GRAPHS_REPRES) is_oriented(0, 1) is_weighted(0, 1)
  254.  
  255.         int eReprType, bIsOriented, bIsWeighted;
  256.  
  257.         if (fscanf_s(pFile, "%d %d %d", &eReprType, &bIsOriented, &bIsWeighted) != 3)
  258.             return E_ERROR::PARSING_ERROR;
  259.  
  260.         m_eReprType = (E_GRAPHS_REPRES)eReprType;
  261.         m_bIsOriented = (bIsOriented != 0);
  262.         m_bIsWeighted = (bIsWeighted != 0);
  263.  
  264.         int nVertexCount = -1;
  265.  
  266.         // read the count of objects
  267.         // mask: VertexCount EdgeCount
  268.  
  269.         if (fscanf_s(pFile, "%d", &nVertexCount) != 1)
  270.             return E_ERROR::PARSING_ERROR;
  271.  
  272.         m_Vertices.resize(nVertexCount);
  273.         for (int i = 0; i < nVertexCount; i++)
  274.         {
  275.             m_Vertices[i] = new CVertex;
  276.         }
  277.  
  278.         // read the repres of graph
  279.         // mask: vert0 -> vert1, vert2, ...,
  280.         // weighted mask: vert0 -> vert1(weight1), vert2(weight2), ...,
  281.         if (m_eReprType == E_GRAPHS_REPRES::ADJ_LIST)
  282.         {
  283.             while (1)
  284.             {
  285.                 int nFID;
  286.  
  287.                 if (fscanf_s(pFile, "%d -> ", &nFID) != 1)
  288.                     goto end;
  289.  
  290.                 if (nFID < 0 || nFID >= nVertexCount)
  291.                     return E_ERROR::BROKEN_DATA;
  292.  
  293.                 m_Vertices[nFID]->dwID = nFID;
  294.                 m_Vertices[nFID]->bIsInGraph = true;
  295.  
  296.                 if (m_bIsWeighted)
  297.                 {
  298.                     float fWeight;
  299.                     int nSID;
  300.  
  301.                     char c;
  302.                     while (fscanf_s(pFile, "%d(%f)%c", &nSID, &fWeight, &c) == 3)
  303.                     {
  304.                         if (nSID < 0 || nSID >= nVertexCount)
  305.                             return E_ERROR::BROKEN_DATA;
  306.  
  307.                         m_Vertices[nSID]->bIsInGraph = true;
  308.                         m_Vertices[nSID]->dwID = nSID;
  309.  
  310.                         CEdge *pEdge = new CEdge;
  311.                         pEdge->bIsInGraph = true;
  312.                         pEdge->fWeight = fWeight;
  313.                         pEdge->pV1 = m_Vertices[nFID];
  314.                         pEdge->pV2 = m_Vertices[nSID];
  315.                         pEdge->dwID = m_Edges.size();
  316.  
  317.                         m_Vertices[nSID]->Edges.push_back(pEdge);
  318.                         m_Vertices[nFID]->Edges.push_back(pEdge);
  319.  
  320.                         m_Edges.push_back(pEdge);
  321.  
  322.                         if (c != ',')
  323.                             break;
  324.                     }
  325.                 }
  326.                 else
  327.                 {
  328.                     int nSID;
  329.  
  330.                     char c;
  331.                     while (fscanf_s(pFile, "%d%c", &nSID, &c) == 2)
  332.                     {
  333.                         if (nSID < 0 || nSID >= nVertexCount)
  334.                             return E_ERROR::BROKEN_DATA;
  335.  
  336.                         CEdge *pEdge = new CEdge;
  337.                         pEdge->bIsInGraph = true;
  338.                         pEdge->pV1 = m_Vertices[nFID];
  339.                         pEdge->pV2 = m_Vertices[nSID];
  340.                         pEdge->dwID = m_Edges.size();
  341.  
  342.                         m_Vertices[nSID]->Edges.push_back(pEdge);
  343.                         m_Vertices[nFID]->Edges.push_back(pEdge);
  344.  
  345.                         m_Edges.push_back(pEdge);
  346.  
  347.                         if (c != ',')
  348.                             break;
  349.                     }
  350.                 }
  351.             }
  352.         }
  353.         else if (m_eReprType == E_GRAPHS_REPRES::ADJ_MAT)
  354.         {
  355.             m_Vertices.resize(nVertexCount);
  356.             for (int i = 0; i < nVertexCount; i++)
  357.             {
  358.                 m_Vertices[i] = new CVertex;
  359.             }
  360.  
  361.             // цикл по кол-ву вершин, читаем по одному числу
  362.             for (int v = 0; v < nVertexCount; v++)
  363.             {
  364.                 CVertex *V1 = m_Vertices[v];
  365.                 V1->bIsInGraph = true;
  366.  
  367.                 for (int v2 = 0; v2 < nVertexCount; v2++)
  368.                 {
  369.                     CVertex *V2 = m_Vertices[v2];
  370.                     V2->bIsInGraph = true;
  371.  
  372.                     if (m_bIsWeighted)
  373.                     {
  374.                         int nAdj;
  375.                         float fWeight;
  376.  
  377.                         if (fscanf_s(pFile, "%d(%f)", &nAdj, &fWeight) != 2)
  378.                             return E_ERROR::PARSING_ERROR;
  379.  
  380.                         if (nAdj == 1)
  381.                         {
  382.                             // из v в v2
  383.  
  384.                             CEdge *pEdge = new CEdge;
  385.                             pEdge->bIsInGraph = true;
  386.                             pEdge->fWeight = fWeight;
  387.                             pEdge->pV1 = V1;
  388.                             pEdge->pV2 = V2;
  389.                             pEdge->dwID = m_Edges.size();
  390.  
  391.                             V1->Edges.push_back(pEdge);
  392.                             V2->Edges.push_back(pEdge);
  393.  
  394.                             m_Edges.push_back(pEdge);
  395.                         }
  396.                     }
  397.                     else
  398.                     {
  399.                         int nAdj;
  400.  
  401.                         if (fscanf_s(pFile, "%d", &nAdj) != 1)
  402.                             return E_ERROR::PARSING_ERROR;
  403.  
  404.                         if (nAdj == 1)
  405.                         {
  406.                             // из v в v2
  407.  
  408.                             CEdge *pEdge = new CEdge;
  409.                             pEdge->bIsInGraph = true;
  410.                             pEdge->pV1 = V1;
  411.                             pEdge->pV2 = V2;
  412.                             pEdge->dwID = m_Edges.size();
  413.  
  414.                             V1->Edges.push_back(pEdge);
  415.                             V2->Edges.push_back(pEdge);
  416.  
  417.                             m_Edges.push_back(pEdge);
  418.                         }
  419.                     }
  420.                 }
  421.             }
  422.         }
  423.         /*
  424.         else if (m_eReprType == E_GRAPHS_REPRES::INC_MAT)
  425.         {
  426.             for (int v = 0; v < nVertexCount; v++)
  427.             {
  428.                 for (int e = 0; e < nEdgeCount; e++)
  429.                 {
  430.                     int nAdj;
  431.  
  432.                     if (fscanf_s(pFile, "%d", &nAdj) != 1)
  433.                         return E_ERROR::PARSING_ERROR;
  434.  
  435.                     if (m_bIsOriented)
  436.                     {
  437.                         // значит, что ребро уходит из вершины
  438.                         if (nAdj == -1)
  439.                         {
  440.                             m_Vertices[v].bIsInGraph = true;
  441.                             m_Vertices[v].Edges.push_back(e);
  442.  
  443.                             m_Edges[e].bIsInGraph = true;
  444.                             m_Edges[e].fWeight = 1.0f;
  445.                             m_Edges[e].nFirstVertexID = v;
  446.                         }
  447.                         else if (nAdj == 1)
  448.                         {
  449.                             m_Vertices[v].bIsInGraph = true;
  450.                             m_Vertices[v].Edges.push_back(e);
  451.  
  452.                             m_Edges[e].bIsInGraph = true;
  453.                             m_Edges[e].fWeight = 1.0f;
  454.                             m_Edges[e].nSecondVertexID = v;
  455.                         }
  456.                     }
  457.                     else if (nAdj == 1)
  458.                     {
  459.                         m_Vertices[v].bIsInGraph = true;
  460.                         m_Vertices[v].Edges.push_back(e);
  461.  
  462.                         m_Edges[e].bIsInGraph = true;
  463.                         m_Edges[e].fWeight = 1.0f;
  464.  
  465.                         // если первая вершина уже стоит(не -1), то ставим вторую
  466.                         if (m_Edges[e].nFirstVertexID == -1)
  467.                             m_Edges[e].nFirstVertexID = v;
  468.                         else
  469.                             m_Edges[e].nSecondVertexID = v;
  470.                     }
  471.                 }
  472.             }
  473.         }
  474.         */
  475.  
  476. end:
  477.         fclose(pFile);
  478.  
  479.         m_bIsParsing = false;
  480.         m_bIsLoaded = true;
  481.  
  482.         return E_ERROR::NONE;
  483.     }
  484.  
  485.     template<class fn>
  486.     void DFS_Rec(CVertex *pVertex, fn &_Func)
  487.     {
  488.         //_Func(pVertex);
  489.         PrintVInfo(pVertex);
  490.  
  491.         // ставим метку, что посетили данную вершину
  492.         pVertex->bIsVisited = true;
  493.  
  494.         if (m_bIsOriented)
  495.         {
  496.             // проходим по все ребрам
  497.             for (auto e : pVertex->Edges)
  498.             {
  499.                 // смотрим были ли мы в вершине соседней раньше
  500.                 // если нет, то запускаемся из нее
  501.                 if (e->pV1 == pVertex && !e->pV2->bIsVisited)
  502.                 {
  503.                     DFS_Rec(e->pV2, _Func);
  504.                 }
  505.             }
  506.         }
  507.         else
  508.         {
  509.             // проходим по все ребрам
  510.             for (auto e : pVertex->Edges)
  511.             {
  512.                 // смотрим были ли мы в вершине соседней раньше
  513.                 // если нет, то запускаемся из нее
  514.                 if (!e->pV2->bIsVisited)
  515.                 {
  516.                     DFS_Rec(e->pV2, _Func);
  517.                 }
  518.                
  519.                 if (!e->pV1->bIsVisited)
  520.                 {
  521.                     DFS_Rec(e->pV1, _Func);
  522.                 }
  523.             }
  524.         }
  525.     }
  526.  
  527.     template<class fn>
  528.     void DFS(fn &_Func)
  529.     {
  530.         DFS_Rec(m_Vertices[0], _Func);
  531.  
  532.         for (CVertex *iVer : m_Vertices)
  533.             iVer->bIsVisited = false;
  534.     }
  535.  
  536.     void PrintVInfo(CVertex *pVertex) const
  537.     {
  538.         printf("Edges of vertex %d:\n", pVertex->dwID);
  539.  
  540.         for (auto iEdge : pVertex->Edges)
  541.         {
  542.             if (m_bIsWeighted)
  543.             {
  544.                 printf("Edge %d: %d -> %d\n",
  545.                     iEdge->dwID,
  546.                     iEdge->pV1->dwID,
  547.                     iEdge->pV2->dwID);
  548.             }
  549.             else
  550.             {
  551.                 printf("Edge %d(%0.3f): %d -> %d\n",
  552.                     iEdge->dwID,
  553.                     iEdge->fWeight,
  554.                     iEdge->pV1->dwID,
  555.                     iEdge->pV2->dwID);
  556.             }
  557.         }
  558.  
  559.         printf("\n");
  560.     }
  561.  
  562.     std::vector<CVertex *> const &GetVertices() const
  563.     {
  564.         return m_Vertices;
  565.     };
  566.  
  567.     std::vector<CVertex *> &GetVertices()
  568.     {
  569.         return m_Vertices;
  570.     };
  571.  
  572.     std::vector<CEdge *> const &GetEdges() const
  573.     {
  574.         return m_Edges;
  575.     };
  576.  
  577.     std::vector<CEdge *> &GetEdges()
  578.     {
  579.         return m_Edges;
  580.     };
  581.  
  582.     bool                    m_bIsOriented;
  583.     bool                    m_bIsWeighted;
  584. private:
  585.     std::vector<CVertex *>  m_Vertices;
  586.     std::vector<CEdge *>    m_Edges;
  587.     E_GRAPHS_REPRES         m_eReprType;
  588.  
  589.     bool                    m_bIsLoaded;
  590.     bool                    m_bIsParsing;
  591. };
  592.  
  593. /*
  594. template <typename T, typename R, typename ...Args>
  595. R proxycall(T & obj, R (T::*mf)(Args...), Args &&... args)
  596. {
  597.     return (obj.*mf)(std::forward<Args>(args)...);
  598. }
  599. */
  600.  
  601. void PrintError(E_ERROR const &er)
  602. {
  603.     switch (er)
  604.     {
  605.     case E_ERROR::BROKEN_DATA:
  606.         printf("Error!!! Data is broken!\n");
  607.         break;
  608.     case E_ERROR::NOT_SETTED_TYPE:
  609.         printf("Error!!! Type of graph wasn't setted!\n");
  610.         break;
  611.     case E_ERROR::PARSING_ERROR:
  612.         printf("Error!!! Parser error!\n");
  613.         break;
  614.     case E_ERROR::WHERE_IS_FILE:
  615.         printf("Error!!! Smth with file(Busy, not finded)!\n");
  616.         break;
  617.     }
  618. }
  619.  
  620. #define V_RET(v) \
  621.     if ((hr = v) != E_ERROR::NONE) \
  622.     { \
  623.         PrintError(hr); \
  624.     } \
  625.  
  626. DWORD DSUGet(DWORD const _dwVertexID, std::vector<CVertex *> &_Vertices)
  627. {
  628.     if (_dwVertexID == *(DWORD *)_Vertices.at(_dwVertexID)->pMyData)
  629.         return _dwVertexID;
  630.  
  631.     *(DWORD *)_Vertices.at(_dwVertexID)->pMyData = DSUGet(*(DWORD *)_Vertices.at(_dwVertexID)->pMyData, _Vertices);
  632.     return *(DWORD *)_Vertices.at(_dwVertexID)->pMyData;
  633. }
  634.  
  635. void RunKruskal()
  636. {
  637.     CGraph graph;
  638.  
  639.     E_ERROR hr;
  640.  
  641.     V_RET(graph.ParseFile("adj_mat.txt"));
  642.  
  643.     DWORD dwTreeID = 0;
  644.     for (auto iVertex : graph.GetVertices())
  645.     {
  646.         iVertex->pMyData = new DWORD;
  647.         iVertex->dwID = dwTreeID;
  648.         *((DWORD *)iVertex->pMyData) = dwTreeID++;
  649.     }
  650.  
  651.     graph.DFS([](int const nid) { printf("%d\n", nid); });
  652.  
  653.     sort(graph.GetEdges().begin(), graph.GetEdges().end(),
  654.         [](CEdge const *const _p1, CEdge const *const _p2)
  655.     {
  656.         return _p1->fWeight < _p2->fWeight;
  657.     });
  658.  
  659.     CGraph SpanningGraph(graph);
  660.     SpanningGraph.GetEdges().clear();
  661.  
  662.     auto Vertices = graph.GetVertices();
  663.  
  664.     for (auto iEdge : graph.GetEdges())
  665.     {
  666.         CVertex *V1 = Vertices.at(DSUGet(iEdge->pV1->dwID, Vertices));
  667.         CVertex *V2 = Vertices.at(DSUGet(iEdge->pV2->dwID, Vertices));
  668.  
  669.         if (V1->dwID != V2->dwID)
  670.         {
  671.             if (rand() & 1)
  672.                 *(DWORD *)V2->pMyData = *(DWORD *)V1->pMyData;
  673.             else
  674.                 *(DWORD *)V1->pMyData = *(DWORD *)V2->pMyData;
  675.  
  676.             SpanningGraph.GetEdges().push_back(iEdge);
  677.         }
  678.     }
  679.  
  680.     printf("\n\n\nSpanning graph:\n\n");
  681.  
  682.     for (auto iEdge : SpanningGraph.GetEdges())
  683.     {
  684.         printf("%d %d\t %0.2f\n", iEdge->pV1->dwID, iEdge->pV2->dwID, iEdge->fWeight);
  685.     }
  686.  
  687.     //SpanningGraph.DFS([](int const nid) { printf("%d\n", nid); });
  688. }
  689.  
  690. void RunPrima()
  691. {
  692.     CGraph graph;
  693.  
  694.     E_ERROR hr;
  695.  
  696.     V_RET(graph.ParseFile("adj_mat.txt"));
  697.  
  698.     graph.DFS([](int const nid) { printf("%d\n", nid); });
  699.  
  700.     CGraph SpanningGraph(graph);
  701.     SpanningGraph.GetEdges().clear();
  702.  
  703.     // говорим графу, что каждое ребро не было добавлено
  704.     for (auto iVertex : graph.GetVertices())
  705.     {
  706.         iVertex->pMyData = new bool;
  707.         *((bool *)iVertex->pMyData) = false;
  708.     }
  709.  
  710.     // добавляем первое ребро(типо случайное) 
  711.     CEdge *pStartMinEdge = nullptr;
  712.  
  713.     DWORD dwRandVertex = rand() % graph.GetVertices().size();
  714.     for (auto iEdge : graph.GetVertices()[dwRandVertex]->Edges)
  715.     {
  716.         // если обе вершины заняты, выходим
  717.         if (*(bool *)iEdge->pV1->pMyData && *(bool *)iEdge->pV2->pMyData)
  718.             continue;
  719.  
  720.         // если не в конечном графе и по весу подходит:
  721.         if (!pStartMinEdge || pStartMinEdge->fWeight > iEdge->fWeight)
  722.         {
  723.             pStartMinEdge = iEdge;
  724.         }
  725.     }
  726.  
  727.     SpanningGraph.GetEdges().push_back(pStartMinEdge);
  728.     *(bool *)pStartMinEdge->pV1->pMyData = true;
  729.     *(bool *)pStartMinEdge->pV2->pMyData = true;
  730.  
  731.     for (DWORD i = 0; i < SpanningGraph.GetVertices().size() - 2; i++)
  732.     {
  733.         CEdge *pMinEdge = nullptr;
  734.  
  735.         // ищем ребро с наименьшим весом во всех рёбрах,
  736.         //      которые касаются конечного графа,
  737.         //      но не в нём
  738.        
  739.         for (auto iEdge : SpanningGraph.GetEdges())
  740.         {
  741.             // проходимся по всем рёбрам из вершины V1:
  742.             for (auto iV1Edge : iEdge->pV1->Edges)
  743.             {
  744.                 // если обе вершины заняты, выходим
  745.                 if (*(bool *)iV1Edge->pV1->pMyData && *(bool *)iV1Edge->pV2->pMyData)
  746.                     continue;
  747.  
  748.                 // если не в конечном графе и по весу подходит:
  749.                 if (!pMinEdge || pMinEdge->fWeight > iV1Edge->fWeight)
  750.                 {
  751.                     pMinEdge = iV1Edge;
  752.                 }
  753.             }
  754.  
  755.             // проходимся по всем рёбрам из вершины V2:
  756.             for (auto iV2Edge : iEdge->pV2->Edges)
  757.             {
  758.                 // если обе вершины заняты, выходим
  759.                 if (*(bool *)iV2Edge->pV1->pMyData && *(bool *)iV2Edge->pV2->pMyData)
  760.                     continue;
  761.  
  762.                 // если не в конечном графе и по весу подходит:
  763.                 if (!pMinEdge || pMinEdge->fWeight > iV2Edge->fWeight)
  764.                 {
  765.                     pMinEdge = iV2Edge;
  766.                 }
  767.             }
  768.         }
  769.  
  770.         // теперь в графе
  771.         *(bool *)pMinEdge->pV1->pMyData = true;
  772.         *(bool *)pMinEdge->pV2->pMyData = true;
  773.  
  774.         SpanningGraph.GetEdges().push_back(pMinEdge);
  775.     }
  776.  
  777.     printf("\n\n\nSpanning graph:\n\n");
  778.  
  779.     for (auto iEdge : SpanningGraph.GetEdges())
  780.     {
  781.         printf("%d %d\t %0.2f\n", iEdge->pV1->dwID, iEdge->pV2->dwID, iEdge->fWeight);
  782.     }
  783. }
  784.  
  785. void RunBoruvka()
  786. {
  787.     struct CBoruvkaInfo
  788.     {
  789.         DWORD dwSize;
  790.         DWORD dwRoot;
  791.         CEdge *pClosest;
  792.     };
  793.  
  794.     CGraph graph;
  795.  
  796.     E_ERROR hr;
  797.  
  798.     V_RET(graph.ParseFile("adj_mat.txt"));
  799.  
  800.     //graph.DFS([](int const nid) { printf("%d\n", nid); });
  801.  
  802.     CGraph SpanningGraph(graph);
  803.     SpanningGraph.GetEdges().clear();
  804.  
  805.     // каждая вершина хранит номер своего дерева
  806.     // в начале - дерево = вершина
  807.     DWORD dwTreeID = 0;
  808.     for (auto iVertex : SpanningGraph.GetVertices())
  809.     {
  810.         iVertex->pMyData = new CBoruvkaInfo;
  811.         ((CBoruvkaInfo *)iVertex->pMyData)->dwRoot = dwTreeID++;
  812.         ((CBoruvkaInfo *)iVertex->pMyData)->dwSize = 1;
  813.     }
  814.    
  815.     auto _FindRoot = [&SpanningGraph](DWORD i)
  816.     {
  817.         while (i != ((CBoruvkaInfo *)SpanningGraph.GetVertices()[i]->pMyData)->dwRoot)
  818.         {
  819.             i = ((CBoruvkaInfo *)SpanningGraph.GetVertices()[i]->pMyData)->dwRoot;
  820.         }
  821.  
  822.         return i;
  823.     };
  824.  
  825.     while (SpanningGraph.GetEdges().size() < SpanningGraph.GetVertices().size() - 1)
  826.     {
  827.         for (auto iVertex : SpanningGraph.GetVertices())
  828.         {
  829.             ((CBoruvkaInfo *)iVertex->pMyData)->pClosest = nullptr;
  830.         }
  831.  
  832.         for (auto iEdge : graph.GetEdges())
  833.         {
  834.             DWORD i = _FindRoot(iEdge->pV1->dwID);
  835.             DWORD j = _FindRoot(iEdge->pV2->dwID);
  836.  
  837.             CVertex *vi = SpanningGraph.GetVertices()[i];
  838.             CVertex *vj = SpanningGraph.GetVertices()[j];
  839.  
  840.             if (i == j)
  841.                 continue;
  842.  
  843.             if (!((CBoruvkaInfo *)vi->pMyData)->pClosest || iEdge->fWeight < ((CBoruvkaInfo *)vi->pMyData)->pClosest->fWeight)
  844.             {
  845.                 ((CBoruvkaInfo *)vi->pMyData)->pClosest = iEdge;
  846.             }
  847.  
  848.             if (!((CBoruvkaInfo *)vj->pMyData)->pClosest || iEdge->fWeight < ((CBoruvkaInfo *)vj->pMyData)->pClosest->fWeight)
  849.             {
  850.                 ((CBoruvkaInfo *)vj->pMyData)->pClosest = iEdge;
  851.             }
  852.         }
  853.  
  854.         for (auto iVertex : SpanningGraph.GetVertices())
  855.         {
  856.             CEdge *pEdge = ((CBoruvkaInfo *)iVertex->pMyData)->pClosest;
  857.  
  858.             if (!pEdge)
  859.                 continue;
  860.  
  861.             DWORD u = _FindRoot(pEdge->pV1->dwID);
  862.             DWORD v = _FindRoot(pEdge->pV2->dwID);
  863.  
  864.             if (u != v)
  865.             {
  866.                 CVertex *vu = SpanningGraph.GetVertices()[u];
  867.                 CVertex *vv = SpanningGraph.GetVertices()[v];
  868.  
  869.                 if (((CBoruvkaInfo *)vu->pMyData)->dwSize < ((CBoruvkaInfo *)vv->pMyData)->dwSize)
  870.                 {
  871.                     ((CBoruvkaInfo *)vu->pMyData)->dwRoot = v;
  872.                     ((CBoruvkaInfo *)vv->pMyData)->dwSize += ((CBoruvkaInfo *)vu->pMyData)->dwSize;
  873.                 }
  874.                 else
  875.                 {
  876.                     ((CBoruvkaInfo *)vv->pMyData)->dwRoot = u;
  877.                     ((CBoruvkaInfo *)vu->pMyData)->dwSize += ((CBoruvkaInfo *)vv->pMyData)->dwSize;
  878.                 }
  879.                
  880.                 SpanningGraph.GetEdges().push_back(pEdge);
  881.             }
  882.         }
  883.     }
  884.  
  885.     printf("\n\n\nSpanning graph:\n\n");
  886.  
  887.     for (auto iEdge : SpanningGraph.GetEdges())
  888.     {
  889.         printf("%d %d\t %0.2f\n", iEdge->pV1->dwID, iEdge->pV2->dwID, iEdge->fWeight);
  890.     }
  891. }
  892.  
  893. void RunRid()
  894. {
  895.     CGraph graph;
  896.  
  897.     E_ERROR hr;
  898.  
  899.     V_RET(graph.ParseFile("adj_mat.txt"));
  900.  
  901.     CVertex *pStartV = nullptr;
  902.     DWORD dwCountOfOdd = 0;
  903.  
  904.     for (auto iV : graph.GetVertices())
  905.     {
  906.         if ((iV->Edges.size() % 2) == 1)
  907.         {
  908.             dwCountOfOdd++;
  909.             pStartV = iV;
  910.         }
  911.     }
  912.  
  913.     if (dwCountOfOdd != 2 && dwCountOfOdd != 0)
  914.         return;
  915.  
  916.     if (dwCountOfOdd == 0)
  917.     {
  918.         pStartV = graph.GetVertices()[1];
  919.     }
  920.  
  921.     //graph.DFS([](int const nid) { printf("%d\n", nid); });
  922.  
  923.     CGraph EulerGraph(graph);
  924.     EulerGraph.GetEdges().clear();
  925.     EulerGraph.GetVertices().clear();
  926.  
  927.     std::stack<CVertex *> st;
  928.     st.push(pStartV);
  929.  
  930.     auto _DelEdge = [](CVertex *_pVertex, CEdge *_pEdge)
  931.     {
  932.         for (DWORD i = 0; i < _pVertex->Edges.size(); i++)
  933.         {
  934.             CEdge *pEdge = _pVertex->Edges[i];
  935.  
  936.             if (pEdge == _pEdge)
  937.             {
  938.                 _pVertex->Edges.erase(_pVertex->Edges.begin() + i);
  939.  
  940.                 break;
  941.             }
  942.         }
  943.     };
  944.  
  945.     while (!st.empty())
  946.     {
  947.         // while if
  948.         while (!st.empty() && st.top()->Edges.size() > 0)
  949.         {
  950.             CVertex *pHead = st.top();
  951.  
  952.             CEdge *pEOut = pHead->Edges.back();
  953.             pEOut->bIsInGraph = false;
  954.  
  955.             if (graph.m_bIsOriented)
  956.             {
  957.                 st.push(pEOut->pV2);
  958.  
  959.                 _DelEdge(pEOut->pV2, pEOut);
  960.             }
  961.             else
  962.             {
  963.                 if (pHead == pEOut->pV1)
  964.                 {
  965.                     st.push(pEOut->pV2);
  966.  
  967.                     _DelEdge(pEOut->pV2, pEOut);
  968.                 }
  969.                 else
  970.                 {
  971.                     st.push(pEOut->pV1);
  972.  
  973.                     _DelEdge(pEOut->pV1, pEOut);
  974.                 }
  975.             }
  976.  
  977.             pHead->Edges.pop_back();
  978.         }
  979.  
  980.         // while if
  981.         while (!st.empty() && st.top()->Edges.size() == 0)
  982.         {
  983.             CVertex *pHead = st.top();
  984.  
  985.             EulerGraph.GetVertices().push_back(pHead);
  986.             st.pop();
  987.  
  988.             printf("%d\n", pHead->dwID);
  989.         }
  990.     }
  991.     /*
  992.     CVertex *pLast = *EulerGraph.GetVertices().begin();
  993.     for (CVertex *pV : EulerGraph.GetVertices())
  994.     {
  995.         if (pLast == pV)
  996.             continue;
  997.  
  998.         CEdge *pEdge = new CEdge;
  999.         pEdge->bIsInGraph = true;
  1000.         pEdge->pV1 = pLast;
  1001.         pEdge->pV2 = pV;
  1002.         pEdge->dwID = EulerGraph.GetEdges().size();
  1003.  
  1004.         pLast->Edges.push_back(pEdge);
  1005.         pV->Edges.push_back(pEdge);
  1006.  
  1007.         EulerGraph.GetEdges().push_back(pEdge);
  1008.  
  1009.         pLast = pV;
  1010.     }*/
  1011.  
  1012.     printf("\n\n\nEuler graph:\n\n");
  1013.  
  1014.     for (auto iEdge : EulerGraph.GetVertices())
  1015.     {
  1016.         printf("%d\n", iEdge->dwID);
  1017.     }
  1018.  
  1019.     /*
  1020.     for (auto iEdge : EulerGraph.GetEdges())
  1021.     {
  1022.         printf("%d %d\t \n", iEdge->pV1->dwID, iEdge->pV2->dwID);
  1023.     }*/
  1024. }
  1025. /*
  1026. void RunFleri()
  1027. {
  1028.     CGraph graph;
  1029.  
  1030.     E_ERROR hr;
  1031.  
  1032.     V_RET(graph.ParseFile("adj_mat.txt"));
  1033.  
  1034.     for (auto iVertex : graph.GetVertices())
  1035.     {
  1036.         iVertex->pMyData = new DWORD;
  1037.         *((DWORD *)iVertex->pMyData) = iVertex->dwID;
  1038.     }
  1039.  
  1040.     //graph.DFS([](int const nid) { printf("%d\n", nid); });
  1041.  
  1042.     CGraph EulerGraph(graph);
  1043.     EulerGraph.GetEdges().clear();
  1044.     //EulerGraph.GetVertices().clear();
  1045.  
  1046.     DWORD iEdge = 0;
  1047.  
  1048.     CVertex *pVCur = EulerGraph.GetVertices().at(rand() % EulerGraph.GetVertices().size());
  1049.  
  1050.  
  1051.     for (DWORD i = 0; i < graph.GetEdges().size(); i++)
  1052.     {
  1053.         CEdge *pBridge = nullptr;
  1054.  
  1055.         // по всем рёбрам
  1056.         // выбираем первое попавшееся ребро, не посещённое и не мост
  1057.  
  1058.         for (auto pEdge : pVCur->Edges)
  1059.         {
  1060.             // посещённое
  1061.             if (pEdge->bIsVisited)
  1062.                 continue;
  1063.  
  1064.             // мост
  1065.  
  1066.             pEdge->bIsVisited = true;
  1067.             pEdge->dwID = iEdge++;
  1068.  
  1069.             if (EulerGraph.m_bIsOriented)
  1070.             {
  1071.                 pVCur = pEdge->pV2;
  1072.             }
  1073.             else
  1074.             {
  1075.                 if (pVCur == pEdge->pV1)
  1076.                     pVCur = pEdge->pV2;
  1077.                 else
  1078.                     pVCur = pEdge->pV1;
  1079.             }
  1080.  
  1081.             DSUGet(iEdge->pV1->dwID, EulerGraph.GetVertices());
  1082.         }
  1083.  
  1084.        
  1085.         if (rand() & 1)
  1086.             *(DWORD *)V2->pMyData = *(DWORD *)V1->pMyData;
  1087.         else
  1088.             *(DWORD *)V1->pMyData = *(DWORD *)V2->pMyData;
  1089.     }
  1090.  
  1091.     printf("\n\n\nEuler graph:\n\n");
  1092.  
  1093.     for (auto iEdge : EulerGraph.GetVertices())
  1094.     {
  1095.         printf("%d\n", iEdge->dwID);
  1096.     }
  1097.  
  1098.    
  1099.     //for (auto iEdge : EulerGraph.GetEdges())
  1100.     //printf("%d %d\t \n", iEdge->pV1->dwID, iEdge->pV2->dwID);
  1101.    
  1102. }
  1103. */
  1104. int main()
  1105. {
  1106.     //std::string sMask = "a?*b*c";
  1107.     //std::string sText = "apbdsadasc";
  1108.  
  1109.     //printf("\"%s\" by mask \"%s\": %d\n", sText.c_str(), sMask.c_str(), iswm(sMask, sText));
  1110.  
  1111.     //RunKruskal();
  1112.     //RunPrima();
  1113.     //RunBoruvka();
  1114.  
  1115.     RunRid();
  1116.     //RunFleri();
  1117.  
  1118.     //CGraph graph;
  1119.  
  1120.     //E_ERROR hr;
  1121.  
  1122.     //V_RET(graph.ParseFile("adj_mat.txt"));
  1123.  
  1124.     _getch();
  1125.     return 0;
  1126. };
Advertisement
Add Comment
Please, Sign In to add comment