diff --git a/main/main.cpp b/main/main.cpp new file mode 100644 index 0000000..359b7cb --- /dev/null +++ b/main/main.cpp @@ -0,0 +1,387 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +template +class Graph { +public: + struct Edge { + Vertex from; + Vertex to; + Distance distance; + + Edge() : from(), to(), distance() {} + Edge(const Vertex& f, const Vertex& t, const Distance& d) + : from(f), to(t), distance(d) { + } + + bool operator==(const Edge& other) const { + return from == other.from && to == other.to && distance == other.distance; + } + }; + +private: + vector _vertices; + multimap _edges; + +public: + bool has_vertex(const Vertex& v) const { + return find(_vertices.begin(), _vertices.end(), v) != _vertices.end(); + } + + bool add_vertex(const Vertex& v) { + if (has_vertex(v)) { + return false; + } + _vertices.push_back(v); + return true; + } + + bool remove_vertex(const Vertex& v) { + auto it = find(_vertices.begin(), _vertices.end(), v); + if (it == _vertices.end()) { + return false; + } + _vertices.erase(it); + + auto range = _edges.equal_range(v); + _edges.erase(range.first, range.second); + + for (auto it = _edges.begin(); it != _edges.end(); ) { + if (it->second.to == v) { + it = _edges.erase(it); + } + else { + ++it; + } + } + return true; + } + + vector vertices() const { + return _vertices; + } + + void add_edge(const Vertex& from, const Vertex& to, const Distance& d) { + if (d < 0) { + throw invalid_argument("Edge distance cannot be negative"); + } + if (!has_vertex(from) || !has_vertex(to)) { + throw invalid_argument("One or both vertices don't exist"); + } + _edges.insert(make_pair(from, Edge(from, to, d))); + } + + void add_undirected_edge(const Vertex& v1, const Vertex& v2, const Distance& d) { + if (d < 0) { + throw invalid_argument("Edge distance cannot be negative"); + } + if (!has_vertex(v1) || !has_vertex(v2)) { + throw invalid_argument("One or both vertices don't exist"); + } + _edges.insert(make_pair(v1, Edge(v1, v2, d))); + _edges.insert(make_pair(v2, Edge(v2, v1, d))); + } + + bool remove_edge(const Vertex& from, const Vertex& to) { + bool removed = false; + for (auto it = _edges.begin(); it != _edges.end(); ) { + if (it->first == from && it->second.to == to) { + it = _edges.erase(it); + removed = true; + } + else { + ++it; + } + } + return removed; + } + + bool remove_edge(const Edge& e) { + auto range = _edges.equal_range(e.from); + for (auto it = range.first; it != range.second; ++it) { + if (it->second == e) { + _edges.erase(it); + return true; + } + } + return false; + } + + bool has_edge(const Vertex& from, const Vertex& to) const { + auto range = _edges.equal_range(from); + for (auto it = range.first; it != range.second; ++it) { + if (it->second.to == to) { + return true; + } + } + return false; + } + + bool has_edge(const Edge& e) const { + auto range = _edges.equal_range(e.from); + for (auto it = range.first; it != range.second; ++it) { + if (it->second == e) { + return true; + } + } + return false; + } + + vector edges(const Vertex& vertex) { + vector result; + auto range = _edges.equal_range(vertex); + for (auto it = range.first; it != range.second; ++it) { + result.push_back(it->second); + } + return result; + } + + size_t order() const { + return _vertices.size(); + } + + size_t degree(const Vertex& v) const { + return _edges.count(v); + } + + bool is_connected() const { + if (_vertices.empty()) return true; + + set visited; + stack stack; + stack.push(_vertices[0]); + visited.insert(_vertices[0]); + + while (!stack.empty()) { + Vertex current = stack.top(); + stack.pop(); + + auto range = _edges.equal_range(current); + for (auto it = range.first; it != range.second; ++it) { + if (visited.find(it->second.to) == visited.end()) { + visited.insert(it->second.to); + stack.push(it->second.to); + } + } + } + + if (visited.size() != _vertices.size()) { + return false; + } + + Graph transposed; + for (size_t i = 0; i < _vertices.size(); ++i) { + transposed.add_vertex(_vertices[i]); + } + for (auto it = _edges.begin(); it != _edges.end(); ++it) { + const Edge& edge = it->second; + transposed.add_edge(edge.to, edge.from, edge.distance); + } + + visited.clear(); + stack.push(_vertices[0]); + visited.insert(_vertices[0]); + + while (!stack.empty()) { + Vertex current = stack.top(); + stack.pop(); + + auto range = transposed._edges.equal_range(current); + for (auto it = range.first; it != range.second; ++it) { + if (visited.find(it->second.to) == visited.end()) { + visited.insert(it->second.to); + stack.push(it->second.to); + } + } + } + + return visited.size() == _vertices.size(); + } + + vector shortest_path(const Vertex& from, const Vertex& to) const { + priority_queue, + vector>, + greater>> pq; + + map distances; + map predecessors; + + for (const auto& v : _vertices) { + distances[v] = numeric_limits::max(); + } + distances[from] = Distance(); + pq.push(make_pair(distances[from], from)); + + while (!pq.empty()) { + Vertex u = pq.top().second; + Distance dist_u = pq.top().first; + pq.pop(); + + if (dist_u > distances[u]) { + continue; + } + + auto range = _edges.equal_range(u); + for (auto it = range.first; it != range.second; ++it) { + const Edge& edge = it->second; + Vertex v = edge.to; + Distance weight = edge.distance; + + if (distances[v] > distances[u] + weight) { + distances[v] = distances[u] + weight; + predecessors[v] = edge; + pq.push(make_pair(distances[v], v)); + } + } + } + + if (distances[to] == numeric_limits::max()) { + return {}; + } + + vector path; + Vertex current = to; + while (current != from) { + auto it = predecessors.find(current); + if (it == predecessors.end()) { + return {}; + } + path.push_back(it->second); + current = it->second.from; + } + + reverse(path.begin(), path.end()); + return path; + } + + vector walk(const Vertex& start_vertex) const { + vector result; + if (!has_vertex(start_vertex)) { + return result; + } + + set visited; + stack stack; + stack.push(start_vertex); + visited.insert(start_vertex); + + while (!stack.empty()) { + Vertex current = stack.top(); + stack.pop(); + result.push_back(current); + + auto range = _edges.equal_range(current); + for (auto it = range.first; it != range.second; ++it) { + if (visited.find(it->second.to) == visited.end()) { + visited.insert(it->second.to); + stack.push(it->second.to); + } + } + } + + return result; + } + + double average_edge_length(const Vertex& v) const { + auto range = _edges.equal_range(v); + size_t count = 0; + Distance sum = 0; + + for (auto it = range.first; it != range.second; ++it) { + sum += it->second.distance; + count++; + } + + for (auto it = _edges.begin(); it != _edges.end(); ++it) { + if (it->second.to == v) { + sum += it->second.distance; + count++; + } + } + + if (count == 0) return 0.0; + return static_cast(sum) / count; + } +}; + +template +Vertex find_most_remote_clinic(const Graph& graph) { + if (graph.vertices().empty()) { + throw runtime_error("Graph is empty"); + } + + Vertex result = graph.vertices()[0]; + double max_avg = graph.average_edge_length(result); + + for (const auto& vertex : graph.vertices()) { + double current_avg = graph.average_edge_length(vertex); + if (current_avg > max_avg) { + max_avg = current_avg; + result = vertex; + } + } + + return result; +} + +void analyze_togliatti_clinics() { + Graph tlt_graph; + + try { + tlt_graph.add_vertex("Травмпункт ГБ №2 — ул. Мира, 125"); + tlt_graph.add_vertex("Травмпункт ГБ №5 — ул. Юбилейная, 31"); + tlt_graph.add_vertex("Травмпункт Поликлиники №3 — ул. Матросова, 17"); + tlt_graph.add_vertex("МЦ XXI век — ул. Революционная, 10"); + tlt_graph.add_vertex("Клиника Эксперт — ул. 40 лет Победы, 48"); + + tlt_graph.add_undirected_edge("Травмпункт ГБ №2 — ул. Мира, 125", + "Травмпункт ГБ №5 — ул. Юбилейная, 31", 4.2); + tlt_graph.add_undirected_edge("Травмпункт ГБ №2 — ул. Мира, 125", + "Травмпункт Поликлиники №3 — ул. Матросова, 17", 3.8); + tlt_graph.add_undirected_edge("Травмпункт ГБ №5 — ул. Юбилейная, 31", + "Клиника Эксперт — ул. 40 лет Победы, 48", 2.5); + tlt_graph.add_undirected_edge("Травмпункт Поликлиники №3 — ул. Матросова, 17", + "МЦ XXI век — ул. Революционная, 10", 1.7); + tlt_graph.add_undirected_edge("МЦ XXI век — ул. Революционная, 10", + "Клиника Эксперт — ул. 40 лет Победы, 48", 3.1); + + if (!tlt_graph.is_connected()) { + cout << "Ошибка: граф травмпунктов несвязный! Некоторые пункты недостижимы.\n"; + return; + } + + string remoteClinic = find_most_remote_clinic(tlt_graph); + double avgDist = tlt_graph.average_edge_length(remoteClinic); + + cout << "Анализ травмпунктов Тольятти:\n"; + cout << "Самый удаленный травмпункт: " << remoteClinic << endl; + cout << "Среднее расстояние до соседей: " << avgDist << " км\n\n"; + cout << "Средние расстояния для всех травмпунктов:\n"; + for (const auto& clinic : tlt_graph.vertices()) { + cout << clinic << ": " << tlt_graph.average_edge_length(clinic) << " км\n"; + } + + } + catch (const invalid_argument& e) { + cerr << "Ошибка в данных: " << e.what() << endl; + } + catch (const runtime_error& e) { + cerr << "Ошибка выполнения: " << e.what() << endl; + } +} + +int main() { + setlocale(LC_ALL, "Russian"); + analyze_togliatti_clinics(); + return 0; +} \ No newline at end of file diff --git a/main/main.sln b/main/main.sln new file mode 100644 index 0000000..7772188 --- /dev/null +++ b/main/main.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.7.34031.279 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "main", "main.vcxproj", "{08174BBD-8B97-4AC1-B2AE-0946EEFBAB4F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {08174BBD-8B97-4AC1-B2AE-0946EEFBAB4F}.Debug|x64.ActiveCfg = Debug|x64 + {08174BBD-8B97-4AC1-B2AE-0946EEFBAB4F}.Debug|x64.Build.0 = Debug|x64 + {08174BBD-8B97-4AC1-B2AE-0946EEFBAB4F}.Debug|x86.ActiveCfg = Debug|Win32 + {08174BBD-8B97-4AC1-B2AE-0946EEFBAB4F}.Debug|x86.Build.0 = Debug|Win32 + {08174BBD-8B97-4AC1-B2AE-0946EEFBAB4F}.Release|x64.ActiveCfg = Release|x64 + {08174BBD-8B97-4AC1-B2AE-0946EEFBAB4F}.Release|x64.Build.0 = Release|x64 + {08174BBD-8B97-4AC1-B2AE-0946EEFBAB4F}.Release|x86.ActiveCfg = Release|Win32 + {08174BBD-8B97-4AC1-B2AE-0946EEFBAB4F}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {2329139C-05D7-468E-8B61-E8C58B67E983} + EndGlobalSection +EndGlobal diff --git a/main/main.vcxproj b/main/main.vcxproj new file mode 100644 index 0000000..083a47a --- /dev/null +++ b/main/main.vcxproj @@ -0,0 +1,135 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {08174bbd-8b97-4ac1-b2ae-0946eefbab4f} + main + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/main/main.vcxproj.filters b/main/main.vcxproj.filters new file mode 100644 index 0000000..3cb3d8b --- /dev/null +++ b/main/main.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Исходные файлы + + + \ No newline at end of file diff --git a/main/main.vcxproj.user b/main/main.vcxproj.user new file mode 100644 index 0000000..0f14913 --- /dev/null +++ b/main/main.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/main/x64/Debug/main.exe b/main/x64/Debug/main.exe new file mode 100644 index 0000000..7b5c2d7 Binary files /dev/null and b/main/x64/Debug/main.exe differ diff --git a/main/x64/Debug/main.exe.recipe b/main/x64/Debug/main.exe.recipe new file mode 100644 index 0000000..7ab9ccf --- /dev/null +++ b/main/x64/Debug/main.exe.recipe @@ -0,0 +1,11 @@ + + + + + C:\Users\SemenS\OneDrive\Рабочий стол\аисд\аисд лабы 2 семак\lab3\main\x64\Debug\main.exe + + + + + + \ No newline at end of file diff --git a/main/x64/Debug/main.ilk b/main/x64/Debug/main.ilk new file mode 100644 index 0000000..59d5f1f Binary files /dev/null and b/main/x64/Debug/main.ilk differ diff --git a/main/x64/Debug/main.log b/main/x64/Debug/main.log new file mode 100644 index 0000000..8897481 --- /dev/null +++ b/main/x64/Debug/main.log @@ -0,0 +1,2 @@ + main.cpp + main.vcxproj -> C:\Users\SemenS\OneDrive\Рабочий стол\аисд\аисд лабы 2 семак\lab3\main\x64\Debug\main.exe diff --git a/main/x64/Debug/main.obj b/main/x64/Debug/main.obj new file mode 100644 index 0000000..4b71670 Binary files /dev/null and b/main/x64/Debug/main.obj differ diff --git a/main/x64/Debug/main.pdb b/main/x64/Debug/main.pdb new file mode 100644 index 0000000..66a0373 Binary files /dev/null and b/main/x64/Debug/main.pdb differ diff --git a/main/x64/Debug/main.tlog/CL.command.1.tlog b/main/x64/Debug/main.tlog/CL.command.1.tlog new file mode 100644 index 0000000..e57a816 Binary files /dev/null and b/main/x64/Debug/main.tlog/CL.command.1.tlog differ diff --git a/main/x64/Debug/main.tlog/CL.read.1.tlog b/main/x64/Debug/main.tlog/CL.read.1.tlog new file mode 100644 index 0000000..bca5a04 Binary files /dev/null and b/main/x64/Debug/main.tlog/CL.read.1.tlog differ diff --git a/main/x64/Debug/main.tlog/CL.write.1.tlog b/main/x64/Debug/main.tlog/CL.write.1.tlog new file mode 100644 index 0000000..13d1137 Binary files /dev/null and b/main/x64/Debug/main.tlog/CL.write.1.tlog differ diff --git a/main/x64/Debug/main.tlog/Cl.items.tlog b/main/x64/Debug/main.tlog/Cl.items.tlog new file mode 100644 index 0000000..f83f2c3 --- /dev/null +++ b/main/x64/Debug/main.tlog/Cl.items.tlog @@ -0,0 +1 @@ +C:\Users\SemenS\OneDrive\Рабочий стол\аисд\аисд лабы 2 семак\lab3\main\main.cpp;C:\Users\SemenS\OneDrive\Рабочий стол\аисд\аисд лабы 2 семак\lab3\main\x64\Debug\main.obj diff --git a/main/x64/Debug/main.tlog/link.command.1.tlog b/main/x64/Debug/main.tlog/link.command.1.tlog new file mode 100644 index 0000000..6a2a17c Binary files /dev/null and b/main/x64/Debug/main.tlog/link.command.1.tlog differ diff --git a/main/x64/Debug/main.tlog/link.read.1.tlog b/main/x64/Debug/main.tlog/link.read.1.tlog new file mode 100644 index 0000000..95f13cb Binary files /dev/null and b/main/x64/Debug/main.tlog/link.read.1.tlog differ diff --git a/main/x64/Debug/main.tlog/link.write.1.tlog b/main/x64/Debug/main.tlog/link.write.1.tlog new file mode 100644 index 0000000..ad41c1f Binary files /dev/null and b/main/x64/Debug/main.tlog/link.write.1.tlog differ diff --git a/main/x64/Debug/main.tlog/main.lastbuildstate b/main/x64/Debug/main.tlog/main.lastbuildstate new file mode 100644 index 0000000..f31d1b1 --- /dev/null +++ b/main/x64/Debug/main.tlog/main.lastbuildstate @@ -0,0 +1,2 @@ +PlatformToolSet=v143:VCToolArchitecture=Native64Bit:VCToolsVersion=14.37.32822:TargetPlatformVersion=10.0.22621.0: +Debug|x64|C:\Users\SemenS\OneDrive\Рабочий стол\аисд\аисд лабы 2 семак\lab3\main\| diff --git a/main/x64/Debug/main.vcxproj.FileListAbsolute.txt b/main/x64/Debug/main.vcxproj.FileListAbsolute.txt new file mode 100644 index 0000000..42d6e2e --- /dev/null +++ b/main/x64/Debug/main.vcxproj.FileListAbsolute.txt @@ -0,0 +1 @@ +C:\Users\SemenS\OneDrive\Рабочий стол\аисд\аисд лабы 2 семак\lab3\main\x64\Debug\main.exe diff --git a/main/x64/Debug/vc143.idb b/main/x64/Debug/vc143.idb new file mode 100644 index 0000000..b380e60 Binary files /dev/null and b/main/x64/Debug/vc143.idb differ diff --git a/main/x64/Debug/vc143.pdb b/main/x64/Debug/vc143.pdb new file mode 100644 index 0000000..1624715 Binary files /dev/null and b/main/x64/Debug/vc143.pdb differ