সেলুলার অটোমেটার সাথে বহুবচন ভোটদান


31

সেলুলার অটোমেটাতে সত্যই একটি গুরুত্বপূর্ণ সমস্যা রয়েছে যার নাম মেজরিটি সমস্যা :

সংখ্যাগরিষ্ঠ সমস্যা, বা ঘনত্বের শ্রেণিবদ্ধকরণ কার্য হ'ল দ্বি-মাত্রিক সেলুলার অটোমেটন বিধিগুলি সুনির্দিষ্টভাবে সংখ্যাগরিষ্ঠ ভোটদান সঞ্চালনের সমস্যা।

...

মোট আই + জে কোষের সাথে দ্বি-রাষ্ট্রের সেলুলার অটোমাতার একটি কনফিগারেশন দেওয়া হয়েছে যার মধ্যে আমি শূন্য অবস্থায় রয়েছি এবং এর মধ্যে জে এক রাজ্যে রয়েছে, ভোটদান সমস্যার সঠিক সমাধানটি অবশ্যই শেষ পর্যন্ত সমস্ত কোষকে শূন্যে সেট করতে হবে i> j এবং অবশেষে আমি <জে> সমস্ত কক্ষকে একটিতে সেট করতে হবে। I = j হলে কাঙ্ক্ষিত ইভেন্টের অবস্থা অনির্ধারিত।

যদিও এটি প্রমাণিত হয়েছে যে কোনও সেলুলার অটোমেটা সব ক্ষেত্রেই সংখ্যাগরিষ্ঠ সমস্যা সমাধান করতে পারে না, এমন অনেক বিধি রয়েছে যা বেশিরভাগ ক্ষেত্রেই এটি সমাধান করতে পারে। গ্যাকস-কুর্দিয়ামোভ-লেভিন অটোমেটনের এলোমেলো প্রাথমিক অবস্থার সাথে প্রায় 78% নির্ভুলতা রয়েছে। জিকেএল নিয়ম জটিল নয়:

  • 3 এর ব্যাসার্ধ, যার অর্থ হ'ল কোষের নতুন রাজ্যটি পূর্ববর্তী 7 টি কোষের উপর নির্ভর করে: নিজেই, ডানদিকে 3 টি কোষ এবং বামে 3 কোষ।
  • যদি কোনও ঘর বর্তমানে থাকে তবে Oএর নতুন রাজ্যটি নিজের সংখ্যাগরিষ্ঠ, তার বাম দিকে ঘর এবং সেলটি তার বাম দিকে 3 ধাপ।
  • যদি কোনও ঘর বর্তমানে থাকে তবে 1তার নতুন রাজ্যটি নিজের সংখ্যাগরিষ্ঠ, তার ডানদিকে ঘর এবং তার ঘরটি তার ডানে 3 ধাপ।

এখানে একটি উদাহরণ:

0 1 0 1 1 1 0 1 1 0 1 0 0 1
0 1 1 1 1 1 1 1 0 0 1 1 0 0
0 1 1 1 1 1 1 1 1 0 1 0 0 0
0 1 1 1 1 1 1 1 0 1 0 1 0 0
0 1 1 1 1 1 1 0 1 0 1 0 1 0
0 1 1 1 1 1 0 1 0 1 0 1 1 1
1 1 1 1 1 0 1 0 1 1 1 1 1 1
1 1 1 1 0 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1

এই উদাহরণে, সেলুলার অটোমেটন সঠিকভাবে গণনা করে যে 8> 6. অন্যান্য উদাহরণগুলি আরও দীর্ঘ সময় নেয় এবং এর মধ্যে কিছু শীতল নিদর্শন তৈরি করে। নীচে দুটি উদাহরণ যা আমি এলোমেলোভাবে পেয়েছি।

0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 1 1 1 1 0 1 0 0 1 1 1
1 0 0 1 1 1 1 1 1 1 1 1 1 0 1 1 0 0 1 0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 1 0 0 1 1

এটি পরবর্তী স্তরে নিয়ে যাওয়া

আমার ইন্টারনেট গবেষণা যতদূর দেখা গেছে, সংখ্যাগরিষ্ঠ সমস্যা নিয়ে প্রায় সমস্ত একাডেমিক গবেষণা 2-রাজ্যের সিএ নিয়ে পরিচালিত হয়েছে। এই চ্যালেঞ্জের মধ্যে আমরা সংখ্যাগরিষ্ঠ সমস্যাটি 3-রাষ্ট্রীয় CAগুলিতে প্রসারিত করতে যাচ্ছি । আমি এটিকে বহুত্ববোধের সমস্যা বলব । বহুবচন বা আপেক্ষিক সংখ্যাগরিষ্ঠতা সেই শর্তটিকে বোঝায় যেখানে বিকল্পগুলির মধ্যে একটিতে বিকল্পগুলির প্রতিটিের চেয়ে বেশি ভোট রয়েছে, তবে অগত্যা সমস্ত ভোটের সংখ্যাগরিষ্ঠ নয়।

সমস্যা বিবৃতি

  1. ব্যাসার্ধ 3 সহ 3-স্টেট 1 ডি সেলুলার অটোমেটন রয়েছে।
  2. আছে 151 একটি বৃত্তাকার সীমানা শর্ত কোষ।
  3. এই কোষগুলিকে একটি এলোমেলোভাবে শুরু করার অবস্থা দেওয়া হয়, একমাত্র শর্তে যে 3 টি রাজ্যের 1 টির একটি বহুবচন রয়েছে। "র্যান্ডম" অর্থ প্রতিটি কক্ষের জন্য একটি স্বতন্ত্র ইউনিফর্ম বিতরণ distribution
  4. কোনও নিয়মের যথার্থতা হ'ল (বৈধ) এলোমেলো প্রাথমিক শর্তের শতাংশ যেখানে 10000 প্রজন্মের মধ্যে সমস্ত কক্ষ সঠিক স্থানে (বহুবচন সহ একটি) সিঙ্ক্রোনাইজ হয় ।
  5. লক্ষ্যটি উচ্চ নির্ভুলতার সাথে একটি নিয়ম সন্ধান করা,

বহুবচন প্রান্তের কেস: 50/50/51 সহ যে কোনও কনফিগারেশন বৈধ প্রারম্ভিক কনফিগারেশন (যেহেতু একটি কঠোর বহুবচন রয়েছে), তবে 51/51/49 সহ কোনও কনফিগারেশন বৈধ নয় (যেহেতু কোনও কঠোর বহুবচন নেই)।

অনুসন্ধানের স্থানটি 3 ^ 3 ^ 7 (e 3e1043), কোনও বিস্তৃত অনুসন্ধানের নাগালের বাইরে। এর অর্থ হ'ল এই সমস্যাটি সমাধান করার জন্য আপনার অন্যান্য কৌশল যেমন জেনেটিক অ্যালগোরিদম ব্যবহার করা প্রয়োজন। এটি কিছু মানব প্রকৌশলও নেবে।

লোকেরা যে নিয়মগুলি খুঁজে পান তার রানটাইম / যথাযথতার উপর নির্ভর করে 10000 প্রজন্মের নিয়মটি পরিবর্তিত হতে পারে। যদি কনভার্সনের যুক্তিসঙ্গত হারের অনুমতি দেওয়া খুব কম হয় তবে আমি এটি বাড়িয়ে তুলতে পারি। বিকল্পভাবে, আমি টাই-ব্রেকার হিসাবে পরিবেশন করতে এটি কমিয়ে আনতে পারি।

জয়লাভ

বিজয়ী হলেন সেই ব্যক্তি যিনি প্রতিযোগীদের মধ্যে সবচেয়ে বেশি যথার্থতার সাথে ব্যাসার্ধ -৩ সিএ নিয়ম জমা দেন।

আপনার জমা দেওয়ার অন্তর্ভুক্ত করা উচিত ...

  • নিয়মের বিবরণ ( প্রয়োজনে ওল্ফ্রাম কোড ব্যবহার করে )
  • নির্ভুলতার হার এবং নমুনার আকার
  • আপনি কীভাবে নিয়মটি সমাধান করার জন্য লিখেছিলেন এমন প্রোগ্রামগুলি বা কোনও "ম্যানুয়াল" ইঞ্জিনিয়ারিং সহ আপনি কীভাবে আবিষ্কার করেছিলেন তার একটি যুক্তিসঙ্গত আকারের ব্যাখ্যা । (এটি সবচেয়ে আকর্ষণীয় অংশ, যেহেতু বাকি সমস্ত কিছুই কেবল কাঁচা সংখ্যা))

পূর্বের কাজ

  • জুয়েল এবং পোল্যাকের একটি কাগজ , যেখানে তারা 86% নির্ভুলতার সাথে কীভাবে 2-রাষ্ট্রীয় বিধি বিবর্তন করেছিল তা বর্ণনা করে।
  • এই কাগজটি r = 3, 149-সেল, 2-রাষ্ট্রের CA ব্যবহার করেছে। এটি সংখ্যাগরিষ্ঠ সমস্যার সমাধানের চেষ্টা করেনি, তবে এর পরিবর্তে এমন একটি নিয়ম সন্ধান করেছিলেন যা দ্রুত পরিবর্তিত 1সর্ব- 0প্যাটার্নের ফলে ঘটে । এই পার্থক্য থাকা সত্ত্বেও, আমি সন্দেহ করি যে অনেক কৌশল একই রকম হবে।
  • উ (ভেলজ এবং ডি অলিভিয়ের একটি কাগজ (এটি খুব বেশি সহায়ক নয় কারণ এটি পে-ওয়াল এর পিছনে রয়েছে) যা বর্তমানে ২-রাজ্যের রেকর্ড ধারণ করে

বহুত্বের ভোটদানের সাথে এর কোনও যোগসূত্র রয়েছে তা খুঁজে পেয়ে আমি খুব হতাশ / অবাক হয়েছিলাম ।
বিড়াল

2
@ কেট আমি আসলে এটির মতো অনুভব করি। প্রতিটি কক্ষের রাজ্য তার "ভোট" (3 জন প্রার্থীর মধ্যে 1 টির পছন্দ) উপস্থাপন করতে পারে, এবং নির্বাচনের বিজয়ী নির্ধারণের লক্ষ্য।
PhiNotPi

2
এটি একটি আকর্ষণীয় কোড চ্যালেঞ্জ। আমি কোনও গল্ফার নই, তাই এই ধরণের ধাঁধাটি দেখে সর্বদা আনন্দিত হয়।
ড্রাকো 18

উত্তর:


6

GKL প্লাস পাহাড়ী আরোহণের সাজান, 61.498%

  • যদি ঘরটি 0 হয় তবে 3 টি বাম দিকে, 1 বাম দিকে এবং নিজেই দেখুন। সংখ্যাগরিষ্ঠে সেট করুন। যদি এটি টাই হয় তবে আপনার মতোই থাকুন।

  • যদি ঘরটি 1 হয় তবে 3 টি ডান থেকে 1 টি ডানদিকে এবং নিজেই দেখুন। সংখ্যাগরিষ্ঠে সেট করুন। যদি এটি টাই হয় তবে আপনার মতোই থাকুন।

  • যদি ঘরটি 2 হয় তবে 2 টি বাম দিকে, 2 টি ডানদিকে এবং 3 টি ডানদিকে দেখুন। সংখ্যাগরিষ্ঠে সেট করুন। যদি এটি টাই হয় তবে আপনার মতোই থাকুন।

আমি মোট 100000 এর মধ্যে 59453 পেয়েছি, 59.453%

কিছু পরিবর্তন এবং পাহাড় আরোহণের ফলস্বরূপ 61498/100000 = 61.498% হয়েছে।

আমি সম্ভবত আরও কিছুটা পরীক্ষা করব এবং পরে আরও কিছু তথ্য পোস্ট করব।


3
আপনার সম্ভবত সম্ভবত আসল 61.498% বিধি অন্তর্ভুক্ত করা উচিত যাতে লোকেরা এটি যাচাই করতে পারে।
মার্টিন এেন্ডার

আপনার সম্ভবত (পরীক্ষা করা) পরীক্ষা করা উচিত।
এরিক আউটগলফার

5

"মাত্র 2s টস আউট এবং GKL করুন" - 55.7%

একটি ভাল নিয়ম কী হবে তা অনুমান করা এত সহজ নয়, তাই আমি কমপক্ষে এমন কিছু নিয়ে আসার চেষ্টা করেছি যা 1/3 এর উপরে হবে score কৌশলটি হ'ল সংখ্যাগরিষ্ঠ রাষ্ট্র 0 বা 1 হলে সঠিক উত্তর পাওয়ার চেষ্টা করা হয় এবং 2 এর ক্ষতি হলে তা মেনে নিতে হয় It GKL এর স্কোর) * 2/3 (উত্তর 0 বা 1 হলে সময়ের ভগ্নাংশ) = 52%।

আরও দৃ concrete়ভাবে, কৌশলটি নিম্নরূপ:

  • সেল 0 বা 1 হয়, GKL কৌশল হিসাবে 3 টি কোষের সিংহভাগ গ্রহণ করুন, তবে যে কোনও প্রতিবেশী ২. এটিকে অগ্রাহ্য করে যদি এটি টাই হয়, ঘরটি অপরিবর্তিত রাখুন।
  • ঘরটি যদি 2 হয় তবে পুরো আশেপাশে 0 বা 1 এর মধ্যে যেকোনও বেশি তা চয়ন করুন। এটি যদি টাই হয় তবে 0 বা 1 এর বামতম মানটি চয়ন করুন all সমস্ত প্রতিবেশী 2 হলে 2 এ থাকুন।

আমি পরীক্ষার জন্য এই কোডটি ব্যবহার করেছি:

#include <iostream>
#include <algorithm>
#include <string.h>
#include <random>
#include <cassert>

#define W 151
#define S 3
#define R 3

typedef int state;

struct tape {
    state s[R+W+R];
    state& operator[](int i) {
        return s[i + R];
    }
    template<typename Rule> void step(Rule r) {
        for(int i = 0; i < R; i++) s[i] = s[W + i];
        for(int i = 0; i < R; i++) s[R + W + i] = s[R + i];
        for(int i = 0; i < W; i++) {
            s[i] = r(s + R + i);
        }
        memmove(s + R, s, W * sizeof(*s));
    }

    state unanimous() {
        state st = (*this)[0];
        for(int i = 1; i < W; i++) {
            if((*this)[i] != st)
                return -1;
        }
        return st;
    }
};

std::ostream& operator<<(std::ostream& s, tape& t) {
    for (int i = 0; i < W; i++)
        s << t[i];
    return s;
}

state randomize(tape& t) {
    static std::mt19937 rg(390332);
    begin:
    int c[S]{};
    for(int i = 0; i < W; i++) {
        state s = rg() % S;
        c[s]++;
        t[i] = s;
    }
    state* smax = std::max_element(c, c + R);
    int nmaj = 0;
    for (int n : c) nmaj += n == *smax;
    if (nmaj > 1) goto begin;
    return smax - c;
}

template<bool PrintSteps, typename Rule> int simulate(Rule r, int trials, int giveup) {
    int successes = 0;
    for(state s = 0; s < S; s++) {
        state t[2 * R + 1];
        for(int i = 0; i <= 2 * R; i++) t[i] = s;
        assert(r(t + R) == s);
    }
    while(trials--) {
        tape tp;
        state desired = randomize(tp);
        int steps = giveup;
        while(steps--) {
            tp.step(r);
            state u = tp.unanimous();
            if(~u) {
                bool correct = u == desired;
                if(PrintSteps) {
                    std::cout << correct << ' ' << giveup - steps << '\n';
                }
                successes += correct;
                break;
            }
        }
    }
    return successes;
}


struct ixList {
    int n;
    int i[2 * R + 1];
};



state rule_justTossOutThe2sAndDoGKL(const state* t) {
    const ixList ixl[] = {
        { 3,{ -3, -1, 0 } },
        { 3,{ 0, 1, 3 } },
        { 6,{ -3, -2, -1, 1, 2, 3 } } 
    };
    int c[S]{};
    for (int i = 0; i < ixl[*t].n; i++)
        c[t[ixl[*t].i[i]]]++;
    if (c[0] > c[1]) return 0;
    if (c[1] > c[0]) return 1;
    if (*t < 2) return *t;
    for (int i = -R; i <= R; i++)
        if (t[i] < 2) return t[i];
    return 2;
}

int main()
{
    int nt = 100000;
    int ns = simulate<false>(rule_justTossOutThe2sAndDoGKL, nt, 10000);

    std::cout << (double)ns / nt << '\n';
    return 0;
}

স্কোরটি আপনি প্রত্যাশার চেয়ে বেশি বেশি কারণ এটি প্রজন্মের সীমাতে বৃদ্ধি পায়। GKL এর% 78% স্কোরটি কয়েক শতাধিক জিনের খুব সামান্য সীমাতে। বিপরীতে, 10,000 জিনগুলি আপনার ফলাফলের সাথে সামঞ্জস্য রেখে জিকেএলকে উচ্চতর নির্ভুলতার হার দেবে।
PhiNotPi

2

"কেবল সর্বোত্তম যা কিছু চুরি করুন এবং এটি বিকশিত করুন", ব্লাহ

সম্পাদনা করুন: বর্তমান অবস্থায় এই উত্তরটি আরও ভাল নিদর্শনগুলি সন্ধান করার চেয়ে আরও ভাল এলোমেলো নমুনা সন্ধান করে।

এই উত্তরটি সমস্ত রাজ্যকে ত্রৈমাসিক সংখ্যার হিসাবে গণ্য করার মাধ্যমে সমাধানগুলি এনকোড / ডিকোড করে (প্রথমে সর্বনিম্ন-উল্লেখযোগ্য অঙ্ক)। 59.2% জন্য সমাধান:

000000000010010010000000000000000000000000000000000000000000010000010000110000000
000000000010010010000000000111111101111111111111111111000011000010011011000011010
000000000012010011001000000021111111111120111211111111000000000000011010000010000
000011000010022110000000202000000002000000000020000000001010000000011011000011010
020000000010010010001000000111101111111111111111111111010011000011111111010011010
000000000010010010000000000111111111101111111111112111000011010110111011010011011
000000000010010010000000000010000000000000000100002011000000000100011010020010000
000020020010010010000200000111102111111111111111111101000011010010111011000011011
000100000010010010000000000121111111111111111111111111000210000012011011002011010
000000000010010110000000000111112112111111111001111111000010000010011011000011010
000000000010010120000200000111211111111111111111110111110011010011100111010011011
000000000010010010000000000011111111111111111111111111000011010010111211210012020
010000000010010010020100020111110111111111111111111110010111010011011111010111011
002000000010010010000000000111110111111111211111111111001111111111111111111111111
000000000110010010000000000111111111111111211111111111010111011111111111011111011
001000000010010010000000000011111101111111111111110111000011010010111011010011010
001000000010010110000000000111111111111111102111110111010111011111111111011111101
000000000210010010000000000111111111111111111111011111010011010011111111010111011
000000000010010010000000000112111111111111111111101011000000000000011010000010000
000000000010010010000000000111111111111111111111111111000011010010111011010011011
000200000012010010000000000111111111111112111111111111000010000210011211001011010
000000000010010211000002000111111111111111111111111111000001010010111011010011010
000021200010210010000101100111111111111211111110110211010111021111111101010111111
000000000010010010000000000111111111111101111111111111010011010111111111010110021
000200000010010010000000010111111111101111111121112111000210001010011011000011010
000000000010010010000000000111111111111111111111111111210011010021111111010111011
000020000010010010000000000111111111111111111111111111000011010010121011010011012

নিম্নলিখিত কোডটি ব্যবহার করে এই উত্তরটি ফেয়ারসামের 55.7% থেকে উদ্ভূত হয়েছিল। এই কোডটির জন্য লাইবপ দরকার , যা আমার ব্যক্তিগত সি ++ কেবলমাত্র শিরোনামের লাইব্রেরি। এটি ইনস্টল করা খুব সহজ, git clone https://github.com/orlp/libopআপনি প্রোগ্রামটি যেখানে সংরক্ষণ করেছেন ঠিক একই ডিরেক্টরিতে করুন। আমি সঙ্গে সংকলন পরামর্শ g++ -O2 -m64 -march=native -std=c++11 -g। দ্রুত বিকাশের জন্য আমি উপরোক্ত কমান্ডটি চালিয়ে লাইবপ পূর্ববর্তী করার পরামর্শ দিই libop/op.h

#include <cstdint>
#include <algorithm>
#include <iostream>
#include <cassert>
#include <random>

#include "libop/op.h"

constexpr int MAX_GENERATIONS = 500;
constexpr int NUM_CELLS = 151;

std::mt19937_64 rng;

double worst_best_fitness;

// We use a system with okay-ish memory density. We represent the ternary as a
// 2-bit integer. This means we have 32 ternaries in a uint64_t.
//
// There are 3^7 possible states, requiring 4374 bits. We store this using 69
// uint64_ts, or little over half a kilobyte.

// Turn 7 cells into a state index, by encoding as ternary.
int state_index(const int* cells) {
    int idx = 0;
    for (int i = 0; i < 7; ++i) {
        idx *= 3;
        idx += cells[6-i];
    }
    return idx;
}

// Get/set a ternary by index from a 2-bit-per-ternary encoded uint64_t array.
int get_ternary(const uint64_t* a, size_t idx) {
    return (a[idx/32] >> (2*(idx % 32))) & 0x3;
}

void set_ternary(uint64_t* a, size_t idx, int val) {
    assert(val < 3);
    int shift = 2*(idx % 32);
    uint64_t shifted_val = uint64_t(val) << shift;
    uint64_t shifted_mask = ~(uint64_t(0x3) << shift);
    a[idx/32] = (a[idx/32] & shifted_mask) | shifted_val;
}


struct Rule {
    uint64_t data[69];
    double cached_fitness;

    Rule(const char* init) {
        cached_fitness = -1;
        for (auto i : op::range(69)) data[i] = 0;
        for (auto i : op::range(2187)) set_ternary(data, i, init[i] - '0');
    }

    double fitness(int num_tests = 1000);

    Rule* random_mutation(int num_mutate) const {
        auto new_rule = new Rule(*this);

        auto r = op::range(2187);
        std::vector<int> indices;
        op::random_sample(r.begin(), r.end(),
                          std::back_inserter(indices), num_mutate, rng);

        for (auto idx : indices) {
            set_ternary(new_rule->data, idx, op::randint(0, 2, rng));
        }

        new_rule->cached_fitness = -1;
        return new_rule;
    }

    int new_state(const int* cells) const {
        return get_ternary(data, state_index(cells));
    }

    void print_rule() const {
        for (auto i : op::range(2187)) {
            std::cout << get_ternary(data, i);
            if (i % 81 == 80) std::cout << "\n";
        }
    }
};


struct Automaton {
    uint64_t state[5];
    int plurality, generation;

    Automaton() : generation(0) {
        for (auto i : op::range(5)) state[i] = 0;

        int strict = 0;
        while (strict != 1) {
            int votes[3] = {};
            for (auto i : op::range(NUM_CELLS)) {
                int vote = op::randint(0, 2, rng);
                set_ternary(state, i, vote);
                votes[vote]++;
            }

            // Ensure strict plurality.
            plurality = std::max_element(votes, votes + 3) - votes;
            strict = 0;
            for (auto i : op::range(3)) strict += (votes[i] == votes[plurality]);
        }
    }

    void print_state() {
        for (int i = 0; i < 151; ++i) std::cout << get_ternary(state, i);
        std::cout << "\n";
    }

    bool concensus_reached() {
        int target = get_ternary(state, 0);
        for (auto i : op::range(NUM_CELLS)) {
            if (get_ternary(state, i) != target) return false;
        }

        return true;
    }

    void next_state(const Rule& rule) {
        uint64_t new_state[5] = {};

        std::vector<int> cells;
        for (auto r : op::range(-3, 4)) {
            cells.push_back(get_ternary(state, (r + NUM_CELLS) % NUM_CELLS));
        }

        for (auto i : op::range(NUM_CELLS)) {
            set_ternary(new_state, i, rule.new_state(cells.data()));
            cells.erase(cells.begin());
            cells.push_back(get_ternary(state, (i + 4) % NUM_CELLS));
        }

        for (auto i : op::range(5)) state[i] = new_state[i];
        generation++;
    }
};


double Rule::fitness(int num_tests) {
    if (cached_fitness == -1) {
        cached_fitness = 0;
        int num_two = 0;
        for (auto test : op::range(num_tests)) {
            Automaton a;
            while (a.generation < MAX_GENERATIONS && !a.concensus_reached()) {
                a.next_state(*this);
            }

            if (a.generation < MAX_GENERATIONS &&
                get_ternary(a.state, 0) == a.plurality &&
                a.plurality == 2) num_two++;

            cached_fitness += (a.generation < MAX_GENERATIONS &&
                               get_ternary(a.state, 0) == a.plurality);

            if (cached_fitness + (num_tests - test) < worst_best_fitness) break;
        }

        if (num_two) std::cout << cached_fitness << " " << num_two << "\n";

        cached_fitness;
    }

    return cached_fitness;
}



int main(int argc, char** argv) {
    std::random_device rd;
    rng.seed(42); // Seed with rd for non-determinism.

    const char* base = 
        "000000000010010010000000000000000000000000000000000000000000000000010000000000000"
        "000000000010010010000000000111111111111111111111111111000010000010011011000011010"
        "000000000010010010000000000111111111111111111111111111000000000000011010000010000"
        "000000000010010010000000000000000000000000000000000000000010000010011011000011010"
        "000000000010010010000000000111111111111111111111111111010011010011111111010111011"
        "000000000010010010000000000111111111111111111111111111000011010010111011010011011"
        "000000000010010010000000000000000000000000000000000000000000000000011010000010000"
        "000000000010010010000000000111111111111111111111111111000011010010111011010011011"
        "000000000010010010000000000111111111111111111111111111000010000010011011000011010"
        "000000000010010010000000000111111111111111111111111111000010000010011011000011010"
        "000000000010010010000000000111111111111111111111111111010011010011111111010111011"
        "000000000010010010000000000111111111111111111111111111000011010010111011010011010"
        "000000000010010010000000000111111111111111111111111111010011010011111111010111011"
        "000000000010010010000000000111111111111111111111111111011111111111111111111111111"
        "000000000010010010000000000111111111111111111111111111010111011111111111011111111"
        "000000000010010010000000000111111111111111111111111111000011010010111011010011010"
        "000000000010010010000000000111111111111111111111111111010111011111111111011111111"
        "000000000010010010000000000111111111111111111111111111010011010011111111010111011"
        "000000000010010010000000000111111111111111111111111111000000000000011010000010000"
        "000000000010010010000000000111111111111111111111111111000011010010111011010011011"
        "000000000010010010000000000111111111111111111111111111000010000010011011000011010"
        "000000000010010010000000000111111111111111111111111111000011010010111011010011010"
        "000000000010010010000000000111111111111111111111111111010111011111111111011111111"
        "000000000010010010000000000111111111111111111111111111010011010011111111010111011"
        "000000000010010010000000000111111111111111111111111111000010000010011011000011010"
        "000000000010010010000000000111111111111111111111111111010011010011111111010111011"
        "000000000010010010000000000111111111111111111111111111000011010010111011010011012"
    ;

    // Simple best-only.
    std::vector<std::unique_ptr<Rule>> best_rules;
    best_rules.emplace_back(new Rule(base));
    worst_best_fitness = best_rules.back()->fitness();
    while (true) {
        const auto& base = *op::random_choice(best_rules.begin(), best_rules.end(), rng);
        std::unique_ptr<Rule> contender(base->random_mutation(op::randint(0, 100, rng)));

        // Sort most fit ones to the beginning.
        auto most_fit = [](const std::unique_ptr<Rule>& a, const std::unique_ptr<Rule>& b) {
            return a->fitness() > b->fitness();
        };

        if (contender->fitness() >= best_rules.back()->fitness()) {
            std::cout << contender->fitness();
            double contender_fitness = contender->fitness();
            best_rules.emplace_back(std::move(contender));
            std::sort(best_rules.begin(), best_rules.end(), most_fit);
            if (best_rules.size() > 5) best_rules.pop_back();
            std::cout << " / " << best_rules[0]->fitness() << "\n";
            worst_best_fitness = best_rules.back()->fitness();

            if (contender_fitness == best_rules.front()->fitness()) {
                best_rules.front()->print_rule();
            }
        }
    }

    return 0;
}

0

হাত কোডড, 57.541%

এটি প্রকৃতপক্ষে কেবলমাত্র এটির উপরে 5 টি কক্ষকে দেখায়। এটি সম্ভবত এটির পরিসর বাড়িয়ে উন্নত হতে পারে be 100,000 পরীক্ষার কেস নিয়ে দৌড়েছে।

অ্যালগরিদম:

If above == 0:
   if to the left there are only 2s or there is a 1 separated by 2s
       next state = 2
   else
       next state = 0
If above == 1:
   if to the right there are only 2s or there is a 0 separated by 2s
       next state = 2
   else
       next state = 1
If above == 2:
   ignore 0s to the left if the 0 is left of a 1 on the left
   ignore 1s to the right if the 1 is right of a 0 on the right
   if the closest 0 on the left is closer than the closest 1 on the right
       next state = 0
   else if the closest 1 on the right is closer than the closest 0 on the left
       next state = 1
   else
       next state = 2

জিন:

000000000222222222000222222222222222222222222222222222000000000222222222000222222
000000000222222222000222222111111111111111111111111111000222222111111111111111111
000000000222222222000222222222222222222222222222222222000000000222222222000222222
000000000222222222000222222222222222222222222222222222000000000222222222222222222
000000000222222222000222222111111111111111111111111111222111111111111111111111111
000000000222222222000222222111111111111111111111111111000000000111111111222111111
000000000222222222000222222222222222222222222222222222000000000222222222000222222
000000000222222222000222222111111111111111111111111111000222222111111111111111111
000000000222222222000222222222222222222222222222222222000000000222222222000222222
000000000222222222000222222222222222222222222222222222000000000222222222000222222
000000000222222222000222222111111111111111111111111111000222222111111111111111111
000000000222222222000222222222222222222222222222222222000000000222222222000222222
000000000222222222000222222222222222222222222222222222000000000222222222222222222
000000000222222222000222222111111111111111111111111111222111111111111111111111111
000000000222222222000222222111111111111111111111111111000000000111111111222111111
000000000222222222000222222222222222222222222222222222000000000222222222000222222
000000000222222222000222222111111111111111111111111111000222222111111111111111111
000000000222222222000222222222222222222222222222222222000000000222222222000222222
000000000222222222000222222222222222222222222222222222000000000222222222000222222
000000000222222222000222222111111111111111111111111111000222222111111111111111111
000000000222222222000222222222222222222222222222222222000000000222222222000222222
000000000222222222000222222222222222222222222222222222000000000222222222222222222
000000000222222222000222222111111111111111111111111111222111111111111111111111111
000000000222222222000222222111111111111111111111111111000000000111111111222111111
000000000222222222000222222222222222222222222222222222000000000222222222000222222
000000000222222222000222222111111111111111111111111111000222222111111111111111111
000000000222222222000222222222222222222222222222222222000000000222222222000222222

পরীক্ষার কোড:

import java.lang.Math.*
import java.util.*

const val RADIUS = 3;
const val STATES = 3;
const val DIAMETER = 2 * RADIUS + 1
const val TAPE_LENGTH = 151

val CODE_SIZE = pow(STATES.toDouble(), DIAMETER.toDouble()).toInt()

const val GRADE_RUNS = 100000
const val GRADE_MAX_TIME = 10000


operator fun IntArray.inc() : IntArray {
    val next = this.clone()
    var i = 0
    while (i < size) {
        if (this[i] == STATES - 1) {
            next[i] = 0
        } else {
            next[i]++
            break
        }
        i++
    }
    return next
}
val IntArray.index : Int
    get() {
        var total = 0
        for (i in (size - 1) downTo 0) {
            total *= STATES
            total += this[i]
        }
        return total
    }

interface IRule {
    operator fun get(states : IntArray) : Int
}

fun IntArray.equalsArray(other: IntArray) = Arrays.equals(this, other)

class Rule : IRule {

    constructor(rule : IRule) {
        val start = IntArray(DIAMETER)
        var current = start.clone()

        code = IntArray(CODE_SIZE)
        try {
            do {
                code[current.index] = rule[current]
                current++
            } while (!current.equalsArray(start));
        } catch (e : Throwable) {
            println(Arrays.toString(code))
            println(Arrays.toString(current))
            throw e
        }
    }
    constructor(code : IntArray) {
        this.code = IntArray(CODE_SIZE) { if (it < code.size) code[it] else 0 }
    }

    val code : IntArray

    override fun get(states: IntArray) : Int {
        return code[states.index]
    }

    override fun toString() : String {
        val b = StringBuilder()
        for (i in 0 until CODE_SIZE) {
            if (i > 0 && i % pow(STATES.toDouble(), RADIUS.toDouble() + 1).toInt() == 0) {
                b.append('\n')
            }
            b.append(code[i])
        }
        return b.toString()
    }

    fun grade() : Double {
        var succeeded = 0
        for (i in 0 until GRADE_RUNS) {
            if (i % (GRADE_RUNS / 100) == 0) {
                println("${i/(GRADE_RUNS / 100)}% done grading.")
            }
            var tape : Tape
            do {
                tape = Tape()
            } while (tape.majority() == -1);
            val majority = tape.majority()
            val beginning = tape
            var j = 0
            while (j < GRADE_MAX_TIME && !tape.allTheSame()) {
                tape = tape.step(this)
                j++
            }
            if (tape.stabilized(this) && tape.majority() == majority) {
                succeeded++
            }/* else if (beginning.majority() != 2) {
                println(beginning.majority())
                tape = beginning
                for (j in 1..100) {
                    println(tape)
                    tape = tape.step(this)
                }
                println(tape)
            }*/
        }
        return succeeded.toDouble() / GRADE_RUNS
    }

}

fun getRandomState() : Int {
    return (random() * STATES).toInt()
}

class Tape(val tape : IntArray) {

    constructor() : this(IntArray(TAPE_LENGTH) { getRandomState() } )

    fun majority() : Int {
        val totals = IntArray(STATES)

        for (cell in tape) {
            totals[cell]++
        }

        var best = -1
        var bestScore = -1

        for (i in 0 until STATES) {
            if (totals[i] > bestScore) {
                best = i
                bestScore = totals[i]
            } else if (totals[i] == bestScore) {
                best = -1
            }
        }

        return best
    }

    fun allTheSame() : Boolean {
        for (i in 1 until TAPE_LENGTH) {
            if (this[i] != this[0]) {
                return false
            }
        }
        return true
    }

    operator fun get(index: Int) = tape[((index % TAPE_LENGTH) + TAPE_LENGTH) % TAPE_LENGTH]

    fun step(rule : IRule) : Tape {
        val nextTape = IntArray ( TAPE_LENGTH )

        for (i in 0 until TAPE_LENGTH) {
            nextTape[i] = rule[IntArray(DIAMETER) { this[i + it - RADIUS] }]
        }

        return Tape(nextTape)
    }

    fun stabilized(rule : IRule) = allTheSame() && majority() == step(rule).majority()

    override fun toString() : String {
        val b = StringBuilder()
        for (cell in tape) {
            b.append(cell)
        }
        return b.toString()
    }

}

fun main(args : Array<String>) {
    val myRule = Rule(object : IRule {
        override fun get(states: IntArray): Int {
            if (states[3] == 0) {
                if (states[2] == 1) {
                    return 2
                } else if (states[2] == 0) {
                    return 0
                } else if (states[1] == 1) {
                    return 2
                } else if (states[1] == 0) {
                    return 0
                } else {
                    return 2
                }
            } else if (states[3] == 1) {
                if (states[4] == 0) {
                    return 2
                } else if (states[4] == 1) {
                    return 1
                } else if (states[5] == 0) {
                    return 2
                } else if (states[5] == 1) {
                    return 1
                } else {
                    return 2
                }
            } else {
                if (states[2] == 0) {
                    if (states[4] != 1) {
                        return 0
                    }
                } else if (states[4] == 1) {
                    return 1
                }
                if (states[1] == 0 && states[2] != 1) {
                    if (states[5] != 1) {
                        return 0
                    }
                } else if (states[5] == 1 && states[4] != 0) {
                    return 1
                }
                return 2
            }
        }

    })
    var tape = Tape()
    println(myRule.grade())
}

উদাহরণ

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.