Отправляет email-рассылки с помощью сервиса Sendsay

RFpro.ru: Microsoft .NET

  Все выпуски  

RFpro.ru: Microsoft .NET


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты по данной тематике

Асмик Гаряка
Статус: Советник
Рейтинг: 10653
∙ повысить рейтинг »
Micren
Статус: Профессор
Рейтинг: 1764
∙ повысить рейтинг »
Александр Чекменёв
Статус: Академик
Рейтинг: 1370
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И СОФТ / Программирование / Microsoft .NET : C#

Номер выпуска:253
Дата выхода:29.01.2014, 13:28
Администратор рассылки:Alexey G. Gladenyuk (Старший модератор)
Подписчиков / экспертов:43 / 22
Вопросов / ответов:3 / 5

Консультация # 183700: Здравствуйте! Прошу помощи в следующем вопросе: Написать Windows-приложение, которое по заданным в файле исходным данным строит столбиковую диаграмму, однако в которой все значения ниже 5 не выводятся на экран. Создать меню с командами Input data, Choose, Show, Quit. Команда Show недоступны. Команда Quit завершает работу приложения.Консультация # 160240: помогите реализовать такой алгоритм кластеризации k-середных для матрицы на С# или С++Builder алгоритм представляет собой итерационную процедуру, в которой выполняються следующие шаги. 1.Выбирается число кластеров k Из исходного множества данных случайным образом выбираются k записей,которые будут служить начальными центрами кластер...


Консультация # 80942: Здравствуйте! Подскажите, пожалуйста, грамотный способ чтения/записи из/в файла в С++.NET. Отличаются ли в этой среде обращение к файлу от любой другой (на языке С++)? Заранее благодарю....

Консультация # 183700:

Здравствуйте! Прошу помощи в следующем вопросе:

Написать Windows-приложение, которое по заданным в файле исходным данным строит столбиковую диаграмму, однако в которой все значения ниже 5 не выводятся на экран.
Создать меню с командами Input data, Choose, Show, Quit.
Команда Show недоступны. Команда Quit завершает работу приложения.
При выборе команды Input data из файла читаются исходные данные (файл сформировать самостоятельно).
По команде Choose открывается диалоговое окно, содержащее:
∙ список для выбора цвета графика типа TListBox;
∙ кнопку типа Button.
После указания параметров становится доступной соответствующая команда меню Show.
По команде Show в главном окне приложения выбранным цветом строится диаграмма. Окно должно содержать заголовок диаграммы, наименование и градацию осей. Изображение должно занимать все окно и масштабироваться при изменении размеров окна.

Есть кое-какие наработки, выкладываю их. Заранее, спасибо боль шое за помощь.

Дата отправки: 22.06.2011, 23:34
Вопрос задал: ProgYul (2-й класс)
Всего ответов: 1
Страница онлайн-консультации »


Консультирует PsySex (Профессионал):

Здравствуйте, Yulesik!
Решение, согласно Вашему заданию, прикрепляю к ответу.
Недоделаная наработка, которую Вы разместили в минифоруме относится к решению задачи чуть с другими условиями...

Консультировал: PsySex (Профессионал)
Дата отправки: 23.06.2011, 15:08
Прикреплённый файл: посмотреть » [34.3 кб]
Рейтинг ответа:

НЕ одобряю 0 одобряю!

Консультация # 160240:

помогите реализовать такой алгоритм кластеризации k-середных
для матрицы на С# или С++Builder

алгоритм представляет собой итерационную процедуру, в которой выполняються следующие шаги.
1.Выбирается число кластеров k
Из исходного множества данных случайным образом выбираются k записей,которые будут служить начальными центрами кластером
2.ля каждой записи исходной выборки определяется ближайший к ней центр кластера.
При етом записи, "притянутые"определенным центром образуют начальные кластеры
3.Вычисляются центроиды - центры тяжести кластеров. Каждый центроид - это вектор, элементы которого представлят собой средние значения признаков, вычисленные по всем записям кластера.
4.Затем центр кластера смещается в его центроид.
затем 3-й и 4-й шаги итеративно повторяются. Очевидно,что на каждой итерации происходит изменение границ кластеров и смещение их
центров.В результате минимизируется расстояние между элементами внутри кластеров. Остановка алгоритма производится тогда, когда
границы кластеров и расположения центроидов не перестанут изменятся отитерации к итерации, т.е.на каждой итерации в каждом кластере будет
оставаться один и тот же набор записей.

алгоритм реализовать в процедуре(функции), входные данные -матриця, результат - число кластеров(и содержание кластеров)

Дата отправки: 11.02.2009, 21:53
Вопрос задал: Иванка
Всего ответов: 1
Страница онлайн-консультации »


Консультирует Micren (Профессор):

Здравствуйте, Иванка!
Сразу разъясню некоторые моменты:
1)В программе матрица генерируется автоматически при помощи System.Random. Т.е. это самый тяжелый случай для кластеризации. На кореллирующихся данных результат будет соответственно лучше.
2)Заранее число кластеров неизвестно и выбирать его случайным образом смысла нет. Это не соответствует практике. Вместо этого вводится допустимое максимальное отклонение записи от центра кластера и начинается перебор кластеров от 1 и до того момента пока максимальное отклонение не станет меньше заданного.
3)Начальные значения для центроидов выбираются не совсем случайно. Для упорядоченных матриц случайный выбор это плохой вариант, а для неупорядоченных разницы нет никакой. Но если же Вам нужно именно случайный выбор то измените функцию InitialCentroids() на свое усмотрение.
4)Результат работы метода кластериз ации это класс с определенными полями, а именно:Size-к-во кластеров;AverageDeviation,MaxDeviation-среднее и максимальное отклонение от записей от центра кластера. Кроме этого добавлен индексатор аргументом которого является номер кластера, а результат список номеров записей в матрице(чтоб постоянно не копировать всю матрицу)
5)Элементом кластера является запись(строка) матрицы, а не отдельный элемент. Иначе нет смысла в матрице вообще. Можно обойтись одномерным массивом.

Малый объем допустимого приложения не позволяет здесь выложить код. Поэтому Вы можете скачать весь проект на http://rapidshare.com/files/198745652/160240.rar

Желаю удачи! smile

Добавлена информация из мини-форума по просьбе эксперта:
Исправил некоторые ошибки. П ожалуй, это можно считать окончательным вариантом.
Кроме того. Если к примеру начальные центроиды расположены близко друг к другу или совсем равны(например все строки матрицы одинаковые), а Вы пытаетесь разбить на много кластеров то реально используется только один центроид, но расчет в первой программе шел все равно по всем центроидам. Это не влияло на результат, но было совершенно излишне. Здесь ситуация исправлена.
Проверялась на .NET 3.5

Код :
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

Консультировал: Micren (Профессор)
Дата отправки: 16.02.2009, 15:26
Рейтинг ответа:

НЕ одобряю 0 одобряю!

Консультация # 80942:

Здравствуйте!
Подскажите, пожалуйста, грамотный способ чтения/записи из/в файла в С++.NET. Отличаются ли в этой среде обращение к файлу от любой другой (на языке С++)?
Заранее благодарю.

Дата отправки: 03.04.2007, 22:38
Вопрос задал: Steazy
Всего ответов: 3
Страница онлайн-консультации »


Консультирует Bevice:

Здравствуйте, Steazy!
Чтением/записью в .net заведуют классы представленные в System.IO

Консультировал: Bevice
Дата отправки: 04.04.2007, 09:21
Рейтинг ответа:

НЕ одобряю 0 одобряю!


Консультирует Necrostaz:

Здравствуйте, Steazy! За запись/чтение в .net отвечает абстракция System.IO.Stream. Базовая реализация поддерживает синхронное чтение/запись байт, а также seeking (поиск). В зависимости от конкретной задачи есть множество реализаций наследников и компонент, использующих потоки. В частности для файлов можно использовать FileStream и\или StreamWriter\StreamWriter

Консультировал: Necrostaz
Дата отправки: 04.04.2007, 12:31
Рейтинг ответа:

НЕ одобряю 0 одобряю!


Консультирует Thread:

Здравствуйте, Steazy!
Все зависит от того с каки файлом вы работаете. Если это некий binary-файл, то лучше использовать класс FileStream и читать побайтно. Если же вы работаете с текстовым файлом. то на мой взгялд самый удобный способ работы с ними это создать экземпляры классов StreamReader и StreamWriter, передав в конструктор экземпляр класса FileStrem. Далее уже используяте методы ReadLine() и WriteLine().

Консультировал: Thread
Дата отправки: 04.04.2007, 16:59
Рейтинг ответа:

НЕ одобряю 0 одобряю!


Оценить выпуск | Задать вопрос экспертам

главная страница  |  стать участником  |  получить консультацию
техническая поддержка  |  восстановить логин/пароль

Дорогой читатель!
Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались. Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора - для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение. Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал, который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом. Заходите - у нас интересно!
МЫ РАБОТАЕМ ДЛЯ ВАС!



В избранное