├── 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 |
--------------------------------------------------------------------------------