Questions sur la langue SI - page 11

 
TheXpert:

pointeur vers un élément de données de taille 4 ou 8 octets.

La taille dépend de la plate-forme en raison de l'alignement. Si vous utilisez quelque chose comme pragma pack 1, la taille sera la même (1 octet probablement).

Je regarde aussi parfois dans VS C++, je compile en mode listing asm et je regarde ensuite, beaucoup de choses deviennent claires. Oui, cela semble effrayant, mais l'asm est la vérité absolue en dernier recours. Et la langue n'est pas difficile à comprendre. C'est difficile de l'écrire correctement ;))

 
Это рекурсия просто. Быстрая сортировка как раз таки и применяет рекурсивный вызов функции. О принципах, преимуществах и недостатках ее использования можете почитать в интернете. И да, это применительно к любому ЯП. В кратце скажу, что главное требование рекурсии - это то, что бы последующий вызов рекурсии приближал алгоритм к завершению. Ну и главный недостаток это требование к оперативной памяти при большое обработке данных, так как каждый вызов такой рекурсии будет блокировать память.... Простой пример с рекурсией на том же си и нахождению факториала в 2 вариациях. 
1) Рекурсия внутри 1 функции:

long long Factorial(int n){
        if(n == 1) return 1;
        return n * Factorial(n-1); // Здесь выполнил требование приближение рекурсии к завершению(то есть n стремится к 1(где исполнится условие выше))
}

2) Рекурсия между несколькими функциями:

int Fun2(int); // Прототип.
int Fun1(int i){
        if(i == -5){return i;}
        return i + Fun2(i-1);
}

int Fun2(int i){
        if(i == -5){return i;}
        return i + Fun1(i-1);
}
 
Gleb Krel:

Oui, merci... comme on dit, je le savais mais j'ai oublié car je ne suis pas un programmeur et je le fais rarement :)

 

Je veux porter ce code source vers MQL, mais je ne suis pas sûr de pouvoir gérer std::deque.

#include <deque>

class net
{   std::deque<float*> w;    // весовые коэффициенты (== это образцам)
    const unsigned     n;    // количество входов сети
    
    float activation(float v) const
    {   return v>n?n:v<0?0:v;
    }
public:
    net(unsigned numInputs):n(numInputs){}
    ~net(void)
    {   for(unsigned i(0); i<w.size();) delete [] w[i++];
    }
    unsigned learnImage(const float* const image)
    {   w.push_back( (float*)memcpy( new float[n],image, sizeof(float)*n) );
        return w.size();
    }
    unsigned recognizeImage(const float* const image) const
    {   float*  axons( (float*)memset(new float[w.size()],0,sizeof(float)*w.size()) );
        float   sum1(.0), sum2(.0), e(0.95 f/w.size());
        unsigned i,j;

        for(i=0; i < w.size(); ++i)    // цикл инициализации сети
        {   for(j=0; j < n; ++j)
                axons[i] += image[j]*w[i][j];
            sum1 += axons[i] = activation(0.5 f*(axons[i]+float(n) ) );
        }
                
        while( sum2 != sum1 )        // цикл пока выходы сети изменяются
        {   sum1 = 0.0 f * ( sum2 = sum1 );
            for(i=0; i < w.size(); ++i)
                sum1 += axons[i] = activation( axons[i]-e*(sum2-axons[i]) );
        }
        for(i=w.size(); i!=-1 u && !axons[i--];);    // поиск активного аксона сети 
        delete [] axons;
        return i;
    }


};



int _tmain(int argc, _TCHAR* argv[])
{  // входы можно сделать и целочисленными, роли играть не будет
    float a1[4][15] = {{1.,1.,1.,  1.,-1.,-1.,  1.,-1.,-1.,  1.,-1.,-1.,  1.,1.,1.},// символ С
                        {1.,1.,1.,  1.,-1.,-1.,  1.,1.,-1.,   1.,-1.,-1.,  1.,1.,1.}, // Символ E
                        {1.,1.,1.,  1.,-1.,1.,   1.,-1.,1.,   1.,-1.,1.,   1.,1.,1.}, // Символ О
                        {1.,1.,1.,  1.,-1.,1.,   1.,-1.,1.,   1.,-1.,1.,   1.,1.,1.}  // искаженный
                      };

    net n(15);
    n.learnImage( a1[0] );
    n.learnImage( a1[1] );    
    n.learnImage( a1[2] );
    return n.recognizeImage( a1[3] );
}


extrait d'ici: https://habr.com/ru/sandbox/43916/

SZY : j'ai cherché sur Google et je n'ai pas trouvé d'autre code source de Hamming, les liens vers d'autres sources sont également les bienvenus (pas le réseau Hopfield !!! - google les donne toujours ensemble)

 
Igor Makanu:

Je veux porter ce code source vers MQL, mais je ne suis pas sûr de pouvoir gérer std::deque.

c'est une liste bidirectionnelle. le code ci-dessus n'a que push_back donc il y a des chances que vous puissiez le remplacer par un vecteur.

si non, vous pouvez faire une implémentation simple de deque via array avec une réserve du début et de la fin. dans STL c'est implémenté de cette façon.

 
Andrei Trukhanovich:

il s'agit d'une liste bidirectionnelle. dans le code ci-dessus il n'y a que push_back donc il y a une chance qu'il puisse être remplacé par un vecteur.

Sinon, vous pouvez faire une implémentation simple de deque via un tableau avec une redondance de début et de fin.

J'ai cherché sur Google std::deque et c'est comme tu l'écris, mais... Je ne sais pas comment l'utiliser, et juste le remplacer par un vecteur... En général, l'exemple est un tutoriel, je ne voudrais pas tout gâcher et être sûr que c'est la façon dont c'est censé fonctionner de manière erronée )))).

ZS : Il y a aussi un exemple en F# - mais je pense que c'est trop ;)

 
Igor Makanu:

Je veux porter ce code source vers MQL, mais je ne suis pas sûr de pouvoir gérer std::Alert( n.recognizeImage( a1_3 ) ) ;

extrait d'ici: https://habr.com/ru/sandbox/43916/

HZZ : googlé, que je n'ai pas trouvé à la volée d'autres sources de réseau de Hamming, les liens vers d'autres sources sont également les bienvenus (ce n'est pas net Hopfield !!! - google les donne toujours ensemble)

Igor, je ne pense pas qu'il soit raisonnable d'écrire un deque, un vecteur suffira dans la grande majorité des cas. J'ai réécrit votre exemple en utilisant un vecteur du fil de discussion sur le stl :

#include <myincl/1_mystd.mqh>

template <typename T>
void fill_vector_from_array(vector_fund<T> &dest, const T &src[]) {
   dest.clear();
   for (int i = 0;  i < ArraySize(src);  ++ i)
      dest.push_back(src[i]);
}
template <typename T>
void fill_vector(vector_fund<T> &dest, T val) {
   for (uint i = 0;  i < dest.size();  ++ i)
      dest.a[i] = val;
}

class net
{   vector_ref<vector_fund<float>> w;    // весовые коэффициенты (== это образцам)
    const uint n;                        // количество входов сети
    
    float activation(float v) const {
        return v>n?n:v<0?0:v;
    }
public:
    net(unsigned numInputs):n(numInputs){}
    unsigned learnImage(const float &image[]) {
        vector_fund<float> tmp;
        fill_vector_from_array(tmp, image);
        w.push_back(tmp);
        return w.size();
    }
    unsigned recognizeImage(const float &image[]) const {   
        vector_fund<float> axons(this.w.size());
        fill_vector<float>(axons, 0);
    
        float   sum1=.0, sum2=.0, e=0.95 f/w.size();
        unsigned i,j;
        vector_fund<float> image_vec;
        fill_vector_from_array(image_vec, image);
        
        for(i=0; i < w.size(); ++i) {   // цикл инициализации сети
            for(j=0; j < n; ++j)
                axons.a[i] += image_vec.a[j]*w.a[i].a[j];
            sum1 += axons.a[i] = activation(0.5 f*(axons.a[i]+float(n) ) );
        }
                
        while( sum2 != sum1 ) {       // цикл пока выходы сети изменяются
            sum1 = 0.0 f * ( sum2 = sum1 );
            for(i=0; i < w.size(); ++i)
                sum1 += axons.a[i] = activation( axons.a[i]-e*(sum2-axons.a[i]) );
        }
        for(i=w.size()-1; i!=(uint)-1 && !axons.a[i--];);    // поиск активного аксона сети 
        return i;
    }


};

unsigned fn() {
   // создал несколько массивов, отказывается мкл передавать многомерные массивы.
   float a1_0[15] = {1.,1.,1.,  1.,-1.,-1.,  1.,-1.,-1.,  1.,-1.,-1.,  1.,1.,1.}; // символ С
   float a1_1[15] = {1.,1.,1.,  1.,-1.,-1.,  1.,1.,-1.,   1.,-1.,-1.,  1.,1.,1.}; // Символ E
   float a1_2[15] = {1.,1.,1.,  1.,-1.,1.,   1.,-1.,1.,   1.,-1.,1.,   1.,1.,1.}; // Символ О
   float a1_3[15] = {1.,1.,1.,  1.,-1.,1.,   1.,-1.,1.,   1.,-1.,1.,   1.,1.,1.}; // искаженный

    net n(15);
    n.learnImage( a1_0 );
    n.learnImage( a1_1 );    
    n.learnImage( a1_2 );

    return n.recognizeImage( a1_3 );
}

void OnStart()
{
   Alert( fn() );
}

Je ne veux pas me planter et être sûr qu'il fonctionne mal )))).

Pour vérifier cela, j'ai testé le code source et le code µl.

    Alert( n.recognizeImage( a1_0 ) );
    Alert( n.recognizeImage( a1_1 ) );
    Alert( n.recognizeImage( a1_2 ) );
    Alert( n.recognizeImage( a1_3 ) );

dans les deux cas, on obtient : 1 1 0 4294967295

HH : au fait, il semble y avoir une erreur dans la source - sortir des limites du tableau (le camarade a oublié d'ajouter -1)

for(i=w.size()-1; i!=-1 u && !axons[i--];);    // поиск активного аксона сети 
 
Vict:

Igor, je ne pense pas qu'il soit raisonnable d'écrire un deque, un vecteur est suffisant dans la grande majorité des cas. J'ai réécrit votre exemple en utilisant le vecteur du fil de discussion sur le stl :

Pour le vérifier, j'ai exécuté sur pluses source et µl code comme

dans les deux cas, on obtient : 1 1 0 4294967295

HH : au fait, dans le code source il semble y avoir une erreur - overrun array (camarade a oublié d'ajouter -1)

О ! C'était si rapide ! Merci HUMAN ! !!

Raison: