| ← Январь 2014 → | ||||||
|
1
|
2
|
3
|
4
|
5
|
||
|---|---|---|---|---|---|---|
|
6
|
7
|
8
|
9
|
10
|
11
|
12
|
|
13
|
14
|
15
|
16
|
17
|
18
|
19
|
|
20
|
21
|
22
|
23
|
24
|
25
|
26
|
|
27
|
28
|
30
|
31
|
|||
За последние 60 дней ни разу не выходила
Сайт рассылки:
http://rusfaq.ru/issues/5/3/454
Открыта:
23-10-2008
Статистика
0 за неделю
RFpro.ru: Microsoft .NET
Хостинг портала RFpro.ru: РАССЫЛКИ ПОРТАЛА RFPRO.RU
Лучшие эксперты по данной тематике
/ КОМПЬЮТЕРЫ И СОФТ / Программирование / Microsoft .NET : C#
Консультация # 183700: Здравствуйте! Прошу помощи в следующем вопросе: Написать Windows-приложение, которое по заданным в файле исходным данным строит столбиковую диаграмму, однако в которой все значения ниже 5 не выводятся на экран. Создать меню с командами Input data, Choose, Show, Quit. Команда Show недоступны. Команда Quit завершает работу приложения. Здравствуйте! Прошу помощи в следующем вопросе:
Дата отправки: 22.06.2011, 23:34 Консультирует PsySex (Профессионал): Здравствуйте, Yulesik!
помогите реализовать такой алгоритм кластеризации k-середных
Дата отправки: 11.02.2009, 21:53 Консультирует Micren (Профессор): Здравствуйте, Иванка! Код :
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using ClusterAnalyze;
namespace _160240
{
class Program
{
static void Main(string[] args)
{
uint rows, cols;
rows = InputUInt("Введите количество строк матрицы:");
cols = InputUInt("Введите количество столбцов матрицы:");
double[,] matrix;
try
{
matrix = new double[rows, cols];
Random rndGen = new Random();
for (uint i = 0; i < rows; i++)
{
for (uint j = 0; j < cols; j++)
{
matrix[i, j] = rndGen.NextDouble() * 100 - 50;
}
}
Console.WriteLine("Исходная матрица:");
for (uint i = 0; i < rows; i++)
{
for (uint j = 0; j < cols; j++)
{
Console.Write("{0,7:F3} ", matrix[i, j]);
}
Console.WriteLine();
}
double deviation = InputDouble("Введите желаемую погрешность:");
try
{
ClusterAnalyze.ClusterResult result = KMeans.Solve(matrix, rows, deviation);
uint clusterNo = 0;
foreach (ClusterAnalyze.ListOfRecords cluster in result)
{
Console.WriteLine("Кластер {0}", ++clusterNo);
foreach (uint line in cluster)
{
for (uint i = 0; i < cols; i++)
{
Console.Write("{0,7:F3} ", matrix[line, i]);
}
Console.WriteLine();
}
}
Console.WriteLine("Среднее отклонение:{0}", result.AverageDeviation);
Console.WriteLine("Максимальное отклонение:{0}", result.MaxDeviation);
}
catch (ClusterAnalyze.ClusterAnalyzeException ex)
{
ErrorMsg(ex.Message);
}
}
catch (OutOfMemoryException)
{
ErrorMsg("Не могу выделить память для матрицы");
}
Console.WriteLine("Нажмите любую клавишу для выхода");
Console.ReadKey();
}
/// <summary>
/// Ввод числа типа double
/// </summary>
/// <param name="msg">Сообщение</param>
/// <returns>Число</returns>
static double InputDouble(string msg)
{
while (true)
{
Console.Write(msg);
try
{
double val = Convert.ToDouble(Console.ReadLine());
return val;
}
catch (FormatException)
{ }
catch (OverflowException)
{ }
ErrorMsg("Неверный ввод: ожидается действительное число");
}
}
/// <summary>
/// Ввод числа типа uint
/// </summary>
/// <param name="msg">Сообщение</param>
/// <returns>Число</returns>
static uint InputUInt(string msg)
{
while (true)
{
Console.Write(msg);
try
{
uint val = Convert.ToUInt32(Console.ReadLine());
return val;
}
catch (FormatException)
{ }
catch (OverflowException)
{ }
ErrorMsg("Неверный ввод: ожидается целое положительное число");
}
}
/// <summary>
/// Ввод числа типа uint в заданном диапазоне
/// </summary>
/// <param name="msg">Сообщение</param>
/// <param name="lo">Нижняя граница</param>
/// <param name="high">Верхняя граница</param>
/// <returns>Число</returns>
static uint InputUInt(string msg, uint lo, uint high)
{
while (true)
{
uint val = InputUInt(msg);
if (val >= lo && val <= high) return val;
ErrorMsg(String.Format("Неверный ввод: ожидается значение в интервале {0}..{1}", lo, high));
}
}
/// <summary>
/// Выводит сообщение об ошибке
/// </summary>
/// <param name="msg">Сообщение</param>
static void ErrorMsg(string msg)
{
ConsoleColor color = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(msg);
Console.ForegroundColor = color;
}
}
}
namespace ClusterAnalyze
{
/// <summary>
/// Класс для кластерного анализа
/// </summary>
static class KMeans
{
/// <summary>
/// Решает задачу кластеризации
/// </summary>
/// <param name="matrix">Исходная матрица</param>
/// <param name="numCluster">Количество кластеров</param>
/// <returns>Результат анализа</returns>
public static ClusterResult Solve(double[,] matrix, uint numCluster)
{
return Clustering(Matrix2JadMatrix(matrix), numCluster);
}
/// <summary>
/// Решает задачу кластеризации
/// </summary>
/// <param name="matrix">Исходная матрица</param>
/// <param name="maxNumCluster">Ограничение на количество кластеров сверху</param>
/// <param name="deviation">Допустимое отклонение записи от центроида</param>
/// <returns>Результат анализа</returns>
public static ClusterResult Solve(double[,] matrix, uint maxNumCluster, double deviation)
{
if (deviation == 0) deviation = 1e-10;
else deviation = deviation < 0 ? -deviation : deviation;
ClusterResult res;
double[][] jadMatrix = Matrix2JadMatrix(matrix);
uint clusters = 0;
do
{
res = Clustering(jadMatrix, ++clusters);
} while ((clusters < maxNumCluster) && (res.MaxDeviation > deviation));
GC.Collect();
return res;
}
/// <summary>
/// Собственно решение здесь
/// </summary>
/// <param name="matrix">Матрица</param>
/// <param name="numCluster">Количество кластеров</param>
/// <returns>Результат анализа</returns>
private static ClusterResult Clustering(double[][] matrix, uint numCluster)
{
uint rows = (uint)matrix.Length;
// Количество кластеров должно быть не менее 1х и не более чем записей
if (numCluster > rows || numCluster < 1)
throw new ClusterAnalyzeException("ClusterResult Clustering(double[][] matrix, uint numCluster):\n" +
"Количество кластеров меньше 1 или больше чем число строк в матрице");
uint cols = (uint)matrix[0].Length;
// Задаем центроиды для начала
double[][] centroids = InitialCentroids(matrix, numCluster);
bool isCont;
// Словарь ключями которого являются номера центроидов, а значениями списки записей в матрице
Dictionary<uint, ListOfRecords> clustersDict;
double averageDeviation, maxDeviation;
do
{
clustersDict = new Dictionary<uint, ListOfRecords>();
// Отклонения от центроидов
averageDeviation = 0;
maxDeviation = 0;
// Для заданных центроидов определяем к какому кластеру относятся записи
for (uint i = 0; i < rows; i++)
{
// Индекс ближайшего
uint nearest = 0;
// Минимальная дистанция
double minDistance = Range(centroids[0], matrix[i]);
// Перебор центроидов
for (uint j = 1; j < numCluster; j++)
{
double distance = Range(centroids[j], matrix[i]);
if (distance < minDistance)
{
minDistance = distance;
nearest = j;
}
}
averageDeviation += minDistance / rows;
maxDeviation = maxDeviation < minDistance ? minDistance : maxDeviation;
// Добавляем в словарь
if (!clustersDict.ContainsKey(nearest))
{
clustersDict.Add(nearest, new ListOfRecords());
}
clustersDict[nearest].Add(i);
}
// Если есть не рабочие центроиды то избавимся от них
if (clustersDict.Count != numCluster)
{
numCluster = (uint)clustersDict.Count;
double[][] tmpCentroids = new double[numCluster][];
Dictionary<uint, ListOfRecords> tmpClusterDict = new Dictionary<uint, ListOfRecords>();
uint newNo = 0;
foreach (uint oldNo in clustersDict.Keys)
{
tmpCentroids[newNo] = centroids[oldNo];
tmpClusterDict.Add(newNo, clustersDict[oldNo]);
newNo++;
}
centroids = tmpCentroids;
clustersDict = tmpClusterDict;
}
// Флаг продолжения итераций
isCont = false;
// Считаем новые центроиды
double[][] newCentroids = new double[numCluster][];
foreach (uint i in clustersDict.Keys)
{
newCentroids[i] = new double[cols];
uint itemsInCluster = (uint)clustersDict[i].Count;
foreach (uint line in clustersDict[i])
{
for (uint j = 0; j < cols; j++)
{
newCentroids[i][j] += matrix[line][j] / itemsInCluster;
}
}
// Сравниваем со старым центроидом и копируем в него, если есть различие
for (uint j = 0; j < cols; j++)
{
if (centroids[i][j] != newCentroids[i][j])
{
centroids[i][j] = newCentroids[i][j];
isCont = true;
}
}
}
} while (isCont);
return new ClusterResult(clustersDict, averageDeviation, maxDeviation);
}
/// <summary>
/// Возвращает начальные значения для центроидов
/// </summary>
/// <param name="matrix">Матрица</param>
/// <param name="numCluster">Количество кластеров</param>
/// <returns>Двухмерный массив центроидов</returns>
private static double[][] InitialCentroids(double[][] matrix, uint numCluster)
{
uint rows = (uint)matrix.Length,
cols = (uint)matrix[0].Length;
double[][] centroids = new double[numCluster][];
for (uint i = 0; i < numCluster; i++)
{
centroids[i] = new double[cols];
uint line = i * rows / numCluster;
for (uint j = 0; j < cols; j++)
{
centroids[i][j] = matrix[line][j];
}
}
return centroids;
}
/// <summary>
/// Вычисляет среднеквадратичное отклонение между двумя векторами
/// </summary>
/// <param name="array1">1й вектор</param>
/// <param name="array2">2й вектор</param>
/// <returns>Отклонение</returns>
private static double Range(double[] array1, double[] array2)
{
uint len;
if ((len = (uint)array1.Length) != array2.Length)
throw new ClusterAnalyzeException("double Range(double[] array1, double[] array2):\n" +
"Массивы имеют разную длину");
double sum = 0;
for (uint i = 0; i < len; i++) sum += Math.Pow(array1[i] - array2[i], 2);
return Math.Sqrt(sum / len);
}
/// <summary>
/// Преобразует массив вида [,] к [][]
/// </summary>
/// <param name="matrix"></param>
/// <returns></returns>
private static double[][] Matrix2JadMatrix(double[,] matrix)
{
uint rows = (uint)matrix.GetLength(0),
cols = (uint)matrix.GetLength(1);
double[][] jadMatrix = new double[rows][];
for (uint i = 0; i < rows; i++)
{
jadMatrix[i] = new double[cols];
for (uint j = 0; j < cols; j++)
{
jadMatrix[i][j] = matrix[i, j];
}
}
return jadMatrix;
}
}
/// <summary>
/// Результат анализа возвращается в виде этого класса
/// </summary>
public class ClusterResult : IEnumerable
{
/// <summary>
/// Конструктор класса
/// </summary>
/// <param name="dict"></param>
/// <param name="averageDeviation">Среднее отклонение</param>
/// <param name="maxDeviation">Максимальное отклонение</param>
public ClusterResult(Dictionary<uint, ListOfRecords> dict, double averageDeviation, double maxDeviation)
{
AverageDeviation = averageDeviation;
MaxDeviation = maxDeviation;
data = dict.Values.ToArray();
}
/// <summary>
/// Список индексов записей в кластере
/// </summary>
/// <param name="Index">Номер кластера</param>
/// <returns>Список индексов записей</returns>
public ListOfRecords this[uint Index]
{
get
{
return data[Index];
}
}
/// <summary>
/// Количество кластеров
/// </summary>
public uint Size
{
get
{
return (uint)data.Length;
}
}
/// <summary>
/// Возвращает тип перечислителя
/// </summary>
/// <returns>Перечислитель</returns>
public IEnumerator GetEnumerator()
{
return data.GetEnumerator();
}
/// <summary>
/// Средне отклонение записей от центроидов кластеров
/// </summary>
public readonly double AverageDeviation;
/// <summary>
/// Максимальное отклонение от центроидов кластеров
/// </summary>
public readonly double MaxDeviation;
private readonly ListOfRecords[] data;
}
/// <summary>
/// Класс-исключение для перехвата ошибок возникающих в классе ClusterAnalyze
/// </summary>
public class ClusterAnalyzeException : ApplicationException
{
/// <summary>
/// Конструктор
/// </summary>
/// <param name="msg">Сообщение об ошибке</param>
public ClusterAnalyzeException(string msg)
: base(msg)
{ }
}
/// <summary>
/// Класс список номеров записей в файле. Служит исключительно как синоним базового класса
/// </summary>
public class ListOfRecords : List<uint>
{ }
}
http://rapidshare.com/files/198909615/160240-2.rar
Здравствуйте!
Дата отправки: 03.04.2007, 22:38 Консультирует Bevice: Здравствуйте, Steazy!
Консультирует Necrostaz: Здравствуйте, Steazy! За запись/чтение в .net отвечает абстракция System.IO.Stream. Базовая реализация поддерживает синхронное чтение/запись байт, а также seeking (поиск). В зависимости от конкретной задачи есть множество реализаций наследников и компонент, использующих потоки. В частности для файлов можно использовать FileStream и\или StreamWriter\StreamWriter
Консультирует Thread: Здравствуйте, Steazy!
Оценить выпуск | Задать вопрос экспертам
главная страница
|
стать участником
|
получить консультацию
© 2001-2012, Портал RFPRO.RU, Россия
Авторское право: ООО "Мастер-Эксперт Про" Калашников О.А. | Гладенюк А.Г. Хостинг: Версия системы: 2011.6.36 от 26.01.2012 |
| В избранное | ||


