From 8a137d5dea317fc5b08edb743b164871286a7f4c Mon Sep 17 00:00:00 2001 From: Liza-Bel Date: Mon, 4 Jun 2018 22:21:30 +0300 Subject: [PATCH 1/6] inital structure --- .../Lab2/build/lab2/Dijkstra/Dijkstra.vcxproj | 160 ++++++++++++++ .../lab2/Dijkstra/Dijkstra.vcxproj.filters | 22 ++ .../Lab2/build/lab2/Djikastra/Djikastra.sln | 67 ++++++ .../build/lab2/Graph_lib/Graph_lib.vcxproj | 163 ++++++++++++++ .../lab2/Graph_lib/Graph_lib.vcxproj.filters | 63 ++++++ .../Lab2/build/lab2/Kruskal/Kruskal.vcxproj | 160 ++++++++++++++ .../lab2/Kruskal/Kruskal.vcxproj.filters | 22 ++ .../Lab2/build/lab2/PySort/PySort.vcxproj | 160 ++++++++++++++ .../build/lab2/PySort/PySort.vcxproj.filters | 22 ++ BelyakovaEA/Lab2/include/Dijkstra.h | 13 ++ BelyakovaEA/Lab2/include/Graph.h | 47 +++++ BelyakovaEA/Lab2/include/Kruskal.h | 63 ++++++ BelyakovaEA/Lab2/include/PriorituQueue.h | 40 ++++ BelyakovaEA/Lab2/include/PySort.h | 41 ++++ BelyakovaEA/Lab2/include/SeparatedSet.h | 18 ++ BelyakovaEA/Lab2/include/dheap.h | 198 ++++++++++++++++++ BelyakovaEA/Lab2/include/edge.h | 47 +++++ BelyakovaEA/Lab2/sample/main.cpp | 92 ++++++++ BelyakovaEA/Lab2/sample/mainDjikstra.cpp | 48 +++++ BelyakovaEA/Lab2/sample/mainKruskal.cpp | 32 +++ BelyakovaEA/Lab2/sample/mainPySort.cpp | 48 +++++ BelyakovaEA/Lab2/src/Djikstra.cpp | 50 +++++ BelyakovaEA/Lab2/src/Graph.cpp | 113 ++++++++++ BelyakovaEA/Lab2/src/Kruskal.cpp | 1 + BelyakovaEA/Lab2/src/PriorituQueue.cpp | 1 + BelyakovaEA/Lab2/src/SeparatedSet.cpp | 48 +++++ 26 files changed, 1739 insertions(+) create mode 100644 BelyakovaEA/Lab2/build/lab2/Dijkstra/Dijkstra.vcxproj create mode 100644 BelyakovaEA/Lab2/build/lab2/Dijkstra/Dijkstra.vcxproj.filters create mode 100644 BelyakovaEA/Lab2/build/lab2/Djikastra/Djikastra.sln create mode 100644 BelyakovaEA/Lab2/build/lab2/Graph_lib/Graph_lib.vcxproj create mode 100644 BelyakovaEA/Lab2/build/lab2/Graph_lib/Graph_lib.vcxproj.filters create mode 100644 BelyakovaEA/Lab2/build/lab2/Kruskal/Kruskal.vcxproj create mode 100644 BelyakovaEA/Lab2/build/lab2/Kruskal/Kruskal.vcxproj.filters create mode 100644 BelyakovaEA/Lab2/build/lab2/PySort/PySort.vcxproj create mode 100644 BelyakovaEA/Lab2/build/lab2/PySort/PySort.vcxproj.filters create mode 100644 BelyakovaEA/Lab2/include/Dijkstra.h create mode 100644 BelyakovaEA/Lab2/include/Graph.h create mode 100644 BelyakovaEA/Lab2/include/Kruskal.h create mode 100644 BelyakovaEA/Lab2/include/PriorituQueue.h create mode 100644 BelyakovaEA/Lab2/include/PySort.h create mode 100644 BelyakovaEA/Lab2/include/SeparatedSet.h create mode 100644 BelyakovaEA/Lab2/include/dheap.h create mode 100644 BelyakovaEA/Lab2/include/edge.h create mode 100644 BelyakovaEA/Lab2/sample/main.cpp create mode 100644 BelyakovaEA/Lab2/sample/mainDjikstra.cpp create mode 100644 BelyakovaEA/Lab2/sample/mainKruskal.cpp create mode 100644 BelyakovaEA/Lab2/sample/mainPySort.cpp create mode 100644 BelyakovaEA/Lab2/src/Djikstra.cpp create mode 100644 BelyakovaEA/Lab2/src/Graph.cpp create mode 100644 BelyakovaEA/Lab2/src/Kruskal.cpp create mode 100644 BelyakovaEA/Lab2/src/PriorituQueue.cpp create mode 100644 BelyakovaEA/Lab2/src/SeparatedSet.cpp diff --git a/BelyakovaEA/Lab2/build/lab2/Dijkstra/Dijkstra.vcxproj b/BelyakovaEA/Lab2/build/lab2/Dijkstra/Dijkstra.vcxproj new file mode 100644 index 000000000..5e9c45a1b --- /dev/null +++ b/BelyakovaEA/Lab2/build/lab2/Dijkstra/Dijkstra.vcxproj @@ -0,0 +1,160 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {0A941875-030C-4C0F-98FF-FCDF8EA39AF6} + Win32Proj + Dijkstra + 8.1 + + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + ..\..\..\include;$(IncludePath) + + + true + + + false + ..\..\..\include;$(IncludePath) + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + Graph_lib.lib;%(AdditionalDependencies) + ..\Debug;%(AdditionalLibraryDirectories) + + + + + + + Level3 + Disabled + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + Graph_lib.lib;%(AdditionalDependencies) + ..\Release;%(AdditionalLibraryDirectories) + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/BelyakovaEA/Lab2/build/lab2/Dijkstra/Dijkstra.vcxproj.filters b/BelyakovaEA/Lab2/build/lab2/Dijkstra/Dijkstra.vcxproj.filters new file mode 100644 index 000000000..37c88ca72 --- /dev/null +++ b/BelyakovaEA/Lab2/build/lab2/Dijkstra/Dijkstra.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;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/BelyakovaEA/Lab2/build/lab2/Djikastra/Djikastra.sln b/BelyakovaEA/Lab2/build/lab2/Djikastra/Djikastra.sln new file mode 100644 index 000000000..c90e54296 --- /dev/null +++ b/BelyakovaEA/Lab2/build/lab2/Djikastra/Djikastra.sln @@ -0,0 +1,67 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Kruskal", "..\Kruskal\Kruskal.vcxproj", "{A79AF118-E17D-458F-B464-C9E646C93C8D}" + ProjectSection(ProjectDependencies) = postProject + {DACC956A-F0C4-4098-8304-530878DCEADE} = {DACC956A-F0C4-4098-8304-530878DCEADE} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PySort", "..\PySort\PySort.vcxproj", "{616C8F6D-0779-455D-B628-FC61B0F35C80}" + ProjectSection(ProjectDependencies) = postProject + {DACC956A-F0C4-4098-8304-530878DCEADE} = {DACC956A-F0C4-4098-8304-530878DCEADE} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Graph_lib", "..\Graph_lib\Graph_lib.vcxproj", "{DACC956A-F0C4-4098-8304-530878DCEADE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Dijkstra", "..\Dijkstra\Dijkstra.vcxproj", "{0A941875-030C-4C0F-98FF-FCDF8EA39AF6}" + ProjectSection(ProjectDependencies) = postProject + {DACC956A-F0C4-4098-8304-530878DCEADE} = {DACC956A-F0C4-4098-8304-530878DCEADE} + EndProjectSection +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 + {A79AF118-E17D-458F-B464-C9E646C93C8D}.Debug|x64.ActiveCfg = Debug|x64 + {A79AF118-E17D-458F-B464-C9E646C93C8D}.Debug|x64.Build.0 = Debug|x64 + {A79AF118-E17D-458F-B464-C9E646C93C8D}.Debug|x86.ActiveCfg = Debug|Win32 + {A79AF118-E17D-458F-B464-C9E646C93C8D}.Debug|x86.Build.0 = Debug|Win32 + {A79AF118-E17D-458F-B464-C9E646C93C8D}.Release|x64.ActiveCfg = Release|x64 + {A79AF118-E17D-458F-B464-C9E646C93C8D}.Release|x64.Build.0 = Release|x64 + {A79AF118-E17D-458F-B464-C9E646C93C8D}.Release|x86.ActiveCfg = Release|Win32 + {A79AF118-E17D-458F-B464-C9E646C93C8D}.Release|x86.Build.0 = Release|Win32 + {616C8F6D-0779-455D-B628-FC61B0F35C80}.Debug|x64.ActiveCfg = Debug|x64 + {616C8F6D-0779-455D-B628-FC61B0F35C80}.Debug|x64.Build.0 = Debug|x64 + {616C8F6D-0779-455D-B628-FC61B0F35C80}.Debug|x86.ActiveCfg = Debug|Win32 + {616C8F6D-0779-455D-B628-FC61B0F35C80}.Debug|x86.Build.0 = Debug|Win32 + {616C8F6D-0779-455D-B628-FC61B0F35C80}.Release|x64.ActiveCfg = Release|x64 + {616C8F6D-0779-455D-B628-FC61B0F35C80}.Release|x64.Build.0 = Release|x64 + {616C8F6D-0779-455D-B628-FC61B0F35C80}.Release|x86.ActiveCfg = Release|Win32 + {616C8F6D-0779-455D-B628-FC61B0F35C80}.Release|x86.Build.0 = Release|Win32 + {DACC956A-F0C4-4098-8304-530878DCEADE}.Debug|x64.ActiveCfg = Debug|x64 + {DACC956A-F0C4-4098-8304-530878DCEADE}.Debug|x64.Build.0 = Debug|x64 + {DACC956A-F0C4-4098-8304-530878DCEADE}.Debug|x86.ActiveCfg = Debug|Win32 + {DACC956A-F0C4-4098-8304-530878DCEADE}.Debug|x86.Build.0 = Debug|Win32 + {DACC956A-F0C4-4098-8304-530878DCEADE}.Release|x64.ActiveCfg = Release|x64 + {DACC956A-F0C4-4098-8304-530878DCEADE}.Release|x64.Build.0 = Release|x64 + {DACC956A-F0C4-4098-8304-530878DCEADE}.Release|x86.ActiveCfg = Release|Win32 + {DACC956A-F0C4-4098-8304-530878DCEADE}.Release|x86.Build.0 = Release|Win32 + {0A941875-030C-4C0F-98FF-FCDF8EA39AF6}.Debug|x64.ActiveCfg = Debug|x64 + {0A941875-030C-4C0F-98FF-FCDF8EA39AF6}.Debug|x64.Build.0 = Debug|x64 + {0A941875-030C-4C0F-98FF-FCDF8EA39AF6}.Debug|x86.ActiveCfg = Debug|Win32 + {0A941875-030C-4C0F-98FF-FCDF8EA39AF6}.Debug|x86.Build.0 = Debug|Win32 + {0A941875-030C-4C0F-98FF-FCDF8EA39AF6}.Release|x64.ActiveCfg = Release|x64 + {0A941875-030C-4C0F-98FF-FCDF8EA39AF6}.Release|x64.Build.0 = Release|x64 + {0A941875-030C-4C0F-98FF-FCDF8EA39AF6}.Release|x86.ActiveCfg = Release|Win32 + {0A941875-030C-4C0F-98FF-FCDF8EA39AF6}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/BelyakovaEA/Lab2/build/lab2/Graph_lib/Graph_lib.vcxproj b/BelyakovaEA/Lab2/build/lab2/Graph_lib/Graph_lib.vcxproj new file mode 100644 index 000000000..db599c8a1 --- /dev/null +++ b/BelyakovaEA/Lab2/build/lab2/Graph_lib/Graph_lib.vcxproj @@ -0,0 +1,163 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {DACC956A-F0C4-4098-8304-530878DCEADE} + Win32Proj + Graph_lib + 8.1 + + + + StaticLibrary + true + v140 + Unicode + + + StaticLibrary + false + v140 + true + Unicode + + + StaticLibrary + true + v140 + Unicode + + + StaticLibrary + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + ..\..\..\include;$(IncludePath) + + + ..\..\..\include;$(IncludePath) + + + + + + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + ..\..\..\include + + + Windows + + + + + + + Level3 + Disabled + _DEBUG;_LIB;%(PreprocessorDefinitions) + true + + + Windows + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + ..\..\..\include + + + Windows + true + true + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_LIB;%(PreprocessorDefinitions) + true + + + Windows + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/BelyakovaEA/Lab2/build/lab2/Graph_lib/Graph_lib.vcxproj.filters b/BelyakovaEA/Lab2/build/lab2/Graph_lib/Graph_lib.vcxproj.filters new file mode 100644 index 000000000..7da1fe814 --- /dev/null +++ b/BelyakovaEA/Lab2/build/lab2/Graph_lib/Graph_lib.vcxproj.filters @@ -0,0 +1,63 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;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/BelyakovaEA/Lab2/build/lab2/Kruskal/Kruskal.vcxproj b/BelyakovaEA/Lab2/build/lab2/Kruskal/Kruskal.vcxproj new file mode 100644 index 000000000..05931032a --- /dev/null +++ b/BelyakovaEA/Lab2/build/lab2/Kruskal/Kruskal.vcxproj @@ -0,0 +1,160 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {A79AF118-E17D-458F-B464-C9E646C93C8D} + Win32Proj + Kruskal + 8.1 + + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + ..\..\..\include;$(IncludePath) + + + true + + + false + ..\..\..\include;$(IncludePath) + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + Graph_lib.lib;%(AdditionalDependencies) + ..\Debug + + + + + + + Level3 + Disabled + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + Graph_lib.lib;%(AdditionalDependencies) + ..\Release + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/BelyakovaEA/Lab2/build/lab2/Kruskal/Kruskal.vcxproj.filters b/BelyakovaEA/Lab2/build/lab2/Kruskal/Kruskal.vcxproj.filters new file mode 100644 index 000000000..0ec3b67aa --- /dev/null +++ b/BelyakovaEA/Lab2/build/lab2/Kruskal/Kruskal.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;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/BelyakovaEA/Lab2/build/lab2/PySort/PySort.vcxproj b/BelyakovaEA/Lab2/build/lab2/PySort/PySort.vcxproj new file mode 100644 index 000000000..2601f8c87 --- /dev/null +++ b/BelyakovaEA/Lab2/build/lab2/PySort/PySort.vcxproj @@ -0,0 +1,160 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {616C8F6D-0779-455D-B628-FC61B0F35C80} + Win32Proj + PySort + 8.1 + + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + ..\..\..\include;$(IncludePath) + + + true + + + false + ..\..\..\include;$(IncludePath) + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + Graph_lib.lib;%(AdditionalDependencies) + ..\Debug;%(AdditionalLibraryDirectories) + + + + + + + Level3 + Disabled + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + Graph_lib.lib;%(AdditionalDependencies) + ..\Release;%(AdditionalLibraryDirectories) + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/BelyakovaEA/Lab2/build/lab2/PySort/PySort.vcxproj.filters b/BelyakovaEA/Lab2/build/lab2/PySort/PySort.vcxproj.filters new file mode 100644 index 000000000..33ac48f08 --- /dev/null +++ b/BelyakovaEA/Lab2/build/lab2/PySort/PySort.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;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/BelyakovaEA/Lab2/include/Dijkstra.h b/BelyakovaEA/Lab2/include/Dijkstra.h new file mode 100644 index 000000000..0eb8a20be --- /dev/null +++ b/BelyakovaEA/Lab2/include/Dijkstra.h @@ -0,0 +1,13 @@ +#ifndef DIJKSTRA_H +#define DIJKSTRA_H + +#include "edge.h" +#include "Graph.h" + +class Dijkstra { +public: + static VertexDist* DijkstraSearch(const Graph& graph); +}; + + +#endif diff --git a/BelyakovaEA/Lab2/include/Graph.h b/BelyakovaEA/Lab2/include/Graph.h new file mode 100644 index 000000000..e70f85c26 --- /dev/null +++ b/BelyakovaEA/Lab2/include/Graph.h @@ -0,0 +1,47 @@ +#ifndef GRAPH_H +#define GRAPH_H + +#include "edge.h" +#include +#include +#include +#include +#include + +struct Neighboor +{ + int vertex; + double edgeWeight; +}; + +typedef std::vector NeighboorVector; + +class Graph +{ +public: + Graph(int nVertex, int nEdges, bool doGenerateEdges = true); + ~Graph() {} + + int GetVertexNum() const; + int GetEdgesNum() const; + double Graph::GetSumOfWeights() const { return sumOfWeights; } + + Edge GetEdge(int idx) const { printf("n: %d, k: %d\n", edges[idx].Ne, edges[idx].Ke); return edges[idx]; } + + void AddEdge(int start, int finish, double weight); + + NeighboorVector GetNeigboors(int vertex) const; // + + void Print(); + +private: + double generateWeight(double minRangw = 0.01, double maxRange = 10.0); + void GenerateEdges(int nEdges); + + int nVertex; + std::vector edges; + + double sumOfWeights; +}; + +#endif \ No newline at end of file diff --git a/BelyakovaEA/Lab2/include/Kruskal.h b/BelyakovaEA/Lab2/include/Kruskal.h new file mode 100644 index 000000000..e96dc4065 --- /dev/null +++ b/BelyakovaEA/Lab2/include/Kruskal.h @@ -0,0 +1,63 @@ +#ifndef KRUSKAL_H +#define KRUSKAL_H + +#include "dheap.h" +#include "Graph.h" +#include "SeparatedSet.h" +#include "PriorituQueue.h" + +template +class Algorithms { +public: + static Graph* Kruskal(const Graph& graph, PriorityQueue* queue); //? +}; + +template +Graph* Algorithms::Kruskal(const Graph& graph, PriorityQueue* queue) +{ + int n = graph.GetVertexNum(); + int m = graph.GetEdgesNum(); + Graph *tree = new Graph(n, m, false); + + SeparatedSet *set = new SeparatedSet(n); + /*for (int i = 0; i < n; ++i) + { + set->makesets(i); + }*/ + + for (int i = 0; i < m; ++i) + { + queue->Push(T(graph.GetEdge(i))); + } + + int treeEdgeSize = 0; + T tmp; + + while ((treeEdgeSize < n - 1) && (!queue->isEmpty())) + { + tmp = queue->Pop(); + + int u = tmp.vertex; + int v = tmp.upVertex; + double weight = tmp.dist; + + int An = set->findsets(u); + int Ak = set->findsets(v); + + if (An != Ak) + { + set->unionsets(An, Ak); + printf("After union\n"); + tree->AddEdge(u, v, weight); + printf("After add\n"); + ++treeEdgeSize; + } + } + + //tree->Print(); + return tree; +} + +template class Algorithms; + +#endif diff --git a/BelyakovaEA/Lab2/include/PriorituQueue.h b/BelyakovaEA/Lab2/include/PriorituQueue.h new file mode 100644 index 000000000..13960b168 --- /dev/null +++ b/BelyakovaEA/Lab2/include/PriorituQueue.h @@ -0,0 +1,40 @@ +#ifndef PRIORITYQUEUE_H +#define PRIORITYQUEUE_H + +#include "dheap.h" + +template class PriorityQueue +{ +public: + virtual void Push(T& t) = 0; + virtual T Pop() = 0; + virtual bool isEmpty() const = 0; +}; + +template class PriorityQueueDHeap : public PriorityQueue +{ +public: + PriorityQueueDHeap(T* keys, int d, int n) + { + dheap = new DHeap(keys, d, n); + } + + virtual void Push(T& t) { dheap->insert(t); } + virtual T Pop() { return dheap->getmin(); } + virtual bool isEmpty() const { return dheap->isEmpty(); } + + + int GetSize() { return dheap->GetSize(); } + T& GetElement(int idx) { return dheap->GetElement(idx); } + void RepairQueue() { dheap->hilling(); } + void SetSize(int new_size) { dheap->SetSize(new_size); } + + virtual ~PriorityQueueDHeap() { delete dheap; } + +private: + DHeap* dheap; +}; + +template class PriorityQueueDHeap; +template class PriorityQueueDHeap; +#endif \ No newline at end of file diff --git a/BelyakovaEA/Lab2/include/PySort.h b/BelyakovaEA/Lab2/include/PySort.h new file mode 100644 index 000000000..9c915cf26 --- /dev/null +++ b/BelyakovaEA/Lab2/include/PySort.h @@ -0,0 +1,41 @@ +#ifndef PYR_SORT_H +#define PYR_SORT_H + +#include "dheap.h" + +/* +template void PyrSort(DHeap* heap) +{ +heap->hilling(); +int size = heap->GetSize(); +while (size > 0) +{ +heap->transpose(0, size - 1); +heap->remove(size - 1); +size--; +heap->sinking(0); +//size--; +} +}*/ + +template void PyrSort(DHeap* heap) +{ + heap->hilling(); + int cur_size = heap->GetSize(); + int old_size = cur_size; + while (cur_size > 0) + { + heap->transpose(0, cur_size - 1); + cur_size--; + heap->SetSize(cur_size); + heap->sinking(0); + } + + heap->SetSize(old_size); +} + +template void PyrSort(DHeap*); + +#endif + + diff --git a/BelyakovaEA/Lab2/include/SeparatedSet.h b/BelyakovaEA/Lab2/include/SeparatedSet.h new file mode 100644 index 000000000..744df285f --- /dev/null +++ b/BelyakovaEA/Lab2/include/SeparatedSet.h @@ -0,0 +1,18 @@ +#ifndef SEPARATEDSET +#define SEPARATEDSET + +class SeparatedSet +{ +public: + SeparatedSet(int size); + ~SeparatedSet() { delete[] harVec; } + + void makesets(int idx); + int findsets(int idx); + void unionsets(int x, int y); + +private: + int* harVec; + int size; +}; +#endif diff --git a/BelyakovaEA/Lab2/include/dheap.h b/BelyakovaEA/Lab2/include/dheap.h new file mode 100644 index 000000000..5e27c41d2 --- /dev/null +++ b/BelyakovaEA/Lab2/include/dheap.h @@ -0,0 +1,198 @@ +#ifndef DHEAP_H +#define DHEAP_H + +#include "edge.h" +#include "Dijkstra.h" + +/*template class PriorityQueue +{ +public: +virtual void Push(T& t) = 0; +virtual T Pop() = 0; +virtual bool isEmpty() const = 0; +};*/ + +template class DHeap +{ +private: + int d; + int n; // + T* keys; // + int min(int a, int b); + +public: + DHeap(T* keys, int d, int n); + DHeap(const DHeap &H); // + ~DHeap(); // + + virtual bool isEmpty() const { return n == 0; } + + void transpose(int i, int j); + void surfacing(int i); + void sinking(int i); // + void hilling(); // + void remove(int i); + void insert(T k); + int minchild(int i); + + T getmin(); + + int GetSize() { return n; } + void SetSize(int new_size) { n = new_size; } + T& GetElement(int idx) { return keys[idx]; } +}; + +template +DHeap ::DHeap(T* keys, int d, int n) +{ + this->keys = keys; + this->d = d; + this->n = n; +} + +template +DHeap::DHeap(const DHeap&H) +{ + d = H.d; + n = H.n; + keys = new T[n]; + for (int i = 0; i < n; i++) + { + keys[i] = H.keys[i]; + } +} + +template +DHeap::~DHeap() { + //Do not delete keys as we do not own it; +} + +template +int DHeap::min(int a, int b) +{ + if (a <= b) return a; + else return b; +} + +template +void DHeap ::transpose(int i, int j) { + T tmp = keys[i]; + keys[i] = keys[j]; + keys[j] = tmp; +} + +template +void DHeap::surfacing(int i) { + int p = (i - 1) / d; + while (p > 0) { //p or i + //p = (i - 1) / d; + if (keys[p] > keys[i]) + { + transpose(p, i); + i = p; + p = (i - 1) / d; + } + + else + { + break; + } + } +} + + +template +void DHeap::sinking(int i) { + int c = minchild(i); + while (c != -1 && keys[c] < keys[i]) { + transpose(c, i); + i = c; + c = minchild(i); + } +} + +template +int DHeap::minchild(int i) { + if (i * d + 1 > n - 1) return -1; + + int minidx = i * d + 1; + int i1 = i * d + 1; + int i2 = min(i * d + d, n - 1); + T minkey = keys[i1]; + for (int i = i1; i <= i2; i++) { + if (keys[minidx] > keys[i]) { + minidx = i; + minkey = keys[i]; + } + } + return minidx; +} + +template +T DHeap ::getmin() { + + T tmp = keys[0]; + transpose(0, n - 1); + n--; + sinking(0); + return tmp; +} + +template +void DHeap::hilling() { + for (int i = n - 1; i >= 0; i--) + sinking(i); +} + +template +void DHeap::remove(int i) { + if (i == n - 1) + { + n--; + return; + } + + keys[i] = keys[n - 1]; + n--; + sinking(i); +} + +template +void DHeap::insert(T k) { + keys[n] = k; + surfacing(n); + ++n; +} + + +/*template class PriorityQueueDHeap : public PriorityQueue +{ +public: +PriorityQueueDHeap(T* keys, int d, int n) +{ +dheap = new DHeap(keys, d, n); +} + +virtual void Push(T& t) { dheap->insert(t); } +virtual T Pop() { return dheap->getmin(); } +virtual bool isEmpty() const { return dheap->isEmpty(); } + + +int GetSize() { return dheap->GetSize(); } +T& GetElement(int idx) { return dheap->GetElement(idx); } +void RepairQueue() { dheap->hilling(); } +void SetSize(int new_size) { dheap->SetSize(new_size); } + +virtual ~PriorityQueueDHeap() { delete dheap; } + +private: +DHeap* dheap; +};*/ + +template class DHeap; +template class DHeap; + +//template class PriorityQueueDHeap; +//template class PriorityQueueDHeap; + +#endif \ No newline at end of file diff --git a/BelyakovaEA/Lab2/include/edge.h b/BelyakovaEA/Lab2/include/edge.h new file mode 100644 index 000000000..21995341c --- /dev/null +++ b/BelyakovaEA/Lab2/include/edge.h @@ -0,0 +1,47 @@ +#ifndef EDGE_H +#define EDGE_H + +class Edge { +public: + int Ne; // + int Ke; // + double W; // + + Edge(int N, int K, double _W) + { + Ne = N; + Ke = K; + W = _W; + } +}; + + +class VertexDist +{ +public: + VertexDist() : vertex(0), dist(0.0), upVertex(0) {} + VertexDist(const Edge& edge) : vertex(edge.Ne), upVertex(edge.Ke), dist(edge.W) {} + + + int vertex; + + double dist; + int upVertex; + + bool operator<(const VertexDist& vd) + { + return dist < vd.dist; + } + + bool operator>(const VertexDist& vd) + { + return dist > vd.dist; + } + + bool operator==(const VertexDist& vd) + { + return dist == vd.dist; + } +}; + +#endif diff --git a/BelyakovaEA/Lab2/sample/main.cpp b/BelyakovaEA/Lab2/sample/main.cpp new file mode 100644 index 000000000..7fb64d3b1 --- /dev/null +++ b/BelyakovaEA/Lab2/sample/main.cpp @@ -0,0 +1,92 @@ +#include "dheap.h" +#include "PyrSort.h" +#include "Graph.h" +#include "Dijkstra.h" +#include "Kruskal.h" + +#include + +const int SIZE = 10; + + +int main() +{ + //TODO: arnost + int d = 4; + //TODO: vertex num + int nVertex = 4; + + //TODO: nEdges + int nEdges = 5; + + if (nEdges <= 0 || nVertex <= 0) + { + printf("ERROR: Number of edges and verteces must be positive!\n"); + return 1; + } + + //printf("Sort\n"); + int *arr = new int[SIZE]; + + for (int i = 0; i < SIZE; ++i) + { + arr[i] = i; + } + + for (int i = 0; i < SIZE; ++i) + { + printf("%d; ", arr[i]); + } + printf("\n"); + + DHeap *heap = new DHeap(arr, d, SIZE); + printf("Sort\n"); + PyrSort(heap); + + for (int i = 0; i < SIZE; ++i) + { + printf("%d; ", arr[i]); + } + + printf("\n"); + + delete heap; + delete[] arr; + // + + Graph graph(nVertex, nEdges); + + printf("Dijkstra\n"); + VertexDist *result = Dijkstra::DijkstraSearch(graph); + + printf("Result:\n"); + for (int i = 0; i < graph.GetVertexNum(); ++i) + { + printf("Vertex: %d, up: %d, ", result[i].vertex, result[i].upVertex); + + if (result[i].dist >= graph.GetSumOfWeights()) + { + printf("UNREACHABLE\n"); + } + + else + { + printf("dist: %f\n", result[i].dist); + } + } + + delete[] result; + + printf("Kruskal\n"); + VertexDist* dheapValues = new VertexDist[graph.GetVertexNum()]; + PriorityQueueDHeap* vdHeap = new PriorityQueueDHeap(dheapValues, d, 0); + Graph* tree = Algorithms::Kruskal(graph, vdHeap); + + printf("Result:\n"); + tree->Print(); + // delete tree; + + int c; + getchar(); + return 0; +} \ No newline at end of file diff --git a/BelyakovaEA/Lab2/sample/mainDjikstra.cpp b/BelyakovaEA/Lab2/sample/mainDjikstra.cpp new file mode 100644 index 000000000..2a7b89961 --- /dev/null +++ b/BelyakovaEA/Lab2/sample/mainDjikstra.cpp @@ -0,0 +1,48 @@ +#include "dheap.h" +#include "Graph.h" +#include "Dijkstra.h" + +#include + +const int SIZE = 10; + + +int main() +{ + int d = 4; + + int nVertex = 4; + + int nEdges = 5; + + if (nEdges <= 0 || nVertex <= 0) + { + printf("ERROR: Number of edges and verteces must be positive!\n"); + return 1; + } + + Graph graph(nVertex, nEdges); + + printf("Dijkstra\n"); + VertexDist *result = Dijkstra::DijkstraSearch(graph); + + printf("Result:\n"); + for (int i = 0; i < graph.GetVertexNum(); ++i) + { + printf("Vertex: %d, up: %d, ", result[i].vertex, result[i].upVertex); + + if (result[i].dist >= graph.GetSumOfWeights()) + { + printf("UNREACHABLE\n"); + } + + else + { + printf("dist: %f\n", result[i].dist); + } + } + + delete[] result; + + return 0; +} \ No newline at end of file diff --git a/BelyakovaEA/Lab2/sample/mainKruskal.cpp b/BelyakovaEA/Lab2/sample/mainKruskal.cpp new file mode 100644 index 000000000..343e411e3 --- /dev/null +++ b/BelyakovaEA/Lab2/sample/mainKruskal.cpp @@ -0,0 +1,32 @@ +#include "Kruskal.h" +#include +#include "PriorituQueue.h" +#include "Graph.h" +#include "edge.h" +#include "dheap.h" + +int main() { + printf("Kruskal\n"); + + int d = 4; + int nVertex = 4; + int nEdges = 5; + if (nEdges <= 0 || nVertex <= 0) + { + printf("ERROR: Number of edges and verteces must be positive!\n"); + return 1; + } + + Graph graph(nVertex, nEdges); + VertexDist* dheapValues = new VertexDist[graph.GetVertexNum()]; + PriorityQueueDHeap* vdHeap = new PriorityQueueDHeap(dheapValues, d, 0); + Graph* tree = Algorithms::Kruskal(graph, vdHeap); + + printf("Result:\n"); + tree->Print(); + // delete tree; + + int c; + getchar(); + return 0; +} \ No newline at end of file diff --git a/BelyakovaEA/Lab2/sample/mainPySort.cpp b/BelyakovaEA/Lab2/sample/mainPySort.cpp new file mode 100644 index 000000000..699587850 --- /dev/null +++ b/BelyakovaEA/Lab2/sample/mainPySort.cpp @@ -0,0 +1,48 @@ +#include "dheap.h" +#include "PySort.h" +#include + +const int SIZE = 10; + +int main() { + + + int d = 4; + int nVertex = 4; + int nEdges = 5; + + if (nEdges <= 0 || nVertex <= 0) + { + printf("ERROR: Number of edges and verteces must be positive!\n"); + return 1; + } + + //printf("Sort\n"); + int *arr = new int[SIZE]; + + for (int i = 0; i < SIZE; ++i) + { + arr[i] = i; + } + + for (int i = 0; i < SIZE; ++i) + { + printf("%d; ", arr[i]); + } + printf("\n"); + + DHeap *heap = new DHeap(arr, d, SIZE); + printf("Sort\n"); + PyrSort(heap); + + for (int i = 0; i < SIZE; ++i) + { + printf("%d; ", arr[i]); + } + + printf("\n"); + + delete heap; + delete[] arr; + return 0; +} \ No newline at end of file diff --git a/BelyakovaEA/Lab2/src/Djikstra.cpp b/BelyakovaEA/Lab2/src/Djikstra.cpp new file mode 100644 index 000000000..c4d5ea27b --- /dev/null +++ b/BelyakovaEA/Lab2/src/Djikstra.cpp @@ -0,0 +1,50 @@ +#include "Dijkstra.h" +#include "dheap.h" +#include "PriorituQueue.h" + +VertexDist* Dijkstra::DijkstraSearch(const Graph& graph /*,TODO: arnost*/) +{ + VertexDist *result = new VertexDist[graph.GetVertexNum()]; + + //Fill values for root + result[0].vertex = 0; + result[0].dist = 0.0; + result[0].upVertex = 0; + + //Fill values for other verteces + //Infinity == (Sum of all weights + 1) + for (int i = 1; i < graph.GetVertexNum(); ++i) + { + result[i].vertex = i; + result[i].dist = graph.GetSumOfWeights(); + result[i].upVertex = i; + } + + PriorityQueueDHeap dheap(result, 4 , graph.GetVertexNum()); + + while (!dheap.isEmpty()) + { + VertexDist vd = dheap.Pop(); + NeighboorVector neighboors = graph.GetNeigboors(vd.vertex); + + for (int i = 0; i < neighboors.size(); ++i) //cocedi + { + for (int j = 0; j < dheap.GetSize(); ++j) //cocedi ostavshiesya v kuche + { + if (dheap.GetElement(j).vertex == neighboors[i].vertex) + { + if (dheap.GetElement(j).dist > vd.dist + neighboors[i].edgeWeight) + { + dheap.GetElement(j).dist = vd.dist + neighboors[i].edgeWeight; + dheap.GetElement(j).upVertex = vd.vertex; + } + } + } + } + + dheap.RepairQueue(); + } + + dheap.SetSize(graph.GetVertexNum()); + return result; +} \ No newline at end of file diff --git a/BelyakovaEA/Lab2/src/Graph.cpp b/BelyakovaEA/Lab2/src/Graph.cpp new file mode 100644 index 000000000..62f7aa959 --- /dev/null +++ b/BelyakovaEA/Lab2/src/Graph.cpp @@ -0,0 +1,113 @@ +#include "Graph.h" +#include +using namespace std; + +Graph::Graph(int nVertex, int nEdges, bool doGenerateEdges) +{ + this->nVertex = nVertex; + this->sumOfWeights = 1.0; + edges.reserve(nEdges); + + if (doGenerateEdges) + { + GenerateEdges(nEdges); + } +} + + +int Graph::GetVertexNum() const { return nVertex; } +int Graph::GetEdgesNum() const { return edges.size(); } + + +void Graph::AddEdge(int start, int finish, double weight) +{ + sumOfWeights += weight; + printf("AddEdge\n"); + edges.push_back(Edge(start, finish, weight)); +} + +double Graph::generateWeight(double minRange, double maxRange) +{ + double d = minRange; + double c = (double)(maxRange - minRange) / RAND_MAX; + double result = c * rand() + d; + return result; +} + +void Graph::Print() +{ + printf("Graph:\n"); + for (int i = 0; i < edges.size(); ++i) + { + printf("Edge %d: %d -> %d with %f\n", i, edges[i].Ne, edges[i].Ke, edges[i].W); + } +} + +NeighboorVector Graph::GetNeigboors(int vertex) const +{ + NeighboorVector result; + for (int i = 0; i < edges.size(); ++i) + { + if (edges[i].Ke == vertex || edges[i].Ne == vertex) + { + Neighboor nv; + nv.edgeWeight = edges[i].W; + + if (edges[i].Ke == vertex) + { + nv.vertex = edges[i].Ne; + } + + else + { + nv.vertex = edges[i].Ke; + } + + result.push_back(nv); + } + } + + return result; +} + +void Graph::GenerateEdges(int nEdges) { + int currentEdgesNum = 0; + + while (edges.size() < nEdges) + { + bool fail = false; + int n = rand() % nVertex; + int k = rand() % nVertex; + + //The same vertex - try again + if (n == k) + { + continue; + } + + //This edge already exists + for (int i = 0; i < edges.size(); ++i) + { + if ((edges[i].Ke == n) && (edges[i].Ne == k) || + (edges[i].Ne == n) && (edges[i].Ke == k)) + { + fail = true; + break; + } + } + + if (fail) + { + continue; + } + + //This is a new edge + double W = generateWeight(); + sumOfWeights += W; + edges.push_back(Edge(n, k, W)); + } + + //print graph + Print(); + printf("\n\n"); +} \ No newline at end of file diff --git a/BelyakovaEA/Lab2/src/Kruskal.cpp b/BelyakovaEA/Lab2/src/Kruskal.cpp new file mode 100644 index 000000000..64be34e28 --- /dev/null +++ b/BelyakovaEA/Lab2/src/Kruskal.cpp @@ -0,0 +1 @@ +#include "Kruskal.h" \ No newline at end of file diff --git a/BelyakovaEA/Lab2/src/PriorituQueue.cpp b/BelyakovaEA/Lab2/src/PriorituQueue.cpp new file mode 100644 index 000000000..505aa0100 --- /dev/null +++ b/BelyakovaEA/Lab2/src/PriorituQueue.cpp @@ -0,0 +1 @@ +#include "PriorituQueue.h" \ No newline at end of file diff --git a/BelyakovaEA/Lab2/src/SeparatedSet.cpp b/BelyakovaEA/Lab2/src/SeparatedSet.cpp new file mode 100644 index 000000000..332413191 --- /dev/null +++ b/BelyakovaEA/Lab2/src/SeparatedSet.cpp @@ -0,0 +1,48 @@ +#include "SeparatedSet.h" + +#include + +SeparatedSet::SeparatedSet(int _size) +{ + this->size = _size; + harVec = new int[size]; + + for (int i = 0; i < size; ++i) + { + harVec[i] = i; + } +} + + +void SeparatedSet::makesets(int idx) +{ + printf("makeset %d\n", idx); + if ((idx > size - 1) || (idx < 0)) + throw ("out of range"); + + harVec[idx] = idx; +} + +int SeparatedSet::findsets(int idx) +{ + printf("findset %d\n", idx); + if ((idx > size - 1) || (idx < 0)) + throw ("out of range"); + + return harVec[idx]; +} + +void SeparatedSet::unionsets(int x, int y) +{ + printf("x %d y %d\n", x, y); + if ((x > size - 1) || (x < 0) || (y > size - 1) || (y < 0)) + throw ("out of range"); + + for (int i = 0; i < size; ++i) + { + if (harVec[i] == y) + { + harVec[i] = x; + } + } +} \ No newline at end of file From 14dc9cc316625460281186daa380e767165da6e3 Mon Sep 17 00:00:00 2001 From: Liza-Bel Date: Mon, 4 Jun 2018 22:37:56 +0300 Subject: [PATCH 2/6] inital structure --- BelyakovaEA/Lab2/sample/main.cpp | 92 -------------------------------- 1 file changed, 92 deletions(-) delete mode 100644 BelyakovaEA/Lab2/sample/main.cpp diff --git a/BelyakovaEA/Lab2/sample/main.cpp b/BelyakovaEA/Lab2/sample/main.cpp deleted file mode 100644 index 7fb64d3b1..000000000 --- a/BelyakovaEA/Lab2/sample/main.cpp +++ /dev/null @@ -1,92 +0,0 @@ -#include "dheap.h" -#include "PyrSort.h" -#include "Graph.h" -#include "Dijkstra.h" -#include "Kruskal.h" - -#include - -const int SIZE = 10; - - -int main() -{ - //TODO: arnost - int d = 4; - //TODO: vertex num - int nVertex = 4; - - //TODO: nEdges - int nEdges = 5; - - if (nEdges <= 0 || nVertex <= 0) - { - printf("ERROR: Number of edges and verteces must be positive!\n"); - return 1; - } - - //printf("Sort\n"); - int *arr = new int[SIZE]; - - for (int i = 0; i < SIZE; ++i) - { - arr[i] = i; - } - - for (int i = 0; i < SIZE; ++i) - { - printf("%d; ", arr[i]); - } - printf("\n"); - - DHeap *heap = new DHeap(arr, d, SIZE); - printf("Sort\n"); - PyrSort(heap); - - for (int i = 0; i < SIZE; ++i) - { - printf("%d; ", arr[i]); - } - - printf("\n"); - - delete heap; - delete[] arr; - // - - Graph graph(nVertex, nEdges); - - printf("Dijkstra\n"); - VertexDist *result = Dijkstra::DijkstraSearch(graph); - - printf("Result:\n"); - for (int i = 0; i < graph.GetVertexNum(); ++i) - { - printf("Vertex: %d, up: %d, ", result[i].vertex, result[i].upVertex); - - if (result[i].dist >= graph.GetSumOfWeights()) - { - printf("UNREACHABLE\n"); - } - - else - { - printf("dist: %f\n", result[i].dist); - } - } - - delete[] result; - - printf("Kruskal\n"); - VertexDist* dheapValues = new VertexDist[graph.GetVertexNum()]; - PriorityQueueDHeap* vdHeap = new PriorityQueueDHeap(dheapValues, d, 0); - Graph* tree = Algorithms::Kruskal(graph, vdHeap); - - printf("Result:\n"); - tree->Print(); - // delete tree; - - int c; - getchar(); - return 0; -} \ No newline at end of file From 7cca1abad5a23fde450e7018b33d31aa95903093 Mon Sep 17 00:00:00 2001 From: Liza-Bel Date: Sun, 2 Sep 2018 13:53:39 +0300 Subject: [PATCH 3/6] delete --- BelyakovaEA/Lab2/include/Dijkstra.h | 13 -- BelyakovaEA/Lab2/include/Graph.h | 47 ------ BelyakovaEA/Lab2/include/Kruskal.h | 63 -------- BelyakovaEA/Lab2/include/PriorituQueue.h | 40 ----- BelyakovaEA/Lab2/include/PySort.h | 41 ----- BelyakovaEA/Lab2/include/SeparatedSet.h | 18 --- BelyakovaEA/Lab2/include/dheap.h | 198 ----------------------- BelyakovaEA/Lab2/include/edge.h | 47 ------ BelyakovaEA/Lab2/sample/mainDjikstra.cpp | 48 ------ BelyakovaEA/Lab2/sample/mainKruskal.cpp | 32 ---- BelyakovaEA/Lab2/sample/mainPySort.cpp | 48 ------ BelyakovaEA/Lab2/src/Djikstra.cpp | 50 ------ BelyakovaEA/Lab2/src/Graph.cpp | 113 ------------- BelyakovaEA/Lab2/src/Kruskal.cpp | 1 - BelyakovaEA/Lab2/src/PriorituQueue.cpp | 1 - BelyakovaEA/Lab2/src/SeparatedSet.cpp | 48 ------ 16 files changed, 808 deletions(-) delete mode 100644 BelyakovaEA/Lab2/include/Dijkstra.h delete mode 100644 BelyakovaEA/Lab2/include/Graph.h delete mode 100644 BelyakovaEA/Lab2/include/Kruskal.h delete mode 100644 BelyakovaEA/Lab2/include/PriorituQueue.h delete mode 100644 BelyakovaEA/Lab2/include/PySort.h delete mode 100644 BelyakovaEA/Lab2/include/SeparatedSet.h delete mode 100644 BelyakovaEA/Lab2/include/dheap.h delete mode 100644 BelyakovaEA/Lab2/include/edge.h delete mode 100644 BelyakovaEA/Lab2/sample/mainDjikstra.cpp delete mode 100644 BelyakovaEA/Lab2/sample/mainKruskal.cpp delete mode 100644 BelyakovaEA/Lab2/sample/mainPySort.cpp delete mode 100644 BelyakovaEA/Lab2/src/Djikstra.cpp delete mode 100644 BelyakovaEA/Lab2/src/Graph.cpp delete mode 100644 BelyakovaEA/Lab2/src/Kruskal.cpp delete mode 100644 BelyakovaEA/Lab2/src/PriorituQueue.cpp delete mode 100644 BelyakovaEA/Lab2/src/SeparatedSet.cpp diff --git a/BelyakovaEA/Lab2/include/Dijkstra.h b/BelyakovaEA/Lab2/include/Dijkstra.h deleted file mode 100644 index 0eb8a20be..000000000 --- a/BelyakovaEA/Lab2/include/Dijkstra.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef DIJKSTRA_H -#define DIJKSTRA_H - -#include "edge.h" -#include "Graph.h" - -class Dijkstra { -public: - static VertexDist* DijkstraSearch(const Graph& graph); -}; - - -#endif diff --git a/BelyakovaEA/Lab2/include/Graph.h b/BelyakovaEA/Lab2/include/Graph.h deleted file mode 100644 index e70f85c26..000000000 --- a/BelyakovaEA/Lab2/include/Graph.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef GRAPH_H -#define GRAPH_H - -#include "edge.h" -#include -#include -#include -#include -#include - -struct Neighboor -{ - int vertex; - double edgeWeight; -}; - -typedef std::vector NeighboorVector; - -class Graph -{ -public: - Graph(int nVertex, int nEdges, bool doGenerateEdges = true); - ~Graph() {} - - int GetVertexNum() const; - int GetEdgesNum() const; - double Graph::GetSumOfWeights() const { return sumOfWeights; } - - Edge GetEdge(int idx) const { printf("n: %d, k: %d\n", edges[idx].Ne, edges[idx].Ke); return edges[idx]; } - - void AddEdge(int start, int finish, double weight); - - NeighboorVector GetNeigboors(int vertex) const; // - - void Print(); - -private: - double generateWeight(double minRangw = 0.01, double maxRange = 10.0); - void GenerateEdges(int nEdges); - - int nVertex; - std::vector edges; - - double sumOfWeights; -}; - -#endif \ No newline at end of file diff --git a/BelyakovaEA/Lab2/include/Kruskal.h b/BelyakovaEA/Lab2/include/Kruskal.h deleted file mode 100644 index e96dc4065..000000000 --- a/BelyakovaEA/Lab2/include/Kruskal.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef KRUSKAL_H -#define KRUSKAL_H - -#include "dheap.h" -#include "Graph.h" -#include "SeparatedSet.h" -#include "PriorituQueue.h" - -template -class Algorithms { -public: - static Graph* Kruskal(const Graph& graph, PriorityQueue* queue); //? -}; - -template -Graph* Algorithms::Kruskal(const Graph& graph, PriorityQueue* queue) -{ - int n = graph.GetVertexNum(); - int m = graph.GetEdgesNum(); - Graph *tree = new Graph(n, m, false); - - SeparatedSet *set = new SeparatedSet(n); - /*for (int i = 0; i < n; ++i) - { - set->makesets(i); - }*/ - - for (int i = 0; i < m; ++i) - { - queue->Push(T(graph.GetEdge(i))); - } - - int treeEdgeSize = 0; - T tmp; - - while ((treeEdgeSize < n - 1) && (!queue->isEmpty())) - { - tmp = queue->Pop(); - - int u = tmp.vertex; - int v = tmp.upVertex; - double weight = tmp.dist; - - int An = set->findsets(u); - int Ak = set->findsets(v); - - if (An != Ak) - { - set->unionsets(An, Ak); - printf("After union\n"); - tree->AddEdge(u, v, weight); - printf("After add\n"); - ++treeEdgeSize; - } - } - - //tree->Print(); - return tree; -} - -template class Algorithms; - -#endif diff --git a/BelyakovaEA/Lab2/include/PriorituQueue.h b/BelyakovaEA/Lab2/include/PriorituQueue.h deleted file mode 100644 index 13960b168..000000000 --- a/BelyakovaEA/Lab2/include/PriorituQueue.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef PRIORITYQUEUE_H -#define PRIORITYQUEUE_H - -#include "dheap.h" - -template class PriorityQueue -{ -public: - virtual void Push(T& t) = 0; - virtual T Pop() = 0; - virtual bool isEmpty() const = 0; -}; - -template class PriorityQueueDHeap : public PriorityQueue -{ -public: - PriorityQueueDHeap(T* keys, int d, int n) - { - dheap = new DHeap(keys, d, n); - } - - virtual void Push(T& t) { dheap->insert(t); } - virtual T Pop() { return dheap->getmin(); } - virtual bool isEmpty() const { return dheap->isEmpty(); } - - - int GetSize() { return dheap->GetSize(); } - T& GetElement(int idx) { return dheap->GetElement(idx); } - void RepairQueue() { dheap->hilling(); } - void SetSize(int new_size) { dheap->SetSize(new_size); } - - virtual ~PriorityQueueDHeap() { delete dheap; } - -private: - DHeap* dheap; -}; - -template class PriorityQueueDHeap; -template class PriorityQueueDHeap; -#endif \ No newline at end of file diff --git a/BelyakovaEA/Lab2/include/PySort.h b/BelyakovaEA/Lab2/include/PySort.h deleted file mode 100644 index 9c915cf26..000000000 --- a/BelyakovaEA/Lab2/include/PySort.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef PYR_SORT_H -#define PYR_SORT_H - -#include "dheap.h" - -/* -template void PyrSort(DHeap* heap) -{ -heap->hilling(); -int size = heap->GetSize(); -while (size > 0) -{ -heap->transpose(0, size - 1); -heap->remove(size - 1); -size--; -heap->sinking(0); -//size--; -} -}*/ - -template void PyrSort(DHeap* heap) -{ - heap->hilling(); - int cur_size = heap->GetSize(); - int old_size = cur_size; - while (cur_size > 0) - { - heap->transpose(0, cur_size - 1); - cur_size--; - heap->SetSize(cur_size); - heap->sinking(0); - } - - heap->SetSize(old_size); -} - -template void PyrSort(DHeap*); - -#endif - - diff --git a/BelyakovaEA/Lab2/include/SeparatedSet.h b/BelyakovaEA/Lab2/include/SeparatedSet.h deleted file mode 100644 index 744df285f..000000000 --- a/BelyakovaEA/Lab2/include/SeparatedSet.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef SEPARATEDSET -#define SEPARATEDSET - -class SeparatedSet -{ -public: - SeparatedSet(int size); - ~SeparatedSet() { delete[] harVec; } - - void makesets(int idx); - int findsets(int idx); - void unionsets(int x, int y); - -private: - int* harVec; - int size; -}; -#endif diff --git a/BelyakovaEA/Lab2/include/dheap.h b/BelyakovaEA/Lab2/include/dheap.h deleted file mode 100644 index 5e27c41d2..000000000 --- a/BelyakovaEA/Lab2/include/dheap.h +++ /dev/null @@ -1,198 +0,0 @@ -#ifndef DHEAP_H -#define DHEAP_H - -#include "edge.h" -#include "Dijkstra.h" - -/*template class PriorityQueue -{ -public: -virtual void Push(T& t) = 0; -virtual T Pop() = 0; -virtual bool isEmpty() const = 0; -};*/ - -template class DHeap -{ -private: - int d; - int n; // - T* keys; // - int min(int a, int b); - -public: - DHeap(T* keys, int d, int n); - DHeap(const DHeap &H); // - ~DHeap(); // - - virtual bool isEmpty() const { return n == 0; } - - void transpose(int i, int j); - void surfacing(int i); - void sinking(int i); // - void hilling(); // - void remove(int i); - void insert(T k); - int minchild(int i); - - T getmin(); - - int GetSize() { return n; } - void SetSize(int new_size) { n = new_size; } - T& GetElement(int idx) { return keys[idx]; } -}; - -template -DHeap ::DHeap(T* keys, int d, int n) -{ - this->keys = keys; - this->d = d; - this->n = n; -} - -template -DHeap::DHeap(const DHeap&H) -{ - d = H.d; - n = H.n; - keys = new T[n]; - for (int i = 0; i < n; i++) - { - keys[i] = H.keys[i]; - } -} - -template -DHeap::~DHeap() { - //Do not delete keys as we do not own it; -} - -template -int DHeap::min(int a, int b) -{ - if (a <= b) return a; - else return b; -} - -template -void DHeap ::transpose(int i, int j) { - T tmp = keys[i]; - keys[i] = keys[j]; - keys[j] = tmp; -} - -template -void DHeap::surfacing(int i) { - int p = (i - 1) / d; - while (p > 0) { //p or i - //p = (i - 1) / d; - if (keys[p] > keys[i]) - { - transpose(p, i); - i = p; - p = (i - 1) / d; - } - - else - { - break; - } - } -} - - -template -void DHeap::sinking(int i) { - int c = minchild(i); - while (c != -1 && keys[c] < keys[i]) { - transpose(c, i); - i = c; - c = minchild(i); - } -} - -template -int DHeap::minchild(int i) { - if (i * d + 1 > n - 1) return -1; - - int minidx = i * d + 1; - int i1 = i * d + 1; - int i2 = min(i * d + d, n - 1); - T minkey = keys[i1]; - for (int i = i1; i <= i2; i++) { - if (keys[minidx] > keys[i]) { - minidx = i; - minkey = keys[i]; - } - } - return minidx; -} - -template -T DHeap ::getmin() { - - T tmp = keys[0]; - transpose(0, n - 1); - n--; - sinking(0); - return tmp; -} - -template -void DHeap::hilling() { - for (int i = n - 1; i >= 0; i--) - sinking(i); -} - -template -void DHeap::remove(int i) { - if (i == n - 1) - { - n--; - return; - } - - keys[i] = keys[n - 1]; - n--; - sinking(i); -} - -template -void DHeap::insert(T k) { - keys[n] = k; - surfacing(n); - ++n; -} - - -/*template class PriorityQueueDHeap : public PriorityQueue -{ -public: -PriorityQueueDHeap(T* keys, int d, int n) -{ -dheap = new DHeap(keys, d, n); -} - -virtual void Push(T& t) { dheap->insert(t); } -virtual T Pop() { return dheap->getmin(); } -virtual bool isEmpty() const { return dheap->isEmpty(); } - - -int GetSize() { return dheap->GetSize(); } -T& GetElement(int idx) { return dheap->GetElement(idx); } -void RepairQueue() { dheap->hilling(); } -void SetSize(int new_size) { dheap->SetSize(new_size); } - -virtual ~PriorityQueueDHeap() { delete dheap; } - -private: -DHeap* dheap; -};*/ - -template class DHeap; -template class DHeap; - -//template class PriorityQueueDHeap; -//template class PriorityQueueDHeap; - -#endif \ No newline at end of file diff --git a/BelyakovaEA/Lab2/include/edge.h b/BelyakovaEA/Lab2/include/edge.h deleted file mode 100644 index 21995341c..000000000 --- a/BelyakovaEA/Lab2/include/edge.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef EDGE_H -#define EDGE_H - -class Edge { -public: - int Ne; // - int Ke; // - double W; // - - Edge(int N, int K, double _W) - { - Ne = N; - Ke = K; - W = _W; - } -}; - - -class VertexDist -{ -public: - VertexDist() : vertex(0), dist(0.0), upVertex(0) {} - VertexDist(const Edge& edge) : vertex(edge.Ne), upVertex(edge.Ke), dist(edge.W) {} - - - int vertex; - - double dist; - int upVertex; - - bool operator<(const VertexDist& vd) - { - return dist < vd.dist; - } - - bool operator>(const VertexDist& vd) - { - return dist > vd.dist; - } - - bool operator==(const VertexDist& vd) - { - return dist == vd.dist; - } -}; - -#endif diff --git a/BelyakovaEA/Lab2/sample/mainDjikstra.cpp b/BelyakovaEA/Lab2/sample/mainDjikstra.cpp deleted file mode 100644 index 2a7b89961..000000000 --- a/BelyakovaEA/Lab2/sample/mainDjikstra.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "dheap.h" -#include "Graph.h" -#include "Dijkstra.h" - -#include - -const int SIZE = 10; - - -int main() -{ - int d = 4; - - int nVertex = 4; - - int nEdges = 5; - - if (nEdges <= 0 || nVertex <= 0) - { - printf("ERROR: Number of edges and verteces must be positive!\n"); - return 1; - } - - Graph graph(nVertex, nEdges); - - printf("Dijkstra\n"); - VertexDist *result = Dijkstra::DijkstraSearch(graph); - - printf("Result:\n"); - for (int i = 0; i < graph.GetVertexNum(); ++i) - { - printf("Vertex: %d, up: %d, ", result[i].vertex, result[i].upVertex); - - if (result[i].dist >= graph.GetSumOfWeights()) - { - printf("UNREACHABLE\n"); - } - - else - { - printf("dist: %f\n", result[i].dist); - } - } - - delete[] result; - - return 0; -} \ No newline at end of file diff --git a/BelyakovaEA/Lab2/sample/mainKruskal.cpp b/BelyakovaEA/Lab2/sample/mainKruskal.cpp deleted file mode 100644 index 343e411e3..000000000 --- a/BelyakovaEA/Lab2/sample/mainKruskal.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "Kruskal.h" -#include -#include "PriorituQueue.h" -#include "Graph.h" -#include "edge.h" -#include "dheap.h" - -int main() { - printf("Kruskal\n"); - - int d = 4; - int nVertex = 4; - int nEdges = 5; - if (nEdges <= 0 || nVertex <= 0) - { - printf("ERROR: Number of edges and verteces must be positive!\n"); - return 1; - } - - Graph graph(nVertex, nEdges); - VertexDist* dheapValues = new VertexDist[graph.GetVertexNum()]; - PriorityQueueDHeap* vdHeap = new PriorityQueueDHeap(dheapValues, d, 0); - Graph* tree = Algorithms::Kruskal(graph, vdHeap); - - printf("Result:\n"); - tree->Print(); - // delete tree; - - int c; - getchar(); - return 0; -} \ No newline at end of file diff --git a/BelyakovaEA/Lab2/sample/mainPySort.cpp b/BelyakovaEA/Lab2/sample/mainPySort.cpp deleted file mode 100644 index 699587850..000000000 --- a/BelyakovaEA/Lab2/sample/mainPySort.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "dheap.h" -#include "PySort.h" -#include - -const int SIZE = 10; - -int main() { - - - int d = 4; - int nVertex = 4; - int nEdges = 5; - - if (nEdges <= 0 || nVertex <= 0) - { - printf("ERROR: Number of edges and verteces must be positive!\n"); - return 1; - } - - //printf("Sort\n"); - int *arr = new int[SIZE]; - - for (int i = 0; i < SIZE; ++i) - { - arr[i] = i; - } - - for (int i = 0; i < SIZE; ++i) - { - printf("%d; ", arr[i]); - } - printf("\n"); - - DHeap *heap = new DHeap(arr, d, SIZE); - printf("Sort\n"); - PyrSort(heap); - - for (int i = 0; i < SIZE; ++i) - { - printf("%d; ", arr[i]); - } - - printf("\n"); - - delete heap; - delete[] arr; - return 0; -} \ No newline at end of file diff --git a/BelyakovaEA/Lab2/src/Djikstra.cpp b/BelyakovaEA/Lab2/src/Djikstra.cpp deleted file mode 100644 index c4d5ea27b..000000000 --- a/BelyakovaEA/Lab2/src/Djikstra.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "Dijkstra.h" -#include "dheap.h" -#include "PriorituQueue.h" - -VertexDist* Dijkstra::DijkstraSearch(const Graph& graph /*,TODO: arnost*/) -{ - VertexDist *result = new VertexDist[graph.GetVertexNum()]; - - //Fill values for root - result[0].vertex = 0; - result[0].dist = 0.0; - result[0].upVertex = 0; - - //Fill values for other verteces - //Infinity == (Sum of all weights + 1) - for (int i = 1; i < graph.GetVertexNum(); ++i) - { - result[i].vertex = i; - result[i].dist = graph.GetSumOfWeights(); - result[i].upVertex = i; - } - - PriorityQueueDHeap dheap(result, 4 , graph.GetVertexNum()); - - while (!dheap.isEmpty()) - { - VertexDist vd = dheap.Pop(); - NeighboorVector neighboors = graph.GetNeigboors(vd.vertex); - - for (int i = 0; i < neighboors.size(); ++i) //cocedi - { - for (int j = 0; j < dheap.GetSize(); ++j) //cocedi ostavshiesya v kuche - { - if (dheap.GetElement(j).vertex == neighboors[i].vertex) - { - if (dheap.GetElement(j).dist > vd.dist + neighboors[i].edgeWeight) - { - dheap.GetElement(j).dist = vd.dist + neighboors[i].edgeWeight; - dheap.GetElement(j).upVertex = vd.vertex; - } - } - } - } - - dheap.RepairQueue(); - } - - dheap.SetSize(graph.GetVertexNum()); - return result; -} \ No newline at end of file diff --git a/BelyakovaEA/Lab2/src/Graph.cpp b/BelyakovaEA/Lab2/src/Graph.cpp deleted file mode 100644 index 62f7aa959..000000000 --- a/BelyakovaEA/Lab2/src/Graph.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include "Graph.h" -#include -using namespace std; - -Graph::Graph(int nVertex, int nEdges, bool doGenerateEdges) -{ - this->nVertex = nVertex; - this->sumOfWeights = 1.0; - edges.reserve(nEdges); - - if (doGenerateEdges) - { - GenerateEdges(nEdges); - } -} - - -int Graph::GetVertexNum() const { return nVertex; } -int Graph::GetEdgesNum() const { return edges.size(); } - - -void Graph::AddEdge(int start, int finish, double weight) -{ - sumOfWeights += weight; - printf("AddEdge\n"); - edges.push_back(Edge(start, finish, weight)); -} - -double Graph::generateWeight(double minRange, double maxRange) -{ - double d = minRange; - double c = (double)(maxRange - minRange) / RAND_MAX; - double result = c * rand() + d; - return result; -} - -void Graph::Print() -{ - printf("Graph:\n"); - for (int i = 0; i < edges.size(); ++i) - { - printf("Edge %d: %d -> %d with %f\n", i, edges[i].Ne, edges[i].Ke, edges[i].W); - } -} - -NeighboorVector Graph::GetNeigboors(int vertex) const -{ - NeighboorVector result; - for (int i = 0; i < edges.size(); ++i) - { - if (edges[i].Ke == vertex || edges[i].Ne == vertex) - { - Neighboor nv; - nv.edgeWeight = edges[i].W; - - if (edges[i].Ke == vertex) - { - nv.vertex = edges[i].Ne; - } - - else - { - nv.vertex = edges[i].Ke; - } - - result.push_back(nv); - } - } - - return result; -} - -void Graph::GenerateEdges(int nEdges) { - int currentEdgesNum = 0; - - while (edges.size() < nEdges) - { - bool fail = false; - int n = rand() % nVertex; - int k = rand() % nVertex; - - //The same vertex - try again - if (n == k) - { - continue; - } - - //This edge already exists - for (int i = 0; i < edges.size(); ++i) - { - if ((edges[i].Ke == n) && (edges[i].Ne == k) || - (edges[i].Ne == n) && (edges[i].Ke == k)) - { - fail = true; - break; - } - } - - if (fail) - { - continue; - } - - //This is a new edge - double W = generateWeight(); - sumOfWeights += W; - edges.push_back(Edge(n, k, W)); - } - - //print graph - Print(); - printf("\n\n"); -} \ No newline at end of file diff --git a/BelyakovaEA/Lab2/src/Kruskal.cpp b/BelyakovaEA/Lab2/src/Kruskal.cpp deleted file mode 100644 index 64be34e28..000000000 --- a/BelyakovaEA/Lab2/src/Kruskal.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "Kruskal.h" \ No newline at end of file diff --git a/BelyakovaEA/Lab2/src/PriorituQueue.cpp b/BelyakovaEA/Lab2/src/PriorituQueue.cpp deleted file mode 100644 index 505aa0100..000000000 --- a/BelyakovaEA/Lab2/src/PriorituQueue.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "PriorituQueue.h" \ No newline at end of file diff --git a/BelyakovaEA/Lab2/src/SeparatedSet.cpp b/BelyakovaEA/Lab2/src/SeparatedSet.cpp deleted file mode 100644 index 332413191..000000000 --- a/BelyakovaEA/Lab2/src/SeparatedSet.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "SeparatedSet.h" - -#include - -SeparatedSet::SeparatedSet(int _size) -{ - this->size = _size; - harVec = new int[size]; - - for (int i = 0; i < size; ++i) - { - harVec[i] = i; - } -} - - -void SeparatedSet::makesets(int idx) -{ - printf("makeset %d\n", idx); - if ((idx > size - 1) || (idx < 0)) - throw ("out of range"); - - harVec[idx] = idx; -} - -int SeparatedSet::findsets(int idx) -{ - printf("findset %d\n", idx); - if ((idx > size - 1) || (idx < 0)) - throw ("out of range"); - - return harVec[idx]; -} - -void SeparatedSet::unionsets(int x, int y) -{ - printf("x %d y %d\n", x, y); - if ((x > size - 1) || (x < 0) || (y > size - 1) || (y < 0)) - throw ("out of range"); - - for (int i = 0; i < size; ++i) - { - if (harVec[i] == y) - { - harVec[i] = x; - } - } -} \ No newline at end of file From 4d34899a97302aae6d74e42714650b196aa6ecbd Mon Sep 17 00:00:00 2001 From: Liza-Bel Date: Sun, 2 Sep 2018 14:49:30 +0300 Subject: [PATCH 4/6] lab2 --- BelyakovaEA/Lab2/build/LAB2/LAB2.sln | 67 +++++++ BelyakovaEA/Lab2/build/LAB2/LAB2/LAB2.vcxproj | 153 ++++++++++++++++ .../Lab2/build/LAB2/LAB2/LAB2.vcxproj.filters | 17 ++ BelyakovaEA/Lab2/include/Dijkstra.h | 13 ++ BelyakovaEA/Lab2/include/Graph.h | 47 +++++ BelyakovaEA/Lab2/include/Kruskal.h | 63 +++++++ BelyakovaEA/Lab2/include/PriorituQueue.h | 40 +++++ BelyakovaEA/Lab2/include/PySort.h | 41 +++++ BelyakovaEA/Lab2/include/SeparatedSet.h | 18 ++ BelyakovaEA/Lab2/include/dheap.h | 163 ++++++++++++++++++ BelyakovaEA/Lab2/include/edge.h | 47 +++++ BelyakovaEA/Lab2/sample/mainDjikstra.cpp | 48 ++++++ BelyakovaEA/Lab2/sample/mainKruskal.cpp | 28 +++ BelyakovaEA/Lab2/sample/mainPySort.cpp | 48 ++++++ BelyakovaEA/Lab2/src/Djikstra.cpp | 50 ++++++ BelyakovaEA/Lab2/src/Graph.cpp | 113 ++++++++++++ BelyakovaEA/Lab2/src/Kruskal.cpp | 1 + BelyakovaEA/Lab2/src/PriorituQueue.cpp | 1 + BelyakovaEA/Lab2/src/SeparatedSet.cpp | 48 ++++++ 19 files changed, 1006 insertions(+) create mode 100644 BelyakovaEA/Lab2/build/LAB2/LAB2.sln create mode 100644 BelyakovaEA/Lab2/build/LAB2/LAB2/LAB2.vcxproj create mode 100644 BelyakovaEA/Lab2/build/LAB2/LAB2/LAB2.vcxproj.filters create mode 100644 BelyakovaEA/Lab2/include/Dijkstra.h create mode 100644 BelyakovaEA/Lab2/include/Graph.h create mode 100644 BelyakovaEA/Lab2/include/Kruskal.h create mode 100644 BelyakovaEA/Lab2/include/PriorituQueue.h create mode 100644 BelyakovaEA/Lab2/include/PySort.h create mode 100644 BelyakovaEA/Lab2/include/SeparatedSet.h create mode 100644 BelyakovaEA/Lab2/include/dheap.h create mode 100644 BelyakovaEA/Lab2/include/edge.h create mode 100644 BelyakovaEA/Lab2/sample/mainDjikstra.cpp create mode 100644 BelyakovaEA/Lab2/sample/mainKruskal.cpp create mode 100644 BelyakovaEA/Lab2/sample/mainPySort.cpp create mode 100644 BelyakovaEA/Lab2/src/Djikstra.cpp create mode 100644 BelyakovaEA/Lab2/src/Graph.cpp create mode 100644 BelyakovaEA/Lab2/src/Kruskal.cpp create mode 100644 BelyakovaEA/Lab2/src/PriorituQueue.cpp create mode 100644 BelyakovaEA/Lab2/src/SeparatedSet.cpp diff --git a/BelyakovaEA/Lab2/build/LAB2/LAB2.sln b/BelyakovaEA/Lab2/build/LAB2/LAB2.sln new file mode 100644 index 000000000..694cec9be --- /dev/null +++ b/BelyakovaEA/Lab2/build/LAB2/LAB2.sln @@ -0,0 +1,67 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Dijkstra", "Dijkstra\Dijkstra.vcxproj", "{26628341-5FBF-4172-A42B-92ACD3CDBD61}" + ProjectSection(ProjectDependencies) = postProject + {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51} = {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Kruskal", "Kruskal\Kruskal.vcxproj", "{834A6CCE-2870-4861-A084-F14FA7873BBA}" + ProjectSection(ProjectDependencies) = postProject + {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51} = {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PySort", "PySort\PySort.vcxproj", "{4A314873-F83F-42A6-8C6E-603C072C4982}" + ProjectSection(ProjectDependencies) = postProject + {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51} = {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Graph_lib", "Graph_lib\Graph_lib.vcxproj", "{F8C5FC5A-829E-4B18-A6ED-F56D0980DB51}" +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 + {26628341-5FBF-4172-A42B-92ACD3CDBD61}.Debug|x64.ActiveCfg = Debug|x64 + {26628341-5FBF-4172-A42B-92ACD3CDBD61}.Debug|x64.Build.0 = Debug|x64 + {26628341-5FBF-4172-A42B-92ACD3CDBD61}.Debug|x86.ActiveCfg = Debug|Win32 + {26628341-5FBF-4172-A42B-92ACD3CDBD61}.Debug|x86.Build.0 = Debug|Win32 + {26628341-5FBF-4172-A42B-92ACD3CDBD61}.Release|x64.ActiveCfg = Release|x64 + {26628341-5FBF-4172-A42B-92ACD3CDBD61}.Release|x64.Build.0 = Release|x64 + {26628341-5FBF-4172-A42B-92ACD3CDBD61}.Release|x86.ActiveCfg = Release|Win32 + {26628341-5FBF-4172-A42B-92ACD3CDBD61}.Release|x86.Build.0 = Release|Win32 + {834A6CCE-2870-4861-A084-F14FA7873BBA}.Debug|x64.ActiveCfg = Debug|x64 + {834A6CCE-2870-4861-A084-F14FA7873BBA}.Debug|x64.Build.0 = Debug|x64 + {834A6CCE-2870-4861-A084-F14FA7873BBA}.Debug|x86.ActiveCfg = Debug|Win32 + {834A6CCE-2870-4861-A084-F14FA7873BBA}.Debug|x86.Build.0 = Debug|Win32 + {834A6CCE-2870-4861-A084-F14FA7873BBA}.Release|x64.ActiveCfg = Release|x64 + {834A6CCE-2870-4861-A084-F14FA7873BBA}.Release|x64.Build.0 = Release|x64 + {834A6CCE-2870-4861-A084-F14FA7873BBA}.Release|x86.ActiveCfg = Release|Win32 + {834A6CCE-2870-4861-A084-F14FA7873BBA}.Release|x86.Build.0 = Release|Win32 + {4A314873-F83F-42A6-8C6E-603C072C4982}.Debug|x64.ActiveCfg = Debug|x64 + {4A314873-F83F-42A6-8C6E-603C072C4982}.Debug|x64.Build.0 = Debug|x64 + {4A314873-F83F-42A6-8C6E-603C072C4982}.Debug|x86.ActiveCfg = Debug|Win32 + {4A314873-F83F-42A6-8C6E-603C072C4982}.Debug|x86.Build.0 = Debug|Win32 + {4A314873-F83F-42A6-8C6E-603C072C4982}.Release|x64.ActiveCfg = Release|x64 + {4A314873-F83F-42A6-8C6E-603C072C4982}.Release|x64.Build.0 = Release|x64 + {4A314873-F83F-42A6-8C6E-603C072C4982}.Release|x86.ActiveCfg = Release|Win32 + {4A314873-F83F-42A6-8C6E-603C072C4982}.Release|x86.Build.0 = Release|Win32 + {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51}.Debug|x64.ActiveCfg = Debug|x64 + {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51}.Debug|x64.Build.0 = Debug|x64 + {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51}.Debug|x86.ActiveCfg = Debug|Win32 + {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51}.Debug|x86.Build.0 = Debug|Win32 + {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51}.Release|x64.ActiveCfg = Release|x64 + {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51}.Release|x64.Build.0 = Release|x64 + {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51}.Release|x86.ActiveCfg = Release|Win32 + {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/BelyakovaEA/Lab2/build/LAB2/LAB2/LAB2.vcxproj b/BelyakovaEA/Lab2/build/LAB2/LAB2/LAB2.vcxproj new file mode 100644 index 000000000..7eb94632d --- /dev/null +++ b/BelyakovaEA/Lab2/build/LAB2/LAB2/LAB2.vcxproj @@ -0,0 +1,153 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {635D0BBA-8C12-4A1D-A0E3-6BDB350C776B} + Win32Proj + LAB2 + 8.1 + + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + + + Level3 + Disabled + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + \ No newline at end of file diff --git a/BelyakovaEA/Lab2/build/LAB2/LAB2/LAB2.vcxproj.filters b/BelyakovaEA/Lab2/build/LAB2/LAB2/LAB2.vcxproj.filters new file mode 100644 index 000000000..f79baca3f --- /dev/null +++ b/BelyakovaEA/Lab2/build/LAB2/LAB2/LAB2.vcxproj.filters @@ -0,0 +1,17 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;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/BelyakovaEA/Lab2/include/Dijkstra.h b/BelyakovaEA/Lab2/include/Dijkstra.h new file mode 100644 index 000000000..0eb8a20be --- /dev/null +++ b/BelyakovaEA/Lab2/include/Dijkstra.h @@ -0,0 +1,13 @@ +#ifndef DIJKSTRA_H +#define DIJKSTRA_H + +#include "edge.h" +#include "Graph.h" + +class Dijkstra { +public: + static VertexDist* DijkstraSearch(const Graph& graph); +}; + + +#endif diff --git a/BelyakovaEA/Lab2/include/Graph.h b/BelyakovaEA/Lab2/include/Graph.h new file mode 100644 index 000000000..6df1beb9d --- /dev/null +++ b/BelyakovaEA/Lab2/include/Graph.h @@ -0,0 +1,47 @@ +#ifndef GRAPH_H +#define GRAPH_H + +#include "edge.h" +#include +#include +#include +#include +#include + +struct Neighboor // +{ + int vertex; + double edgeWeight; +}; + +typedef std::vector NeighboorVector; + +class Graph +{ +public: + Graph(int nVertex, int nEdges, bool doGenerateEdges = true); + ~Graph() {} + + int GetVertexNum() const; + int GetEdgesNum() const; + double Graph::GetSumOfWeights() const { return sumOfWeights; } + + Edge GetEdge(int idx) const {/* printf("n: %d, k: %d\n", edges[idx].Ne, edges[idx].Ke);*/ return edges[idx]; } + + void AddEdge(int start, int finish, double weight); + + NeighboorVector GetNeigboors(int vertex) const; // + + void Print(); + +private: + double generateWeight(double minRangw = 0.01, double maxRange = 10.0); + void GenerateEdges(int nEdges); + + int nVertex; + std::vector edges; + + double sumOfWeights; +}; + +#endif \ No newline at end of file diff --git a/BelyakovaEA/Lab2/include/Kruskal.h b/BelyakovaEA/Lab2/include/Kruskal.h new file mode 100644 index 000000000..77f6c31bc --- /dev/null +++ b/BelyakovaEA/Lab2/include/Kruskal.h @@ -0,0 +1,63 @@ +#ifndef KRUSKAL_H +#define KRUSKAL_H + +#include "dheap.h" +#include "Graph.h" +#include "SeparatedSet.h" +#include "PriorituQueue.h" + +template +class Algorithms { +public: + static Graph* Kruskal(const Graph& graph, PriorityQueue* queue); +}; + +template +Graph* Algorithms::Kruskal(const Graph& graph, PriorityQueue* queue) +{ + int n = graph.GetVertexNum(); + int m = graph.GetEdgesNum(); + Graph *tree = new Graph(n, m, false); + + SeparatedSet *set = new SeparatedSet(n); + for (int i = 0; i < n; ++i) + { + set->makesets(i); + } + + for (int i = 0; i < m; ++i) + { + queue->Push(T(graph.GetEdge(i))); + } + + int treeEdgeSize = 0; + T tmp; + + while ((treeEdgeSize < n - 1) && (!queue->isEmpty())) + { + tmp = queue->Pop(); + + int u = tmp.vertex; + int v = tmp.upVertex; + double weight = tmp.dist; + + int An = set->findsets(u); + int Ak = set->findsets(v); + + if (An != Ak) + { + set->unionsets(An, Ak); + //printf("After union\n"); + tree->AddEdge(u, v, weight); + //printf("After add\n"); + ++treeEdgeSize; + } + } + + //tree->Print(); + return tree; +} + +template class Algorithms; + +#endif diff --git a/BelyakovaEA/Lab2/include/PriorituQueue.h b/BelyakovaEA/Lab2/include/PriorituQueue.h new file mode 100644 index 000000000..13960b168 --- /dev/null +++ b/BelyakovaEA/Lab2/include/PriorituQueue.h @@ -0,0 +1,40 @@ +#ifndef PRIORITYQUEUE_H +#define PRIORITYQUEUE_H + +#include "dheap.h" + +template class PriorityQueue +{ +public: + virtual void Push(T& t) = 0; + virtual T Pop() = 0; + virtual bool isEmpty() const = 0; +}; + +template class PriorityQueueDHeap : public PriorityQueue +{ +public: + PriorityQueueDHeap(T* keys, int d, int n) + { + dheap = new DHeap(keys, d, n); + } + + virtual void Push(T& t) { dheap->insert(t); } + virtual T Pop() { return dheap->getmin(); } + virtual bool isEmpty() const { return dheap->isEmpty(); } + + + int GetSize() { return dheap->GetSize(); } + T& GetElement(int idx) { return dheap->GetElement(idx); } + void RepairQueue() { dheap->hilling(); } + void SetSize(int new_size) { dheap->SetSize(new_size); } + + virtual ~PriorityQueueDHeap() { delete dheap; } + +private: + DHeap* dheap; +}; + +template class PriorityQueueDHeap; +template class PriorityQueueDHeap; +#endif \ No newline at end of file diff --git a/BelyakovaEA/Lab2/include/PySort.h b/BelyakovaEA/Lab2/include/PySort.h new file mode 100644 index 000000000..9c915cf26 --- /dev/null +++ b/BelyakovaEA/Lab2/include/PySort.h @@ -0,0 +1,41 @@ +#ifndef PYR_SORT_H +#define PYR_SORT_H + +#include "dheap.h" + +/* +template void PyrSort(DHeap* heap) +{ +heap->hilling(); +int size = heap->GetSize(); +while (size > 0) +{ +heap->transpose(0, size - 1); +heap->remove(size - 1); +size--; +heap->sinking(0); +//size--; +} +}*/ + +template void PyrSort(DHeap* heap) +{ + heap->hilling(); + int cur_size = heap->GetSize(); + int old_size = cur_size; + while (cur_size > 0) + { + heap->transpose(0, cur_size - 1); + cur_size--; + heap->SetSize(cur_size); + heap->sinking(0); + } + + heap->SetSize(old_size); +} + +template void PyrSort(DHeap*); + +#endif + + diff --git a/BelyakovaEA/Lab2/include/SeparatedSet.h b/BelyakovaEA/Lab2/include/SeparatedSet.h new file mode 100644 index 000000000..744df285f --- /dev/null +++ b/BelyakovaEA/Lab2/include/SeparatedSet.h @@ -0,0 +1,18 @@ +#ifndef SEPARATEDSET +#define SEPARATEDSET + +class SeparatedSet +{ +public: + SeparatedSet(int size); + ~SeparatedSet() { delete[] harVec; } + + void makesets(int idx); + int findsets(int idx); + void unionsets(int x, int y); + +private: + int* harVec; + int size; +}; +#endif diff --git a/BelyakovaEA/Lab2/include/dheap.h b/BelyakovaEA/Lab2/include/dheap.h new file mode 100644 index 000000000..cf5f45099 --- /dev/null +++ b/BelyakovaEA/Lab2/include/dheap.h @@ -0,0 +1,163 @@ +#ifndef DHEAP_H +#define DHEAP_H + +#include "edge.h" +#include "Dijkstra.h" + + +template class DHeap +{ +private: + int d; + int n; // + T* keys; // + int min(int a, int b); + +public: + DHeap(T* keys, int d, int n); + DHeap(const DHeap &H); // + ~DHeap(); // + + virtual bool isEmpty() const { return n == 0; } + + void transpose(int i, int j); + void surfacing(int i); + void sinking(int i); // + void hilling(); // + void remove(int i); + void insert(T k); + int minchild(int i); + + T getmin(); + + int GetSize() { return n; } + void SetSize(int new_size) { n = new_size; } + T& GetElement(int idx) { return keys[idx]; } +}; + +template +DHeap ::DHeap(T* keys, int d, int n) +{ + this->keys = keys; + this->d = d; + this->n = n; +} + +template +DHeap::DHeap(const DHeap&H) +{ + d = H.d; + n = H.n; + keys = new T[n]; + for (int i = 0; i < n; i++) + { + keys[i] = H.keys[i]; + } +} + +template +DHeap::~DHeap() { + //Do not delete keys as we do not own it; +} + +template +int DHeap::min(int a, int b) +{ + if (a <= b) return a; + else return b; +} + +template +void DHeap ::transpose(int i, int j) { + T tmp = keys[i]; + keys[i] = keys[j]; + keys[j] = tmp; +} + +template +void DHeap::surfacing(int i) { + int p = (i - 1) / d; + while (p > 0) { + if (keys[p] > keys[i]) + { + transpose(p, i); + i = p; + p = (i - 1) / d; + } + + else + { + break; + } + } +} + + +template +void DHeap::sinking(int i) { + int c = minchild(i); + while (c != -1 && keys[c] < keys[i]) { + transpose(c, i); + i = c; + c = minchild(i); + } +} + +template +int DHeap::minchild(int i) { + if (i * d + 1 > n - 1) return -1; + + int minidx = i * d + 1; + int i1 = i * d + 1; + int i2 = min(i * d + d, n - 1); + T minkey = keys[i1]; + for (int i = i1; i <= i2; i++) { + if (keys[minidx] > keys[i]) { + minidx = i; + minkey = keys[i]; + } + } + return minidx; +} + +template +T DHeap ::getmin() { + + T tmp = keys[0]; + transpose(0, n - 1); + n--; + sinking(0); + return tmp; +} + +template +void DHeap::hilling() { + for (int i = n - 1; i >= 0; i--) + sinking(i); +} + +template +void DHeap::remove(int i) { + if (i == n - 1) + { + n--; + return; + } + + keys[i] = keys[n - 1]; + n--; + sinking(i); +} + +template +void DHeap::insert(T k) { + keys[n] = k; + surfacing(n); + ++n; +} + + +template class DHeap; +template class DHeap; + +#endif \ No newline at end of file diff --git a/BelyakovaEA/Lab2/include/edge.h b/BelyakovaEA/Lab2/include/edge.h new file mode 100644 index 000000000..21995341c --- /dev/null +++ b/BelyakovaEA/Lab2/include/edge.h @@ -0,0 +1,47 @@ +#ifndef EDGE_H +#define EDGE_H + +class Edge { +public: + int Ne; // + int Ke; // + double W; // + + Edge(int N, int K, double _W) + { + Ne = N; + Ke = K; + W = _W; + } +}; + + +class VertexDist +{ +public: + VertexDist() : vertex(0), dist(0.0), upVertex(0) {} + VertexDist(const Edge& edge) : vertex(edge.Ne), upVertex(edge.Ke), dist(edge.W) {} + + + int vertex; + + double dist; + int upVertex; + + bool operator<(const VertexDist& vd) + { + return dist < vd.dist; + } + + bool operator>(const VertexDist& vd) + { + return dist > vd.dist; + } + + bool operator==(const VertexDist& vd) + { + return dist == vd.dist; + } +}; + +#endif diff --git a/BelyakovaEA/Lab2/sample/mainDjikstra.cpp b/BelyakovaEA/Lab2/sample/mainDjikstra.cpp new file mode 100644 index 000000000..2a7b89961 --- /dev/null +++ b/BelyakovaEA/Lab2/sample/mainDjikstra.cpp @@ -0,0 +1,48 @@ +#include "dheap.h" +#include "Graph.h" +#include "Dijkstra.h" + +#include + +const int SIZE = 10; + + +int main() +{ + int d = 4; + + int nVertex = 4; + + int nEdges = 5; + + if (nEdges <= 0 || nVertex <= 0) + { + printf("ERROR: Number of edges and verteces must be positive!\n"); + return 1; + } + + Graph graph(nVertex, nEdges); + + printf("Dijkstra\n"); + VertexDist *result = Dijkstra::DijkstraSearch(graph); + + printf("Result:\n"); + for (int i = 0; i < graph.GetVertexNum(); ++i) + { + printf("Vertex: %d, up: %d, ", result[i].vertex, result[i].upVertex); + + if (result[i].dist >= graph.GetSumOfWeights()) + { + printf("UNREACHABLE\n"); + } + + else + { + printf("dist: %f\n", result[i].dist); + } + } + + delete[] result; + + return 0; +} \ No newline at end of file diff --git a/BelyakovaEA/Lab2/sample/mainKruskal.cpp b/BelyakovaEA/Lab2/sample/mainKruskal.cpp new file mode 100644 index 000000000..7bb408939 --- /dev/null +++ b/BelyakovaEA/Lab2/sample/mainKruskal.cpp @@ -0,0 +1,28 @@ +#include "Kruskal.h" +#include +#include "PriorituQueue.h" +#include "Graph.h" +#include "edge.h" +#include "dheap.h" + +int main() { + + int d = 4; + int nVertex = 4; + int nEdges = 5; + if (nEdges <= 0 || nVertex <= 0) + { + printf("ERROR: Number of edges and verteces must be positive!\n"); + return 1; + } + + Graph graph(nVertex, nEdges); + VertexDist* dheapValues = new VertexDist[graph.GetVertexNum()]; + PriorityQueueDHeap* vdHeap = new PriorityQueueDHeap(dheapValues, d, 0); + printf("Kruskal\n"); + Graph* tree = Algorithms::Kruskal(graph, vdHeap); + + printf("Result:\n"); + tree->Print(); + +} \ No newline at end of file diff --git a/BelyakovaEA/Lab2/sample/mainPySort.cpp b/BelyakovaEA/Lab2/sample/mainPySort.cpp new file mode 100644 index 000000000..699587850 --- /dev/null +++ b/BelyakovaEA/Lab2/sample/mainPySort.cpp @@ -0,0 +1,48 @@ +#include "dheap.h" +#include "PySort.h" +#include + +const int SIZE = 10; + +int main() { + + + int d = 4; + int nVertex = 4; + int nEdges = 5; + + if (nEdges <= 0 || nVertex <= 0) + { + printf("ERROR: Number of edges and verteces must be positive!\n"); + return 1; + } + + //printf("Sort\n"); + int *arr = new int[SIZE]; + + for (int i = 0; i < SIZE; ++i) + { + arr[i] = i; + } + + for (int i = 0; i < SIZE; ++i) + { + printf("%d; ", arr[i]); + } + printf("\n"); + + DHeap *heap = new DHeap(arr, d, SIZE); + printf("Sort\n"); + PyrSort(heap); + + for (int i = 0; i < SIZE; ++i) + { + printf("%d; ", arr[i]); + } + + printf("\n"); + + delete heap; + delete[] arr; + return 0; +} \ No newline at end of file diff --git a/BelyakovaEA/Lab2/src/Djikstra.cpp b/BelyakovaEA/Lab2/src/Djikstra.cpp new file mode 100644 index 000000000..c4d5ea27b --- /dev/null +++ b/BelyakovaEA/Lab2/src/Djikstra.cpp @@ -0,0 +1,50 @@ +#include "Dijkstra.h" +#include "dheap.h" +#include "PriorituQueue.h" + +VertexDist* Dijkstra::DijkstraSearch(const Graph& graph /*,TODO: arnost*/) +{ + VertexDist *result = new VertexDist[graph.GetVertexNum()]; + + //Fill values for root + result[0].vertex = 0; + result[0].dist = 0.0; + result[0].upVertex = 0; + + //Fill values for other verteces + //Infinity == (Sum of all weights + 1) + for (int i = 1; i < graph.GetVertexNum(); ++i) + { + result[i].vertex = i; + result[i].dist = graph.GetSumOfWeights(); + result[i].upVertex = i; + } + + PriorityQueueDHeap dheap(result, 4 , graph.GetVertexNum()); + + while (!dheap.isEmpty()) + { + VertexDist vd = dheap.Pop(); + NeighboorVector neighboors = graph.GetNeigboors(vd.vertex); + + for (int i = 0; i < neighboors.size(); ++i) //cocedi + { + for (int j = 0; j < dheap.GetSize(); ++j) //cocedi ostavshiesya v kuche + { + if (dheap.GetElement(j).vertex == neighboors[i].vertex) + { + if (dheap.GetElement(j).dist > vd.dist + neighboors[i].edgeWeight) + { + dheap.GetElement(j).dist = vd.dist + neighboors[i].edgeWeight; + dheap.GetElement(j).upVertex = vd.vertex; + } + } + } + } + + dheap.RepairQueue(); + } + + dheap.SetSize(graph.GetVertexNum()); + return result; +} \ No newline at end of file diff --git a/BelyakovaEA/Lab2/src/Graph.cpp b/BelyakovaEA/Lab2/src/Graph.cpp new file mode 100644 index 000000000..186ac7903 --- /dev/null +++ b/BelyakovaEA/Lab2/src/Graph.cpp @@ -0,0 +1,113 @@ +#include "Graph.h" +#include +using namespace std; + +Graph::Graph(int nVertex, int nEdges, bool doGenerateEdges) +{ + this->nVertex = nVertex; + this->sumOfWeights = 1.0; + edges.reserve(nEdges); + + if (doGenerateEdges) + { + GenerateEdges(nEdges); + } +} + + +int Graph::GetVertexNum() const { return nVertex; } +int Graph::GetEdgesNum() const { return edges.size(); } + + +void Graph::AddEdge(int start, int finish, double weight) +{ + sumOfWeights += weight; + //printf("AddEdge\n"); + edges.push_back(Edge(start, finish, weight)); +} + +double Graph::generateWeight(double minRange, double maxRange) +{ + double d = minRange; + double c = (double)(maxRange - minRange) / RAND_MAX; + double result = c * rand() + d; + return result; +} + +void Graph::Print() +{ + printf("Graph:\n"); + for (int i = 0; i < edges.size(); ++i) + { + printf("Edge %d: %d -> %d with %f\n", i, edges[i].Ne, edges[i].Ke, edges[i].W); + } +} + +NeighboorVector Graph::GetNeigboors(int vertex) const +{ + NeighboorVector result; + for (int i = 0; i < edges.size(); ++i) + { + if (edges[i].Ke == vertex || edges[i].Ne == vertex) + { + Neighboor nv; + nv.edgeWeight = edges[i].W; + + if (edges[i].Ke == vertex) + { + nv.vertex = edges[i].Ne; + } + + else + { + nv.vertex = edges[i].Ke; + } + + result.push_back(nv); + } + } + + return result; +} + +void Graph::GenerateEdges(int nEdges) { + int currentEdgesNum = 0; + + while (edges.size() < nEdges) + { + bool fail = false; + int n = rand() % nVertex; + int k = rand() % nVertex; + + //The same vertex - try again + if (n == k) + { + continue; + } + + //This edge already exists + for (int i = 0; i < edges.size(); ++i) + { + if ((edges[i].Ke == n) && (edges[i].Ne == k) || + (edges[i].Ne == n) && (edges[i].Ke == k)) + { + fail = true; + break; + } + } + + if (fail) + { + continue; + } + + //This is a new edge + double W = generateWeight(); + sumOfWeights += W; + edges.push_back(Edge(n, k, W)); + } + + //print graph + Print(); + printf("\n\n"); +} \ No newline at end of file diff --git a/BelyakovaEA/Lab2/src/Kruskal.cpp b/BelyakovaEA/Lab2/src/Kruskal.cpp new file mode 100644 index 000000000..64be34e28 --- /dev/null +++ b/BelyakovaEA/Lab2/src/Kruskal.cpp @@ -0,0 +1 @@ +#include "Kruskal.h" \ No newline at end of file diff --git a/BelyakovaEA/Lab2/src/PriorituQueue.cpp b/BelyakovaEA/Lab2/src/PriorituQueue.cpp new file mode 100644 index 000000000..505aa0100 --- /dev/null +++ b/BelyakovaEA/Lab2/src/PriorituQueue.cpp @@ -0,0 +1 @@ +#include "PriorituQueue.h" \ No newline at end of file diff --git a/BelyakovaEA/Lab2/src/SeparatedSet.cpp b/BelyakovaEA/Lab2/src/SeparatedSet.cpp new file mode 100644 index 000000000..0de2bfbd0 --- /dev/null +++ b/BelyakovaEA/Lab2/src/SeparatedSet.cpp @@ -0,0 +1,48 @@ +#include "SeparatedSet.h" + +#include + +SeparatedSet::SeparatedSet(int _size) +{ + this->size = _size; + harVec = new int[size]; + + for (int i = 0; i < size; ++i) + { + harVec[i] = i; + } +} + + +void SeparatedSet::makesets(int idx) +{ + //printf("makeset %d\n", idx); + if ((idx > size - 1) || (idx < 0)) + throw ("out of range"); + + harVec[idx] = idx; +} + +int SeparatedSet::findsets(int idx) +{ + //printf("findset %d\n", idx); + if ((idx > size - 1) || (idx < 0)) + throw ("out of range"); + + return harVec[idx]; +} + +void SeparatedSet::unionsets(int x, int y) +{ + //printf("x %d y %d\n", x, y); + if ((x > size - 1) || (x < 0) || (y > size - 1) || (y < 0)) + throw ("out of range"); + + for (int i = 0; i < size; ++i) + { + if (harVec[i] == y) + { + harVec[i] = x; + } + } +} \ No newline at end of file From 08a8db8779c3fcd20eea380d467e109ee7d2cf14 Mon Sep 17 00:00:00 2001 From: Liza-Bel Date: Sun, 2 Sep 2018 14:55:37 +0300 Subject: [PATCH 5/6] lab2 --- BelyakovaEA/Lab2/build/LAB2/LAB2.sln | 67 -------- BelyakovaEA/Lab2/build/LAB2/LAB2/LAB2.vcxproj | 153 ------------------ .../Lab2/build/LAB2/LAB2/LAB2.vcxproj.filters | 17 -- 3 files changed, 237 deletions(-) delete mode 100644 BelyakovaEA/Lab2/build/LAB2/LAB2.sln delete mode 100644 BelyakovaEA/Lab2/build/LAB2/LAB2/LAB2.vcxproj delete mode 100644 BelyakovaEA/Lab2/build/LAB2/LAB2/LAB2.vcxproj.filters diff --git a/BelyakovaEA/Lab2/build/LAB2/LAB2.sln b/BelyakovaEA/Lab2/build/LAB2/LAB2.sln deleted file mode 100644 index 694cec9be..000000000 --- a/BelyakovaEA/Lab2/build/LAB2/LAB2.sln +++ /dev/null @@ -1,67 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Dijkstra", "Dijkstra\Dijkstra.vcxproj", "{26628341-5FBF-4172-A42B-92ACD3CDBD61}" - ProjectSection(ProjectDependencies) = postProject - {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51} = {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Kruskal", "Kruskal\Kruskal.vcxproj", "{834A6CCE-2870-4861-A084-F14FA7873BBA}" - ProjectSection(ProjectDependencies) = postProject - {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51} = {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PySort", "PySort\PySort.vcxproj", "{4A314873-F83F-42A6-8C6E-603C072C4982}" - ProjectSection(ProjectDependencies) = postProject - {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51} = {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Graph_lib", "Graph_lib\Graph_lib.vcxproj", "{F8C5FC5A-829E-4B18-A6ED-F56D0980DB51}" -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 - {26628341-5FBF-4172-A42B-92ACD3CDBD61}.Debug|x64.ActiveCfg = Debug|x64 - {26628341-5FBF-4172-A42B-92ACD3CDBD61}.Debug|x64.Build.0 = Debug|x64 - {26628341-5FBF-4172-A42B-92ACD3CDBD61}.Debug|x86.ActiveCfg = Debug|Win32 - {26628341-5FBF-4172-A42B-92ACD3CDBD61}.Debug|x86.Build.0 = Debug|Win32 - {26628341-5FBF-4172-A42B-92ACD3CDBD61}.Release|x64.ActiveCfg = Release|x64 - {26628341-5FBF-4172-A42B-92ACD3CDBD61}.Release|x64.Build.0 = Release|x64 - {26628341-5FBF-4172-A42B-92ACD3CDBD61}.Release|x86.ActiveCfg = Release|Win32 - {26628341-5FBF-4172-A42B-92ACD3CDBD61}.Release|x86.Build.0 = Release|Win32 - {834A6CCE-2870-4861-A084-F14FA7873BBA}.Debug|x64.ActiveCfg = Debug|x64 - {834A6CCE-2870-4861-A084-F14FA7873BBA}.Debug|x64.Build.0 = Debug|x64 - {834A6CCE-2870-4861-A084-F14FA7873BBA}.Debug|x86.ActiveCfg = Debug|Win32 - {834A6CCE-2870-4861-A084-F14FA7873BBA}.Debug|x86.Build.0 = Debug|Win32 - {834A6CCE-2870-4861-A084-F14FA7873BBA}.Release|x64.ActiveCfg = Release|x64 - {834A6CCE-2870-4861-A084-F14FA7873BBA}.Release|x64.Build.0 = Release|x64 - {834A6CCE-2870-4861-A084-F14FA7873BBA}.Release|x86.ActiveCfg = Release|Win32 - {834A6CCE-2870-4861-A084-F14FA7873BBA}.Release|x86.Build.0 = Release|Win32 - {4A314873-F83F-42A6-8C6E-603C072C4982}.Debug|x64.ActiveCfg = Debug|x64 - {4A314873-F83F-42A6-8C6E-603C072C4982}.Debug|x64.Build.0 = Debug|x64 - {4A314873-F83F-42A6-8C6E-603C072C4982}.Debug|x86.ActiveCfg = Debug|Win32 - {4A314873-F83F-42A6-8C6E-603C072C4982}.Debug|x86.Build.0 = Debug|Win32 - {4A314873-F83F-42A6-8C6E-603C072C4982}.Release|x64.ActiveCfg = Release|x64 - {4A314873-F83F-42A6-8C6E-603C072C4982}.Release|x64.Build.0 = Release|x64 - {4A314873-F83F-42A6-8C6E-603C072C4982}.Release|x86.ActiveCfg = Release|Win32 - {4A314873-F83F-42A6-8C6E-603C072C4982}.Release|x86.Build.0 = Release|Win32 - {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51}.Debug|x64.ActiveCfg = Debug|x64 - {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51}.Debug|x64.Build.0 = Debug|x64 - {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51}.Debug|x86.ActiveCfg = Debug|Win32 - {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51}.Debug|x86.Build.0 = Debug|Win32 - {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51}.Release|x64.ActiveCfg = Release|x64 - {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51}.Release|x64.Build.0 = Release|x64 - {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51}.Release|x86.ActiveCfg = Release|Win32 - {F8C5FC5A-829E-4B18-A6ED-F56D0980DB51}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/BelyakovaEA/Lab2/build/LAB2/LAB2/LAB2.vcxproj b/BelyakovaEA/Lab2/build/LAB2/LAB2/LAB2.vcxproj deleted file mode 100644 index 7eb94632d..000000000 --- a/BelyakovaEA/Lab2/build/LAB2/LAB2/LAB2.vcxproj +++ /dev/null @@ -1,153 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - {635D0BBA-8C12-4A1D-A0E3-6BDB350C776B} - Win32Proj - LAB2 - 8.1 - - - - Application - true - v140 - Unicode - - - Application - false - v140 - true - Unicode - - - Application - true - v140 - Unicode - - - Application - false - v140 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - - - true - - - false - - - false - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - - - - - - - Level3 - Disabled - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - - - - - Level3 - - - MaxSpeed - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - - - - - - - - \ No newline at end of file diff --git a/BelyakovaEA/Lab2/build/LAB2/LAB2/LAB2.vcxproj.filters b/BelyakovaEA/Lab2/build/LAB2/LAB2/LAB2.vcxproj.filters deleted file mode 100644 index f79baca3f..000000000 --- a/BelyakovaEA/Lab2/build/LAB2/LAB2/LAB2.vcxproj.filters +++ /dev/null @@ -1,17 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;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 From 2685c94539d520620854ce190c81f68b0738a8ef Mon Sep 17 00:00:00 2001 From: Liza-Bel Date: Sun, 2 Sep 2018 18:51:02 +0300 Subject: [PATCH 6/6] lab2 --- BelyakovaEA/Lab2/doc/Belyakova.doc | Bin 0 -> 246272 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 BelyakovaEA/Lab2/doc/Belyakova.doc diff --git a/BelyakovaEA/Lab2/doc/Belyakova.doc b/BelyakovaEA/Lab2/doc/Belyakova.doc new file mode 100644 index 0000000000000000000000000000000000000000..d1ca91b6c1a024a0b3ee147b91d4bea1503d5147 GIT binary patch literal 246272 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%0D%uay&Bi&y1ZsacW(4ebtom!oq3wb<@Y! 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 u}XGnUtOu;L^z5)5SSHEjB$aDJ?O;rCZn5 zZayx~nOV_kanUL1Y4HIrY3VLOf&MYRUDAhU#KvbjcZpAlkIjmY>ykAxg}3{LbPRFt z*`>XUv*v}!=u}?hH5X^TCoR)ACctH2R@Pu&50A{)f$^!)neOR>#qu=ATuoHZ&utu-}qz z%XyIA1-?qn=Szy0*$ieJnJhR!slBjZ+0&VAx%bYE2e-H!#5wN*40Yv&bMt0yWUI!S iV_QTQ^%B`lQz%i--Sv6T-A8_FzG28qW{UsN$NwKuyV$k> literal 0 HcmV?d00001