🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: be.comp.programming
9 messages
9 total messages Started by Aquila Wed, 15 Dec 2004 09:06
Rare C++ fout (std::map)
#1706
Author: Aquila
Date: Wed, 15 Dec 2004 09:06
96 lines
3469 bytes
Voor een AI programma krijg ik heel rare fouten met onderstaande code. (Ik
weet dat het nogal lang is maar ik heb al heel hard gewerkt om het probleem
te verkleinen).

possiblestate.h:

#ifndef POSSIBLESTATE_H
#define POSSIBLESTATE_H

class PossibleState{
 public:
  PossibleState(bool);
  PossibleState();
  ~PossibleState();
  bool operator < (const PossibleState &) const; 
 private:
  bool turning;
};
#endif


possiblestate.cpp:

#include "possiblestate.h"
PossibleState::PossibleState(bool turninger):
 turning(turninger)
{}
PossibleState::PossibleState():
 turning()
{}
PossibleState::~PossibleState(){}
bool PossibleState::operator<(const PossibleState & state) const{
 return turning != state.turning;
}


onlinelrta.h:

#ifndef ONLINELRTA_H
#define ONLINELRTA_H
#include <string>
#include <map>
class OnlineLRTA{
 public:
  OnlineLRTA(std::string );
  void lrtaAgent();
};
#endif


onlinelrta.cpp:
#include "onlinelrta.h"
#include "possiblestate.h"
#include <iostream>

void OnlineLRTA::lrtaAgent() {
 PossibleState s(false);
 static std::map<const PossibleState,int>  H;
 if (H.find(s) == H.end()) H[s] = 5;
 
 H[PossibleState(true)] = 8;
 if (H.find(PossibleState(true)) != H.end()) std::cout << "ok\n";
 
 
 std::map<const PossibleState,int>  K;
 PossibleState s2(false);
 if (K.find(s2) == K.end()) K[s2] = 5;
 
 K[PossibleState(true)] = 8;
 if (K.find(PossibleState(true)) != K.end()) std::cout << "ok\n";
 
}


OnlineLRTA::OnlineLRTA(std::string str)
{
 std::map<const PossibleState,int>  H;
 H[PossibleState(true)] = 8;
 if (H.find(PossibleState(true)) != H.end()) std::cout << "ok\n";
}

int main(int argc, char** argv){
 OnlineLRTA lrta("test");
 lrta.lrtaAgent();
}

Gewoon uitvoeren geeft raar maar waar als resultaat 1 ok ipv 3, dat is dus
het probleem. Als ik nu in de method lrtaAgent de if (H.find(s) == H.end())
H[s] = 5; en idem voor K uitquote dan krijg ik opeens 3 keer ok: waarom?
Kan iemand hier enige duidelijkheid scheppen want ik begrijp echt niet
waarom dit is en het ligt bv. niet aan de compiler, ik heb het getest met
gcc �n icc.

Bedankt!
-- 
"May the source be with you"
Re: Rare C++ fout (std::map)
#1707
Author: Niels Basjes
Date: Wed, 15 Dec 2004 09:40
26 lines
1585 bytes
On Wed, 15 Dec 2004 10:06:44 +0100, the lifeform known as Aquila
<braempje@netscape.net> wrote:

>Voor een AI programma krijg ik heel rare fouten met onderstaande code. 

Je gebruikt een class als index voor een map:
> static std::map<const PossibleState,int>  H;

Wat verwacht jij dat code als dit doet ?
> H[PossibleState(true)] = 8;

Elke keer dat ik deze regel aan roep zal er een nieuw object gemaakt
worden en dus een nieuwe array index.

Hetzelfde bij deze regel:
> if (H.find(PossibleState(true)) != H.end()) std::cout << "ok\n";

Je zoekt naar een object dat je in de call naar find gemaakt hebt.



-- 
Niels.

Niels Basjes - http://niels.basjes.nl/ - VCV 20000302
mailto:`echo 'Niels Basjes'|awk '{print$1"@"$2".nl"}'`
Re: Rare C++ fout (std::map)
#1708
Author: Arnold Hendriks
Date: Wed, 15 Dec 2004 09:48
21 lines
1815 bytes
"Aquila" <braempje@netscape.net> wrote in message 
news:ZJKdne45LpA4YyLcRVnyvA@scarlet.biz...

> bool PossibleState::operator<(const PossibleState & state) const{
> return turning != state.turning;
Deze is verdacht. De operator zegt het volgende:

false < false == false
false < true  == true
true  < false == true
true  < true  == false

Met andere woorden: false < true, en true < false. Daarmee voldoet je 
compare niet aan de eis dat het een 'strict weak ordering' is: als a < b, en 
b < c, dan moet a < c ook waar zijn. Bij bijvoorbeeld a=false,b=true,c=false 
gaat dit mis.

Als je je operator bijvoorbeeld als turning < state.turning definieert, dan 
zou de compare wel moeten werken. Nu de compare niet strict is, deugt de 
sortering niet en dat kan best verklaren waarom de find() functie niet goed 
werkt.
Re: Rare C++ fout (std::map)
#1709
Author: Aquila
Date: Wed, 15 Dec 2004 10:13
23 lines
2316 bytes
Arnold Hendriks wrote:

> Als je je operator bijvoorbeeld als turning < state.turning definieert,
> dan zou de compare wel moeten werken. Nu de compare niet strict is, deugt
> de sortering niet en dat kan best verklaren waarom de find() functie niet
> goed werkt.

Je hebt gelijk, ik had daar een < moeten gebruiken. Nu ben ik er nog niet
want dat was een (domme) vereenvoudiging. Normaal bestaat possiblestate uit
een positie pos, een direction dir en een boolean turning. Maar ik wil dat
die laatste 2 genegeerd worden want dat mag in die map geen verschil maken.
Dus heb ik:
bool PossibleState::operator<(const PossibleState & state) const{
 return (getPos().x < state.getPos().x) || (getPos().y < state.getPos().y);
}
Is dat ook verkeerd met die strict weak ordering? Ik heb eens gekeken op
<http://www.sgi.com/tech/stl/StrictWeakOrdering.html> en dan zou ik niet
voldoen aan antisymmetrie: (4,4) < (4,4) is false maar het omgekeerde is
niet true zoals ge�ist...

Bedankt voor uw hulp!
-- 
"May the source be with you"
Re: Rare C++ fout (std::map)
#1710
Author: Aquila
Date: Wed, 15 Dec 2004 10:20
46 lines
2433 bytes
Niels Basjes wrote:

> Je gebruikt een class als index voor een map:
>> static std::map<const PossibleState,int>��H;
> 
Ja omdat ik wil indexeren op PossibleState

> Wat verwacht jij dat code als dit doet ?
>> H[PossibleState(true)] = 8;
> 
Dat in de map op index PossibleState(true) de waarde 8 wordt ingevuld, dus
dat als ik indexeer op een PossibleState(true) dat daar 8 uit komt.

> Elke keer dat ik deze regel aan roep zal er een nieuw object gemaakt
> worden en dus een nieuwe array index.
> 
Zoals ik het begreep test de map via operator< op gelijkheid dus moet dat
maar een object zijn. Doe de test:

#include <map>
#include <iostream>

class Klasse{
 public:
  Klasse(int x): fX(x) {};
  bool operator<(const Klasse& k) const{
   return fX < k.fX;
  }
 private:
  int fX;
};

int main(){
 std::map<Klasse,int> mapje;
 mapje[Klasse(1)] = 2;
 std::cout << &mapje.begin()->first << "\n";
 mapje[Klasse(1)] = 3;
 std::cout << &mapje.begin()->first << "\n";
}

Volgens jou moet dat twee verschillende adressen geven, maar zowel gcc als
icc geven hetzelfde adres, telkens opnieuw.
Of vergis ik mij volledig?

-- 
"May the source be with you"
Re: Rare C++ fout (std::map)
#1713
Author: Suzan Foster
Date: Wed, 15 Dec 2004 12:24
48 lines
2047 bytes
Aquila wrote:

> Voor een AI programma krijg ik heel rare fouten met onderstaande code. (Ik
> weet dat het nogal lang is maar ik heb al heel hard gewerkt om het probleem
> te verkleinen).
> 
> possiblestate.h:
> 
> #ifndef POSSIBLESTATE_H
> #define POSSIBLESTATE_H
> 
> class PossibleState{
>  public:
>   PossibleState(bool);
>   PossibleState();
>   ~PossibleState();
>   bool operator < (const PossibleState &) const; 
>  private:
>   bool turning;
> };
> #endif
> 
> 
> possiblestate.cpp:
> 
> #include "possiblestate.h"
> PossibleState::PossibleState(bool turninger):
>  turning(turninger)
> {}
> PossibleState::PossibleState():
>  turning()
> {}

ongedefinieerde waarde in turning.

> PossibleState::~PossibleState(){}
> bool PossibleState::operator<(const PossibleState & state) const{
>  return turning != state.turning;
> }

deze slaat echt nergens op:

true < false = true
false < true = true

welke is nou lager dan welke?

groetjes, su.
Re: Rare C++ fout (std::map)
#1717
Author: Aquila
Date: Wed, 15 Dec 2004 18:22
27 lines
2010 bytes
Suzan Foster <http://members.home.nl/foz/foaf.rdf> wrote:

>> PossibleState::PossibleState():
>>turning()
>> {}
> 
> ongedefinieerde waarde in turning.
> 

Een default constructor is nodig voor map indexering...

>> PossibleState::~PossibleState(){}
>> bool PossibleState::operator<(const PossibleState & state) const{
>>return�turning�!=�state.turning;
>> }
> 
> deze slaat echt nergens op:
> 
> true < false = true
> false < true = true
> 
> welke is nou lager dan welke?

Aangepast maar het werkt nog niet (zie andere thread). Bedankt voor je
opmerkingen!
-- 
"May the source be with you"
Re: Rare C++ fout (std::map)
#1721
Author: dichtertje
Date: Wed, 15 Dec 2004 21:35
41 lines
2926 bytes
Aquila <braempje@netscape.net> wrote:
> Arnold Hendriks wrote:
> 
>> Als je je operator bijvoorbeeld als turning < state.turning definieert,
>> dan zou de compare wel moeten werken. Nu de compare niet strict is, deugt
>> de sortering niet en dat kan best verklaren waarom de find() functie niet
>> goed werkt.
> 
> Je hebt gelijk, ik had daar een < moeten gebruiken. Nu ben ik er nog niet
> want dat was een (domme) vereenvoudiging. Normaal bestaat possiblestate uit
> een positie pos, een direction dir en een boolean turning. Maar ik wil dat
> die laatste 2 genegeerd worden want dat mag in die map geen verschil maken.
> Dus heb ik:
> bool PossibleState::operator<(const PossibleState & state) const{
> return (getPos().x < state.getPos().x) || (getPos().y < state.getPos().y);
> }
> Is dat ook verkeerd met die strict weak ordering? Ik heb eens gekeken op
> <http://www.sgi.com/tech/stl/StrictWeakOrdering.html> en dan zou ik niet
> voldoen aan antisymmetrie: (4,4) < (4,4) is false maar het omgekeerde is
> niet true zoals ge?ist...
> 
> Bedankt voor uw hulp!

Die antisymmetrie geldt enkel voor over verschillende waarden, als ze
gelijk zijn geldt de irreflixitiviteitsregel.

Ik heb de oorspronkelijke code niet bekeken, maar bovenstaande operator<
kan heel onverwachte resultaten geven. Immers maps werken met
equivalentie en niet met gelijkheid en met jouw operato< is (2,4) en
(2,3) equivalent, en dus als je zoekt naar (2,4) kun je een iterator
naar (2,3) terugkrijgen.
Ik kan niet oordelen of dit in uw geval een praktisch probleem is of
niet.

Bert

-- 
The three laws of thermodynamics:
	(1) You can't get anything without working for it.
	(2) The most you can accomplish by working is to break even.
	(3) You can only break even at absolute zero.
Re: Rare C++ fout (std::map)
#1725
Author: Aquila
Date: Thu, 16 Dec 2004 13:27
30 lines
2553 bytes
dichtertje wrote:

>> Dus heb ik:
>> bool PossibleState::operator<(const PossibleState & state) const{
>> return (getPos().x < state.getPos().x) || (getPos().y <
>> state.getPos().y); }
>> Is dat ook verkeerd met die strict weak ordering? Ik heb eens gekeken op
>> <http://www.sgi.com/tech/stl/StrictWeakOrdering.html> en dan zou ik niet
>> voldoen aan antisymmetrie: (4,4) < (4,4) is false maar het omgekeerde is
>> niet true zoals ge?ist...
>> 
>> Bedankt voor uw hulp!
> 
> Die antisymmetrie geldt enkel voor over verschillende waarden, als ze
> gelijk zijn geldt de irreflixitiviteitsregel.
> 
> Ik heb de oorspronkelijke code niet bekeken, maar bovenstaande operator<
> kan heel onverwachte resultaten geven. Immers maps werken met
> equivalentie en niet met gelijkheid en met jouw operato< is (2,4) en
> (2,3) equivalent, en dus als je zoekt naar (2,4) kun je een iterator
> naar (2,3) terugkrijgen.
> Ik kan niet oordelen of dit in uw geval een praktisch probleem is of
> niet.

Dat was het dus wel, bedankt voor de inspiratie! Ik heb een implementatie
gemaakt die prioriteit geeft aan x en dan op y sorteert, dat werkt perfect.

Allen bedankt voor uw hulp!
-- 
"May the source be with you"
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads