SI言語に関する質問 - ページ 11

 
TheXpert:

サイズ4バイトまたは8バイトのデータへのポインタ。

アライメントの関係でサイズはプラットフォームに依存します。 pragma pack 1などを使えばサイズは同じになります(おそらく1バイト)

私も時々VS C++で、asmリストモードでコンパイルしてから見ると、いろいろと腑に落ちます。そう、怖いようですが、アズムは最後の手段で絶対的な真理なのです。言葉も難しくないしね。正しく書くのは難しいです))

 
Это рекурсия просто. Быстрая сортировка как раз таки и применяет рекурсивный вызов функции. О принципах, преимуществах и недостатках ее использования можете почитать в интернете. И да, это применительно к любому ЯП. В кратце скажу, что главное требование рекурсии - это то, что бы последующий вызов рекурсии приближал алгоритм к завершению. Ну и главный недостаток это требование к оперативной памяти при большое обработке данных, так как каждый вызов такой рекурсии будет блокировать память.... Простой пример с рекурсией на том же си и нахождению факториала в 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:

はい、ありがとうございます...よく言われるように、私はプログラマーではなく、ほとんどやらないので、知っていましたが忘れていました :)

 

このソースコードをMQLに移植したいのですが、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] );
}


ここから引用: https://habr.com/ru/sandbox/43916/

SZZY: ググっても他のハミングのソースコードが見つからなかったので、他のソースへのリンクを歓迎します(ホップフィールドネットワークはダメ! - Googleはいつも一緒に出す)。

 
Igor Makanu:

このソースコードをMQLに移植したいのですが、std::dequeを扱えるかどうかがわかりません。

上記のコードではpush_backしかないので、vectorに置き換えることができる可能性があります。

もしそうでなければ,配列を使ったdequeの簡単な実装を,先頭と末尾をリザーブして作ることができます.

 
Andrei Trukhanovich:

これは双方向のリストです。上のコードではpush_backしかないので、vectorに置き換えることができる可能性があります。

そうでない場合は、開始と終了を冗長化した配列を介して、dequeの簡単な実装を行うことができます。

std::dequeでググると、お書きになっている通りですが。使い方がわからず、ただベクターに置き換えるだけ...。一般的に、例はチュートリアルです、私は台無しにしたくないし、それが間違って動作するようになっていることを確認する ))) 。)

ZS: F#の例もあるんですが、やりすぎだと思います;)

 
Igor Makanu:

このソースコードをMQLに移植したいのですが、std::Alert( n.recognizeImage( a1_3 ) )を処理できるかどうかが不安です。

ここから引用: https://habr.com/ru/sandbox/43916/

HZZ:私はその場で他のハミングネットワークのソースを見つけなかったことを、グーグル、他のソースへのリンクも歓迎されている(それはネットホップフィールドではありません!! - googleは常に一緒にそれらを与える)。

Igorさん、dequeを書くのは合理的ではないと思います。大半の場合、vectorで十分です。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() );
}

私は失敗したくないし、それが不適切に動作するはずであることを確認する )))

これを確認するために、ソースコードとµlコードでテストしてみました

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

どちらの場合も、次のようになりました: 1 1 0 4294967295

HH:ところで、ソースに間違いがあったようです。配列の境界の外に出ること(同志が-1を加えるのを忘れた)。

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

Igorさん、dequeを書くのは合理的ではないと思います。大半の場合、vectorで十分です。stlについてのスレッドからvectorを使った例を書き直しました。

それを確認するために、plusのソースとµlのコードで次のように実行しました。

どちらの場合も、次のようになりました: 1 1 0 4294967295

HH:ところで、ソースコードでは、オーバーラン配列(同志が-1を追加するのを忘れた)というエラーがあったようです。

О!めっちゃ早いやんけHUMANさんありがとうございます!!!