Re: [C++] Programma C++ con classi non funziona bene.

Messaggioda Daniele_97 » 21/01/2019, 02:01

Grazie mille
Daniele_97
Junior Member
Junior Member
 
Messaggio: 34 di 102
Iscritto il: 10/12/2016, 19:38

Re: [C++] Programma C++ con classi non funziona bene.

Messaggioda Raptorista » 21/01/2019, 02:28

In generale, sarebbe meglio rimpiazzare tutti gli array che hai nel codice con dei vector.
Un matematico ha scritto:... come mia nonna che vuole da anni il sistema per vincere al lotto e crede che io, in quanto matematico, sia fallito perché non glielo trovo


Immagine
Avatar utente
Raptorista
Moderatore
Moderatore
 
Messaggio: 5171 di 9616
Iscritto il: 28/09/2008, 19:58

Re: [C++] Programma C++ con classi non funziona bene.

Messaggioda vict85 » 21/01/2019, 14:25

Codice:
class Utente
{
public:
    Utente()
    {
        NumeroDiTransazioni[Nut] = {0};
        float Reliability_value[Nut] = {0};
        Trust_value[Nut] = {0.0};
        Reputation = 0.5;
        cheat = false;
    }


Questo costruttore è completamente sbagliato. La prima riga accede e riscrive qualcosa al di fuori dell'array NumeroDiTransazioni. La seconda riga definisce un array locale al costruttore e lo inizializza a 0 (ma quell'array è eliminato alla fine del costruttore e non modifica l'array che è membro della classe). La terza riga fa la stessa cosa della prima. La quarta e la quinta hanno senso. Quello non è il modo in cui azzeri un array in un costruttore, ti suggerisco di fare un for per inizializzare a 0 ogni elemento dell'array.
vict85
Moderatore
Moderatore
 
Messaggio: 9465 di 19253
Iscritto il: 16/01/2008, 00:13
Località: Berlin

Re: [C++] Programma C++ con classi non funziona bene.

Messaggioda Raptorista » 22/01/2019, 09:00

@vict: qui si vede che non ho proprio letto il codice, l'ho solo fatto passare in gdb e valgrind ed è saltato fuori l'errore :D
Comunque, curioso che valgrind/memcheck non si sia lamentato di niente...
Un matematico ha scritto:... come mia nonna che vuole da anni il sistema per vincere al lotto e crede che io, in quanto matematico, sia fallito perché non glielo trovo


Immagine
Avatar utente
Raptorista
Moderatore
Moderatore
 
Messaggio: 5173 di 9616
Iscritto il: 28/09/2008, 19:58

Re: [C++] Programma C++ con classi non funziona bene.

Messaggioda vict85 » 22/01/2019, 09:42

È possibile che sia legato al fatto che il costruttore, per quanto sbagliato, non accede a nulla al di fuori della classe. Supponendo che int e float abbiano la stessa dimensione nella sua architettura e che il compilatore non riordini gli elementi della struttura, la prima riga dovrebbe assegnare 0 al primo elemento del secondo array, La terza assegna 0.0 a Reputation.

Detto questo il design del programma è sbagliato. Insomma crea un array di Utenti in cui ogni utente dovrebbe avere degli array della stessa dimensione del numero degli utenti. Il design del programma dovrebbe costruire direttamente le matrici (o comunque dovrebbe avere una classe che ingloba tutti gli utenti e che gestisce in modo appropriato la loro costruzione).

@Daniele_97: ma qual'è il testo del problema?
vict85
Moderatore
Moderatore
 
Messaggio: 9467 di 19253
Iscritto il: 16/01/2008, 00:13
Località: Berlin

Re: [C++] Programma C++ con classi non funziona bene.

Messaggioda Super Squirrel » 22/01/2019, 14:17

Raptorista ha scritto:@vict: qui si vede che non ho proprio letto il codice, l'ho solo fatto passare in gdb e valgrind ed è saltato fuori l'errore :D

Non è mica obbligatorio rispondere ad un topic se non si ha molta voglia di farlo! :roll:
Chi dorme in democrazia, si sveglia in dittatura.
Super Squirrel
Senior Member
Senior Member
 
Messaggio: 336 di 1486
Iscritto il: 16/05/2013, 22:05

Re: [C++] Programma C++ con classi non funziona bene.

Messaggioda Daniele_97 » 22/01/2019, 15:38

vict85 ha scritto:
Codice:
class Utente
{
public:
    Utente()
    {
        NumeroDiTransazioni[Nut] = {0};
        float Reliability_value[Nut] = {0};
        Trust_value[Nut] = {0.0};
        Reputation = 0.5;
        cheat = false;
    }


Questo costruttore è completamente sbagliato. La prima riga accede e riscrive qualcosa al di fuori dell'array NumeroDiTransazioni. La seconda riga definisce un array locale al costruttore e lo inizializza a 0 (ma quell'array è eliminato alla fine del costruttore e non modifica l'array che è membro della classe). La terza riga fa la stessa cosa della prima. La quarta e la quinta hanno senso. Quello non è il modo in cui azzeri un array in un costruttore, ti suggerisco di fare un for per inizializzare a 0 ogni elemento dell'array.

Grazie mille, ho corretto il costruttore, penso che così dovrebbe andar bene.
Codice:
Utente()
    {   
        for (int i=0;i<Nut;i++){
        NumeroDiTransazioni[i]=0;
        Reliability_value[i]=0;
        Trust_value[i]=0.0;}
        Reputation=0.5;
        cheat=false;
    }
Daniele_97
Junior Member
Junior Member
 
Messaggio: 35 di 102
Iscritto il: 10/12/2016, 19:38

Re: [C++] Programma C++ con classi non funziona bene.

Messaggioda Daniele_97 » 22/01/2019, 15:45

vict85 ha scritto:
@Daniele_97: ma qual'è il testo del problema?

Il problema consiste nel trovare gli imbroglioni che sono i primi 100 utenti (da 0 a 99), ho modificato un po' il codice e quando metto da 4000 a 10000 transazioni riesco a trovarli tutti. Però se metto 8000 transazioni accuso un onesto, o più di uno se ne metto ancora meno. I file in input contengono delle transazioni con rispettivamente l'id del compratore, del venditore, il valore dell'oggetto scambiato e il feedback. Gli imbroglioni danno feed bassi agli onesti e prendono sempre feed bassi
Daniele_97
Junior Member
Junior Member
 
Messaggio: 36 di 102
Iscritto il: 10/12/2016, 19:38

Re: [C++] Programma C++ con classi non funziona bene.

Messaggioda vict85 » 22/01/2019, 22:18

Due considerazioni aggiuntive:
  1. Gran parte dei dati che memorizzi e che calcoli non li usi per calcolare la reputazione finale degli utenti. Per capirci, questo codice è equivalente al tuo:
    Codice:
    #include <array>
    #include <iostream>
    #include <fstream>

    #include <cstdlib>

    class Utente
    {
    public:
       constexpr Utente() noexcept : m_reputazione{ 0.5f } {};

       constexpr float reputazione() const { return m_reputazione; }

       constexpr void aggiorna_repuntazione(float recensione, float reputazione_compratore) noexcept
       {
          const float factor = (reputazione_compratore < 0.5f)
             ? reputazione_compratore * reputazione_compratore * reputazione_compratore
             : reputazione_compratore * reputazione_compratore;
          m_reputazione = m_reputazione * (1 - factor) + factor * recensione;
       }

       constexpr bool imbroglia() noexcept { return m_reputazione < 0.5f; }

    private:
       float m_reputazione;
    };

    int main()
    {
       constexpr unsigned int NUMERO_UTENTI = 100;
       std::array< Utente, NUMERO_UTENTI > utenti;

       std::ifstream ifile("transaction1.dat", std::ios::in);
       if (!ifile) {
          std::cerr << "File transaction1.dat could not be opened" << std::endl;
          exit(EXIT_FAILURE);
       }

       for (;;)
       {
          int mittente = 0, destinatario = 0;
          float voto = 0.0f;
          {
             float valore_da_ignorare = 0.0f;
             ifile >> mittente >> destinatario >> valore_da_ignorare >> voto;
          }
          if (!ifile)
          {
             ifile.close();
             break;
          }
          if ( mittente == destinatario
             || mittente < 0 || mittente >= NUMERO_UTENTI
             || destinatario < 0 || destinatario >= NUMERO_UTENTI
             || voto < 0.0f || voto > 1.0f )
          {
             std::cerr << "Transazione invalida: "
                << mittente << " -> " << destinatario
                << " feed=" << voto << std::endl;
             ifile.close();
             exit(EXIT_FAILURE);
          }
          Utente& utente_mittente = utenti[mittente];
          Utente& utente_destinatario = utenti[destinatario];
          utente_destinatario.aggiorna_repuntazione(voto, utente_mittente.reputazione());
       }

       for (int i = 0; i != utenti.size( ); ++i)
       {
          if (utenti[i].imbroglia())
          {
             std::cout << i << std::endl;
          }
       }
    }

  2. Al fine di avere un risultato attendibile, ogni utente deve essere il destinatario di un numero sufficiente di transazioni. Di fatto stai usando un numero piuttosto basso di transazioni.
vict85
Moderatore
Moderatore
 
Messaggio: 9469 di 19253
Iscritto il: 16/01/2008, 00:13
Località: Berlin

Re: [C++] Programma C++ con classi non funziona bene.

Messaggioda Raptorista » 22/01/2019, 22:40

vict85 ha scritto:È possibile che sia legato al fatto che il costruttore, per quanto sbagliato, non accede a nulla al di fuori della classe.

Giusto, non avevo pensato a questo comportamento assurdo del C/C++.

Super Squirrel ha scritto:Non è mica obbligatorio rispondere ad un topic se non si ha molta voglia di farlo! :roll:

Non so se te ne sei accorto ma io ho dato la risposta alla domanda posta, a differenza tua che hai scritto un messaggio per togliere la polvere dalla tastiera.

vict85 ha scritto:Gran parte dei dati che memorizzi e che calcoli non li usi per calcolare la reputazione finale degli utenti. Per capirci, questo codice è equivalente al tuo:

Buon codice, ma mi sa che molte di queste cose sono sconosciute all'utente. Spero non gli siano più di confusione che di aiuto.
Un matematico ha scritto:... come mia nonna che vuole da anni il sistema per vincere al lotto e crede che io, in quanto matematico, sia fallito perché non glielo trovo


Immagine
Avatar utente
Raptorista
Moderatore
Moderatore
 
Messaggio: 5174 di 9616
Iscritto il: 28/09/2008, 19:58

PrecedenteProssimo

Torna a Informatica

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite