je suis en train d'apprendre les conteneurs de la stl, et dans quel cas
utiliser l'un plutôt que l'autre... j'ai un petit problème a vous
soumettre.
Disons que j'ai un objet A qui contient un string et un ensemble
ordonné de pointeurs sur des objets A.
pour cet ensemble ordonné, j'utilise std::set, qui me permet d'ajouter
des éléments qui sont inséré directement au bon endroit selon la
relation d'ordre définie pour A.
maintenant j'ai quelques problèmes :
class MaString
{
public:
string s;
set<const MaString *> tab;
le vector<MaString> pris en argument par MiseAjour contient tout un tas
d'objet MaString non ordonnés, dont l'objet en cours lui même, et le
set de l'objet, doit se remplir avec les pointeurs vers les autres
objets du vector, sauf bien sûr le pointeur sur lui même. Et les
pointeurs doivent etre rangés selon la relation d'ordre de MaString.
(la relation d'ordre de MaString est tout simplement l'opérateur '<' de
son membre string)
je n'ai pas l'impression que ça marche correctement, de plus, la
méthode 'insert' doit renvoyer un objet 'pair<iterator,bool>' indiquant
si l'insertion a bien eu lieu, si j'ai bien compris. Mais je pige pas
trop ce qu'est cet objet, ni comment le déclarer pour vérifier le
retour de insert.
maintenant autre question, les set ne disposent pas de l'opérateur []
pour accéder a un de leurs membres, ou alors j'ai pas vu pas
compris...? donc le moyen pour aller sur un objet d'un set et
l'iterateur... je m'en sert pour ma surcharge d'affichage de mon objet
MaString, mais apparement j'ai une faute sur l'iterator, et je
comprends pas
je suis en train d'apprendre les conteneurs de la stl, et dans quel cas utiliser l'un plutôt que l'autre... j'ai un petit problème a vous soumettre.
Disons que j'ai un objet A qui contient un string et un ensemble ordonné de pointeurs sur des objets A.
pour cet ensemble ordonné, j'utilise std::set, qui me permet d'ajouter des éléments qui sont inséré directement au bon endroit selon la relation d'ordre définie pour A.
maintenant j'ai quelques problèmes :
class MaString { public: string s; set<const MaString *> tab;
le vector<MaString> pris en argument par MiseAjour contient tout un tas d'objet MaString non ordonnés, dont l'objet en cours lui même, et le set de l'objet, doit se remplir avec les pointeurs vers les autres objets du vector, sauf bien sûr le pointeur sur lui même. Et les pointeurs doivent etre rangés selon la relation d'ordre de MaString.
(la relation d'ordre de MaString est tout simplement l'opérateur '<' de son membre string)
je n'ai pas l'impression que ça marche correctement, de plus, la méthode 'insert' doit renvoyer un objet 'pair<iterator,bool>' indiquant si l'insertion a bien eu lieu, si j'ai bien compris. Mais je pige pas trop ce qu'est cet objet, ni comment le déclarer pour vérifier le retour de insert.
une pair est tout simplement une structure contenant deux membres : first (du 1er type) et second (du second type). Par ex : std::pair< std::vector<MaString>::iterator, bool> P tab.insert(&(*iter_s)); if(P.second) // c'est bon, P.first référence l'élement ajouté else // c'est pas bon.
maintenant autre question, les set ne disposent pas de l'opérateur [] pour accéder a un de leurs membres, ou alors j'ai pas vu pas compris...? donc le moyen pour aller sur un objet d'un set et l'iterateur... je m'en sert pour ma surcharge d'affichage de mon objet MaString, mais apparement j'ai une faute sur l'iterator, et je comprends pas
si tu nous donnais le message d'erreur du compilo (si erreur à la compil) ou ce qui se passe (si erreur à l'execution) ça nous gagnerait du temps ;-)
"Nicolas Aunai" <nicolas.aunai@free.fr> a écrit dans le message de
news:mesnews.64bf7d42.93eb6e1a.119.1437@free.fr...
salut,
je suis en train d'apprendre les conteneurs de la stl, et dans quel cas
utiliser l'un plutôt que l'autre... j'ai un petit problème a vous
soumettre.
Disons que j'ai un objet A qui contient un string et un ensemble
ordonné de pointeurs sur des objets A.
pour cet ensemble ordonné, j'utilise std::set, qui me permet d'ajouter
des éléments qui sont inséré directement au bon endroit selon la
relation d'ordre définie pour A.
maintenant j'ai quelques problèmes :
class MaString
{
public:
string s;
set<const MaString *> tab;
le vector<MaString> pris en argument par MiseAjour contient tout un tas
d'objet MaString non ordonnés, dont l'objet en cours lui même, et le
set de l'objet, doit se remplir avec les pointeurs vers les autres
objets du vector, sauf bien sûr le pointeur sur lui même. Et les
pointeurs doivent etre rangés selon la relation d'ordre de MaString.
(la relation d'ordre de MaString est tout simplement l'opérateur '<' de
son membre string)
je n'ai pas l'impression que ça marche correctement, de plus, la
méthode 'insert' doit renvoyer un objet 'pair<iterator,bool>' indiquant
si l'insertion a bien eu lieu, si j'ai bien compris. Mais je pige pas
trop ce qu'est cet objet, ni comment le déclarer pour vérifier le
retour de insert.
une pair est tout simplement une structure contenant deux membres : first
(du 1er type) et second (du second type).
Par ex :
std::pair< std::vector<MaString>::iterator, bool> P tab.insert(&(*iter_s));
if(P.second)
// c'est bon, P.first référence l'élement ajouté
else
// c'est pas bon.
maintenant autre question, les set ne disposent pas de l'opérateur []
pour accéder a un de leurs membres, ou alors j'ai pas vu pas
compris...? donc le moyen pour aller sur un objet d'un set et
l'iterateur... je m'en sert pour ma surcharge d'affichage de mon objet
MaString, mais apparement j'ai une faute sur l'iterator, et je
comprends pas
si tu nous donnais le message d'erreur du compilo (si erreur à la compil) ou
ce qui se passe (si erreur à l'execution) ça nous gagnerait du temps ;-)
je suis en train d'apprendre les conteneurs de la stl, et dans quel cas utiliser l'un plutôt que l'autre... j'ai un petit problème a vous soumettre.
Disons que j'ai un objet A qui contient un string et un ensemble ordonné de pointeurs sur des objets A.
pour cet ensemble ordonné, j'utilise std::set, qui me permet d'ajouter des éléments qui sont inséré directement au bon endroit selon la relation d'ordre définie pour A.
maintenant j'ai quelques problèmes :
class MaString { public: string s; set<const MaString *> tab;
le vector<MaString> pris en argument par MiseAjour contient tout un tas d'objet MaString non ordonnés, dont l'objet en cours lui même, et le set de l'objet, doit se remplir avec les pointeurs vers les autres objets du vector, sauf bien sûr le pointeur sur lui même. Et les pointeurs doivent etre rangés selon la relation d'ordre de MaString.
(la relation d'ordre de MaString est tout simplement l'opérateur '<' de son membre string)
je n'ai pas l'impression que ça marche correctement, de plus, la méthode 'insert' doit renvoyer un objet 'pair<iterator,bool>' indiquant si l'insertion a bien eu lieu, si j'ai bien compris. Mais je pige pas trop ce qu'est cet objet, ni comment le déclarer pour vérifier le retour de insert.
une pair est tout simplement une structure contenant deux membres : first (du 1er type) et second (du second type). Par ex : std::pair< std::vector<MaString>::iterator, bool> P tab.insert(&(*iter_s)); if(P.second) // c'est bon, P.first référence l'élement ajouté else // c'est pas bon.
maintenant autre question, les set ne disposent pas de l'opérateur [] pour accéder a un de leurs membres, ou alors j'ai pas vu pas compris...? donc le moyen pour aller sur un objet d'un set et l'iterateur... je m'en sert pour ma surcharge d'affichage de mon objet MaString, mais apparement j'ai une faute sur l'iterator, et je comprends pas
si tu nous donnais le message d'erreur du compilo (si erreur à la compil) ou ce qui se passe (si erreur à l'execution) ça nous gagnerait du temps ;-)
ah oui, mon set étant un ensemble de pointeur sur des objets perso, il est stupide de vouloir trier des pointeurs par triage des adresses, comment faire en sorte que le trie se fasse par rapport aux objets pointés ?
ah oui, mon set étant un ensemble de pointeur sur des objets perso, il
est stupide de vouloir trier des pointeurs par triage des adresses,
comment faire en sorte que le trie se fasse par rapport aux objets
pointés ?
ah oui, mon set étant un ensemble de pointeur sur des objets perso, il est stupide de vouloir trier des pointeurs par triage des adresses, comment faire en sorte que le trie se fasse par rapport aux objets pointés ?
ah oui, mon set étant un ensemble de pointeur sur des objets perso, il est stupide de vouloir trier des pointeurs par triage des adresses, comment faire en sorte que le trie se fasse par rapport aux objets pointés ?
Le template set possède un paramètre facultatif qui permet d'indiquer
comment comparer les éléments de ton set deux à deux.
-- Loïc
Nicolas Aunai wrote:
ah oui, mon set étant un ensemble de pointeur sur des objets perso, il
est stupide de vouloir trier des pointeurs par triage des adresses,
comment faire en sorte que le trie se fasse par rapport aux objets
pointés ?
Le template set possède un paramètre facultatif qui permet d'indiquer
comment comparer les éléments de ton set deux à deux.
ah oui, mon set étant un ensemble de pointeur sur des objets perso, il est stupide de vouloir trier des pointeurs par triage des adresses, comment faire en sorte que le trie se fasse par rapport aux objets pointés ?
Le template set possède un paramètre facultatif qui permet d'indiquer
comment comparer les éléments de ton set deux à deux.
je n'ai pas l'impression que ça marche correctement, Il ne manquerait pas un '++iter_s' quelque part par hasard ?
La forme "canonique" de cette boucle serait for(vector<MaString>::const_iterator iter_s = s.begin(); iter_s != s.end(); ++iter_s) if(&*iter_s != this) tab.insert(&*iter_s);
de plus, la méthode 'insert' doit renvoyer un objet 'pair<iterator,bool>' indiquant si l'insertion a bien eu lieu, si j'ai bien compris. Mais je pige pas trop ce qu'est cet objet, ni comment le déclarer pour vérifier le retour de insert.
une pair est tout simplement une structure contenant deux membres : first (du 1er type) et second (du second type). Par ex : std::pair< std::vector<MaString>::iterator, bool> P > tab.insert(&(*iter_s)); if(P.second) // c'est bon, P.first référence l'élement ajouté else // c'est pas bon. Si 'P.second' vaut 'false', c'est que l'élément qu'on voulait insérer
était déjà dedans, et dans ce cas 'P.first' pointe sur cet élément.
Je ne saurais pas dire ce qui doit se passer selon la Norme si 'insert' échoue pour d'autres raisons (genre s.size() atteint s.max_size()), mon programme de test compilé avec gcc 3.3.1 / cygwin lève une exception std::bad_alloc bien avant.
Falk
Alexandre wrote:
"Nicolas Aunai" <nicolas.aunai@free.fr> a écrit dans le message de
[...]
je n'ai pas l'impression que ça marche correctement,
Il ne manquerait pas un '++iter_s' quelque part par hasard ?
La forme "canonique" de cette boucle serait
for(vector<MaString>::const_iterator iter_s = s.begin(); iter_s != s.end(); ++iter_s)
if(&*iter_s != this)
tab.insert(&*iter_s);
de plus, la
méthode 'insert' doit renvoyer un objet 'pair<iterator,bool>' indiquant
si l'insertion a bien eu lieu, si j'ai bien compris. Mais je pige pas
trop ce qu'est cet objet, ni comment le déclarer pour vérifier le
retour de insert.
une pair est tout simplement une structure contenant deux membres : first
(du 1er type) et second (du second type).
Par ex :
std::pair< std::vector<MaString>::iterator, bool> P > tab.insert(&(*iter_s));
if(P.second)
// c'est bon, P.first référence l'élement ajouté
else
// c'est pas bon.
Si 'P.second' vaut 'false', c'est que l'élément qu'on voulait insérer
était déjà dedans, et dans ce cas 'P.first' pointe sur cet élément.
Je ne saurais pas dire ce qui doit se passer selon la Norme si 'insert' échoue
pour d'autres raisons (genre s.size() atteint s.max_size()), mon programme
de test compilé avec gcc 3.3.1 / cygwin lève une exception std::bad_alloc
bien avant.
je n'ai pas l'impression que ça marche correctement, Il ne manquerait pas un '++iter_s' quelque part par hasard ?
La forme "canonique" de cette boucle serait for(vector<MaString>::const_iterator iter_s = s.begin(); iter_s != s.end(); ++iter_s) if(&*iter_s != this) tab.insert(&*iter_s);
de plus, la méthode 'insert' doit renvoyer un objet 'pair<iterator,bool>' indiquant si l'insertion a bien eu lieu, si j'ai bien compris. Mais je pige pas trop ce qu'est cet objet, ni comment le déclarer pour vérifier le retour de insert.
une pair est tout simplement une structure contenant deux membres : first (du 1er type) et second (du second type). Par ex : std::pair< std::vector<MaString>::iterator, bool> P > tab.insert(&(*iter_s)); if(P.second) // c'est bon, P.first référence l'élement ajouté else // c'est pas bon. Si 'P.second' vaut 'false', c'est que l'élément qu'on voulait insérer
était déjà dedans, et dans ce cas 'P.first' pointe sur cet élément.
Je ne saurais pas dire ce qui doit se passer selon la Norme si 'insert' échoue pour d'autres raisons (genre s.size() atteint s.max_size()), mon programme de test compilé avec gcc 3.3.1 / cygwin lève une exception std::bad_alloc bien avant.
Falk
Nicolas Aunai
Loïc Joly a formulé ce vendredi :
Nicolas Aunai wrote:
ah oui, mon set étant un ensemble de pointeur sur des objets perso, il est stupide de vouloir trier des pointeurs par triage des adresses, comment faire en sorte que le trie se fasse par rapport aux objets pointés ?
Le template set possède un paramètre facultatif qui permet d'indiquer comment
comparer les éléments de ton set deux à deux.
en effet, j'ai vu ça... j'ai fait un "foncteur" qui compare deux objets a partir de leur adresse. ça me trie mon set en évaluant l'élément a insérer par rapport aux autre.
cependant, ce que je veux faire est quelque peut différent.
class A {
set<const A*> s; }
chaque adresse à ajouter dans le set de A, doit être comparée aux autres selon une relation d'ordre qui prend en compte l'objet courant.
c'est comme si je voulais entrer dans le set, une série de pointeurs vers des points, du points le plus proche de l'objet courant, au points le plus éloigné.
class ComparePointeur { public: bool operator()(const A *a1,const A *a2){return ??;} };
en fait la relation d'ordre serait :
a1 < a2
si et seulement si a1 est plus proche de *this que a2 ne l'est.
ah oui, mon set étant un ensemble de pointeur sur des objets perso, il est
stupide de vouloir trier des pointeurs par triage des adresses, comment
faire en sorte que le trie se fasse par rapport aux objets pointés ?
Le template set possède un paramètre facultatif qui permet d'indiquer comment
comparer les éléments de ton set deux à deux.
en effet, j'ai vu ça... j'ai fait un "foncteur" qui compare deux objets
a partir de leur adresse. ça me trie mon set en évaluant l'élément a
insérer par rapport aux autre.
cependant, ce que je veux faire est quelque peut différent.
class A
{
set<const A*> s;
}
chaque adresse à ajouter dans le set de A, doit être comparée aux
autres selon une relation d'ordre qui prend en compte l'objet courant.
c'est comme si je voulais entrer dans le set, une série de pointeurs
vers des points, du points le plus proche de l'objet courant, au points
le plus éloigné.
class ComparePointeur
{
public:
bool operator()(const A *a1,const A *a2){return ??;}
};
en fait la relation d'ordre serait :
a1 < a2
si et seulement si a1 est plus proche de *this que a2 ne l'est.
ah oui, mon set étant un ensemble de pointeur sur des objets perso, il est stupide de vouloir trier des pointeurs par triage des adresses, comment faire en sorte que le trie se fasse par rapport aux objets pointés ?
Le template set possède un paramètre facultatif qui permet d'indiquer comment
comparer les éléments de ton set deux à deux.
en effet, j'ai vu ça... j'ai fait un "foncteur" qui compare deux objets a partir de leur adresse. ça me trie mon set en évaluant l'élément a insérer par rapport aux autre.
cependant, ce que je veux faire est quelque peut différent.
class A {
set<const A*> s; }
chaque adresse à ajouter dans le set de A, doit être comparée aux autres selon une relation d'ordre qui prend en compte l'objet courant.
c'est comme si je voulais entrer dans le set, une série de pointeurs vers des points, du points le plus proche de l'objet courant, au points le plus éloigné.
class ComparePointeur { public: bool operator()(const A *a1,const A *a2){return ??;} };
en fait la relation d'ordre serait :
a1 < a2
si et seulement si a1 est plus proche de *this que a2 ne l'est.
cependant, ce que je veux faire est quelque peut différent. class A { set<const A*> s; }
chaque adresse à ajouter dans le set de A, doit être comparée aux autres selon une relation d'ordre qui prend en compte l'objet courant.
c'est comme si je voulais entrer dans le set, une série de pointeurs vers des points, du points le plus proche de l'objet courant, au points le plus éloigné.
class ComparePointeur { public: bool operator()(const A *a1,const A *a2){return ??;} };
en fait la relation d'ordre serait :
a1 < a2
si et seulement si a1 est plus proche de *this que a2 ne l'est. Essaye quelque chose du genre :
_____________________________________________________ class A;
Il faut cependant faire attention au cas où deux points différents a1, a2 ont la même distance à '*this' - dans ce cas, ils seront considérés comme équivalents par 'std::set', donc il n'en gardera qu'un seul. Si ce n'est pas ce que tu veux, il faut plutôt utiliser std::multiset.
Falk
Nicolas Aunai wrote:
cependant, ce que je veux faire est quelque peut différent.
class A
{
set<const A*> s;
}
chaque adresse à ajouter dans le set de A, doit être comparée aux
autres selon une relation d'ordre qui prend en compte l'objet courant.
c'est comme si je voulais entrer dans le set, une série de pointeurs
vers des points, du points le plus proche de l'objet courant, au points
le plus éloigné.
class ComparePointeur
{
public:
bool operator()(const A *a1,const A *a2){return ??;}
};
en fait la relation d'ordre serait :
a1 < a2
si et seulement si a1 est plus proche de *this que a2 ne l'est.
Essaye quelque chose du genre :
_____________________________________________________
class A;
Il faut cependant faire attention au cas où deux points différents a1, a2
ont la même distance à '*this' - dans ce cas, ils seront considérés comme
équivalents par 'std::set', donc il n'en gardera qu'un seul.
Si ce n'est pas ce que tu veux, il faut plutôt utiliser std::multiset.
cependant, ce que je veux faire est quelque peut différent. class A { set<const A*> s; }
chaque adresse à ajouter dans le set de A, doit être comparée aux autres selon une relation d'ordre qui prend en compte l'objet courant.
c'est comme si je voulais entrer dans le set, une série de pointeurs vers des points, du points le plus proche de l'objet courant, au points le plus éloigné.
class ComparePointeur { public: bool operator()(const A *a1,const A *a2){return ??;} };
en fait la relation d'ordre serait :
a1 < a2
si et seulement si a1 est plus proche de *this que a2 ne l'est. Essaye quelque chose du genre :
_____________________________________________________ class A;
Il faut cependant faire attention au cas où deux points différents a1, a2 ont la même distance à '*this' - dans ce cas, ils seront considérés comme équivalents par 'std::set', donc il n'en gardera qu'un seul. Si ce n'est pas ce que tu veux, il faut plutôt utiliser std::multiset.
Falk
Nicolas Aunai
Falk Tannhäuser a utilisé son clavier pour écrire :
Essaye quelque chose du genre : _____________________________________________________ class A;
et cette insertion triée dans le set, ça marche pour n éléments ? nan parce que... j'ai un comportement TRES bizarre sur un programme, que je ne comprends vraiment pas...
voici l'explication du probleme :
j'ai mon vector d'objets qui contient n objets. chaque objet a son set de pointeurs sur les n-1 autres objets, triés selon la relation d'ordre.
dans la théorie ça marche, le probleme survient lorsque n>=4
j'explique en détail :
pour n=2, chaque objet a dans son set UN seul pointeur, pas de pb...
pour n=3, chaque objet a dans son set, DEUX pointeurs, le second est inséré en comparaison avec le premier selon la relation d'ordre... et mon set est convenablement trié...
par contre, pour n=4 là commencent les ennuis... en effet, alors que mes deux premiers pointeurs étaient bien insérés l'un par raport a l'autre, le 3eme pointeur s'insère apparement systématiquement mal (au début du set semble-t-il)
bref je comprends pas, ça doit etre moi qui me sert mal de la fonction insert.
voici un peu de copier/collé de l'execution pour illustrer un peu ce que je dis :
pour n=3 objets (Cluster) dans le vector (Systeme)
cluster 0 : ======================================= Position : [ 1, 2, 3 ] Mes influences : ---------------- -Position : [ 1, 2, 3.5 ] D = 0.5 -Position : [ 1, 2, 4.1 ] D = 1.1 ======================================== cluster 1 : ======================================= Position : [ 1, 2, 4.1 ] Mes influences : ---------------- -Position : [ 1, 2, 3.5 ] D = 0.6 -Position : [ 1, 2, 3 ] D = 1.1 ======================================== cluster 2 : ======================================= Position : [ 1, 2, 3.5 ] Mes fils : ---------- Mes influences : ---------------- -Position : [ 1, 2, 3 ] D = 0.5 -Position : [ 1, 2, 4.1 ] D = 0.6 ========================================
vous voyez que les set qui sont les influences, sont correctement triés par distance croissante des autres points du systeme.
maintenant si j'insère un autre point :
cluster 0 : ======================================= Position : [ 1, 2, 3 ] Mes influences : ---------------- -Position : [ 1, 10, 10 ] D = 10.63 -Position : [ 1, 2, 4.1 ] D = 1.1 -Position : [ 1, 2, 3.5 ] D = 0.5 ========================================
cluster 1 : ======================================= Position : [ 1, 2, 4.1 ] Mes influences : ---------------- -Position : [ 1, 10, 10 ] D = 9.94 -Position : [ 1, 2, 3.5 ] D = 0.6 -Position : [ 1, 2, 3 ] D = 1.1 ========================================
cluster 2 : ======================================= Position : [ 1, 2, 3.5 ] Mes influences : ---------------- -Position : [ 1, 10, 10 ] D = 10.31 -Position : [ 1, 2, 4.1 ] D = 0.6 -Position : [ 1, 2, 3 ] D = 0.5 ========================================
cluster 3 : ======================================= Position : [ 1, 10, 10 ] Mes influences : ---------------- -Position : [ 1, 2, 4.1 ] D = 9.94 -Position : [ 1, 2, 3.5 ] D = 10.31 -Position : [ 1, 2, 3 ] D = 10.63 ========================================
systématiquement le point rajouté (1,2,4.1) se place mal dans le set.
ma fonction d'insertion est :
void Cluster::maj_influences(const vector<Cluster> &t) { vector<Cluster>::const_iterator i = t.begin(); Influences.clear(); //efface les influences pour refaire...
et cette insertion triée dans le set, ça marche pour n éléments ?
nan parce que... j'ai un comportement TRES bizarre sur un programme,
que je ne comprends vraiment pas...
voici l'explication du probleme :
j'ai mon vector d'objets qui contient n objets.
chaque objet a son set de pointeurs sur les n-1 autres objets, triés
selon la relation d'ordre.
dans la théorie ça marche, le probleme survient lorsque n>=4
j'explique en détail :
pour n=2, chaque objet a dans son set UN seul pointeur, pas de pb...
pour n=3, chaque objet a dans son set, DEUX pointeurs, le second est
inséré en comparaison avec le premier selon la relation d'ordre... et
mon set est convenablement trié...
par contre, pour n=4 là commencent les ennuis...
en effet, alors que mes deux premiers pointeurs étaient bien insérés
l'un par raport a l'autre, le 3eme pointeur s'insère apparement
systématiquement mal (au début du set semble-t-il)
bref je comprends pas, ça doit etre moi qui me sert mal de la fonction
insert.
voici un peu de copier/collé de l'execution pour illustrer un peu ce
que je dis :
pour n=3 objets (Cluster) dans le vector (Systeme)
cluster 0 :
======================================= Position : [ 1, 2, 3 ]
Mes influences :
----------------
-Position : [ 1, 2, 3.5 ] D = 0.5
-Position : [ 1, 2, 4.1 ] D = 1.1
========================================
cluster 1 :
======================================= Position : [ 1, 2, 4.1 ]
Mes influences :
----------------
-Position : [ 1, 2, 3.5 ] D = 0.6
-Position : [ 1, 2, 3 ] D = 1.1
========================================
cluster 2 :
======================================= Position : [ 1, 2, 3.5 ]
Mes fils :
----------
Mes influences :
----------------
-Position : [ 1, 2, 3 ] D = 0.5
-Position : [ 1, 2, 4.1 ] D = 0.6
========================================
vous voyez que les set qui sont les influences, sont correctement triés
par distance croissante des autres points du systeme.
maintenant si j'insère un autre point :
cluster 0 :
======================================= Position : [ 1, 2, 3 ]
Mes influences :
----------------
-Position : [ 1, 10, 10 ] D = 10.63
-Position : [ 1, 2, 4.1 ] D = 1.1
-Position : [ 1, 2, 3.5 ] D = 0.5
========================================
cluster 1 :
======================================= Position : [ 1, 2, 4.1 ]
Mes influences :
----------------
-Position : [ 1, 10, 10 ] D = 9.94
-Position : [ 1, 2, 3.5 ] D = 0.6
-Position : [ 1, 2, 3 ] D = 1.1
========================================
cluster 2 :
======================================= Position : [ 1, 2, 3.5 ]
Mes influences :
----------------
-Position : [ 1, 10, 10 ] D = 10.31
-Position : [ 1, 2, 4.1 ] D = 0.6
-Position : [ 1, 2, 3 ] D = 0.5
========================================
cluster 3 :
======================================= Position : [ 1, 10, 10 ]
Mes influences :
----------------
-Position : [ 1, 2, 4.1 ] D = 9.94
-Position : [ 1, 2, 3.5 ] D = 10.31
-Position : [ 1, 2, 3 ] D = 10.63
========================================
systématiquement le point rajouté (1,2,4.1) se place mal dans le set.
ma fonction d'insertion est :
void
Cluster::maj_influences(const vector<Cluster> &t)
{
vector<Cluster>::const_iterator i = t.begin();
Influences.clear(); //efface les influences pour refaire...
et cette insertion triée dans le set, ça marche pour n éléments ? nan parce que... j'ai un comportement TRES bizarre sur un programme, que je ne comprends vraiment pas...
voici l'explication du probleme :
j'ai mon vector d'objets qui contient n objets. chaque objet a son set de pointeurs sur les n-1 autres objets, triés selon la relation d'ordre.
dans la théorie ça marche, le probleme survient lorsque n>=4
j'explique en détail :
pour n=2, chaque objet a dans son set UN seul pointeur, pas de pb...
pour n=3, chaque objet a dans son set, DEUX pointeurs, le second est inséré en comparaison avec le premier selon la relation d'ordre... et mon set est convenablement trié...
par contre, pour n=4 là commencent les ennuis... en effet, alors que mes deux premiers pointeurs étaient bien insérés l'un par raport a l'autre, le 3eme pointeur s'insère apparement systématiquement mal (au début du set semble-t-il)
bref je comprends pas, ça doit etre moi qui me sert mal de la fonction insert.
voici un peu de copier/collé de l'execution pour illustrer un peu ce que je dis :
pour n=3 objets (Cluster) dans le vector (Systeme)
cluster 0 : ======================================= Position : [ 1, 2, 3 ] Mes influences : ---------------- -Position : [ 1, 2, 3.5 ] D = 0.5 -Position : [ 1, 2, 4.1 ] D = 1.1 ======================================== cluster 1 : ======================================= Position : [ 1, 2, 4.1 ] Mes influences : ---------------- -Position : [ 1, 2, 3.5 ] D = 0.6 -Position : [ 1, 2, 3 ] D = 1.1 ======================================== cluster 2 : ======================================= Position : [ 1, 2, 3.5 ] Mes fils : ---------- Mes influences : ---------------- -Position : [ 1, 2, 3 ] D = 0.5 -Position : [ 1, 2, 4.1 ] D = 0.6 ========================================
vous voyez que les set qui sont les influences, sont correctement triés par distance croissante des autres points du systeme.
maintenant si j'insère un autre point :
cluster 0 : ======================================= Position : [ 1, 2, 3 ] Mes influences : ---------------- -Position : [ 1, 10, 10 ] D = 10.63 -Position : [ 1, 2, 4.1 ] D = 1.1 -Position : [ 1, 2, 3.5 ] D = 0.5 ========================================
cluster 1 : ======================================= Position : [ 1, 2, 4.1 ] Mes influences : ---------------- -Position : [ 1, 10, 10 ] D = 9.94 -Position : [ 1, 2, 3.5 ] D = 0.6 -Position : [ 1, 2, 3 ] D = 1.1 ========================================
cluster 2 : ======================================= Position : [ 1, 2, 3.5 ] Mes influences : ---------------- -Position : [ 1, 10, 10 ] D = 10.31 -Position : [ 1, 2, 4.1 ] D = 0.6 -Position : [ 1, 2, 3 ] D = 0.5 ========================================
cluster 3 : ======================================= Position : [ 1, 10, 10 ] Mes influences : ---------------- -Position : [ 1, 2, 4.1 ] D = 9.94 -Position : [ 1, 2, 3.5 ] D = 10.31 -Position : [ 1, 2, 3 ] D = 10.63 ========================================
systématiquement le point rajouté (1,2,4.1) se place mal dans le set.
ma fonction d'insertion est :
void Cluster::maj_influences(const vector<Cluster> &t) { vector<Cluster>::const_iterator i = t.begin(); Influences.clear(); //efface les influences pour refaire...
pair<set<const Cluster*>::iterator,bool> p; [...] p = Influences.insert(&*i);//devrait insérer au bon endroit
Comme p est utilisé comme resultat de Influences.insert j'en déduis que le type de Influences -- ou un de ses types de base -- est set<const Cluster*>. Il suit que le tri est fait avec std::less< const Cluster* >::operator() qui, par défaut, va ordonner les pointeurs.
La solution n'est pas évidente car tu veux trier les "influences" d'un cluster, la référence, fonction de la distance Euclidienne des positions absolues des autres clusters. Donc l'opérateur de tri :
doit connaître la position absolue de la référence.
-- Franck Branjonneau
Nicolas Aunai <nicolas.aunai@free.fr> écrivait:
voici l'explication du probleme :
C'est un peu confus.
pair<set<const Cluster*>::iterator,bool> p;
[...]
p = Influences.insert(&*i);//devrait insérer au bon endroit
Comme p est utilisé comme resultat de Influences.insert j'en déduis
que le type de Influences -- ou un de ses types de base -- est
set<const Cluster*>. Il suit que le tri est fait avec std::less< const
Cluster* >::operator() qui, par défaut, va ordonner les pointeurs.
La solution n'est pas évidente car tu veux trier les "influences" d'un
cluster, la référence, fonction de la distance Euclidienne des
positions absolues des autres clusters. Donc l'opérateur de tri :
pair<set<const Cluster*>::iterator,bool> p; [...] p = Influences.insert(&*i);//devrait insérer au bon endroit
Comme p est utilisé comme resultat de Influences.insert j'en déduis que le type de Influences -- ou un de ses types de base -- est set<const Cluster*>. Il suit que le tri est fait avec std::less< const Cluster* >::operator() qui, par défaut, va ordonner les pointeurs.
La solution n'est pas évidente car tu veux trier les "influences" d'un cluster, la référence, fonction de la distance Euclidienne des positions absolues des autres clusters. Donc l'opérateur de tri :