├── App.config ├── Properties ├── Settings.settings ├── Settings.Designer.cs ├── AssemblyInfo.cs ├── Resources.Designer.cs └── Resources.resx ├── Program.cs ├── DataTransmittionType.cs ├── Clusterization_algorithms.sln ├── GraphicsController.cs ├── README.md ├── Clusterization_algorithms.csproj ├── K_means.cs ├── SeedGenerator.cs ├── Forel.cs ├── Form1.resx ├── .gitignore ├── RouteBuilder.cs ├── Calculator.cs ├── EnergyCalculator.cs ├── Form1.cs └── Form1.Designer.cs /App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace Clusterization_algorithms 5 | { 6 | static class Program 7 | { 8 | [STAThread] 9 | static void Main() 10 | { 11 | Application.EnableVisualStyles(); 12 | Application.SetCompatibleTextRenderingDefault(false); 13 | Application.Run(new Form1()); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /DataTransmittionType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Clusterization_algorithms 8 | { 9 | public enum DataTransmittionType 10 | { 11 | DT_to_Center, //direct transmittion, send to center of cluster (station static position) 12 | DT_to_Route, // *to closer point on station route 13 | PP_to_Center, // Point to point 14 | PP_to_Route 15 | } 16 | 17 | public enum ClusterizationType 18 | { 19 | K_means, 20 | Forel 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | 12 | namespace Clusterization_algorithms.Properties 13 | { 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 17 | { 18 | 19 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 20 | 21 | public static Settings Default 22 | { 23 | get 24 | { 25 | return defaultInstance; 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Clusterization_algorithms.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31005.135 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Clusterization_algorithms", "Clusterization_algorithms.csproj", "{F07E1343-9534-406F-B84A-FCF2D10670EB}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {F07E1343-9534-406F-B84A-FCF2D10670EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {F07E1343-9534-406F-B84A-FCF2D10670EB}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {F07E1343-9534-406F-B84A-FCF2D10670EB}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {F07E1343-9534-406F-B84A-FCF2D10670EB}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {D2A626E6-659B-4747-B6B1-797DB806FD43} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Общие сведения об этой сборке предоставляются следующим набором 6 | // набора атрибутов. Измените значения этих атрибутов для изменения сведений, 7 | // связанных со сборкой. 8 | [assembly: AssemblyTitle("Clusterization_algorithms")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Clusterization_algorithms")] 13 | [assembly: AssemblyCopyright("Copyright © 2021")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми 18 | // для компонентов COM. Если необходимо обратиться к типу в этой сборке через 19 | // COM, следует установить атрибут ComVisible в TRUE для этого типа. 20 | [assembly: ComVisible(false)] 21 | 22 | // Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM 23 | [assembly: Guid("f07e1343-9534-406f-b84a-fcf2d10670eb")] 24 | 25 | // Сведения о версии сборки состоят из указанных ниже четырех значений: 26 | // 27 | // Основной номер версии 28 | // Дополнительный номер версии 29 | // Номер сборки 30 | // Редакция 31 | // 32 | // Можно задать все значения или принять номера сборки и редакции по умолчанию 33 | // используя "*", как показано ниже: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // Этот код создан программным средством. 4 | // Версия среды выполнения: 4.0.30319.42000 5 | // 6 | // Изменения в этом файле могут привести к неправильному поведению и будут утрачены, если 7 | // код создан повторно. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | 12 | namespace Clusterization_algorithms.Properties 13 | { 14 | /// 15 | /// Класс ресурсов со строгим типом для поиска локализованных строк и пр. 16 | /// 17 | // Этот класс был автоматически создан при помощи StronglyTypedResourceBuilder 18 | // класс с помощью таких средств, как ResGen или Visual Studio. 19 | // Для добавления или удаления члена измените файл .ResX, а затем перезапустите ResGen 20 | // с параметром /str или заново постройте свой VS-проект. 21 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 22 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 23 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 24 | internal class Resources 25 | { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() 33 | { 34 | } 35 | 36 | /// 37 | /// Возврат кэшированного экземпляра ResourceManager, используемого этим классом. 38 | /// 39 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 40 | internal static global::System.Resources.ResourceManager ResourceManager 41 | { 42 | get 43 | { 44 | if ((resourceMan == null)) 45 | { 46 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Clusterization_algorithms.Properties.Resources", typeof(Resources).Assembly); 47 | resourceMan = temp; 48 | } 49 | return resourceMan; 50 | } 51 | } 52 | 53 | /// 54 | /// Переопределяет свойство CurrentUICulture текущего потока для всех 55 | /// подстановки ресурсов с помощью этого класса ресурсов со строгим типом. 56 | /// 57 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 58 | internal static global::System.Globalization.CultureInfo Culture 59 | { 60 | get 61 | { 62 | return resourceCulture; 63 | } 64 | set 65 | { 66 | resourceCulture = value; 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /GraphicsController.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Drawing; 3 | using System.Threading; 4 | 5 | namespace Clusterization_algorithms 6 | { 7 | public class GraphicsController 8 | { 9 | private Graphics _graphics; 10 | 11 | public GraphicsController(Graphics graphics) 12 | { 13 | _graphics = graphics; 14 | } 15 | 16 | public GraphicsController() 17 | { 18 | } 19 | 20 | public void PAUSE(int pause = 100) 21 | { 22 | Thread.Sleep(pause); // set this value to set drawing speed 23 | } 24 | 25 | public void DrawLine(Point p1, Point p2, Color color) 26 | { 27 | Pen pen = new Pen(color); 28 | pen.Width = 3; 29 | _graphics.DrawLine(pen, p1, p2); 30 | } 31 | 32 | public void DrawCircle(Point p, int radius, Color color, int pause = 30) 33 | { 34 | Pen pen = new Pen(color); 35 | pen.Width = 2; 36 | _graphics.DrawEllipse(pen, p.X - radius, p.Y - radius, 2 * radius, 2 * radius); 37 | PAUSE(pause); 38 | } 39 | 40 | public void DrawPoint(Point p, Brush brush, int size = 4) 41 | { 42 | int s = (int)(size/2); 43 | _graphics.FillRectangle(brush, p.X - s, p.Y - s, size, size); 44 | } 45 | 46 | public void DrawPointArray(Point[] points) 47 | { 48 | for (int i = 0; i < points.Length; i++) 49 | { 50 | DrawPoint(points[i], Brushes.Black); 51 | } 52 | } 53 | 54 | public void DrawPointDictionary(Dictionary points) 55 | { 56 | foreach (KeyValuePair result in points) 57 | DrawPoint(result.Key, Brushes.Black); 58 | } 59 | 60 | public void DrawPointList(List points) 61 | { 62 | foreach (Point point in points) 63 | DrawPoint(point, Brushes.Black); 64 | } 65 | 66 | public void ClearImage() 67 | { 68 | _graphics.Clear(Color.White); 69 | } 70 | 71 | public void DrawRoute(List points, Color color, int pause = 10) 72 | { 73 | for (int i = 1; i < points.Count; i++) 74 | { 75 | DrawLine(points[i - 1], points[i], color); 76 | PAUSE(pause); 77 | } 78 | } 79 | 80 | public void DrawNet(int x_count, int y_count, double width, double heigth) 81 | { 82 | // cell sides size 83 | double x_side = width / x_count; 84 | double y_side = heigth / y_count; 85 | 86 | // draw horisontal lines 87 | for (int ix = 0; ix <= x_count; ix++) 88 | { 89 | int x_position = (int) (x_side * ix); 90 | Point pointUp = new Point(x_position, 0); 91 | Point pointDown = new Point(x_position, (int)heigth); 92 | 93 | DrawLine(pointUp, pointDown, Color.DarkGray); 94 | } 95 | 96 | // draw vertical lines 97 | for (int iy = 0; iy <= x_count; iy++) 98 | { 99 | int y_position = (int)(y_side * iy); 100 | Point pointLeft = new Point(0, y_position); 101 | Point pointRight = new Point((int)width, y_position); 102 | 103 | DrawLine(pointLeft, pointRight, Color.DarkGray); 104 | } 105 | 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # About "Clusterization_algorithms" project 2 | 3 | ## Abbreviations, terms and articles links 4 | 5 | ### Abbreviations 6 | 7 | - [UAV](https://en.wikipedia.org/wiki/Unmanned_aerial_vehicle) - *Unmanned aerial vehicle* 8 | - [WSN](https://en.wikipedia.org/wiki/Wireless_sensor_network) - *Wireless sensor network* 9 | - [TSP](https://en.wikipedia.org/wiki/Travelling_salesman_problem) - *Travelling salesman problem* 10 | - DEEC - *Distributed energy-efficient clustering algorithm* 11 | 12 | ### Terms 13 | 14 | #### General 15 | 16 | - [Cluster analysis](https://en.wikipedia.org/wiki/Cluster_analysis) 17 | - [Convex hull algorithms](https://en.wikipedia.org/wiki/Convex_hull_algorithms) 18 | - [Gift wrapping algorithm (Jarvis march)](https://en.wikipedia.org/wiki/Gift_wrapping_algorithm) 19 | - [Greedy algorithm](https://en.wikipedia.org/wiki/Greedy_algorithm) 20 | 21 | #### Clustering algorithms 22 | 23 | - [K-means](https://en.wikipedia.org/wiki/K-means_clustering) 24 | - [K-means++](https://en.wikipedia.org/wiki/K-means%2B%2B) 25 | - [Forel](https://ru.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D1%81%D0%B5%D0%BC%D0%B5%D0%B9%D1%81%D1%82%D0%B2%D0%B0_FOREL) 26 | 27 | #### Route search algorithms 28 | 29 | - [Brute-force](https://en.wikipedia.org/wiki/Brute-force_search) 30 | - [Convex hull insertion](https://www2.isye.gatech.edu/~mgoetsch/cali/VEHICLE/TSP/TSP017__.HTM) 31 | - [Nearest neighbour](https://en.wikipedia.org/wiki/Nearest_neighbour_algorithm) 32 | - [Spiral route](https://www.researchgate.net/figure/Spiral-search-route-of-area-target_fig6_349545726) 33 | - FPPWR 34 | 35 | ### References to used articles 36 | - [Initial Centroid Selection Method for an Enhanced K-means Clustering Algorithm](https://link.springer.com/chapter/10.1007/978-3-030-58008-7_15#:~:text=K%2Dmeans%20is%20one%20of,or%20given%20by%20the%20user.) 37 | - [Centroid Initialization Methods for k-means Clustering](https://www.kdnuggets.com/2020/06/centroid-initialization-k-means-clustering.html) 38 | - [Data Clustering with K-Means++ Using C#](https://visualstudiomagazine.com/Articles/2020/05/06/data-clustering-k-means.aspx?Page=1) 39 | - [An energy-efficient distributed clustering algorithm for heterogeneous WSNs](https://jwcn-eurasipjournals.springeropen.com/articles/10.1186/s13638-015-0376-4#Equ10) 40 | - [Design of a distributed energy-efficient clustering algorithm for heterogeneous wireless sensor networks](https://www.sciencedirect.com/science/article/abs/pii/S0140366406000727) 41 | - [Energy-efficient clustering algorithm based on game theory for wireless sensor networks](https://journals.sagepub.com/doi/full/10.1177/1550147717743701) 42 | - [Ameliored Threshold Distributed Energy Efficient Clustering Algorithm for Heterogeneous Wireless Sensor Networks](https://www.researchgate.net/publication/262916599_Ameliored_Threshold_Distributed_Energy_Efficient_Clustering_Algorithm_for_Heterogeneous_Wireless_Sensor_Networks) 43 | 44 | ## Project goals and objectives 45 | 46 | ### Physical model of system operation 47 | 48 | We have a field with positioned sensor nodes. 49 | 1. Detect sensors position. 50 | 2. Create sensor network map. 51 | 3. Clustering of nodes (according to specified parameters). 52 | 4. Build optimal route for UAV station (according to specified parameters). 53 | 5. Collect data from nodes. 54 | 55 | ### Project tasks 56 | 57 | 1. Create a node generator. 58 | 2. Create a node map. 59 | 3. Node clustering. Algorithm comparison. 60 | - k-means++ 61 | - forel 62 | 4. Route calculation. Algorithm comparison. 63 | With mathematical calculation: 64 | - Brute-force 65 | - Nearest neighbour 66 | - Convex hull insertion (by angle of rotation) 67 | - Spiral route 68 | - FPPWR 69 | 5. Process of data collection. 70 | 1. DEEC algorithm. 71 | 2. Data transmission types. 72 | - Direct transmittion. 73 | - Point-to-point. 74 | 4. Create an energy model of the system. 75 | 5. Create statistic. 76 | -------------------------------------------------------------------------------- /Clusterization_algorithms.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {F07E1343-9534-406F-B84A-FCF2D10670EB} 8 | WinExe 9 | Clusterization_algorithms 10 | Clusterization_algorithms 11 | v4.7.2 12 | 512 13 | true 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | Form 55 | 56 | 57 | Form1.cs 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | Form1.cs 67 | 68 | 69 | ResXFileCodeGenerator 70 | Resources.Designer.cs 71 | Designer 72 | 73 | 74 | True 75 | Resources.resx 76 | 77 | 78 | SettingsSingleFileGenerator 79 | Settings.Designer.cs 80 | 81 | 82 | True 83 | Settings.settings 84 | True 85 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /K_means.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.Linq; 5 | 6 | namespace Clusterization_algorithms 7 | { 8 | public class K_means 9 | { 10 | /* Dictionary contain all pairs (point, number_of_cluster), 11 | * if (cluster = 0) => point not belong to cluster*/ 12 | private Dictionary _points = new Dictionary(); 13 | private List _seeds; 14 | private GraphicsController _graphic; 15 | 16 | public List Seeds { get => _seeds; set => _seeds = value; } 17 | 18 | public K_means() 19 | { 20 | } 21 | 22 | public K_means(GraphicsController graphic) 23 | { 24 | this._graphic = graphic; 25 | } 26 | 27 | public void SetPoints(Dictionary pointDictionary) 28 | { 29 | _points.Clear(); 30 | 31 | foreach (KeyValuePair point in pointDictionary) 32 | { 33 | _points.Add(point.Key, point.Value); 34 | } 35 | } 36 | 37 | public Dictionary GetPoints() => _points; 38 | 39 | public void DrawSeeds() 40 | { 41 | foreach (Point seed in _seeds) 42 | _graphic.DrawPoint(seed, Brushes.Red, 6); 43 | } 44 | 45 | /// 46 | /// Add point/node to the cluster 47 | /// 48 | private void AddToCluster(KeyValuePair point, int clusterNum) 49 | { 50 | _points.Remove(point.Key); 51 | _points.Add(point.Key, clusterNum); 52 | } 53 | 54 | private void FindAllClusters() 55 | { 56 | for (int i = 0; i < _points.Count; i++) 57 | { 58 | double distance = double.MaxValue; 59 | int closerSeedNum = 0; 60 | KeyValuePair point = _points.ElementAt(i); 61 | 62 | for (int j = 0; j < _seeds.Count; j++) 63 | { 64 | double dist = Calculator.CalcDistance(point.Key, _seeds.ElementAt(j)); 65 | 66 | if (dist < distance) 67 | { 68 | distance = dist; 69 | closerSeedNum = j + 1; 70 | } 71 | } 72 | 73 | AddToCluster(point, closerSeedNum); 74 | _graphic.DrawLine(_seeds.ElementAt(closerSeedNum - 1), point.Key, Color.LightGreen); 75 | } 76 | } 77 | 78 | private Boolean FindCentroids() 79 | { 80 | List centroids = new List { }; 81 | 82 | for (int i = 0; i < _seeds.Count; i++) 83 | { 84 | List pointList = new List { }; 85 | 86 | foreach (KeyValuePair pair in _points) 87 | { 88 | if (i + 1 == pair.Value) 89 | pointList.Add(pair.Key); 90 | } 91 | 92 | Point centroid = Calculator.FindCentroid(pointList); 93 | centroids.Add(centroid); 94 | } 95 | 96 | if (!IsEqualSeed(centroids)) 97 | { 98 | _seeds = centroids; 99 | } 100 | else return false; 101 | 102 | return true; 103 | } 104 | 105 | public void StartK_means() 106 | { 107 | _graphic.DrawPointDictionary(_points); 108 | DrawSeeds(); 109 | FindAllClusters(); 110 | 111 | if (FindCentroids()) 112 | { 113 | _graphic.PAUSE(100); 114 | _graphic.ClearImage(); 115 | StartK_means(); 116 | } 117 | 118 | DrawSeeds(); 119 | } 120 | 121 | private Boolean IsEqualSeed(List list) 122 | { 123 | for (int i = 0; i < _seeds.Count; i++) 124 | { 125 | if (_seeds.ElementAt(i) != list.ElementAt(i)) 126 | return false; 127 | } 128 | 129 | return true; 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /SeedGenerator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.Linq; 5 | 6 | namespace Clusterization_algorithms 7 | { 8 | /// 9 | /// Weighed random with points to k-means++ algorithm 10 | /// Allows to calculate optimal start positions to seeds 11 | /// 12 | public class SeedGenerator 13 | { 14 | private Dictionary _points = new Dictionary { }; // ; Weight is equal to distance 15 | public int _seedCount = 2; 16 | private Random _rand = new Random(); 17 | private List _seeds = new List { }; 18 | private double _sumOfWeight = 0; 19 | 20 | public SeedGenerator() 21 | { 22 | } 23 | 24 | public SeedGenerator(Dictionary points, int seedCount) 25 | { 26 | SetPoints(points); 27 | _seedCount = seedCount; 28 | } 29 | 30 | public List GetSeeds() 31 | { 32 | int rnum = _rand.Next(0, _points.Count - 1); 33 | Point seed1 = _points.ElementAt(rnum).Key; // get 1-st random seed from points 34 | _seeds.Add(seed1); // add point to seed list 35 | _points.Remove(seed1); // remove this point from points 36 | 37 | CalculatePointsWeight(seed1); 38 | 39 | for (int i = 1; i < _seedCount; i++) 40 | { 41 | FindNewSeed(); 42 | } 43 | 44 | return _seeds; 45 | } 46 | 47 | private void FindNewSeed() 48 | { 49 | SortPoints(); 50 | 51 | double rsum = _rand.Next(0, (int)_sumOfWeight); 52 | 53 | for (int i = 0; i < _points.Count; i++) 54 | { 55 | var pair = _points.ElementAt(i); 56 | 57 | if (pair.Value >= rsum) 58 | { 59 | _seeds.Add(pair.Key); 60 | _points.Remove(pair.Key); 61 | CalculatePointsWeight(pair.Key); 62 | break; 63 | } 64 | 65 | rsum -= pair.Value; 66 | } 67 | } 68 | 69 | private void SortPoints() 70 | { 71 | Dictionary newPoints = new Dictionary { }; 72 | 73 | foreach (var pair in _points.OrderBy(ppair => ppair.Value)) 74 | { 75 | newPoints.Add(pair.Key, pair.Value); 76 | } 77 | _points = newPoints; 78 | } 79 | 80 | private void CalculatePointsWeight(Point seed) 81 | { 82 | Dictionary newPoints = new Dictionary { }; 83 | _sumOfWeight = 0; 84 | 85 | for (int i = 0; i < _points.Count; i++) 86 | { 87 | Point point = _points.ElementAt(i).Key; 88 | double weigh = _points.ElementAt(i).Value; 89 | 90 | double dist = Calculator.CalcDistance(seed, point); 91 | weigh += dist; 92 | _sumOfWeight += weigh; 93 | 94 | newPoints.Add(point, weigh); 95 | } 96 | _points = newPoints; 97 | } 98 | 99 | public void SetPoints(Dictionary dictionary) 100 | { 101 | _points.Clear(); 102 | 103 | foreach (var pair in dictionary) 104 | { 105 | _points.Add(pair.Key, 0); 106 | } 107 | } 108 | 109 | public String PrintPoints() 110 | { 111 | String str = ""; 112 | 113 | Console.WriteLine("Points list:"); 114 | 115 | foreach (var point in _points) 116 | { 117 | Console.WriteLine(point.ToString()); 118 | str += point.ToString() + "\n"; 119 | } 120 | 121 | Console.WriteLine(); 122 | return str; 123 | } 124 | 125 | public void PrintSeeds() 126 | { 127 | Console.WriteLine("Print seeds:"); 128 | 129 | foreach (Point seed in _seeds) 130 | { 131 | Console.WriteLine(seed.ToString()); 132 | } 133 | 134 | Console.WriteLine(); 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /Forel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.Linq; 5 | 6 | namespace Clusterization_algorithms 7 | { 8 | public class Forel 9 | { 10 | public int clusterNum = 0; 11 | public List ListOfClastersCenter = new List(); 12 | 13 | /* Dictionary contain all pairs (point, number_of_cluster), 14 | * if (cluster = 0) => point/node not belong to cluster*/ 15 | private Dictionary _points = new Dictionary(); 16 | private int _radius; // nodes search radius 17 | private GraphicsController _graphics; 18 | 19 | public int Radius { get => _radius; set => _radius = value; } 20 | 21 | public Forel() 22 | { 23 | } 24 | 25 | public Forel(GraphicsController graphics) 26 | { 27 | _graphics = graphics; 28 | } 29 | 30 | public void SetPoints(Dictionary pointDictionary) 31 | { 32 | _points.Clear(); 33 | ListOfClastersCenter.Clear(); 34 | 35 | foreach (KeyValuePair point in pointDictionary) 36 | { 37 | _points.Add(point.Key, point.Value); 38 | } 39 | } 40 | 41 | public Dictionary GetPoints() 42 | { 43 | return _points; 44 | } 45 | 46 | /// 47 | /// Add selected point to cluster 48 | /// 49 | private void AddToCluster(Point key) 50 | { 51 | _points.Remove(key); 52 | _points.Add(key, clusterNum); 53 | } 54 | 55 | /// 56 | /// Add points to the cluster 57 | /// 58 | private void AddPointsToCluster(List pointsList) 59 | { 60 | foreach (Point point in pointsList) 61 | { 62 | AddToCluster(point); 63 | } 64 | } 65 | 66 | /// 67 | /// Get cluster from the cluster center coordinates 68 | /// 69 | private List GetCluster(Point center) 70 | { 71 | List cluster = new List { }; 72 | 73 | for (int i = 0; i < _points.Count; i++) 74 | { 75 | 76 | if (_points.ElementAt(i).Value == 0) 77 | { 78 | double distance = Calculator.CalcDistance(center, _points.ElementAt(i).Key); 79 | 80 | if (distance <= _radius) 81 | { 82 | cluster.Add(_points.ElementAt(i).Key); 83 | } 84 | } 85 | } 86 | 87 | return cluster; 88 | } 89 | 90 | /// 91 | /// Calculate new centroid (mass center) 92 | /// 93 | private Point FindNewCenter(Point center) 94 | { 95 | List cluster = GetCluster(center); 96 | 97 | if (cluster.Count == 0){ // if cluster no have elements, new_center = center 98 | 99 | _graphics.DrawCircle(center, _radius, Color.Black); 100 | ListOfClastersCenter.Add(center); 101 | return center; 102 | } 103 | 104 | Point newCenter = Calculator.FindCentroid(cluster); 105 | _graphics.DrawPoint(newCenter, Brushes.Pink, 6); 106 | _graphics.DrawCircle(newCenter, _radius, Color.LightGray); 107 | 108 | if (center == newCenter){ 109 | _graphics.DrawCircle(center, _radius, Color.Black); 110 | _graphics.DrawPoint(newCenter, Brushes.Red, 6); 111 | ListOfClastersCenter.Add(center); 112 | } 113 | 114 | return newCenter; 115 | } 116 | 117 | /// 118 | /// Start calculating clusters 119 | /// 120 | private Point StartClusterisation(Point center) 121 | { 122 | Point newCenter = FindNewCenter(center); 123 | 124 | if (newCenter != center) 125 | StartClusterisation(newCenter); 126 | else 127 | AddPointsToCluster(GetCluster(newCenter)); 128 | 129 | return newCenter; 130 | } 131 | 132 | 133 | /// 134 | /// START FOREL CLUSTERISATION 135 | /// 136 | public void StartForel() 137 | { 138 | clusterNum = 0; 139 | 140 | for (int i = 0; i < _points.Count; i++) 141 | { 142 | 143 | if (_points.ElementAt(i).Value == 0) 144 | { 145 | clusterNum++; 146 | StartClusterisation(_points.ElementAt(i).Key); 147 | } 148 | } 149 | } 150 | 151 | /// 152 | /// Print formatted to TextBox 153 | /// 154 | private void PrintList(List list) 155 | { 156 | Console.WriteLine("Print point list:"); 157 | int counter = 1; 158 | 159 | foreach (Point p in list) 160 | { 161 | Console.Write(p + " "); 162 | if (counter % 10 == 0) 163 | Console.WriteLine(); 164 | counter++; 165 | } 166 | } 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /Form1.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | 124 | Calculate the energy consumption for data transmission. 125 | Draw the transmission path. 126 | Select connection type: 127 | DT - direct transmittion (next: tr) 128 | DT center - tr to cluster (mass) centers 129 | DT route - tr to station move way 130 | PP - point-to-point connection 131 | PP center - from point to point to cluster center 132 | PP route - PP to station move way 133 | 134 | 135 | 136 | Draw a net, build route by cells. 137 | Move like a snake in every cells to closer point 138 | then move to next cell. 139 | Cells: from left to right > down 1 > right-left 140 | again to the end of row 141 | if all rows is passed, move to start 142 | 143 | 144 | 42 145 | 146 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Aa][Rr][Mm]/ 27 | [Aa][Rr][Mm]64/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | [Ll]ogs/ 33 | 34 | # Visual Studio 2015/2017 cache/options directory 35 | .vs/ 36 | # Uncomment if you have tasks that create the project's static files in wwwroot 37 | #wwwroot/ 38 | 39 | # Visual Studio 2017 auto generated files 40 | Generated\ Files/ 41 | 42 | # MSTest test Results 43 | [Tt]est[Rr]esult*/ 44 | [Bb]uild[Ll]og.* 45 | 46 | # NUnit 47 | *.VisualState.xml 48 | TestResult.xml 49 | nunit-*.xml 50 | 51 | # Build Results of an ATL Project 52 | [Dd]ebugPS/ 53 | [Rr]eleasePS/ 54 | dlldata.c 55 | 56 | # Benchmark Results 57 | BenchmarkDotNet.Artifacts/ 58 | 59 | # .NET Core 60 | project.lock.json 61 | project.fragment.lock.json 62 | artifacts/ 63 | 64 | # StyleCop 65 | StyleCopReport.xml 66 | 67 | # Files built by Visual Studio 68 | *_i.c 69 | *_p.c 70 | *_h.h 71 | *.ilk 72 | *.meta 73 | *.obj 74 | *.iobj 75 | *.pch 76 | *.pdb 77 | *.ipdb 78 | *.pgc 79 | *.pgd 80 | *.rsp 81 | *.sbr 82 | *.tlb 83 | *.tli 84 | *.tlh 85 | *.tmp 86 | *.tmp_proj 87 | *_wpftmp.csproj 88 | *.log 89 | *.vspscc 90 | *.vssscc 91 | .builds 92 | *.pidb 93 | *.svclog 94 | *.scc 95 | 96 | # Chutzpah Test files 97 | _Chutzpah* 98 | 99 | # Visual C++ cache files 100 | ipch/ 101 | *.aps 102 | *.ncb 103 | *.opendb 104 | *.opensdf 105 | *.sdf 106 | *.cachefile 107 | *.VC.db 108 | *.VC.VC.opendb 109 | 110 | # Visual Studio profiler 111 | *.psess 112 | *.vsp 113 | *.vspx 114 | *.sap 115 | 116 | # Visual Studio Trace Files 117 | *.e2e 118 | 119 | # TFS 2012 Local Workspace 120 | $tf/ 121 | 122 | # Guidance Automation Toolkit 123 | *.gpState 124 | 125 | # ReSharper is a .NET coding add-in 126 | _ReSharper*/ 127 | *.[Rr]e[Ss]harper 128 | *.DotSettings.user 129 | 130 | # TeamCity is a build add-in 131 | _TeamCity* 132 | 133 | # DotCover is a Code Coverage Tool 134 | *.dotCover 135 | 136 | # AxoCover is a Code Coverage Tool 137 | .axoCover/* 138 | !.axoCover/settings.json 139 | 140 | # Visual Studio code coverage results 141 | *.coverage 142 | *.coveragexml 143 | 144 | # NCrunch 145 | _NCrunch_* 146 | .*crunch*.local.xml 147 | nCrunchTemp_* 148 | 149 | # MightyMoose 150 | *.mm.* 151 | AutoTest.Net/ 152 | 153 | # Web workbench (sass) 154 | .sass-cache/ 155 | 156 | # Installshield output folder 157 | [Ee]xpress/ 158 | 159 | # DocProject is a documentation generator add-in 160 | DocProject/buildhelp/ 161 | DocProject/Help/*.HxT 162 | DocProject/Help/*.HxC 163 | DocProject/Help/*.hhc 164 | DocProject/Help/*.hhk 165 | DocProject/Help/*.hhp 166 | DocProject/Help/Html2 167 | DocProject/Help/html 168 | 169 | # Click-Once directory 170 | publish/ 171 | 172 | # Publish Web Output 173 | *.[Pp]ublish.xml 174 | *.azurePubxml 175 | # Note: Comment the next line if you want to checkin your web deploy settings, 176 | # but database connection strings (with potential passwords) will be unencrypted 177 | *.pubxml 178 | *.publishproj 179 | 180 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 181 | # checkin your Azure Web App publish settings, but sensitive information contained 182 | # in these scripts will be unencrypted 183 | PublishScripts/ 184 | 185 | # NuGet Packages 186 | *.nupkg 187 | # NuGet Symbol Packages 188 | *.snupkg 189 | # The packages folder can be ignored because of Package Restore 190 | **/[Pp]ackages/* 191 | # except build/, which is used as an MSBuild target. 192 | !**/[Pp]ackages/build/ 193 | # Uncomment if necessary however generally it will be regenerated when needed 194 | #!**/[Pp]ackages/repositories.config 195 | # NuGet v3's project.json files produces more ignorable files 196 | *.nuget.props 197 | *.nuget.targets 198 | 199 | # Microsoft Azure Build Output 200 | csx/ 201 | *.build.csdef 202 | 203 | # Microsoft Azure Emulator 204 | ecf/ 205 | rcf/ 206 | 207 | # Windows Store app package directories and files 208 | AppPackages/ 209 | BundleArtifacts/ 210 | Package.StoreAssociation.xml 211 | _pkginfo.txt 212 | *.appx 213 | *.appxbundle 214 | *.appxupload 215 | 216 | # Visual Studio cache files 217 | # files ending in .cache can be ignored 218 | *.[Cc]ache 219 | # but keep track of directories ending in .cache 220 | !?*.[Cc]ache/ 221 | 222 | # Others 223 | ClientBin/ 224 | ~$* 225 | *~ 226 | *.dbmdl 227 | *.dbproj.schemaview 228 | *.jfm 229 | *.pfx 230 | *.publishsettings 231 | orleans.codegen.cs 232 | 233 | # Including strong name files can present a security risk 234 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 235 | #*.snk 236 | 237 | # Since there are multiple workflows, uncomment next line to ignore bower_components 238 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 239 | #bower_components/ 240 | 241 | # RIA/Silverlight projects 242 | Generated_Code/ 243 | 244 | # Backup & report files from converting an old project file 245 | # to a newer Visual Studio version. Backup files are not needed, 246 | # because we have git ;-) 247 | _UpgradeReport_Files/ 248 | Backup*/ 249 | UpgradeLog*.XML 250 | UpgradeLog*.htm 251 | ServiceFabricBackup/ 252 | *.rptproj.bak 253 | 254 | # SQL Server files 255 | *.mdf 256 | *.ldf 257 | *.ndf 258 | 259 | # Business Intelligence projects 260 | *.rdl.data 261 | *.bim.layout 262 | *.bim_*.settings 263 | *.rptproj.rsuser 264 | *- [Bb]ackup.rdl 265 | *- [Bb]ackup ([0-9]).rdl 266 | *- [Bb]ackup ([0-9][0-9]).rdl 267 | 268 | # Microsoft Fakes 269 | FakesAssemblies/ 270 | 271 | # GhostDoc plugin setting file 272 | *.GhostDoc.xml 273 | 274 | # Node.js Tools for Visual Studio 275 | .ntvs_analysis.dat 276 | node_modules/ 277 | 278 | # Visual Studio 6 build log 279 | *.plg 280 | 281 | # Visual Studio 6 workspace options file 282 | *.opt 283 | 284 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 285 | *.vbw 286 | 287 | # Visual Studio LightSwitch build output 288 | **/*.HTMLClient/GeneratedArtifacts 289 | **/*.DesktopClient/GeneratedArtifacts 290 | **/*.DesktopClient/ModelManifest.xml 291 | **/*.Server/GeneratedArtifacts 292 | **/*.Server/ModelManifest.xml 293 | _Pvt_Extensions 294 | 295 | # Paket dependency manager 296 | .paket/paket.exe 297 | paket-files/ 298 | 299 | # FAKE - F# Make 300 | .fake/ 301 | 302 | # CodeRush personal settings 303 | .cr/personal 304 | 305 | # Python Tools for Visual Studio (PTVS) 306 | __pycache__/ 307 | *.pyc 308 | 309 | # Cake - Uncomment if you are using it 310 | # tools/** 311 | # !tools/packages.config 312 | 313 | # Tabs Studio 314 | *.tss 315 | 316 | # Telerik's JustMock configuration file 317 | *.jmconfig 318 | 319 | # BizTalk build output 320 | *.btp.cs 321 | *.btm.cs 322 | *.odx.cs 323 | *.xsd.cs 324 | 325 | # OpenCover UI analysis results 326 | OpenCover/ 327 | 328 | # Azure Stream Analytics local run output 329 | ASALocalRun/ 330 | 331 | # MSBuild Binary and Structured Log 332 | *.binlog 333 | 334 | # NVidia Nsight GPU debugger configuration file 335 | *.nvuser 336 | 337 | # MFractors (Xamarin productivity tool) working folder 338 | .mfractor/ 339 | 340 | # Local History for Visual Studio 341 | .localhistory/ 342 | 343 | # BeatPulse healthcheck temp database 344 | healthchecksdb 345 | 346 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 347 | MigrationBackup/ 348 | 349 | # Ionide (cross platform F# VS Code tools) working folder 350 | .ionide/ 351 | -------------------------------------------------------------------------------- /RouteBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Drawing; 3 | 4 | namespace Clusterization_algorithms 5 | { 6 | public class RouteBuilder 7 | { 8 | private Point _startPoint = new Point(0, 0); 9 | private List _all_points = new List { }; // start point position 10 | private List _routeList = new List { }; // finish point position 11 | private List _convex_hull = new List { }; 12 | private List _inside_points = new List { }; 13 | 14 | private double _length; 15 | 16 | public List Convex_hull { get => _convex_hull; } 17 | public List RouteList { get => _routeList; set => _routeList = value; } 18 | 19 | public RouteBuilder() { } 20 | 21 | public void SetPoints(List points) 22 | { 23 | _all_points.Clear(); 24 | _all_points.AddRange(points); 25 | } 26 | 27 | public List CalculateRouteByConvexHullInsertion() 28 | { 29 | JarvisMarch(); 30 | ConvexHullInsertion(); 31 | 32 | List unsort_route = new List { }; 33 | unsort_route.AddRange(_routeList); 34 | _routeList.Clear(); 35 | 36 | SortInsidePoints(); 37 | ConvexHullInsertion(); 38 | 39 | double unsorted_route_length = Calculator.CalcRouteLength(unsort_route); 40 | double sorted_route_length = Calculator.CalcRouteLength(_routeList); 41 | 42 | if (unsorted_route_length < sorted_route_length) 43 | { 44 | _routeList.Clear(); 45 | _routeList.AddRange(unsort_route); 46 | } 47 | 48 | return _routeList; 49 | } 50 | 51 | private List ConvexHullInsertion() 52 | { 53 | _routeList.AddRange(_convex_hull); 54 | 55 | for (int i = 0; i < _inside_points.Count; i++) 56 | { 57 | double minCos = Calculator.GetCOS(_routeList[0], _inside_points[i], _routeList[1]); // variables value when j = 0 in loop 58 | int pos = 0; // first selected position in route 59 | 60 | for (int j = 1; j < _routeList.Count - 1; j++) 61 | { 62 | double cos = Calculator.GetCOS(_routeList[j], _inside_points[i], _routeList[j + 1]); 63 | 64 | if (cos >= minCos) 65 | { 66 | minCos = cos; 67 | pos = j; 68 | } 69 | } 70 | 71 | AddToRouteAtPos(pos + 1, _inside_points[i]); 72 | } 73 | return _routeList; 74 | } 75 | 76 | /// 77 | /// Add point at the selected position in route 78 | /// 79 | private void AddToRouteAtPos(int position, Point point) 80 | { 81 | 82 | List newRoute = new List { }; 83 | 84 | for (int i = 0; i < _routeList.Count; i++) 85 | { 86 | 87 | if (i == position) 88 | newRoute.Add(point); 89 | 90 | newRoute.Add(_routeList[i]); 91 | } 92 | _routeList.Clear(); 93 | _routeList.AddRange(newRoute); 94 | } 95 | 96 | /// 97 | /// Jarvis march algorithm, also known as gift wrappening algorithm. 98 | /// If not stop it on a start point when wrappening is finished, will create a spiral route 99 | /// 100 | public void JarvisMarch(bool getSpiralRoute = false) 101 | { 102 | _routeList.Clear(); 103 | _convex_hull.Clear(); 104 | _inside_points.Clear(); 105 | 106 | List points = new List { }; 107 | points.AddRange(_all_points); 108 | 109 | Point falsePoint = new Point(_startPoint.X - 1, _startPoint.Y); // line(vector) point where wrappening starts (counterclockwise) 110 | 111 | // axes directions -> ↓(Y) →(X) 112 | _convex_hull.Add(_startPoint); 113 | _convex_hull.Add(falsePoint); 114 | 115 | Point point = points[0]; 116 | 117 | if(!getSpiralRoute) 118 | points.Add(_startPoint); // if we want to wrap points 119 | 120 | int ki = 0; 121 | 122 | do 123 | { 124 | double max_cos = -1; // cos(0°...90°...180°) = 1...0...-1 125 | Point nextPoint = _startPoint; 126 | 127 | for (int i = 0; i < points.Count; i++) 128 | { // where cos is min that point is next 129 | double cos = Calculator.GetCOS(_convex_hull[ki], _convex_hull[ki + 1], points[i]); // шукаємо косинус кута між векторами 130 | //Console.WriteLine("cos = " + 131 | if (cos > max_cos) // the less cos the larger angle between vectors 132 | { 133 | max_cos = cos; 134 | nextPoint = points[i]; 135 | } 136 | } 137 | 138 | point = nextPoint; 139 | ki++; 140 | points.Remove(nextPoint); 141 | _convex_hull.Add(nextPoint); 142 | } 143 | while (point != _startPoint); 144 | 145 | _convex_hull.Remove(falsePoint); 146 | _inside_points.AddRange(points); 147 | 148 | if (getSpiralRoute) 149 | { 150 | _routeList = _convex_hull; 151 | } 152 | } 153 | 154 | /// 155 | /// Sort points inside convex hull by they mass center 156 | /// 157 | private void SortInsidePoints() // TODO: I definitely wanted to improve something here. 158 | { 159 | Point center = Calculator.FindCentroid(_all_points); 160 | Dictionary dict = new Dictionary { }; 161 | 162 | for (int i = 0; i < _inside_points.Count; i++) 163 | { 164 | double dist = Calculator.CalcDistance(center, _inside_points[i]); 165 | dict.Add(_inside_points[i], dist); 166 | } 167 | 168 | dict = Calculator.SortDictionaryByValue(dict); 169 | 170 | _inside_points.Clear(); 171 | _inside_points.AddRange(Calculator.DictionaryToList(dict)); 172 | } 173 | 174 | public List CalculateRouteBruteForce(List pointList) 175 | { 176 | if (pointList.Count < 10) 177 | { 178 | List points = new List { }; 179 | points.Add(_startPoint); 180 | points.AddRange(pointList); 181 | points.Add(_startPoint); 182 | 183 | _length = double.MaxValue; 184 | RecursivePermutation(1, points); 185 | } 186 | 187 | return _routeList; 188 | } 189 | 190 | private void RecursivePermutation(int startPos, List points) // first and last points are fixed 191 | { 192 | int size = points.Count; 193 | 194 | if (startPos == size - 1) 195 | { 196 | double newLength = Calculator.CalcRouteLength(points); 197 | if (newLength < _length) 198 | { 199 | _length = newLength; 200 | _routeList.Clear(); 201 | _routeList.AddRange(points); 202 | } 203 | } 204 | else 205 | { 206 | for (int j = startPos; j < size - 1; ++j) 207 | { 208 | Swap(startPos, j, points); 209 | startPos++; 210 | RecursivePermutation(startPos, points); 211 | startPos--; 212 | Swap(startPos, j, points); 213 | } 214 | } 215 | } 216 | 217 | private void Swap(int pos_1, int pos_2, List points) 218 | { 219 | Point point = points[pos_1]; 220 | points[pos_1] = points[pos_2]; 221 | points[pos_2] = point; 222 | } 223 | 224 | public List CalculateRouteByNearestNeighbour(List pointList) 225 | { 226 | List points = new List { }; 227 | points.AddRange(pointList); 228 | List pointIsUsed = new List {}; 229 | 230 | foreach (Point point in points) 231 | { 232 | pointIsUsed.Add(false); 233 | } 234 | 235 | List route = new List { _startPoint }; 236 | Point current_point = _startPoint; 237 | 238 | for (int j = 0; j < points.Count; j++) 239 | { 240 | int min_point_index = 0; 241 | double min_distance = double.MaxValue; 242 | 243 | for (int i = 0; i < points.Count; i++) 244 | { 245 | if (!pointIsUsed[i]) 246 | { 247 | double distance = Calculator.CalcDistance(current_point, points[i]); 248 | 249 | if (distance < min_distance) 250 | { 251 | min_distance = distance; 252 | min_point_index = i; 253 | } 254 | } 255 | } 256 | 257 | current_point = points[min_point_index]; 258 | pointIsUsed[min_point_index] = true; 259 | route.Add(current_point); 260 | } 261 | 262 | route.Add(_startPoint); 263 | _routeList = route; 264 | return route; 265 | } 266 | 267 | public List CalculateRouteByFPPWR(List pointList, int x_count, int y_count, double width, double heigth) 268 | { 269 | List points = new List { }; 270 | points.AddRange(pointList); 271 | List route = new List { _startPoint }; 272 | 273 | // cell sides size 274 | double x_side = width / x_count; 275 | double y_side = heigth / y_count; 276 | 277 | for (int iy = 0; iy < y_count; iy++) 278 | { 279 | double y_up = y_side * iy; 280 | double y_down = y_side * (iy + 1); 281 | 282 | if (iy % 2 == 0) 283 | { 284 | for (int ix = 0; ix < x_count; ix++) 285 | { 286 | double x_left = x_side * ix; 287 | double x_right = x_side * (ix + 1); 288 | 289 | List cell = GetCellPointList(points, x_left, x_right, y_up, y_down, route); 290 | cell = Calculator.SortPointListByX(cell); 291 | 292 | route.AddRange(cell); 293 | } 294 | } 295 | else { 296 | for (int ix = x_count; ix > 0; ix--) 297 | { 298 | double x_right = x_side * ix; 299 | double x_left = x_side * (ix - 1); 300 | 301 | List cell = GetCellPointList(points, x_left, x_right, y_up, y_down, route); 302 | cell = Calculator.SortPointListByX(cell); 303 | cell.Reverse(); 304 | route.AddRange(cell); 305 | } 306 | } 307 | } 308 | 309 | route.Add(_startPoint); 310 | _routeList = route; 311 | return route; 312 | } 313 | 314 | private List GetCellPointList(List points, double x_left, double x_rigth, double y_up, double y_down, List route) 315 | { 316 | List cell = new List { }; 317 | 318 | foreach (Point point in points) 319 | { 320 | if ((point.X >= x_left) && (point.X) <= x_rigth) 321 | { 322 | if ((point.Y >= y_up) && (point.Y) <= y_down) 323 | { 324 | if (!route.Contains(point)) 325 | { 326 | cell.Add(point); 327 | } 328 | } 329 | } 330 | } 331 | return cell; 332 | } 333 | } 334 | } 335 | -------------------------------------------------------------------------------- /Calculator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.Linq; 5 | 6 | namespace Clusterization_algorithms 7 | { 8 | /// 9 | /// Class calculate math operations and print data. Call without creating object. 10 | /// 11 | public class Calculator 12 | { 13 | /// 14 | /// Find points center | centroid | barycenter | mass center 15 | /// 16 | public static Point FindCentroid(List pointGroup) 17 | { 18 | int x = 0; 19 | int y = 0; 20 | 21 | for (int i = 0; i < pointGroup.Count; i++) 22 | { 23 | x += pointGroup.ElementAt(i).X; 24 | y += pointGroup.ElementAt(i).Y; 25 | } 26 | 27 | x = x / pointGroup.Count; 28 | y = y / pointGroup.Count; 29 | 30 | Point point = new Point(x, y); 31 | return point; 32 | } 33 | 34 | /// 35 | /// Calculates distance between A, B points 36 | /// 37 | public static double CalcDistance(Point a, Point b) 38 | { 39 | double delX = Math.Pow(b.X - a.X, 2); 40 | double delY = Math.Pow(b.Y - a.Y, 2); 41 | return Math.Sqrt(delX + delY); 42 | } 43 | 44 | /// 45 | /// Generate random points and add them to the dictionary 46 | /// 47 | public static Dictionary GeneratePoints(int count, int rangeX, int rangeY) 48 | { 49 | Random rand = new Random(); 50 | 51 | Dictionary points = new Dictionary(); 52 | 53 | for (int i = 0; i < count; i++) 54 | { 55 | Point point; 56 | 57 | do 58 | { 59 | point = new Point(rand.Next(rangeX), rand.Next(rangeY)); 60 | } 61 | while (points.ContainsKey(point)); 62 | 63 | points.Add(point, 0); 64 | } 65 | return points; 66 | } 67 | 68 | public static string PrintNodesAndCharge(Dictionary nodes, Dictionary nodesCharge) 69 | { 70 | nodes = SortDictionaryByValue(nodes); 71 | string str = ""; 72 | 73 | foreach (var node in nodes) 74 | { 75 | nodesCharge.TryGetValue(node.Key, out int charge); 76 | str += node.ToString() + " " + charge + "%\n"; 77 | } 78 | return str; 79 | } 80 | 81 | public static double Find3PointsLength(Point a, Point b, Point c) 82 | { 83 | double l1 = CalcDistance(a, b); 84 | double l2 = CalcDistance(b, c); 85 | return l1 + l1; 86 | } 87 | 88 | /// 89 | /// Calculates external corner cos between the lines. 90 | /// 91 | public static double GetCOS(Point a, Point b, Point c) 92 | { 93 | Point v1 = new Point(b.X - a.X, b.Y - a.Y); // calculate ab vector 94 | Point v2 = new Point(c.X - b.X, c.Y - b.Y); // calculate bc vector 95 | 96 | double modV1 = Math.Sqrt(v1.X * v1.X + v1.Y * v1.Y); 97 | double modV2 = Math.Sqrt(v2.X * v2.X + v2.Y * v2.Y); 98 | double skal = v1.X * v2.X + v1.Y * v2.Y; 99 | 100 | return skal / (modV1 * modV2); 101 | } 102 | 103 | public static double GetSIN(Point a, Point b, Point c) 104 | { 105 | double cos = GetCOS(a, b, c); 106 | return Math.Sqrt(1 - cos * cos); 107 | } 108 | 109 | public static List DictionaryToList(Dictionary dictionary) 110 | { 111 | List points = new List() { }; 112 | 113 | for (int i = 0; i < dictionary.Count; i++) 114 | points.Add(dictionary.ElementAt(i).Key); 115 | 116 | return points; 117 | } 118 | 119 | public static List DictionaryToList(Dictionary dictionary) 120 | { 121 | List points = new List() { }; 122 | 123 | for (int i = 0; i < dictionary.Count; i++) 124 | points.Add(dictionary.ElementAt(i).Key); 125 | 126 | return points; 127 | } 128 | 129 | public static Dictionary ListToDictionary(List pointList) 130 | { 131 | Dictionary dictionary = new Dictionary { }; 132 | 133 | for (int i = 0; i < pointList.Count; i++) 134 | dictionary.Add(pointList[i], 0); 135 | 136 | return dictionary; 137 | } 138 | 139 | public static double CalcRouteLength(List points) 140 | { 141 | if(points.Count == 0) 142 | return 0; 143 | 144 | double dist = CalcDistance(points[0], points[points.Count - 1]); 145 | 146 | for (int i = 0; i < points.Count - 1; i++) 147 | dist += CalcDistance(points[i], points[i + 1]); 148 | 149 | return dist; 150 | } 151 | 152 | public static Dictionary SortDictionaryByValue(Dictionary dictionary) 153 | { 154 | return dictionary.OrderBy(x => x.Value).ToDictionary(x => x.Key, x => x.Value); 155 | } 156 | 157 | public static Dictionary SortDictionaryByValue(Dictionary dictionary) 158 | { 159 | return dictionary.OrderBy(x => x.Value).ToDictionary(x => x.Key, x => x.Value); 160 | } 161 | 162 | public static List GetClusterList(int clusterNum, Dictionary dictionary) 163 | { 164 | List cluster = new List { }; 165 | 166 | for (int i = 0; i < dictionary.Count; i++) 167 | { 168 | if (dictionary.ElementAt(i).Value == clusterNum) 169 | { 170 | cluster.Add(dictionary.ElementAt(i).Key); 171 | } 172 | } 173 | return cluster; 174 | } 175 | 176 | public static Dictionary GetClusterDictionary(int clusterNum, Dictionary dictionary) 177 | { 178 | Dictionary cluster = new Dictionary { }; 179 | 180 | for (int i = 0; i < dictionary.Count; i++) 181 | { 182 | if (dictionary.ElementAt(i).Value == clusterNum) 183 | { 184 | cluster.Add(dictionary.ElementAt(i).Key, dictionary.ElementAt(i).Value); 185 | } 186 | } 187 | return cluster; 188 | } 189 | 190 | public static void MovePointList(List cluster, Point vector) 191 | { 192 | for (int i = 0; i < cluster.Count; i++) 193 | { 194 | cluster[i] = new Point(cluster[i].X - vector.X, cluster[i].Y - vector.Y); 195 | } 196 | } 197 | 198 | public static void ZoomPointList(List list, double zoom) 199 | { 200 | for (int i = 0; i < list.Count; i++) 201 | { 202 | list[i] = new Point((int)Math.Round(list[i].X * zoom), (int)Math.Round(list[i].Y * zoom)); 203 | } 204 | } 205 | 206 | public static Dictionary CopyDictionary(Dictionary dictionary) 207 | { 208 | Dictionary newDictionary = new Dictionary { }; 209 | 210 | foreach (var pair in dictionary) 211 | newDictionary.Add(pair.Key, pair.Value); 212 | 213 | return newDictionary; 214 | } 215 | 216 | public static void PrintIntArray(int[] array) 217 | { 218 | Console.WriteLine("Print int array"); 219 | 220 | foreach (int num in array) 221 | { 222 | Console.Write(num + " "); 223 | } 224 | } 225 | 226 | public static void PrintIntList(List list) 227 | { 228 | Console.WriteLine("Print int list"); 229 | 230 | foreach (int num in list) 231 | { 232 | Console.WriteLine(num.ToString()); 233 | } 234 | } 235 | 236 | public static int GenRandInt(int startNum, int endNum) 237 | { 238 | Random rand = new Random(); 239 | return rand.Next(startNum, endNum); 240 | } 241 | 242 | public static List GetRouteFragment(Point point, List routeList) 243 | { 244 | List fragment = new List { }; 245 | 246 | for (int i = 0; i < routeList.Count; i++) 247 | { 248 | if (routeList[i] == point) 249 | { 250 | fragment.Add(routeList[i - 1]); 251 | fragment.Add(routeList[i]); 252 | fragment.Add(routeList[i + 1]); 253 | 254 | return fragment; 255 | } 256 | } 257 | return routeList; 258 | } 259 | 260 | public static Point GetPointProjectionOnLine(Point point, Point a_point_inLine, Point b_point_inLine) 261 | { 262 | Point fulcrum = new Point(); // point projection on ab line 263 | double x4, y4; 264 | 265 | double dx = b_point_inLine.X - a_point_inLine.X; 266 | double dy = b_point_inLine.Y - a_point_inLine.Y; 267 | double mag = Math.Sqrt(dx * dx + dy * dy); 268 | dx /= mag; 269 | dy /= mag; 270 | 271 | // translate the point and get the dot product 272 | double lambda = (dx * (point.X - a_point_inLine.X)) + (dy * (point.Y - a_point_inLine.Y)); 273 | x4 = (dx * lambda) + a_point_inLine.X; 274 | y4 = (dy * lambda) + a_point_inLine.Y; 275 | 276 | fulcrum.X = (int)Math.Round(x4); 277 | fulcrum.Y = (int)Math.Round(y4); 278 | 279 | return fulcrum; 280 | } 281 | 282 | public static Point GetPointProjectionOnMultiLine(Point point, List intersectionList) 283 | { 284 | Point closerFulcrum; 285 | double minDistance = double.MaxValue; 286 | 287 | if (intersectionList.Contains(point)) 288 | { 289 | closerFulcrum = point; 290 | } 291 | else 292 | { 293 | closerFulcrum = Calculator.FindClosestPoint(point, intersectionList); // if no projection return closer intersection 294 | } 295 | 296 | for (int j = 0; j < intersectionList.Count - 1; j++) 297 | { 298 | Point fulcrum = Calculator.GetPointProjectionOnLine(point, intersectionList[j], intersectionList[j + 1]); 299 | double dist_point_fulcrum = Calculator.CalcDistance(fulcrum, point); 300 | 301 | if (dist_point_fulcrum < minDistance) 302 | { 303 | // Point must be between a,b point (i, i+1 route). Then, check this by _length between points: 304 | double ab_distance = Calculator.CalcDistance(intersectionList[j], intersectionList[j + 1]); 305 | double af_distance = Calculator.CalcDistance(intersectionList[j], fulcrum); 306 | double bf_distance = Calculator.CalcDistance(intersectionList[j + 1], fulcrum); 307 | 308 | if ((af_distance < ab_distance) && (bf_distance < ab_distance)) 309 | { // then fulcrum is between route points 310 | minDistance = dist_point_fulcrum; 311 | closerFulcrum = fulcrum; 312 | } 313 | } 314 | } 315 | return closerFulcrum; 316 | } 317 | 318 | public static List SortPointListByX(List points) 319 | { 320 | return points.OrderBy(point => point.X).ToList(); 321 | } 322 | 323 | public static Point FindClosestPoint(Point point, List list) 324 | { 325 | Point minPoint = list[0]; 326 | double minDist = Calculator.CalcDistance(point, minPoint); 327 | 328 | foreach (Point p in list) { 329 | 330 | double dist = Calculator.CalcDistance(p, point); 331 | 332 | if (dist > 0 && dist < minDist) { 333 | minDist = dist; 334 | minPoint = p; 335 | } 336 | } 337 | return minPoint; 338 | } 339 | 340 | public static void Console_PrintDictionary(Dictionary dictionary) 341 | { 342 | Console.WriteLine("*** Dictionary ***"); 343 | 344 | foreach (var keyValuePair in dictionary) 345 | Console.WriteLine(keyValuePair.Key + "/" + keyValuePair.Value); 346 | 347 | Console.WriteLine("******************"); 348 | } 349 | 350 | 351 | public static String Console_PrintPointList(List points) 352 | { 353 | String str = ""; 354 | Console.WriteLine("*** Points list: ***"); 355 | 356 | foreach (var point in points) 357 | { 358 | Console.WriteLine(point.ToString()); 359 | str += point.ToString() + "\n"; 360 | } 361 | 362 | Console.WriteLine("********************"); 363 | return str; 364 | } 365 | } 366 | } 367 | -------------------------------------------------------------------------------- /EnergyCalculator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | 5 | namespace Clusterization_algorithms 6 | { 7 | public class EnergyCalculator // DEEC algorithm 8 | { 9 | private GraphicsController _graphics; 10 | private Dictionary _allNodes; // int - cluster number, for searching cluster by number 11 | private Dictionary _nodesLevelCharge = new Dictionary { }; 12 | private int _stationUsedE = 0; //energy used by station 13 | 14 | #region Energy consumption parameters 15 | 16 | public double E_fs = 0.01;//nJ(10^-9) amplifier energy, free space model (short distance) | d < d0 17 | public double E_mp = 0.0000013; //nJ // amplifier energy, multipath fading model (large distance) | d >= d0 18 | public int E_elec = 50; //nJ/bit, energy for work signal transmission/recieve 19 | public int node_E = 500000000; //nJ; = 0,5J // initial node energy 20 | public double d0 = 87.7; // (m) distance threshold for swapping amplification models (d0 need amplifier, high consumption) 21 | public int package = 32000; // bit, package size (can be from 20 to 65535 bits), represents the volume of information sent 22 | 23 | #endregion 24 | 25 | public EnergyCalculator(GraphicsController graphics, Dictionary allNodes) 26 | { 27 | _graphics = graphics; 28 | _allNodes = allNodes; 29 | 30 | foreach (var node in allNodes) 31 | _nodesLevelCharge.Add(node.Key, node_E); 32 | } 33 | 34 | /// 35 | /// Set energy model 36 | /// 37 | /// (nJ) (10^-9J) amplifier energy, free space model (short distance) | d 38 | /// (nJ) multipath fading model (large distance) | d >= d0 39 | /// (nJ/bit) energy for work signal transmission/recieve 40 | /// (nJ) initial node energy 41 | /// (m) distance threshold for swapping amplification models 42 | /// (bit) test package size 43 | public void SetEnergyModel(double e_fs = 0.01, double e_mp = 0.0000013, 44 | int e_elec = 50, int node_e = 500000000, 45 | double d0 = 87.7, int package_size = 32000) 46 | { 47 | E_fs = e_fs; 48 | E_mp = e_mp; 49 | E_elec = e_elec; 50 | node_E = node_e; 51 | d0 = this.d0; 52 | package = package_size; 53 | } 54 | 55 | /// 56 | /// Calculate all nodes charge capacity in Joules 57 | /// 58 | public double GetNodesCapacity(int nodesCount) 59 | { 60 | return node_E/1000000000.000 * nodesCount; 61 | } 62 | 63 | /// 64 | /// Get current charge sum of all nodes 65 | /// 66 | /// summary charge (Joules) 67 | public double GetMapCurrentCharge() 68 | { 69 | double sum_charge = 0; 70 | 71 | foreach (var node in _nodesLevelCharge) 72 | sum_charge += node.Value / 1000000; 73 | sum_charge = sum_charge / 1000; 74 | 75 | return sum_charge; 76 | } 77 | 78 | public double GetMapCurrentChargeInPercents() 79 | { 80 | double total_capacity = GetNodesCapacity(_allNodes.Count); 81 | double sum_charge = GetMapCurrentCharge(); 82 | 83 | return sum_charge * 100 / total_capacity; 84 | } 85 | 86 | /// 87 | /// Nodes energy used (Joules) 88 | /// 89 | /// 90 | public double GetMapUsedEnergy() 91 | { 92 | double total_capacity = GetNodesCapacity(_allNodes.Count); 93 | double sum_charge = GetMapCurrentCharge(); 94 | return total_capacity - sum_charge; 95 | } 96 | 97 | public Dictionary GetNodesChargeDictionary() 98 | { 99 | Dictionary chargeList = new Dictionary { }; 100 | int onePercent = node_E / 100; // 1% = ?nJ (calculate how much nJ is equal to 1%) 101 | 102 | foreach (var node in _nodesLevelCharge) 103 | { 104 | int charge = node.Value / onePercent; // (node charge in %) 105 | chargeList.Add(node.Key, charge); 106 | } 107 | return chargeList; 108 | } 109 | 110 | public void CalculteAllNodesEnergy(DataTransmittionType connectionType, Dictionary nodesClustered, List routeList, int stationHeight) 111 | { 112 | for (int i = 1; i < routeList.Count - 1; i++) 113 | { 114 | List cluster = Calculator.GetClusterList(i, nodesClustered); 115 | 116 | switch (connectionType) 117 | { 118 | case DataTransmittionType.DT_to_Center: 119 | Start_DT_Protocol(cluster, stationHeight); 120 | break; 121 | 122 | case DataTransmittionType.DT_to_Route: 123 | Start_DT_ToRoute(cluster, stationHeight, routeList); 124 | break; 125 | 126 | case DataTransmittionType.PP_to_Center: 127 | Start_PP_Protocol(cluster, stationHeight); 128 | break; 129 | 130 | case DataTransmittionType.PP_to_Route: 131 | Start_PP_ToRoute(cluster, stationHeight, routeList); 132 | break; 133 | } 134 | } 135 | } 136 | 137 | #region Transmission protocols 138 | 139 | /// 140 | /// Peer to peer transmission along the path. 141 | /// Data transfer occurs while the station is moving. 142 | /// 143 | /// The cluster through which the station passes 144 | /// Station height. 0 can be used for ground stations (cars and so on), higher values for flying stations (flying drones, planes and so on) 145 | /// Station path 146 | public void Start_PP_ToRoute(List cluster, int stationHeight, List routeList) 147 | { 148 | Point center = Calculator.FindCentroid(cluster); 149 | List routeFragment = Calculator.GetRouteFragment(center, routeList); 150 | List packetCountList = new List { }; 151 | 152 | for (int i = 0; i < _allNodes.Count; i++) 153 | packetCountList.Add(1); 154 | 155 | for (int i = 0; i < cluster.Count; i++) 156 | { 157 | Point closer = Calculator.GetPointProjectionOnMultiLine(cluster[i], routeFragment); // set value of closer fulcrum 158 | double dist_i_to_fulcrum = Calculator.CalcDistance(cluster[i], closer); 159 | double dist_to_closer = dist_i_to_fulcrum; 160 | int index = -1; 161 | 162 | for (int j = 0; j < cluster.Count; j++) 163 | { 164 | if (i != j) 165 | { 166 | double dist_to_node = Calculator.CalcDistance(cluster[i], cluster[j]); 167 | Point j_fulcrum = Calculator.GetPointProjectionOnMultiLine(cluster[j], routeFragment); 168 | double dist_j_to_fulcrum = Calculator.CalcDistance(cluster[j], j_fulcrum); 169 | 170 | if (dist_to_node < dist_to_closer && dist_j_to_fulcrum < dist_i_to_fulcrum) 171 | { 172 | closer = cluster[j]; 173 | dist_to_closer = dist_to_node; 174 | index = j; 175 | } 176 | } 177 | } 178 | 179 | if (index == -1) 180 | { 181 | PPConnection(cluster[i], closer, stationHeight, packetCountList[i]); 182 | } 183 | else 184 | { 185 | packetCountList[index] = packetCountList[i] + 1; //packet last node + 1 his packet 186 | PPConnection(cluster[i], closer, 0, packetCountList[i]); 187 | } 188 | } 189 | } 190 | 191 | /// 192 | /// Peer to peer transmission to the cluster center. 193 | /// The station stops in the centre of the cluster and data transfer occurs. 194 | /// 195 | /// The cluster through which the station passes 196 | /// Station height. 0 can be used for ground stations (cars and so on), higher values for flying stations (flying drones, planes and so on) 197 | public void Start_PP_Protocol(List cluster, int stationHeight) 198 | { 199 | List packetCountList = new List { }; 200 | Point center = Calculator.FindCentroid(cluster); 201 | 202 | for (int i = 0; i < _allNodes.Count; i++) 203 | packetCountList.Add(1); 204 | 205 | for (int i = 0; i < cluster.Count; i++) 206 | { 207 | Point closer = center; 208 | double dist_i_to_center = Calculator.CalcDistance(cluster[i], center); 209 | double dist_to_closer = dist_i_to_center; 210 | int index = -1; 211 | 212 | for (int j = 0; j < cluster.Count; j++) 213 | { 214 | if (i != j) 215 | { 216 | double dist_to_node = Calculator.CalcDistance(cluster[i], cluster[j]); 217 | double dist_j_to_center = Calculator.CalcDistance(cluster[j], center); 218 | 219 | if (dist_to_node < dist_to_closer && dist_j_to_center < dist_i_to_center) 220 | { 221 | closer = cluster[j]; 222 | dist_to_closer = dist_to_node; 223 | index = j; 224 | } 225 | } 226 | } 227 | 228 | if (index == -1) 229 | { 230 | PPConnection(cluster[i], closer, stationHeight, packetCountList[i]); 231 | } 232 | else 233 | { 234 | packetCountList[index] = packetCountList[i] + 1; //packet last node + 1 his packet 235 | PPConnection(cluster[i], closer, 0, packetCountList[i]); 236 | } 237 | } 238 | } 239 | 240 | /// 241 | /// Direct transmission along the path. 242 | /// Data transfer occurs while the station is moving. 243 | /// 244 | /// The cluster through which the station passes 245 | /// Station height. 0 can be used for ground stations (cars and so on), higher values for flying stations (flying drones, planes and so on) 246 | /// Station path 247 | public void Start_DT_ToRoute(List cluster, int stationHeight, List routeList) 248 | { 249 | Point center = Calculator.FindCentroid(cluster); 250 | List routeFragment = Calculator.GetRouteFragment(center, routeList); 251 | 252 | for (int i = 0; i < cluster.Count; i++) 253 | { 254 | Point closerFulcrum = Calculator.GetPointProjectionOnMultiLine(cluster[i], routeFragment); 255 | PPConnection(cluster[i], closerFulcrum, stationHeight); 256 | } 257 | } 258 | 259 | /// 260 | /// Direct transmission to the cluster center. 261 | /// The station stops in the centre of the cluster and data transfer occurs. 262 | /// 263 | /// The cluster through which the station passes 264 | /// Station height. 0 can be used for ground stations (cars and so on), higher values for flying stations (flying drones, planes and so on) 265 | public void Start_DT_Protocol(List cluster, int stationHeight) 266 | { 267 | Point center = Calculator.FindCentroid(cluster); 268 | foreach (Point point in cluster) 269 | PPConnection(point, center, stationHeight); 270 | } 271 | 272 | #endregion 273 | 274 | /// 275 | /// Simulate sending data from one node to another or from node to the station 276 | /// 277 | public int PPConnection(Point node, Point station, int stationHeight, int packetCount = 1) 278 | { 279 | double distH0 = Calculator.CalcDistance(node, station); 280 | double dist = Math.Sqrt(distH0 * distH0 + stationHeight * stationHeight); 281 | double E_transmission = 0; 282 | 283 | if (dist < d0) 284 | { 285 | E_transmission = (package * packetCount) * E_elec + (package * packetCount) * E_fs * Math.Pow(dist, 2); // nJ (value in nanojoules) 286 | _graphics.DrawLine(node, station, Color.LimeGreen); 287 | } 288 | else { 289 | E_transmission = (package * packetCount) * E_elec + (package * packetCount) * E_mp * Math.Pow(dist, 4); // nJ 290 | _graphics.DrawLine(node, station, Color.IndianRed); 291 | } 292 | 293 | double E_receive = (package * packetCount) * E_elec; 294 | 295 | //minus used energy from nodes charge 296 | if (_nodesLevelCharge.TryGetValue(node, out int oldCharge)) 297 | { 298 | int newCharge = oldCharge - (int)E_transmission; 299 | 300 | if (newCharge < 0) { 301 | newCharge = 0; 302 | _graphics.DrawPoint(node, Brushes.Red); 303 | } 304 | 305 | _nodesLevelCharge.Remove(node); 306 | _nodesLevelCharge.Add(node, newCharge); 307 | } 308 | 309 | _stationUsedE += Convert.ToInt32(E_receive); 310 | return 0; 311 | } 312 | } 313 | } 314 | -------------------------------------------------------------------------------- /Form1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.Windows.Forms; 5 | 6 | namespace Clusterization_algorithms 7 | { 8 | public partial class Form1 : Form 9 | { 10 | private GraphicsController _graphicsController; 11 | private Graphics _graphics; 12 | private Forel _forel; 13 | private K_means _k_means; 14 | private RouteBuilder _routeBuilder; 15 | private EnergyCalculator _energyCalculator; 16 | private Dictionary _allPoints; 17 | private Dictionary _allPointsClustered; 18 | private List _clusterCenters = new List { }; 19 | private int _forelRadius; 20 | private ClusterizationType _clusterizationType; 21 | 22 | #region Default values 23 | 24 | private int _defaultPointsCount = 100; // count nodes generated on map 25 | private int _defaultClusterRadius = 100; // round forel cluster radius 26 | private int _defaultSeedCount = 2; // count of centroids in k-means 27 | 28 | private int _fppwrDefaultNetRows = 6; 29 | private int _fppwrDefaultNetCols = 6; 30 | 31 | #endregion 32 | 33 | #region Counters 34 | 35 | int loop_count = 0; // times was data collected from map by station 36 | double map_usedE = 0; // used energy in current loop 37 | double map_last_usedE = 0; // used energy in last loop 38 | 39 | #endregion 40 | 41 | public Form1() 42 | { 43 | InitializeComponent(); 44 | 45 | _graphics = pictBoxArea.CreateGraphics(); 46 | _graphicsController = new GraphicsController(_graphics); 47 | 48 | _forel = new Forel(_graphicsController); 49 | _k_means = new K_means(_graphicsController); 50 | _routeBuilder = new RouteBuilder(); 51 | } 52 | 53 | private void btnGenPoints_Click(object sender, EventArgs e) 54 | { 55 | DisableAll(); 56 | EnableClusterization(); 57 | Labels_ClearText(); 58 | buttonReloadMap.Enabled = true; 59 | buttonEnergyModel.Enabled = true; 60 | 61 | if (checkBoxAllowGeneratePoints.Checked == true) 62 | { 63 | if (Int32.TryParse(textBoxSetPointsCount.Text, out int pointsCount)) 64 | { 65 | _allPoints = Calculator.GeneratePoints(pointsCount, pictBoxArea.Width, pictBoxArea.Height); 66 | } 67 | else 68 | { 69 | _allPoints = Calculator.GeneratePoints(_defaultPointsCount, pictBoxArea.Width, pictBoxArea.Height); 70 | } 71 | } 72 | 73 | _allPointsClustered = _allPoints; 74 | _routeBuilder.RouteList = new List { }; 75 | _energyCalculator = new EnergyCalculator(_graphicsController, _allPoints); 76 | 77 | ClearFields(); 78 | } 79 | 80 | public void ClearFields() 81 | { 82 | _graphics.Clear(Color.White); 83 | textBoxInfo.Clear(); 84 | _graphicsController.DrawPointDictionary(_allPoints); 85 | PrintToTextBoxInfo(_allPoints); 86 | _clusterCenters.Clear(); 87 | } 88 | 89 | private void btnKMeans_Click(object sender, EventArgs e) 90 | { 91 | _clusterizationType = ClusterizationType.K_means; 92 | Labels_ClearText(); 93 | ClearFields(); 94 | EnableRouteCalculating(); 95 | DisallowSelectClusterAndCalculateEnergy(); 96 | 97 | SeedGenerator seedGenerator = new SeedGenerator(); 98 | seedGenerator.SetPoints(_allPoints); 99 | seedGenerator._seedCount = _defaultSeedCount; 100 | 101 | if (Int32.TryParse(textBoxSetSeedsCount.Text, out int seedCount)) 102 | { 103 | seedGenerator._seedCount = seedCount; 104 | } 105 | 106 | List seeds = seedGenerator.GetSeeds(); 107 | 108 | _k_means.SetPoints(_allPoints); 109 | _k_means.Seeds = seeds; 110 | _k_means.StartK_means(); 111 | 112 | _clusterCenters = _k_means.Seeds; 113 | 114 | PrintToTextBoxInfo(_k_means.GetPoints()); 115 | _allPointsClustered = _k_means.GetPoints(); 116 | } 117 | 118 | private void btnForel_Click(object sender, EventArgs e) 119 | { 120 | _clusterizationType = ClusterizationType.Forel; 121 | Labels_ClearText(); 122 | ClearFields(); 123 | EnableRouteCalculating(); 124 | DisallowSelectClusterAndCalculateEnergy(); 125 | 126 | _forel.SetPoints(_allPoints); 127 | _forel.Radius = _defaultClusterRadius; 128 | 129 | if (Int32.TryParse(textBoxSetRadius.Text, out int r)) 130 | { 131 | _forel.Radius = r; 132 | } 133 | 134 | _forelRadius = _forel.Radius; 135 | _forel.StartForel(); 136 | _clusterCenters = _forel.ListOfClastersCenter; 137 | 138 | PrintToTextBoxInfo(_forel.GetPoints()); 139 | _allPointsClustered = _forel.GetPoints(); 140 | } 141 | 142 | private void btnClustersRoute_Click(object sender, EventArgs e) 143 | { 144 | AllowSelectClusterAndCalculateEnergy(); 145 | 146 | if (_clusterCenters.Count == 0) 147 | { 148 | _routeBuilder.SetPoints(Calculator.DictionaryToList(_allPoints)); 149 | } 150 | else 151 | { 152 | _routeBuilder.SetPoints(_clusterCenters); 153 | } 154 | 155 | _routeBuilder.CalculateRouteByConvexHullInsertion(); 156 | _graphicsController.DrawRoute(_routeBuilder.RouteList, Color.Yellow); 157 | labelRoute.Text = "Route _length: " + Math.Round(Calculator.CalcRouteLength(_routeBuilder.RouteList), 3); 158 | 159 | PrintToTextBoxInfo(_allPointsClustered); 160 | } 161 | 162 | private void btnSpiralRoute_Click(object sender, EventArgs e) 163 | { 164 | AllowSelectClusterAndCalculateEnergy(); 165 | btnConvexHull.Enabled = false; 166 | 167 | if (_clusterCenters.Count > 0) 168 | { 169 | _routeBuilder.SetPoints(_clusterCenters); 170 | } 171 | else 172 | { 173 | _routeBuilder.SetPoints(Calculator.DictionaryToList(_allPoints)); 174 | } 175 | 176 | _routeBuilder.JarvisMarch(true); 177 | _graphicsController.DrawRoute(_routeBuilder.Convex_hull, Color.Aqua); 178 | labelRoute.Text = "Route _length: " + Math.Round(Calculator.CalcRouteLength(_routeBuilder.Convex_hull), 3); 179 | } 180 | 181 | private void btnGenPoints_MouseMove(object sender, MouseEventArgs e) 182 | { 183 | btnGenPoints.BackColor = Color.LightGreen; 184 | } 185 | 186 | private void btnGenPoints_MouseLeave(object sender, EventArgs e) 187 | { 188 | btnGenPoints.BackColor = Color.DarkGray; 189 | } 190 | 191 | private void btnBruteForce_Click(object sender, EventArgs e) 192 | { 193 | AllowSelectClusterAndCalculateEnergy(); 194 | List route = new List { }; 195 | 196 | if (_clusterCenters.Count > 0) 197 | { 198 | route = _routeBuilder.CalculateRouteBruteForce(_clusterCenters); 199 | } 200 | else 201 | { 202 | route = _routeBuilder.CalculateRouteBruteForce(Calculator.DictionaryToList(_allPoints)); 203 | } 204 | 205 | _graphicsController.DrawRoute(route, Color.Blue); 206 | labelRoute.Text = "Route _length: " + Math.Round(Calculator.CalcRouteLength(route), 3); 207 | PrintToTextBoxInfo(_allPointsClustered); 208 | } 209 | 210 | private void btn1ClusterOn_Click(object sender, EventArgs e) 211 | { 212 | DisableAll(); 213 | btnDeselectCluster.Enabled = true; 214 | _graphics.Clear(Color.White); 215 | int clusterNum = 1; 216 | 217 | if (Int32.TryParse(textBoxSetClusterNum.Text, out int num)) // get cluster number 218 | { 219 | clusterNum = num; 220 | } 221 | 222 | List cluster = Calculator.GetClusterList(clusterNum, _allPointsClustered); 223 | PrintToTextBoxInfo(Calculator.GetClusterDictionary(clusterNum, _allPointsClustered)); 224 | 225 | Point center = Calculator.FindCentroid(cluster); // find cluster center 226 | List routeFragment = Calculator.GetRouteFragment(center, _routeBuilder.RouteList); // find part route go throught cluster 227 | 228 | //< Move all points to the start coordinate 229 | Point vector = new Point(center.X - _forelRadius, center.Y - _forelRadius); 230 | center = new Point(_forelRadius, _forelRadius); 231 | Calculator.MovePointList(cluster, vector); 232 | Calculator.MovePointList(routeFragment, vector); 233 | //> 234 | 235 | //< Calculate zoom coefficient. 236 | int size = pictBoxArea.Height; 237 | if (pictBoxArea.Width < size) 238 | { 239 | size = pictBoxArea.Width; 240 | } 241 | 242 | double zoom = size / (_forelRadius * 2.0); // proportion between cluster zone size and field size 243 | //> 244 | 245 | //< Calculate new points position, radius with zooming 246 | int newRadius = (int)Math.Round(_forelRadius * zoom); 247 | Point newCenter = new Point((int)Math.Round(center.X * zoom), (int)Math.Round(center.Y * zoom)); 248 | Calculator.ZoomPointList(cluster, zoom); 249 | Calculator.ZoomPointList(routeFragment, zoom); 250 | 251 | _graphicsController.DrawPoint(newCenter, Brushes.Red); 252 | _graphicsController.DrawCircle(newCenter, newRadius, Color.Black, 0); 253 | _graphicsController.DrawPointList(cluster); 254 | _graphicsController.DrawRoute(routeFragment, Color.Orange); 255 | //> 256 | } 257 | 258 | private void DrawAllSavedObjects() 259 | { 260 | _graphics.Clear(Color.White); 261 | textBoxInfo.Clear(); 262 | PrintToTextBoxInfo(_allPointsClustered); 263 | 264 | if (_allPoints.Count != 0) 265 | { 266 | _graphicsController.DrawPointDictionary(_allPoints); 267 | } 268 | 269 | if (_clusterCenters.Count != 0) 270 | { 271 | for (int i = 0; i < _clusterCenters.Count; i++) 272 | { 273 | _graphicsController.DrawPoint(_clusterCenters[i], Brushes.Red, 6); 274 | 275 | if (_clusterizationType == ClusterizationType.Forel) 276 | { 277 | _graphicsController.DrawCircle(_clusterCenters[i], _forelRadius, Color.Black, 0); 278 | } 279 | } 280 | } 281 | 282 | if (_routeBuilder.RouteList.Count != 0) 283 | { 284 | _graphicsController.DrawRoute(_routeBuilder.RouteList, Color.Orange, 0); 285 | labelRoute.Text = "Route _length: " + Math.Round(Calculator.CalcRouteLength(_routeBuilder.RouteList), 3); 286 | } 287 | } 288 | 289 | private void btnCalcEnergy_Click(object sender, EventArgs e) 290 | { 291 | DrawAllSavedObjects(); 292 | buttonStatistic.Enabled = true; 293 | loop_count++; 294 | map_last_usedE = map_usedE; 295 | 296 | DataTransmittionType connectionType = DataTransmittionType.DT_to_Center; // default connection 297 | 298 | switch (comboBoxConnectionType.SelectedIndex) 299 | { 300 | case 1: 301 | connectionType = DataTransmittionType.DT_to_Route; 302 | break; 303 | 304 | case 2: 305 | connectionType = DataTransmittionType.PP_to_Center; 306 | break; 307 | 308 | case 3: 309 | connectionType = DataTransmittionType.PP_to_Route; 310 | break; 311 | } 312 | 313 | _energyCalculator.CalculteAllNodesEnergy(connectionType, _allPointsClustered, _routeBuilder.RouteList, ReadStationHeighth()); 314 | PrintToTextBoxInfo(_allPointsClustered); 315 | 316 | labelCharge.Visible = true; 317 | labelUsedEnergy.Visible = true; 318 | map_usedE = _energyCalculator.GetMapUsedEnergy(); 319 | labelCharge.Text = "Total charge: " + String.Format("{0:0.000}", _energyCalculator.GetMapCurrentChargeInPercents()) + "%"; 320 | labelUsedEnergy.Text = "Used energy: " + String.Format("{0:0.000}", map_usedE) + " (J)"; 321 | if (labelInfo.Enabled) ReloadStatistic(); 322 | } 323 | 324 | private int ReadStationHeighth() 325 | { 326 | int station_height = 0; 327 | 328 | if (int.TryParse(textBoxSetHeight.Text, out int height)) 329 | station_height = height; 330 | 331 | return station_height; 332 | } 333 | 334 | private void PrintToTextBoxInfo(Dictionary dictionary) 335 | { 336 | textBoxInfo.Text = Calculator.PrintNodesAndCharge(dictionary, _energyCalculator.GetNodesChargeDictionary()); 337 | } 338 | 339 | private void Form1_Shown(object sender, EventArgs e) 340 | { 341 | DrawScale(); 342 | } 343 | 344 | private void DrawScale() // draw scale in panel related to picturebox 345 | { 346 | int step = 25; 347 | 348 | // Set panel size to all window 349 | panel.Size = new Size(this.Size.Width, this.Size.Height); 350 | panel.Location = new Point(0, 0); 351 | 352 | Graphics graphicsVector = panel.CreateGraphics(); 353 | 354 | Pen pen = new Pen(Color.Black, 2); 355 | Point zeroPosition = new Point(pictBoxArea.Location.X - 25, pictBoxArea.Location.Y - 25); 356 | int X = zeroPosition.X; 357 | int Y = zeroPosition.Y; 358 | 359 | graphicsVector.DrawLine(pen, new Point(X, Y), new Point(pictBoxArea.Location.X + pictBoxArea.Width, Y)); 360 | graphicsVector.DrawLine(pen, new Point(X, Y), new Point(X, pictBoxArea.Location.Y + pictBoxArea.Height)); 361 | 362 | int distanceX = pictBoxArea.Width + 10; 363 | 364 | int number = 0; 365 | 366 | for (int i = step; i <= distanceX;) 367 | { 368 | graphicsVector.DrawLine(pen, new Point(X + i, Y - 3), new Point(X + i, Y + 3)); 369 | 370 | if (i % (2 * step) != 0) 371 | { 372 | if (number == 0) 373 | { 374 | Label lb = new Label 375 | { 376 | Location = new Point(X + i - 6, Y - 15), 377 | Text = $"{number}", 378 | AutoSize = true 379 | }; 380 | panel.Controls.Add(lb); 381 | } 382 | else 383 | { 384 | Label label = new Label 385 | { 386 | Location = new Point(X + i - 10, Y - 15), 387 | Text = $"{number}", 388 | AutoSize = true 389 | }; 390 | panel.Controls.Add(label); 391 | } 392 | } 393 | 394 | i += 25; 395 | number += 25; 396 | } 397 | 398 | number = 0; 399 | 400 | int distanceY = pictBoxArea.Height + 25; 401 | 402 | for (int i = 25; i < distanceY;) 403 | { 404 | graphicsVector.DrawLine(pen, new Point(X - 3, Y + i), new Point(X + 3, Y + i)); 405 | if (i % 50 != 0) 406 | { 407 | if (number == 0) 408 | { 409 | Label lb = new Label 410 | { 411 | Location = new Point(X - 15, Y + i - 7), 412 | Text = $"{number}", 413 | AutoSize = true 414 | 415 | }; 416 | panel.Controls.Add(lb); 417 | } 418 | else if (number == 50) 419 | { 420 | Label lb = new Label 421 | { 422 | Location = new Point(X - 23, Y + i - 7), 423 | Text = $"{number}", 424 | AutoSize = true 425 | 426 | }; 427 | panel.Controls.Add(lb); 428 | } 429 | else 430 | { 431 | Label lb = new Label 432 | { 433 | Location = new Point(X - 27, Y + i - 7), 434 | Text = $"{number}", 435 | AutoSize = true 436 | 437 | }; 438 | panel.Controls.Add(lb); 439 | } 440 | 441 | } 442 | 443 | i += 25; 444 | number += 25; 445 | } 446 | } 447 | 448 | private void btnNearestNeighbour_Click(object sender, EventArgs e) 449 | { 450 | AllowSelectClusterAndCalculateEnergy(); 451 | btnConvexHull.Enabled = true; 452 | List route = new List { }; 453 | 454 | if (_clusterCenters.Count > 0) 455 | { 456 | route = _routeBuilder.CalculateRouteByNearestNeighbour(_clusterCenters); 457 | } 458 | else 459 | { 460 | route = _routeBuilder.CalculateRouteByNearestNeighbour(Calculator.DictionaryToList(_allPoints)); 461 | } 462 | 463 | _graphicsController.DrawRoute(route, Color.Salmon); 464 | labelRoute.Text = "Route _length: " + Math.Round(Calculator.CalcRouteLength(route), 3); 465 | PrintToTextBoxInfo(_allPointsClustered); 466 | } 467 | 468 | private void btnFPPWR_Click(object sender, EventArgs e) 469 | { 470 | AllowSelectClusterAndCalculateEnergy(); 471 | btnConvexHull.Enabled = true; 472 | List route = new List { }; 473 | 474 | //< draw net on pictBoxArea 475 | // divide field on cells; cells count: 476 | int x_count = _fppwrDefaultNetCols; 477 | int y_count = _fppwrDefaultNetRows; 478 | _graphicsController.DrawNet(x_count, y_count, pictBoxArea.Width, pictBoxArea.Height); 479 | 480 | if (_clusterCenters.Count > 0) 481 | { 482 | route = _routeBuilder.CalculateRouteByFPPWR(_clusterCenters, x_count, y_count, pictBoxArea.Width, pictBoxArea.Height); 483 | } 484 | else 485 | { 486 | route = _routeBuilder.CalculateRouteByFPPWR(Calculator.DictionaryToList(_allPoints), x_count, y_count, pictBoxArea.Width, pictBoxArea.Height); 487 | } 488 | 489 | _graphicsController.DrawRoute(route, Color.Purple); 490 | labelRoute.Text = "Route _length: " + Math.Round(Calculator.CalcRouteLength(route), 3); 491 | PrintToTextBoxInfo(_allPointsClustered); 492 | } 493 | 494 | private void btnHelp_Click(object sender, EventArgs e) 495 | { 496 | labelInfo.Text = 497 | "black points - nodes\n" + 498 | "big red points - mass centers of clusters\n" + 499 | "red points - nodes with 0 % charge\n" + 500 | "black circles - clusters\n" + 501 | "gray circles - clusters iterations\n" + 502 | "green line - transmittion model for close distance (< 87, 7m)\n" + 503 | "red line - transmittion model for long distance (> 87, 7m) (with using amplifier)\n" + 504 | "route colors -different for each route-building algorithm, allow to see difference"; 505 | 506 | CheckLabelInfo(); 507 | } 508 | 509 | private void Labels_ClearText() { 510 | labelRoute.Text = ""; 511 | labelCharge.Text = " "; 512 | labelUsedEnergy.Text = " "; 513 | } 514 | 515 | #region User input control 516 | 517 | private void EnableClusterization() { 518 | btnKMeans.Enabled = true; 519 | btnForel.Enabled = true; 520 | } 521 | private void DisableClusterization() 522 | { 523 | btnKMeans.Enabled = false; 524 | btnForel.Enabled = false; 525 | } 526 | 527 | private void EnableRouteCalculating() 528 | { 529 | btnNearestNeighbour.Enabled = true; 530 | btnConvexHull.Enabled = true; 531 | btnBruteForce.Enabled = true; 532 | btnSpiralRoute.Enabled = true; 533 | btnFPPWR.Enabled = true; 534 | } 535 | 536 | private void DisableRouteCalculating() 537 | { 538 | btnNearestNeighbour.Enabled = false; 539 | btnConvexHull.Enabled = false; 540 | btnBruteForce.Enabled = false; 541 | btnSpiralRoute.Enabled = false; 542 | btnFPPWR.Enabled = false; 543 | } 544 | 545 | private void DisableAll() { 546 | DisableClusterization(); 547 | DisableRouteCalculating(); 548 | btnSelectCluster.Enabled = false; 549 | btnCalcEnergy.Enabled = false; 550 | buttonStatistic.Enabled = false; 551 | } 552 | 553 | private void AllowSelectClusterAndCalculateEnergy() { 554 | btnSelectCluster.Enabled = true; 555 | btnCalcEnergy.Enabled = true; 556 | buttonStatistic.Enabled = false; 557 | } 558 | 559 | private void DisallowSelectClusterAndCalculateEnergy() 560 | { 561 | btnSelectCluster.Enabled = false; 562 | btnCalcEnergy.Enabled = false; 563 | buttonStatistic.Enabled = false; 564 | loop_count = 0; 565 | map_usedE = 0; 566 | map_last_usedE = 0; 567 | } 568 | 569 | #endregion 570 | 571 | private void btnDeselectCluster_Click(object sender, EventArgs e) 572 | { 573 | DrawAllSavedObjects(); 574 | btnDeselectCluster.Enabled = false; 575 | btnSelectCluster.Enabled = true; 576 | btnCalcEnergy.Enabled = true; 577 | EnableClusterization(); 578 | EnableRouteCalculating(); 579 | } 580 | 581 | private void buttonStatistic_Click(object sender, EventArgs e) 582 | { 583 | ReloadStatistic(); 584 | CheckLabelInfo(); 585 | } 586 | 587 | private void ReloadStatistic() 588 | { 589 | double map_capacity = _energyCalculator.GetNodesCapacity(_allPoints.Count); 590 | double map_charge = _energyCalculator.GetMapCurrentCharge(); 591 | double map_charge_percents = _energyCalculator.GetMapCurrentChargeInPercents(); 592 | int nodes_available = GetCountOfAvailableNodes(); 593 | 594 | labelInfo.Text = 595 | "Total nodes charge: " + map_charge_percents + "% (" + map_charge + " / " + map_capacity + " J)\n" + 596 | "Available nodes: " + nodes_available + " / " + _allPointsClustered.Count + "\n" + 597 | "Clusters count: " + _forel.clusterNum + "\n" + 598 | "Loops: " + loop_count + "\n" + 599 | "Average E, per loop: " + String.Format("{0:0.000}", (map_capacity - map_charge) / loop_count) + " J\n" + 600 | "Last loop used E: " + String.Format("{0:0.000}", map_usedE - map_last_usedE) + " J"; 601 | } 602 | 603 | private void buttonReloadMap_Click(object sender, EventArgs e) 604 | { 605 | DrawAllSavedObjects(); 606 | } 607 | 608 | private void CheckLabelInfo() 609 | { 610 | if (labelInfo.Visible) 611 | { 612 | labelInfo.Visible = false; 613 | } 614 | else 615 | { 616 | labelInfo.Visible = true; 617 | } 618 | } 619 | 620 | private int GetCountOfAvailableNodes() { 621 | 622 | int count = 0; 623 | var nodes_charge = _energyCalculator.GetNodesChargeDictionary(); 624 | 625 | foreach (var node in nodes_charge) 626 | { 627 | if (node.Value != 0) 628 | { 629 | count++; 630 | } 631 | } 632 | return count; 633 | } 634 | 635 | private void buttonEnergyModel_Click(object sender, EventArgs e) 636 | { 637 | CheckLabelInfo(); 638 | 639 | labelInfo.Text = 640 | "Field size: " + pictBoxArea.Width + " x " + pictBoxArea.Height + " m" + 641 | "\nAmplifier energy:" + 642 | "\n Free space model " + "(<= " + _energyCalculator.d0 + " m): " + _energyCalculator.E_fs + " nJ" + 643 | "\n Multipath fading model " + "(> " + _energyCalculator.d0 + " m): " + _energyCalculator.E_mp * 1000000 + " mJ" + 644 | "\nInitial node energy: " + _energyCalculator.node_E / 1000000000.000 + " J" + 645 | "\nEnergy for signal transmittion / recieve: " + _energyCalculator.E_elec + " nJ/bit" + 646 | "\nPackage size (20 - 65535): " + _energyCalculator.package + " bit" + 647 | "\nThreshold for swapping amplification models: " + _energyCalculator.d0 + " m"; 648 | } 649 | 650 | private void btnLink_Click(object sender, EventArgs e) 651 | { 652 | //System.Diagnostics.Process.Start("http://www.facebook.com"); 653 | } 654 | } 655 | } -------------------------------------------------------------------------------- /Form1.Designer.cs: -------------------------------------------------------------------------------- 1 | 2 | namespace Clusterization_algorithms 3 | { 4 | partial class Form1 5 | { 6 | /// 7 | /// Обязательная переменная конструктора. 8 | /// 9 | private System.ComponentModel.IContainer components = null; 10 | 11 | /// 12 | /// Освободить все используемые ресурсы. 13 | /// 14 | /// истинно, если управляемый ресурс должен быть удален; иначе ложно. 15 | protected override void Dispose(bool disposing) 16 | { 17 | if (disposing && (components != null)) 18 | { 19 | components.Dispose(); 20 | } 21 | base.Dispose(disposing); 22 | } 23 | 24 | #region Код, автоматически созданный конструктором форм Windows 25 | 26 | /// 27 | /// Требуемый метод для поддержки конструктора — не изменяйте 28 | /// содержимое этого метода с помощью редактора кода. 29 | /// 30 | private void InitializeComponent() 31 | { 32 | this.components = new System.ComponentModel.Container(); 33 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); 34 | this.textBoxInfo = new System.Windows.Forms.TextBox(); 35 | this.textBoxSetPointsCount = new System.Windows.Forms.TextBox(); 36 | this.label2 = new System.Windows.Forms.Label(); 37 | this.label1 = new System.Windows.Forms.Label(); 38 | this.textBoxSetRadius = new System.Windows.Forms.TextBox(); 39 | this.btnForel = new System.Windows.Forms.Button(); 40 | this.btnGenPoints = new System.Windows.Forms.Button(); 41 | this.btnKMeans = new System.Windows.Forms.Button(); 42 | this.label3 = new System.Windows.Forms.Label(); 43 | this.textBoxSetSeedsCount = new System.Windows.Forms.TextBox(); 44 | this.btnSpiralRoute = new System.Windows.Forms.Button(); 45 | this.btnConvexHull = new System.Windows.Forms.Button(); 46 | this.btnBruteForce = new System.Windows.Forms.Button(); 47 | this.btnSelectCluster = new System.Windows.Forms.Button(); 48 | this.textBoxSetClusterNum = new System.Windows.Forms.TextBox(); 49 | this.btnDeselectCluster = new System.Windows.Forms.Button(); 50 | this.btnCalcEnergy = new System.Windows.Forms.Button(); 51 | this.textBoxSetHeight = new System.Windows.Forms.TextBox(); 52 | this.label4 = new System.Windows.Forms.Label(); 53 | this.comboBoxConnectionType = new System.Windows.Forms.ComboBox(); 54 | this.checkBoxAllowGeneratePoints = new System.Windows.Forms.CheckBox(); 55 | this.panel = new System.Windows.Forms.Panel(); 56 | this.buttonEnergyModel = new System.Windows.Forms.Button(); 57 | this.buttonReloadMap = new System.Windows.Forms.Button(); 58 | this.labelUsedEnergy = new System.Windows.Forms.Label(); 59 | this.buttonStatistic = new System.Windows.Forms.Button(); 60 | this.btnLink = new System.Windows.Forms.Button(); 61 | this.labelCharge = new System.Windows.Forms.Label(); 62 | this.labelInfo = new System.Windows.Forms.Label(); 63 | this.btnHelp = new System.Windows.Forms.Button(); 64 | this.labelRoute = new System.Windows.Forms.Label(); 65 | this.pictBoxArea = new System.Windows.Forms.PictureBox(); 66 | this.btnNearestNeighbour = new System.Windows.Forms.Button(); 67 | this.btnFPPWR = new System.Windows.Forms.Button(); 68 | this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); 69 | this.labelTextBoxInfoTip = new System.Windows.Forms.Label(); 70 | this.panel.SuspendLayout(); 71 | ((System.ComponentModel.ISupportInitialize)(this.pictBoxArea)).BeginInit(); 72 | this.SuspendLayout(); 73 | // 74 | // textBoxInfo 75 | // 76 | this.textBoxInfo.AcceptsReturn = true; 77 | this.textBoxInfo.AcceptsTab = true; 78 | this.textBoxInfo.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 79 | this.textBoxInfo.Location = new System.Drawing.Point(887, 38); 80 | this.textBoxInfo.Margin = new System.Windows.Forms.Padding(4); 81 | this.textBoxInfo.Multiline = true; 82 | this.textBoxInfo.Name = "textBoxInfo"; 83 | this.textBoxInfo.ReadOnly = true; 84 | this.textBoxInfo.RightToLeft = System.Windows.Forms.RightToLeft.No; 85 | this.textBoxInfo.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; 86 | this.textBoxInfo.Size = new System.Drawing.Size(268, 758); 87 | this.textBoxInfo.TabIndex = 9; 88 | // 89 | // textBoxSetPointsCount 90 | // 91 | this.textBoxSetPointsCount.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 92 | this.textBoxSetPointsCount.Location = new System.Drawing.Point(1336, 118); 93 | this.textBoxSetPointsCount.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); 94 | this.textBoxSetPointsCount.Name = "textBoxSetPointsCount"; 95 | this.textBoxSetPointsCount.Size = new System.Drawing.Size(145, 32); 96 | this.textBoxSetPointsCount.TabIndex = 16; 97 | this.toolTip1.SetToolTip(this.textBoxSetPointsCount, "default: 100"); 98 | // 99 | // label2 100 | // 101 | this.label2.AutoSize = true; 102 | this.label2.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 103 | this.label2.Location = new System.Drawing.Point(1162, 121); 104 | this.label2.Name = "label2"; 105 | this.label2.Size = new System.Drawing.Size(150, 24); 106 | this.label2.TabIndex = 15; 107 | this.label2.Text = "Set nodes count:"; 108 | // 109 | // label1 110 | // 111 | this.label1.AutoSize = true; 112 | this.label1.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 113 | this.label1.Location = new System.Drawing.Point(1164, 241); 114 | this.label1.Name = "label1"; 115 | this.label1.Size = new System.Drawing.Size(159, 24); 116 | this.label1.TabIndex = 14; 117 | this.label1.Text = "Set cluster radius:"; 118 | this.toolTip1.SetToolTip(this.label1, "Forel have round clusters.\r\nSet cluster radius to start"); 119 | // 120 | // textBoxSetRadius 121 | // 122 | this.textBoxSetRadius.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 123 | this.textBoxSetRadius.Location = new System.Drawing.Point(1168, 267); 124 | this.textBoxSetRadius.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); 125 | this.textBoxSetRadius.Name = "textBoxSetRadius"; 126 | this.textBoxSetRadius.Size = new System.Drawing.Size(137, 32); 127 | this.textBoxSetRadius.TabIndex = 13; 128 | this.toolTip1.SetToolTip(this.textBoxSetRadius, "default: 100"); 129 | // 130 | // btnForel 131 | // 132 | this.btnForel.BackColor = System.Drawing.Color.DarkGray; 133 | this.btnForel.Enabled = false; 134 | this.btnForel.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 135 | this.btnForel.Location = new System.Drawing.Point(1330, 260); 136 | this.btnForel.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); 137 | this.btnForel.Name = "btnForel"; 138 | this.btnForel.Size = new System.Drawing.Size(154, 45); 139 | this.btnForel.TabIndex = 11; 140 | this.btnForel.Text = "Forel"; 141 | this.toolTip1.SetToolTip(this.btnForel, "Click to start.\r\nDon\'t forget to generate _points at first!"); 142 | this.btnForel.UseVisualStyleBackColor = false; 143 | this.btnForel.Click += new System.EventHandler(this.btnForel_Click); 144 | // 145 | // btnGenPoints 146 | // 147 | this.btnGenPoints.BackColor = System.Drawing.Color.DarkGray; 148 | this.btnGenPoints.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 149 | this.btnGenPoints.Location = new System.Drawing.Point(1170, 28); 150 | this.btnGenPoints.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); 151 | this.btnGenPoints.Name = "btnGenPoints"; 152 | this.btnGenPoints.Size = new System.Drawing.Size(317, 52); 153 | this.btnGenPoints.TabIndex = 10; 154 | this.btnGenPoints.Text = "Draw nodes map"; 155 | this.btnGenPoints.UseVisualStyleBackColor = false; 156 | this.btnGenPoints.Click += new System.EventHandler(this.btnGenPoints_Click); 157 | this.btnGenPoints.MouseLeave += new System.EventHandler(this.btnGenPoints_MouseLeave); 158 | this.btnGenPoints.MouseMove += new System.Windows.Forms.MouseEventHandler(this.btnGenPoints_MouseMove); 159 | // 160 | // btnKMeans 161 | // 162 | this.btnKMeans.BackColor = System.Drawing.Color.DarkGray; 163 | this.btnKMeans.Enabled = false; 164 | this.btnKMeans.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 165 | this.btnKMeans.Location = new System.Drawing.Point(1332, 194); 166 | this.btnKMeans.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); 167 | this.btnKMeans.Name = "btnKMeans"; 168 | this.btnKMeans.Size = new System.Drawing.Size(154, 45); 169 | this.btnKMeans.TabIndex = 17; 170 | this.btnKMeans.Text = "k-means++"; 171 | this.toolTip1.SetToolTip(this.btnKMeans, "Click to start.\r\nDon\'t forget to generate _points at first!"); 172 | this.btnKMeans.UseVisualStyleBackColor = false; 173 | this.btnKMeans.Click += new System.EventHandler(this.btnKMeans_Click); 174 | // 175 | // label3 176 | // 177 | this.label3.AutoSize = true; 178 | this.label3.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 179 | this.label3.Location = new System.Drawing.Point(1168, 175); 180 | this.label3.Name = "label3"; 181 | this.label3.Size = new System.Drawing.Size(141, 24); 182 | this.label3.TabIndex = 23; 183 | this.label3.Text = "Set seeds count"; 184 | this.toolTip1.SetToolTip(this.label3, "Seeds - it\'s clusters centroids.\r\nSet value to start"); 185 | // 186 | // textBoxSetSeedsCount 187 | // 188 | this.textBoxSetSeedsCount.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 189 | this.textBoxSetSeedsCount.Location = new System.Drawing.Point(1171, 201); 190 | this.textBoxSetSeedsCount.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); 191 | this.textBoxSetSeedsCount.Name = "textBoxSetSeedsCount"; 192 | this.textBoxSetSeedsCount.Size = new System.Drawing.Size(137, 32); 193 | this.textBoxSetSeedsCount.TabIndex = 24; 194 | this.toolTip1.SetToolTip(this.textBoxSetSeedsCount, "default: 2"); 195 | // 196 | // btnSpiralRoute 197 | // 198 | this.btnSpiralRoute.BackColor = System.Drawing.Color.Aqua; 199 | this.btnSpiralRoute.Enabled = false; 200 | this.btnSpiralRoute.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 201 | this.btnSpiralRoute.Location = new System.Drawing.Point(1168, 461); 202 | this.btnSpiralRoute.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); 203 | this.btnSpiralRoute.Name = "btnSpiralRoute"; 204 | this.btnSpiralRoute.Size = new System.Drawing.Size(319, 45); 205 | this.btnSpiralRoute.TabIndex = 29; 206 | this.btnSpiralRoute.Text = "Spiral route"; 207 | this.toolTip1.SetToolTip(this.btnSpiralRoute, "Build a spiral route on _points.\r\nLike convex hull but without final point"); 208 | this.btnSpiralRoute.UseVisualStyleBackColor = false; 209 | this.btnSpiralRoute.Click += new System.EventHandler(this.btnSpiralRoute_Click); 210 | // 211 | // btnConvexHull 212 | // 213 | this.btnConvexHull.BackColor = System.Drawing.Color.Yellow; 214 | this.btnConvexHull.Enabled = false; 215 | this.btnConvexHull.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 216 | this.btnConvexHull.Location = new System.Drawing.Point(1168, 363); 217 | this.btnConvexHull.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); 218 | this.btnConvexHull.Name = "btnConvexHull"; 219 | this.btnConvexHull.Size = new System.Drawing.Size(319, 45); 220 | this.btnConvexHull.TabIndex = 30; 221 | this.btnConvexHull.Text = "Convex hull insertion (modified)"; 222 | this.toolTip1.SetToolTip(this.btnConvexHull, "Build route like a rope\r\n1. creates an outer contour\r\n2. narrows the contour ever" + 223 | "y time"); 224 | this.btnConvexHull.UseVisualStyleBackColor = false; 225 | this.btnConvexHull.Click += new System.EventHandler(this.btnClustersRoute_Click); 226 | // 227 | // btnBruteForce 228 | // 229 | this.btnBruteForce.BackColor = System.Drawing.Color.Blue; 230 | this.btnBruteForce.Enabled = false; 231 | this.btnBruteForce.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 232 | this.btnBruteForce.Location = new System.Drawing.Point(1168, 314); 233 | this.btnBruteForce.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); 234 | this.btnBruteForce.Name = "btnBruteForce"; 235 | this.btnBruteForce.Size = new System.Drawing.Size(319, 45); 236 | this.btnBruteForce.TabIndex = 31; 237 | this.btnBruteForce.Text = "Route by Brute-force"; 238 | this.toolTip1.SetToolTip(this.btnBruteForce, "Calculate all routes and find least\r\nNP-complete algorithm!\r\nCan be long calculat" + 239 | "ing time!\r\nRecommended route _points count <10"); 240 | this.btnBruteForce.UseVisualStyleBackColor = false; 241 | this.btnBruteForce.Click += new System.EventHandler(this.btnBruteForce_Click); 242 | // 243 | // btnSelectCluster 244 | // 245 | this.btnSelectCluster.BackColor = System.Drawing.Color.DarkGray; 246 | this.btnSelectCluster.Enabled = false; 247 | this.btnSelectCluster.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 248 | this.btnSelectCluster.Location = new System.Drawing.Point(1169, 574); 249 | this.btnSelectCluster.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); 250 | this.btnSelectCluster.Name = "btnSelectCluster"; 251 | this.btnSelectCluster.Size = new System.Drawing.Size(156, 45); 252 | this.btnSelectCluster.TabIndex = 32; 253 | this.btnSelectCluster.Text = "Select cluster"; 254 | this.toolTip1.SetToolTip(this.btnSelectCluster, "Zoom and draw selected cluster"); 255 | this.btnSelectCluster.UseVisualStyleBackColor = false; 256 | this.btnSelectCluster.Click += new System.EventHandler(this.btn1ClusterOn_Click); 257 | // 258 | // textBoxSetClusterNum 259 | // 260 | this.textBoxSetClusterNum.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 261 | this.textBoxSetClusterNum.Location = new System.Drawing.Point(1377, 581); 262 | this.textBoxSetClusterNum.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); 263 | this.textBoxSetClusterNum.Name = "textBoxSetClusterNum"; 264 | this.textBoxSetClusterNum.Size = new System.Drawing.Size(110, 32); 265 | this.textBoxSetClusterNum.TabIndex = 33; 266 | this.toolTip1.SetToolTip(this.textBoxSetClusterNum, "Write cluster number"); 267 | // 268 | // btnDeselectCluster 269 | // 270 | this.btnDeselectCluster.BackColor = System.Drawing.Color.Salmon; 271 | this.btnDeselectCluster.Enabled = false; 272 | this.btnDeselectCluster.Font = new System.Drawing.Font("Microsoft Sans Serif", 13.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 273 | this.btnDeselectCluster.Location = new System.Drawing.Point(1331, 574); 274 | this.btnDeselectCluster.Name = "btnDeselectCluster"; 275 | this.btnDeselectCluster.Size = new System.Drawing.Size(40, 45); 276 | this.btnDeselectCluster.TabIndex = 35; 277 | this.btnDeselectCluster.Text = "×"; 278 | this.toolTip1.SetToolTip(this.btnDeselectCluster, "Deselect cluster, draw map"); 279 | this.btnDeselectCluster.UseVisualStyleBackColor = false; 280 | this.btnDeselectCluster.Click += new System.EventHandler(this.btnDeselectCluster_Click); 281 | // 282 | // btnCalcEnergy 283 | // 284 | this.btnCalcEnergy.BackColor = System.Drawing.Color.DarkGray; 285 | this.btnCalcEnergy.Enabled = false; 286 | this.btnCalcEnergy.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 287 | this.btnCalcEnergy.Location = new System.Drawing.Point(1170, 623); 288 | this.btnCalcEnergy.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); 289 | this.btnCalcEnergy.Name = "btnCalcEnergy"; 290 | this.btnCalcEnergy.Size = new System.Drawing.Size(184, 45); 291 | this.btnCalcEnergy.TabIndex = 36; 292 | this.btnCalcEnergy.Text = "Calculate energy"; 293 | this.toolTip1.SetToolTip(this.btnCalcEnergy, resources.GetString("btnCalcEnergy.ToolTip")); 294 | this.btnCalcEnergy.UseVisualStyleBackColor = false; 295 | this.btnCalcEnergy.Click += new System.EventHandler(this.btnCalcEnergy_Click); 296 | // 297 | // textBoxSetHeight 298 | // 299 | this.textBoxSetHeight.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 300 | this.textBoxSetHeight.Location = new System.Drawing.Point(1384, 677); 301 | this.textBoxSetHeight.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); 302 | this.textBoxSetHeight.Name = "textBoxSetHeight"; 303 | this.textBoxSetHeight.Size = new System.Drawing.Size(103, 32); 304 | this.textBoxSetHeight.TabIndex = 37; 305 | this.toolTip1.SetToolTip(this.textBoxSetHeight, "Set high"); 306 | // 307 | // label4 308 | // 309 | this.label4.AutoSize = true; 310 | this.label4.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 311 | this.label4.Location = new System.Drawing.Point(1159, 680); 312 | this.label4.Name = "label4"; 313 | this.label4.Size = new System.Drawing.Size(212, 24); 314 | this.label4.TabIndex = 38; 315 | this.label4.Text = "Set station flying height:"; 316 | this.toolTip1.SetToolTip(this.label4, "Height where will move station.\r\nMore high - more distance to station\r\n(we can\'t " + 317 | "see it on 2D proection)"); 318 | // 319 | // comboBoxConnectionType 320 | // 321 | this.comboBoxConnectionType.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 322 | this.comboBoxConnectionType.FormattingEnabled = true; 323 | this.comboBoxConnectionType.Items.AddRange(new object[] { 324 | "DT center", 325 | "DT route", 326 | "PP center", 327 | "PP route"}); 328 | this.comboBoxConnectionType.Location = new System.Drawing.Point(1360, 630); 329 | this.comboBoxConnectionType.Name = "comboBoxConnectionType"; 330 | this.comboBoxConnectionType.Size = new System.Drawing.Size(127, 32); 331 | this.comboBoxConnectionType.TabIndex = 39; 332 | this.toolTip1.SetToolTip(this.comboBoxConnectionType, "Select connection type"); 333 | // 334 | // checkBoxAllowGeneratePoints 335 | // 336 | this.checkBoxAllowGeneratePoints.AutoSize = true; 337 | this.checkBoxAllowGeneratePoints.Checked = true; 338 | this.checkBoxAllowGeneratePoints.CheckState = System.Windows.Forms.CheckState.Checked; 339 | this.checkBoxAllowGeneratePoints.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 340 | this.checkBoxAllowGeneratePoints.Location = new System.Drawing.Point(1167, 85); 341 | this.checkBoxAllowGeneratePoints.Name = "checkBoxAllowGeneratePoints"; 342 | this.checkBoxAllowGeneratePoints.Size = new System.Drawing.Size(274, 28); 343 | this.checkBoxAllowGeneratePoints.TabIndex = 40; 344 | this.checkBoxAllowGeneratePoints.Text = "Allow to generate a new map"; 345 | this.checkBoxAllowGeneratePoints.UseVisualStyleBackColor = true; 346 | // 347 | // panel 348 | // 349 | this.panel.Controls.Add(this.buttonEnergyModel); 350 | this.panel.Controls.Add(this.buttonReloadMap); 351 | this.panel.Controls.Add(this.labelUsedEnergy); 352 | this.panel.Controls.Add(this.buttonStatistic); 353 | this.panel.Controls.Add(this.btnLink); 354 | this.panel.Controls.Add(this.labelCharge); 355 | this.panel.Controls.Add(this.labelInfo); 356 | this.panel.Controls.Add(this.btnHelp); 357 | this.panel.Controls.Add(this.labelRoute); 358 | this.panel.Controls.Add(this.pictBoxArea); 359 | this.panel.Location = new System.Drawing.Point(0, -1); 360 | this.panel.Name = "panel"; 361 | this.panel.Size = new System.Drawing.Size(888, 816); 362 | this.panel.TabIndex = 41; 363 | // 364 | // buttonEnergyModel 365 | // 366 | this.buttonEnergyModel.BackColor = System.Drawing.Color.Magenta; 367 | this.buttonEnergyModel.Enabled = false; 368 | this.buttonEnergyModel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 369 | this.buttonEnergyModel.Location = new System.Drawing.Point(829, 145); 370 | this.buttonEnergyModel.Name = "buttonEnergyModel"; 371 | this.buttonEnergyModel.Size = new System.Drawing.Size(42, 37); 372 | this.buttonEnergyModel.TabIndex = 34; 373 | this.buttonEnergyModel.Text = "M"; 374 | this.toolTip1.SetToolTip(this.buttonEnergyModel, "(Model) Energy model parameters"); 375 | this.buttonEnergyModel.UseVisualStyleBackColor = false; 376 | this.buttonEnergyModel.Click += new System.EventHandler(this.buttonEnergyModel_Click); 377 | // 378 | // buttonReloadMap 379 | // 380 | this.buttonReloadMap.BackColor = System.Drawing.Color.Gold; 381 | this.buttonReloadMap.Enabled = false; 382 | this.buttonReloadMap.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 383 | this.buttonReloadMap.Location = new System.Drawing.Point(830, 231); 384 | this.buttonReloadMap.Name = "buttonReloadMap"; 385 | this.buttonReloadMap.Size = new System.Drawing.Size(42, 37); 386 | this.buttonReloadMap.TabIndex = 33; 387 | this.buttonReloadMap.Text = "R"; 388 | this.toolTip1.SetToolTip(this.buttonReloadMap, "Reload Map"); 389 | this.buttonReloadMap.UseVisualStyleBackColor = false; 390 | this.buttonReloadMap.Click += new System.EventHandler(this.buttonReloadMap_Click); 391 | // 392 | // labelUsedEnergy 393 | // 394 | this.labelUsedEnergy.AutoSize = true; 395 | this.labelUsedEnergy.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 396 | this.labelUsedEnergy.Location = new System.Drawing.Point(544, 760); 397 | this.labelUsedEnergy.Name = "labelUsedEnergy"; 398 | this.labelUsedEnergy.Size = new System.Drawing.Size(120, 24); 399 | this.labelUsedEnergy.TabIndex = 32; 400 | this.labelUsedEnergy.Text = "___________"; 401 | // 402 | // buttonStatistic 403 | // 404 | this.buttonStatistic.BackColor = System.Drawing.Color.Red; 405 | this.buttonStatistic.Enabled = false; 406 | this.buttonStatistic.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 407 | this.buttonStatistic.Location = new System.Drawing.Point(829, 188); 408 | this.buttonStatistic.Name = "buttonStatistic"; 409 | this.buttonStatistic.Size = new System.Drawing.Size(42, 37); 410 | this.buttonStatistic.TabIndex = 31; 411 | this.buttonStatistic.Text = "S"; 412 | this.toolTip1.SetToolTip(this.buttonStatistic, "Statistic"); 413 | this.buttonStatistic.UseVisualStyleBackColor = false; 414 | this.buttonStatistic.Click += new System.EventHandler(this.buttonStatistic_Click); 415 | // 416 | // btnLink 417 | // 418 | this.btnLink.BackColor = System.Drawing.Color.DeepSkyBlue; 419 | this.btnLink.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 420 | this.btnLink.Location = new System.Drawing.Point(829, 102); 421 | this.btnLink.Name = "btnLink"; 422 | this.btnLink.Size = new System.Drawing.Size(42, 37); 423 | this.btnLink.TabIndex = 30; 424 | this.btnLink.Text = "L"; 425 | this.toolTip1.SetToolTip(this.btnLink, "Link to project site"); 426 | this.btnLink.UseVisualStyleBackColor = false; 427 | this.btnLink.Click += new System.EventHandler(this.btnLink_Click); 428 | // 429 | // labelCharge 430 | // 431 | this.labelCharge.AutoSize = true; 432 | this.labelCharge.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 433 | this.labelCharge.Location = new System.Drawing.Point(325, 760); 434 | this.labelCharge.Name = "labelCharge"; 435 | this.labelCharge.Size = new System.Drawing.Size(120, 24); 436 | this.labelCharge.TabIndex = 29; 437 | this.labelCharge.Text = "___________"; 438 | // 439 | // labelInfo 440 | // 441 | this.labelInfo.AutoSize = true; 442 | this.labelInfo.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 443 | this.labelInfo.Location = new System.Drawing.Point(80, 65); 444 | this.labelInfo.Name = "labelInfo"; 445 | this.labelInfo.Size = new System.Drawing.Size(0, 25); 446 | this.labelInfo.TabIndex = 28; 447 | this.labelInfo.Visible = false; 448 | // 449 | // btnHelp 450 | // 451 | this.btnHelp.BackColor = System.Drawing.Color.Lime; 452 | this.btnHelp.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 453 | this.btnHelp.Location = new System.Drawing.Point(829, 59); 454 | this.btnHelp.Name = "btnHelp"; 455 | this.btnHelp.Size = new System.Drawing.Size(42, 37); 456 | this.btnHelp.TabIndex = 27; 457 | this.btnHelp.Text = "?"; 458 | this.toolTip1.SetToolTip(this.btnHelp, "Help"); 459 | this.btnHelp.UseVisualStyleBackColor = false; 460 | this.btnHelp.Click += new System.EventHandler(this.btnHelp_Click); 461 | // 462 | // labelRoute 463 | // 464 | this.labelRoute.AutoSize = true; 465 | this.labelRoute.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 466 | this.labelRoute.Location = new System.Drawing.Point(92, 760); 467 | this.labelRoute.Name = "labelRoute"; 468 | this.labelRoute.Size = new System.Drawing.Size(120, 24); 469 | this.labelRoute.TabIndex = 26; 470 | this.labelRoute.Text = "___________"; 471 | // 472 | // pictBoxArea 473 | // 474 | this.pictBoxArea.BackColor = System.Drawing.Color.White; 475 | this.pictBoxArea.Enabled = false; 476 | this.pictBoxArea.Location = new System.Drawing.Point(72, 59); 477 | this.pictBoxArea.Margin = new System.Windows.Forms.Padding(0); 478 | this.pictBoxArea.Name = "pictBoxArea"; 479 | this.pictBoxArea.Size = new System.Drawing.Size(800, 738); 480 | this.pictBoxArea.TabIndex = 1; 481 | this.pictBoxArea.TabStop = false; 482 | // 483 | // btnNearestNeighbour 484 | // 485 | this.btnNearestNeighbour.BackColor = System.Drawing.Color.Salmon; 486 | this.btnNearestNeighbour.Enabled = false; 487 | this.btnNearestNeighbour.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 488 | this.btnNearestNeighbour.Location = new System.Drawing.Point(1169, 412); 489 | this.btnNearestNeighbour.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); 490 | this.btnNearestNeighbour.Name = "btnNearestNeighbour"; 491 | this.btnNearestNeighbour.Size = new System.Drawing.Size(319, 45); 492 | this.btnNearestNeighbour.TabIndex = 42; 493 | this.btnNearestNeighbour.Text = "Route by nearest neighbour"; 494 | this.toolTip1.SetToolTip(this.btnNearestNeighbour, "Build route to closest point every step"); 495 | this.btnNearestNeighbour.UseVisualStyleBackColor = false; 496 | this.btnNearestNeighbour.Click += new System.EventHandler(this.btnNearestNeighbour_Click); 497 | // 498 | // btnFPPWR 499 | // 500 | this.btnFPPWR.BackColor = System.Drawing.Color.Purple; 501 | this.btnFPPWR.Enabled = false; 502 | this.btnFPPWR.Font = new System.Drawing.Font("Calibri", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 503 | this.btnFPPWR.Location = new System.Drawing.Point(1168, 510); 504 | this.btnFPPWR.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); 505 | this.btnFPPWR.Name = "btnFPPWR"; 506 | this.btnFPPWR.Size = new System.Drawing.Size(319, 45); 507 | this.btnFPPWR.TabIndex = 43; 508 | this.btnFPPWR.Text = "Route by FPPWR"; 509 | this.toolTip1.SetToolTip(this.btnFPPWR, resources.GetString("btnFPPWR.ToolTip")); 510 | this.btnFPPWR.UseVisualStyleBackColor = false; 511 | this.btnFPPWR.Click += new System.EventHandler(this.btnFPPWR_Click); 512 | // 513 | // labelTextBoxInfoTip 514 | // 515 | this.labelTextBoxInfoTip.AutoSize = true; 516 | this.labelTextBoxInfoTip.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); 517 | this.labelTextBoxInfoTip.Location = new System.Drawing.Point(894, 9); 518 | this.labelTextBoxInfoTip.Name = "labelTextBoxInfoTip"; 519 | this.labelTextBoxInfoTip.Size = new System.Drawing.Size(223, 25); 520 | this.labelTextBoxInfoTip.TabIndex = 44; 521 | this.labelTextBoxInfoTip.Text = "[position, cluster] charge"; 522 | // 523 | // Form1 524 | // 525 | this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); 526 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 527 | this.ClientSize = new System.Drawing.Size(1498, 817); 528 | this.Controls.Add(this.labelTextBoxInfoTip); 529 | this.Controls.Add(this.btnFPPWR); 530 | this.Controls.Add(this.btnNearestNeighbour); 531 | this.Controls.Add(this.checkBoxAllowGeneratePoints); 532 | this.Controls.Add(this.comboBoxConnectionType); 533 | this.Controls.Add(this.label4); 534 | this.Controls.Add(this.textBoxSetHeight); 535 | this.Controls.Add(this.btnCalcEnergy); 536 | this.Controls.Add(this.btnDeselectCluster); 537 | this.Controls.Add(this.textBoxSetClusterNum); 538 | this.Controls.Add(this.btnSelectCluster); 539 | this.Controls.Add(this.btnBruteForce); 540 | this.Controls.Add(this.btnConvexHull); 541 | this.Controls.Add(this.btnSpiralRoute); 542 | this.Controls.Add(this.textBoxSetSeedsCount); 543 | this.Controls.Add(this.label3); 544 | this.Controls.Add(this.btnKMeans); 545 | this.Controls.Add(this.textBoxSetPointsCount); 546 | this.Controls.Add(this.label2); 547 | this.Controls.Add(this.label1); 548 | this.Controls.Add(this.textBoxSetRadius); 549 | this.Controls.Add(this.btnForel); 550 | this.Controls.Add(this.btnGenPoints); 551 | this.Controls.Add(this.textBoxInfo); 552 | this.Controls.Add(this.panel); 553 | this.Name = "Form1"; 554 | this.Text = "Clusterization algorithms"; 555 | this.Shown += new System.EventHandler(this.Form1_Shown); 556 | this.panel.ResumeLayout(false); 557 | this.panel.PerformLayout(); 558 | ((System.ComponentModel.ISupportInitialize)(this.pictBoxArea)).EndInit(); 559 | this.ResumeLayout(false); 560 | this.PerformLayout(); 561 | 562 | } 563 | 564 | #endregion 565 | private System.Windows.Forms.TextBox textBoxSetPointsCount; 566 | private System.Windows.Forms.Label label2; 567 | private System.Windows.Forms.Label label1; 568 | private System.Windows.Forms.TextBox textBoxSetRadius; 569 | private System.Windows.Forms.Button btnForel; 570 | private System.Windows.Forms.Button btnGenPoints; 571 | private System.Windows.Forms.Button btnKMeans; 572 | private System.Windows.Forms.Label label3; 573 | private System.Windows.Forms.TextBox textBoxSetSeedsCount; 574 | private System.Windows.Forms.Button btnSpiralRoute; 575 | private System.Windows.Forms.Button btnConvexHull; 576 | private System.Windows.Forms.Button btnBruteForce; 577 | private System.Windows.Forms.Button btnSelectCluster; 578 | private System.Windows.Forms.TextBox textBoxSetClusterNum; 579 | private System.Windows.Forms.Button btnDeselectCluster; 580 | private System.Windows.Forms.Button btnCalcEnergy; 581 | private System.Windows.Forms.TextBox textBoxSetHeight; 582 | private System.Windows.Forms.Label label4; 583 | private System.Windows.Forms.TextBox textBoxInfo; 584 | private System.Windows.Forms.ComboBox comboBoxConnectionType; 585 | private System.Windows.Forms.CheckBox checkBoxAllowGeneratePoints; 586 | private System.Windows.Forms.Panel panel; 587 | private System.Windows.Forms.Button btnNearestNeighbour; 588 | private System.Windows.Forms.PictureBox pictBoxArea; 589 | private System.Windows.Forms.Label labelRoute; 590 | private System.Windows.Forms.Button btnFPPWR; 591 | private System.Windows.Forms.ToolTip toolTip1; 592 | private System.Windows.Forms.Label labelTextBoxInfoTip; 593 | private System.Windows.Forms.Button btnHelp; 594 | private System.Windows.Forms.Label labelInfo; 595 | private System.Windows.Forms.Label labelCharge; 596 | private System.Windows.Forms.Button buttonStatistic; 597 | private System.Windows.Forms.Label labelUsedEnergy; 598 | private System.Windows.Forms.Button buttonReloadMap; 599 | private System.Windows.Forms.Button buttonEnergyModel; 600 | private System.Windows.Forms.Button btnLink; 601 | } 602 | } 603 | 604 | --------------------------------------------------------------------------------