Salve sono nuovo nel forum,
sono uno studente al 3° anno di ingegneria informatica.
dovrei consegnare un programma come progetto finale del corso di programmazione e progettazione software.
Oggi quando ero sicuro di averlo fatto al meglio mi dava SEGMENTATION FAULT 11.
Si tratta di un programma che mediante algoritmo kmeans dovrebbe riordinare dei documenti per genere.
Vi allego la traccia e il codice, sperando che possiate aiutarmi.
Grazie in anticipo a tutti voi.
//
// main.cpp
//
#include <iostream>
#include <vector>
#include <map>
#include <fstream>
#include <algorithm>
#include <dirent.h>
#include <random>
#include <string>
#include <stdio.h>
using namespace std;
vector <string> preps={"di","a","da","in","con","su","per","tra","fra","del","dello","della","dei","degli","delle","al","allo","alla","ai","agli","alle","dal","dallo","dalla","dall’","dai","dagli","dalle","nel","nello","nella","nell’","nei","negli","nelle","col ","collo","colla","coi","cogli","colle","sul","sullo","sulla","sull’","sui","sugli","sulle"};
vector <string> artics={"il","lo","la","i","gli","le","l'","uno","una","un","un'"};
class Document{
private:
map <string,int> doc;
public:
Document(){
doc.clear();
}
Document(string fileroot){
string word;
ifstream is(fileroot);
if(is.good()){
while(is>>word){
transform(word.begin(), word.end(), word.begin(), ::tolower);
bool ex=false;
vector<string>::iterator y= preps.begin();
vector<string>::iterator x= artics.begin();
for(;x!=artics.end();x++){
if((*x)==word) ex=true;
}
for(;y!=preps.end();y++){
if((*y)==word) ex=true;
}
if(!ex) doc[word]++;
y=preps.begin();
x=artics.begin();
ex=false;
}
}
is.close();
}
map<string,int>::iterator getiterdoc(){
map<string,int>::iterator it=doc.begin();
return it;
}
map<string,int>::iterator getend_doc(){
map<string,int>::iterator it=doc.end();
return it;
}
unsigned long getnumelem(){
return doc.size();
}
};
class DocumentCollection{
private:
vector <Document> collection;
public:
DocumentCollection(){
collection.clear();
}
void pushel(Document d){
collection.push_back(d);
}
vector<Document>::iterator getstructure(){
vector<Document>::iterator t=collection.begin();
return t;
}
vector<Document>::iterator getend(){
vector<Document>::iterator t=collection.end();
return t;
}
unsigned long getsize(){
return collection.size();
}
};
class Clustering{
private:
//ve<string,map<string,float>> cluster;
public:
Clustering(){
//cluster.clear();
}
//Clustering(string w,float weight)=0;
virtual void Algorithm(DocumentCollection d)=0;
virtual void Cluster(int center)=0;
};
class kmeans:public Clustering{
private:
int n;
int k;
vector<Document>::iterator it;
map<string,vector<float> >indexes;
multimap<string,map<string,float> >cluster;
public:
kmeans(){
k=n=0;
indexes.clear();
}
void Algorithm(DocumentCollection d){
vector<Document>::iterator it;
//using of Kmeans Algorithm
it=d.getstructure();
map<string,int>::iterator iti;
Document doc;
vector <float> vec(d.getsize()-1,0.0);
n=int(d.getsize()); //conversione perche la dimensione un unsigned long
for(;it!=d.getend();it++){
doc=*it;
iti=doc.getiterdoc();
for(;iti!=doc.getend_doc();iti++){
indexes[iti->first]=vec;
}
}
it=d.getstructure();
map<string,vector<float> >::iterator iter_x= indexes.begin();
int i=0;
for(;iter_x!=indexes.end();iter_x++){
string a= iter_x->first;
for(;it!=d.getend();it++){
doc=*it;
iti=doc.getiterdoc();
for(;iti!=doc.getend_doc();iti++){
if (iti->first==a){
vec[i]=iti->second/doc.getnumelem();
}
i++;
}
iter_x->second=vec;
for(i=0;i<vec.size();i++){
vec[i]=0.0;
}
i=0;
}
}
}
void Cluster(int centers){
k=centers;
map<string,vector<float> >::iterator it=indexes.begin();
multimap<std::string,map<string,float> >::iterator cl_it=cluster.begin();
random_device rd; // ottengo numeri casuali dall'hardware
mt19937 eng(rd()); // istanzio il generatore
uniform_int_distribution<> distr(0, n-1); // definisco il range
for(int i=0; i<k; i++){
map <string,float> appoggio;
int a =distr(eng);
for(;it!=indexes.end();it++){
string word= it->first;
vector <float> weight_w=it->second;
vector <float>::iterator iw=weight_w.begin();
int pos=0;
for(;iw!=weight_w.end();iw++){
if(pos==a){
appoggio.insert(make_pair(word, *iw));
}
pos++;
}
}
cl_it->second=appoggio;
cl_it++;
}
cl_it=cluster.begin();
string provas;
float provaf;
for(;cl_it!=cluster.end();cl_it++){
map <string,float> m=cl_it->second;
map<string,float>::iterator i=m.begin();
provas=i->first;
provaf=i->second;
for(;i!=m.end();i++){
if((i->second) >provaf) {
provas=i->first;
provaf=i->second;
}
}
map<string,float> mpc=cl_it->second;
cluster.erase(cl_it);
cluster.insert(make_pair(provas, mpc));
}
it=indexes.begin();
cl_it=cluster.begin();
for(;it!=indexes.end();it++){
bool exist=false;
map <string,float> appoggio;
string word= it->first;
vector <float> weight_w=it->second;
vector <float>::iterator iw=weight_w.begin();
for(;iw!=weight_w.end();iw++){
appoggio.insert(make_pair(word, *iw));
}
for(;cl_it!=cluster.end();cl_it++){
if(appoggio==cl_it->second) exist=true;
}
cl_it=cluster.begin();
if(!exist) cluster.insert(make_pair("", appoggio));
}
cl_it=cluster.begin();
for(;cl_it!=cluster.end();cl_it++){
map <string,float> m=cl_it->second;
map<string,float>::iterator i=m.begin();
provas=i->first;
provaf=i->second;
for(;i!=m.end();i++){
if((i->second) >provaf) {
provas=i->first;
provaf=i->second;
}
}
map<string,float> mpc=cl_it->second;
cluster.erase(cl_it);
cluster.insert(make_pair(provas, mpc));
}
}
};
int main(int argc, const char * argv[]) {
int centers;
string path_name;
vector <string> file_ns;
DocumentCollection d_coll;
if(string(argv[1])!=""){
path_name=string(argv[1]);
DIR *dir;
struct dirent *ent;
if ((dir = opendir(argv[1])) != NULL) {
//leggo tutti i file all'interno della directory
while ((ent = readdir (dir)) != NULL) {
//printf ("%s\n", ent->d_name);
file_ns.push_back(ent->d_name);
}
closedir (dir);
} else {
/* non posso aprire la directory */
perror ("...........Non posso aprire la directory.............");
return EXIT_FAILURE;
}
for(int i=0;i<file_ns.size();i++){
string name=path_name+file_ns[i];
Document d(name);
d_coll.pushel(d);
}
Clustering* k;
k=new kmeans();
k->Algorithm(d_coll);
cout<<"si prega di immettere k(il numero di centri iniziali); N.B. k deve essere minore di"<<d_coll.getsize()<<endl;
cin>>centers;
k->Cluster(centers);
}
else cout<<"errore nome della DIRECTORY"<<endl;
}
in seguito la traccia del progetto:
Realizzare una classe per il clustering di documenti usando l'algoritmo Kmeans. Per dettagli sull'agoritmo vedere:
http://en.wikipedia.org/wiki/Kmean
Il clustering di documenti, data una collezione documentale, li raccoglie in gruppi. I documenti all'interno di un singolo gruppo devono avere contenuto tendenzialmente omogeneo.
La collezione documentale viene realizzata tramite una classe DocumentCollection che contiene un vettore di documenti, ognuno realizzato tramite un istanza di classe Document che contiene la rappresentazione bag-of-words parola->numero_occorrenze.
Realizzare quindi una classe astratta Clustering che implementa l'interfaccia di un generico algoritmo di Clustering. In particolare, dovra' essere presente un metodo Cluster() che ritorni un vettore di vettori di indici dei documenti. **
Realizzare la classe Kmeans come figlia di Clustering.
L'algoritmo Kmeans parte scegliendo K documenti in modo casuale nella collezione: questi sono detti centri. Una prima creazione di gruppi avviene assegnando i documenti nella collezione al centro più' vicino.
L'algoritmo quindi ricalcola i centri calcolando i baricentri dei documenti assegnati ad un centro. Quindi si itera il processo, si riassegnano i documenti al centro più' vicino, ecc.
L'algoritmo termina quando le assegnazioni dei documenti non cambiano tra due iterazioni successive.