Ошибки в консольном приложении (шаблоны…векторы)

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

б_д_в
Сообщения: 20
Зарегистрирован: 17 сен 2009, 12:11

Номера примера как такового нет, но есть тема "6.1 Классификация и кластеризация", там этот пример. Я ипользую Visual C++ 6.0.
Сбрасываю всю программу, компилируется без ошибок (некоторые ф-ии заменены...кажется они были Борландовские). Но при выполнении слетает на строчке кода в ф-ии main() которую я пометил (//error). Может, кто поймет, подскажите, в чем тут дело?

Код: Выделить всё

#include "stdafx.h"

#include <vector>
#include <list>
#include <math.h>
#include <iomanip.h>
#include <time.h>
#include <limits>


using namespace std;


//Ф-ия Centroid(...) возвращает центроид набора объектов, задаваемого итераторами begin и end
template <class Iterator>
Iterator::value_type Centroid(const Iterator begin, const Iterator end) 
{
	double MinDist = numeric_limits<double>::max(); 
	Iterator::value_type Element;

	for(Iterator current = begin; current != end; ++current)
	{
		double Dist = 0;
		for(Iterator c = begin; c != end; ++c) 
			Dist += Distance(*current, *c);

		if(Dist < MinDist)
		{ 
			MinDist = Dist; 
			Element = *current;   
		}
	}

	return Element;
}

//Ф-ция кластеризации произвольной  коллекции
template <class Iterator>
vector<list<typename Iterator::value_type> > Cluster(const Iterator begin, const Iterator end, int M)
{
	// создать M кластеров
	vector<list<Iterator::value_type> > Clusters(M);

	//приписать каждый объект к случайному кластеру 
	for(Iterator c = begin; c != end; ++c) 
		Clusters[rand()].push_back(*c);
	
	vector<Iterator::value_type> Centroids(M);

	bool modified;
	do
	{
	// найти центроиды 
	for(int i = 0; i < M; ++i)
	Centroids[i] = Centroid(Clusters[i].begin(), Clusters[i].end()) ;

	modified = false;
	vector<list<Iterator::value_type> > NewClusters(M);

	for(int OldCl = 0;  OldCl < M;  ++OldCl)
	for(Iterator c = Clusters[OldCl].begin(); c != Clusters[OldCl].end(); ++c)
	{
		double MinDist = numeric_limits<double>::max(); 
		int ClusterNo;

	// найти кластер ближайшего к элементу центроида 
	for(int centroid = 0;  centroid < M;  ++centroid) 
	{
		double Dist = Distance(*c,  Centroids[centroid]);

		if(Dist < MinDist)
		{ 
			MinDist = Dist; 
			ClusterNo = centroid;  
		}
	}
	// если центроид принадлежит другому кластеру 
	if(ClusterNo  != OldCl)
	     modified = true; 
				
	NewClusters[ClusterNo].push_back(*c);
	}
		Clusters = NewClusters;
            }
	while(modified); // пока происходят изменения

	return Clusters;
}

//Структура - "точка на плоскости"
struct Point 
{
	int x, y;
};

// расстояние между точками на плоскости
double Distance(const Point& p1, const Point& p2)
{
return sqrt((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p1.y)*( p1.y - p1.y));
}


int main(int argc, char* argv[])
{
	srand((unsigned)time(NULL));

	int N, M; 

	cout << "Vvesti kolichestvo tochek: ";
	cin >> N; 
	cout << endl << "Vvesti kolichestvo klasterov: ";
	cin >> M; 

	list<Point> lp;

	for( int i = 0; i < N; ++i ) // считать список точек
	{
		Point p; 

		cout << endl << endl << "Vvesti koordinatu X: ";
		cin >> p.x; 

		cout << endl << "Vvesti koordinatu Y: ";
		cin >> p.y; 

		lp.push_back(p);
	}

	// выполнить кластеризацию
vector<list<Point> > Clusters = Cluster(lp.begin(), lp.end(), M); [B]//error[/B]

// распечатать результаты (номер кластера, x, y) 
for( i = 0; i < M; ++i )
for(list<Point>::iterator p = Clusters[i].begin(); p != Clusters[i].end(); ++p) 
	cout << endl << i << ": " << p->x <<" "<< p->y << endl;


	return 0;
}
--------------------------------------------------------------------------------
Добавлено сообщение
--------------------------------------------------------------------------------
Нашел в чем ошибка, все заработало!!! :D
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Указывай в чём ошибка. Не стесняйся. Потомки тебя не забудут.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
б_д_в
Сообщения: 20
Зарегистрирован: 17 сен 2009, 12:11

Все просто...вместо Clusters[rand()].push_back(*c); нужно использовать
Clusters[rand()%M+0].push_back(*c);
Ответить