1. 資料分群

要注意 new Random() 需要共用instance,不然結果會不隨機 = =

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using System.Xml.Serialization.Configuration;

namespace Q1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            var n = int.Parse(textBox1.Text);
            textBox6.Text = "";
            string a = "";
            string b = "";
            draw = false;
            var rd = new Random();
            for (int i = 0; i < n; i++)
            {
                textBox6.Text +=
                    (i + 1).ToString().PadLeft(2) + " ";
                a += rd.Next(0, 101) + " ";
                b += rd.Next(0, 101) + " ";
            }
            textBox3.Text = a.Substring(0, a.Length - 1);
            textBox4.Text = b.Substring(0, b.Length - 1);
            button2_Click(null, null);
            textBox5.Text = "";
        }

        private void button2_Click(object sender, EventArgs e)
        {
            int N = int.Parse(textBox1.Text);
            int Q = int.Parse(textBox2.Text);
            int K = 2;
            int P = 0;

            var data = new List<(double, double)>();
            var s1 = textBox3.Text.Split(' ');
            var s2 = textBox4.Text.Split(' ');
            for (int i = 0; i < N; i++)
            {
                data.Add(
(
                    int.Parse(s1[i]),
                                        int.Parse(s2[i])
)
                    );
            }
            var series = new Series();
            series.IsVisibleInLegend = false;
            series.ChartType = SeriesChartType.Line;
            series.BorderWidth = 3;
            series.BorderColor = Color.Blue;
            var area = new ChartArea();
            chart1.ChartAreas.Clear();
            chart1.ChartAreas.Add(area);
            chart1.Series.Clear();
            if (draw) chart1.Series.Add(series);

            var rd = new Random();
            var copy = data.OrderBy(x =>rd.Next()).ToList();
            var random = copy.Take(K).ToList();
            List<List<(double, double)>> groups = new List<List<(double, double)>>();
            for (int i = 0; i < K; i++) groups.Add(new List<(double, double)>());
            textBox5.Text = "";
            while (P < Q)
            {
                foreach (var item in groups)
                {
                    item.Clear();
                }
                foreach (var xj in data)
                {
                    double min = Double.MaxValue;
                    int k = -1;

                    for (int i = 0; i < random.Count; i++)
                    {
                        var ui = random[i];
                        double dist =
                            Math.Sqrt(
                                Math.Pow(
                                xj.Item1 - ui.Item1
                                , 2) +
                                Math.Pow(
                                xj.Item2 - ui.Item2, 2)
                                );
                        if (dist < min)
                        {
                            min = dist;
                            k = i;
                        }
                    }

                    if (P == Q - 1)
                    {
                        textBox5.Text += (k + 1).ToString().PadLeft(2) + " ";
                    }
                    groups[k].Add(xj);
                }

                for (int i = 0; i < random.Count; i++)
                {
                    random[i] =
                        (
                        groups[i].Average(r => r.Item1),
                        groups[i].Average(r => r.Item2));
                }

                var mse = 0.0;
                for (int i = 0; i < random.Count; i++)
                {
                    (double, double) u = random[i];
                    foreach (var item in groups[i])
                    {
                        mse +=
                        Math.Sqrt(Math.Pow(item.Item1 - u.Item1, 2) +
                            Math.Pow(item.Item2 - u.Item2, 2));
                    }
                }
                mse /= N;
                series.Points.AddXY(P, mse);

                P++;
            }
            area.AxisY.Minimum = series.Points.Min(r => r.YValues[0]);
            area.AxisY.LabelStyle.Format = "0";
            area.AxisX.Title = "疊代次數";
            area.AxisY.Title = "MSE";
        }

        bool draw = false;
        private void button3_Click(object sender, EventArgs e)
        {
            draw = true;
            button2_Click(null, null);
        }

        private void textBox4_TextChanged(object sender, EventArgs e)
        {

        }
    }
}

Last updated