https://pastein.ru/t/5D
скопируйте уникальную ссылку для отправки
Загрузка данных
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Laba2Ml
{
public partial class Form1 : Form
{
const int maxiter = 11;
static string path = $@"D:/ML/Laba2/data1.txt";
const int makol = 10000;
static int realkol;
const int amofAt = 2;
static double[,] dataset = new double [makol, amofAt];
static int[] classi_0 = new int[makol];
static int[] classi_1 = new int[makol];
static int kk = 5;
static int[] used;
static double[,] centra;
static int iterforkmean = 0;
static bool f = false;//разрешение на выполнение FindNearest()
static bool pc = false;//разрешение на выполнение пересчет
static bool vsekonech = false;
const int kolloktya = 11;
static double[] rezloktya = new double[kolloktya+1];
static void perechetcentrov()
{
if (!pc)
return;
double[] dyncentra = new double[kk];
for (int k = 0; k < kk; k++)
{
double koorx;
double koory;
double sumx = 0;
double sumy = 0;
int koltoch = 0;
for (int i = 0; i < realkol; i++)
{
if (classi_0[i] == k)
{
sumx += dataset[i, 0];
sumy += dataset[i, 1];
koltoch++;
}
}
koorx = sumx / koltoch;
koory = sumy / koltoch;
centra[k, 0] = koorx;
centra[k, 1] = koory;
}
pc = false;
f = true;
}
static void FindNearest()
{
if (vsekonech)
{
return;
}
for (int i = 0; i < realkol; i++)//перебор всех точек
{
double[] vremrast = new double[kk];//расстояния до всех центров, потом выбирается наименьшее и добавляется в rast[i]
for (int j = 0; j < kk; j++)
{
double slag1 = Math.Pow((centra[j, 0] - dataset[i, 0]), 2);
double slag2 = Math.Pow((centra[j, 1] - dataset[i, 1]), 2);
vremrast[j] = Math.Sqrt(slag1 + slag2);//расстояние до j центра
}
double minrast = vremrast[0];
int nomercentra = 0;
for (int j = 1; j < kk; j++)
{
if (minrast > vremrast[j])
{
minrast = vremrast[j];
nomercentra = j;
}
}
classi_1[i] = nomercentra;
}
bool aa1 = false;
for (int i = 0; i < realkol; i++)
{
if (classi_1[i] != classi_0[i])
{
aa1 = true;
}
}
if (aa1)
{
Array.Copy(classi_1, classi_0, realkol);
}
else
{
vsekonech = true;
}
f = false;
pc = true;
}
static void loktya()
{
FindCent(kk);
f = true;
pc = false;
while (!vsekonech)
{
FindNearest();
perechetcentrov();
}
double sumkvarvnrast = 0;
for (int k = 0; k < kk; k++)
{
double sumxy = 0;
for (int i = 0; i < realkol; i++)
{
if (classi_0[i] == k)
{
sumxy += Math.Pow((dataset[i, 0]-centra[k,0]),2)+ Math.Pow((dataset[i, 1] - centra[k, 1]), 2);
}
}
sumkvarvnrast += sumxy;
}
rezloktya[kk] = sumkvarvnrast;
vsekonech = false;
f = false;
pc = false;
}
static void FindCent(int kk1 )
{
double sumrast = 0;
int kolvocentrov = 0;//сколько уже выбранно центров
double[] rast = new double[realkol];//расстояния точки I доближайшего центра = rasr[i]
used = new int[kk1];//записываются какие точки уже используются как центра
centra = new double[kk1, amofAt];//матрица цетров
Random rnd = new Random();
int ind1 = rnd.Next(0, realkol);//выбор случайной точки, как первый центр
centra[0, 0] = dataset[ind1, 0];//добавление в матрицу
centra[0, 1] = dataset[ind1, 1];
used[0] = ind1;
kolvocentrov++;
for (int k = 1; k < kk1; k++)
{
sumrast = 0;
for (int i = 0; i < realkol; i++)//перебор всех точек
{
double[] vremrast = new double[kolvocentrov];//расстояния до всех центров, потом выбирается наименьшее и добавляется в rast[i]
for (int j = 0; j < kolvocentrov; j++)
{
double slag1 = Math.Pow((centra[j, 0] - dataset[i, 0]), 2);
double slag2 = Math.Pow((centra[j, 1] - dataset[i, 1]), 2);
vremrast[j] = Math.Sqrt(slag1 + slag2);//расстояние до j центра
}
rast[i] = FindMin(vremrast);
sumrast = sumrast + rast[i];
}
double sumrast1 = 0;
double p = rnd.NextDouble() * sumrast;
for (int i = 0; i < realkol; i++)
{
sumrast1 += rast[i];
if (sumrast1 > p)
{
ind1 = i;
break;
}
}
centra[k, 0] = dataset[ind1, 0];//добавление в матрицу
centra[k, 1] = dataset[ind1, 1];
used[k] = ind1;
kolvocentrov++;
}
f = true;
}
static double FindMin(double[] rast)
{
double min = rast[0];
for (int i = 1; i < rast.Length; i++)
{
if (min > rast[i])
{
min = rast[i];
}
}
return min;
}
public Form1()
{
InitializeComponent();
}
private void chart1_Click(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
int count = 0;
string line;
string[] s;
System.IO.StreamReader file = new System.IO.StreamReader(path);
while ((line = file.ReadLine()) != null)
{
s = line.Split();
if (s.Length == 0)
continue;
try
{
dataset[count, 0] = Convert.ToDouble(s[1], CultureInfo.InvariantCulture);
dataset[count, 1] = Convert.ToDouble(s[3], CultureInfo.InvariantCulture);
}
catch (Exception eeerr)
{
richTextBox1.Text = eeerr.ToString();
count--;
continue;
}
count++;
}
realkol = count;
file.Close();
for (int i = 0; i < realkol - 1; i++)
{
chart1.Series[0].Points.AddXY(dataset[i, 0], dataset[i, 1]);
}
}
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
for (int k = 0; k < kk; k++)
{
chart1.Series[k + 1].Points.Clear();
chart2.Series[k + 1].Points.Clear();
}
FindCent(kk);
for (int k = 0; k < kk; k++)
{
chart1.Series[k + 1].Points.AddXY(centra[k, 0], centra[k, 1]);
chart2.Series[k + 1].Points.AddXY(centra[k, 0], centra[k, 1]);
richTextBox1.Text += $@"
";
richTextBox1.Text += $"{k+1} центр -" + used[k].ToString();
richTextBox1.Text += $@"
{ centra[k, 0].ToString()} {centra[k, 1].ToString()} ";
}
}
private void chart2_Click(object sender, EventArgs e)
{
}
private void button3_Click(object sender, EventArgs e)
{
for (int i = 0; i < realkol; i++)
{
chart2.Series[(classi_1[i] + 1)].Points.AddXY(dataset[i,0], dataset[i, 1] );
}
}
private void button3_Click_1(object sender, EventArgs e)
{
if (vsekonech)
{
richTextBox1.Text = $"Дальше некуда, конец";
return;
}
if (!f)
{
richTextBox1.Text = $"ошибка нахождения кластера";
return;
}
FindNearest();
for (int k = 0; k < kk+1; k++)
{
chart1.Series[k].Points.Clear();
}
for (int i = 0; i < realkol; i++)
{
chart1.Series[classi_0[i] + 1].Points.AddXY(dataset[i, 0], dataset[i, 1]);
}
}
private void button4_Click(object sender, EventArgs e)
{
if (vsekonech)
{
richTextBox1.Text = $"Дальше некуда, конец";
return;
}
if (!pc)
{
richTextBox1.Text = $"ошибка пересчета центров";
return;
}
perechetcentrov();
for (int k = 0; k < 11; k++)
{
chart2.Series[k].Points.Clear();
}
for (int k = 0; k < kk; k++)
{
chart2.Series[k + 1].Points.AddXY(centra[k, 0], centra[k, 1]);
}
}
private void button5_Click(object sender, EventArgs e)
{
for (int k = 1; k <= kolloktya; k++)
{
kk = k;
loktya();
chart3.Series["loktya"].Points.AddXY(kk, rezloktya[kk]);
chart3.Series["Tochki"].Points.AddXY(kk, rezloktya[kk]);
}
double opredvel = rezloktya[1] / 16;
for (int k = 2; k <= kolloktya; k++)
{
double znachforprov = Math.Abs(rezloktya[k] - rezloktya[k - 1]);
if (znachforprov < opredvel)
{
kk = k;
richTextBox1.Text = $"Оптимальное кол-во кластеров = " + k.ToString();
break;
}
}
}
private void chart3_Click(object sender, EventArgs e)
{
}
}
}