Modellierung der Quantenverschränkung auf C #

Published on August 19, 2018

Modellierung der Quantenverschränkung auf C #

    Als das Thema der Quantenverschränkung immer mehr auftaucht, wollte ich ein wenig aufgehen. Nach den Kommentaren zu den Artikeln zur Quantenverschränkung zu urteilen, sind diese Informationen für mich allein nicht nützlich. Nun, unter Berücksichtigung der Tatsache, dass der Programmcode für die meisten von uns viel bequemer ist als alle Allegorien - es wurde beschlossen, mein Verständnis in Form von Code darzustellen.

    Dieser Artikel erweitert den Artikel eines anderen Autors "Quantenverschränkung für Dummies" (ich empfehle zu lesen, er hat mir sehr geholfen). In seinem Artikel gab indomit ein Beispiel für ein Programm, das das Problem der Theorie der verborgenen Parameter deutlich zeigt, aber kein Beispiel für Code für Partikel in Überlagerung geben konnte. In diesem Artikel werden wir versuchen, zwei Fälle zu simulieren:

    1. Wenn sich verschränkte Teilchen unter Determinismus verhalten, können wir den Zustand der Teilchen vor der Messung nicht einfach messen, ohne Verzerrungen einzuführen (das ist die Theorie der verborgenen Parameter). Wir bekommen die Zahlen und sehen die Diskrepanz mit der Praxis.
    2. Wir schreiben ein Modell verschlungener Teilchen in Überlagerung (der Zustand der Teilchen wird nicht vor der Messung bestimmt). Versuchen wir anzunehmen, wie das Teilchen im Inneren programmiert ist, das heißt, wir passen seinen Code an die experimentell erhaltenen Daten an.

    Der Artikel basiert auf einer populären Erklärung des Phänomens der Quantenverschränkung von Mermin:

    Mermin Paradox erklärt
    Для популярного донесения парадокса Д. Мермин предлагает сконструировать простое устройство[23]. Устройство должно состоять из излучателя частиц и двух детекторов. Две одинаковые частицы испускаются к каждому из них. Поймав частицу, детектор даёт двоичный ответ (0 или 1), зависящий от частицы и своего трёхпозиционного переключателя настройки. Детектирование пары частиц должно дать одинаковые ответы:

    1. Всякий раз, когда детекторы настроены одинаково.
    2. По статистике в половине случаев, когда они настроены случайным образом.

    Первое свойство требует, чтобы все детекторы использовали одну и ту же кодировку позиция переключателя ∈ {1,2,3} ↦ отклик ∈ {0,1}, без какого бы то ни было элемента случайности. То есть они должны заранее сговориться какой из откликов, 0 или 1, давать на позицию переключателя, выбрав для каждой частицы одну из восьми возможных функций, 000, 001, 010, 011, 100, 101, 110 и 111. Выбор 000 или 111 приведёт к 100 % совпадению показаний детекторов вне зависимости от положения ручки настройки. Если же детекторы реализуют одну из шести оставшихся функций, одна из цифр вытягивается случайно настроенным переключателем в 2/3 случаев, другая — с вероятностью 1/3. Вероятность совпадения двух ответов при этом составит (⅔)² + (⅓)² = 5/9. Так что каков бы ни был алгоритм автомата, корреляция неизбежно превышает 50 %, нарушая второе требование.

    Но поскольку такую машину всё-таки соорудить можно (например, располагая позиции поляризаторов под 120° как в опыте Бома), то никакого детерминизма (параметров) не может быть даже в скрытой форме. Вместо этого корреляции откликов поддерживаются за счёт передачи информации от одной «измеренной» частицы к другой быстрее, чем произойдёт второе измерение.

    Взято отсюда.

    Leider mache ich weder professionell noch auf der Ebene eines Amateurs Physik, ich behaupte nicht, dass es zu Irrglauben kommt. Das Hauptziel des Artikels besteht darin, zu zeigen, wie ein Modell erstellt wird, das für Programmierer verständlich ist. Wenn jemand professionell in diesem Bereich arbeitet, dann versuchen Sie, anstatt Vorwürfe zu machen, genauere Interaktionsmodelle basierend auf meinem Artikel zu schreiben.

    [Update] Erklärung der Beschreibung von Mermin


    Obwohl seit der Veröffentlichung des Artikels mehrere Monate vergangen sind und niemand zurückkehren wird, entschied er sich zu klären, um sein Gewissen zu beruhigen.

    Er ging etwas tiefer und kam zu dem Schluss, dass die Beschreibung gemäß Mermin stark vereinfacht wurde und Versuche, ihn an reale physische Experimente zu binden, bedeutungslos sind .

    Anfangs habe ich versucht, den Artikel mit einem echten Experiment mit zirkularer Polarisation zu verknüpfen, und ich habe mich darüber geirrt. ARad versuchte, eine Bindung zu realen physischen Experimenten zu entwickeln, schrieb über die Fehler und bot sogar eine eigene Version des Codes an (die auch keinem physischen Experiment entspricht).

    Damit der Artikel zumindest einen Sinn hat, wurde beschlossen, alle imaginären Bindungen an reale physikalische Experimente zu entfernenErklären Sie die Beschreibung von Mermin im Code . Echte Experimente sind schwieriger und für ihre Modellierung ist viel mehr Zeit erforderlich.

    In der ersten Version des Artikels haben wir angenommen, dass im ersten Experiment (die Position der Sensoren stimmt überein) die Partikel ein Spiegelergebnis ergeben, aber in der ursprünglichen Beschreibung von Mermin stimmt das Messergebnis mit der gleichen Position der Sensoren immer überein. Das ist behoben .

    Zusätzlich werde ich die Erklärung zu diesem Mermin hinzufügen, da es nicht eindeutig geschrieben ist:

    Das heißt, sie sollten sich vorher einig sein, welche der Antworten 0 oder 1 an die Schalterposition gegeben werden sollte, wobei für jedes Teilchen eine der acht möglichen Funktionen 000, 001, 010, 011, 100, 101, 110 und 111 ausgewählt wird.

    Der Satz "acht mögliche Funktionen" ist nicht unkompliziert. Es handelt sich um acht mögliche Varianten des möglichen Einflusses von Partikeln auf den Sensor. Es gibt drei Sensorpositionen (siehe vollständige Beschreibung oben). Wenn wir davon ausgehen, dass der Zustand von zwei Partikeln übereinstimmt und im Voraus festgelegt ist, können wir im Voraus festlegen, welche Antwort (0 oder 1) wir potentiell für jede der drei Schalterpositionen erhalten (obwohl wir nur eine der drei Optionen messen können).

    Die Auswahl von 000 oder 111 führt unabhängig von der Position des Einstellknopfs zu einem 100% igen Übereinstimmen der Messwerte der Detektoren.

    Wenn die Partikel den Wert annehmen können, bei dem möglicherweise die Antwort "1" an einer beliebigen Position des Schalters (sowie 0 an einer beliebigen Position des Schalters) auftritt, dann ergibt das zweite Experiment in diesen Fällen eine Übereinstimmung von 100%. Um 50% zu erreichen, können diese Optionen ausgeschlossen werden.

    Wenn die Detektoren eine der sechs verbleibenden Funktionen implementieren, wird in 2/3 Fällen eine der Zahlen von einem zufällig eingestellten Schalter gezogen, die andere mit einer Wahrscheinlichkeit von 1/3.

    Das bedeutet, dass in jedem der 6 Tripel (001, 010, 011, 100, 101, 110) nur zwei der drei Ziffern übereinstimmen (in der ersten Version sind zwei der drei "0" und eine der drei ist "1"). ).

    Um die Wahrscheinlichkeit abzuschätzen, erstellen wir eine Tabelle für den ersten Fall 001 :

    Sensorposition 1 Sensorposition 2 Stimmen die Maße überein?
    1 1 +
    1 2 +
    1 3 -
    2 1 +
    2 2 +
    2 3 -
    3 1 -
    3 2 -
    3 3 +

    Es ist ersichtlich, dass in fünf Fällen von neun Messungen zusammenfallen werden. Die gleiche Wahrscheinlichkeit gilt für jede dieser sechs Optionen (schließlich sind in jeder von ihnen zwei Zahlen gleich).

    Messungen


    In jedem der Modelle (sowohl deterministisch als auch überlagert) werden wir zwei Experimente mit verschränkten Teilchen durchführen, die den ersten und zweiten Bedingungen gemäß Mermin entsprechen:

    1. Zuerst setzen wir beide Sensoren auf dieselbe Position. In diesem Fall erhalten wir 100% identische Ergebnisse (wenn das erste Photon den Polarisator durchläuft, durchläuft auch das zugehörige Photon den Polarisator im gleichen Winkel).
    2. Dann werden wir die Position der Sensoren zufällig einstellen.

    Hier ist der Code für das erste Experiment:

    var totalAttempts = 10000; // всего измерений
    var coincidenceCount = 0; // сколько значений совпало
    for (int attemptNumber = 1; attemptNumber <= totalAttempts; attemptNumber++)
    {
        var entanglementParticles = new EntanglementParticles(); // Зарождение пары запутанных частиц
        var position = GetRandomInteger(1, 3); // Выбираем позицию переключателя на датчике случайным образом
        // Первый и второй датчик устанавливаем в одну и ту же позицию
        int firstSensorPosition = position;
        int secondSensorPosition = position;
        bool firstValue = entanglementParticles.First.GetValue(firstSensorPosition); // Значение первой частицы с учетом позиции первого датчика
        bool secondValue = entanglementParticles.Second.GetValue(secondSensorPosition); // Значение второй частицы с учетом позиции второго датчика
        if (firstValue == secondValue) // подсчет количества совпавших значений
            coincidenceCount ++;
    }
    Console.WriteLine("Эксперимент №1: {0}% значений совпало", (decimal)coincidenceCount / totalAttempts * 100); // все совпали
    

    Hier ist der Code für das zweite Experiment:

    var totalAttempts = 10000; // всего измерений
    var coincidenceCount = 0; // сколько значений совпало
    for (int attemptNumber = 1; attemptNumber <= totalAttempts; attemptNumber++)
    {
        var entanglementParticles = new EntanglementParticles(); // Зарождение пары запутанных частиц
        int firstSensorPosition = GetRandomInteger(1, 3); // Случайным образом устанавливаем позицию датчика 1
        int secondSensorPosition = GetRandomInteger(1, 3); // Случайным образом устанавливаем позицию датчика 2
        bool firstValue = entanglementParticles.First.GetValue(firstSensorPosition); // Значение первой частицы с учетом позиции первого датчика
        bool secondValue = entanglementParticles.Second.GetValue(secondSensorPosition); // Значение второй частицы с учетом позиции второго датчика
        if (firstValue == secondValue) // подсчет количества совпавших значений
            coincidenceCount ++;
    }
    Console.WriteLine("Эксперимент №2: {0}% значений совпало", (decimal)coincidenceCount / totalAttempts * 100);
    

    Für alle Partikelmodelle gelten dieselben Tests, nur der Code der Partikel unterscheidet sich für die deterministischen und Superpositionsmodelle (siehe unten).

    Deterministisches Modell


    Achtung! Siehe UPDATE am Ende des Artikels!

    Für diejenigen, die den Code sofort ausführen möchten, kann dies über den Browser erfolgen: dotnetfiddle.net/N5Xg18

    Laut Mermins Erklärung haben wir ein Quantenteilchen mit 3 Parametern:

    // Элементарная частица (к примеру, фотон)
    public class Particle
    {
        private bool _measured = false;
        public bool A { get; private set; } // Зафиксирует ли датчик в позиции переключателя 1
        public bool B { get; private set; } // Зафиксирует ли датчик в позиции переключателя 2
        public bool C { get; private set; } // Зафиксирует ли датчик в позиции переключателя 3
        public Particle(bool a, bool b, bool c)
        {
            A = a;
            B = b;
            C = c;
        }
        // Получаем значение с учетом позиции переключателя на датчике (всего 3 позиции).
        public bool GetValue(int sensorPosition)
        {
            if (_measured)
                throw new InvalidOperationException("Измерить можно только один раз!");
            _measured = true;
            switch (sensorPosition)
            {
                case 1:
                    return A;
                case 2:
                    return B;
                case 3:
                    return C;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
    }
    

    Da das Modell deterministisch ist, werden alle Parameter des Teilchens zum Zeitpunkt seiner Erstellung, dh direkt im Konstruktor, initialisiert. Einzige Bedingung ist, dass nur einmal gemessen werden darf!

    Weiter Ein Paar verschlungener Teilchen:

    // Пара запутанных частиц
    public class EntanglementParticles
    {
        public Particle First { get; private set; } // Первая частица
        public Particle Second { get; private set; } // Вторая частица
        // Создание пары запутанных частиц (пока верим в детерминизм, считаем что с каждая частица уже имеет установленное значение)
        public EntanglementParticles()
        {
            // Вычисляем в какой позиции частицу потенциально зафиксирует датчик
            bool a;
            bool b;
            bool c;
            do
            {
                a = GetRandomBoolean(); // Зафиксирует ли в позиции 1
                b = GetRandomBoolean(); // Зафиксирует ли в позиции 2
                c = GetRandomBoolean(); ; // Зафиксирует ли в позиции 3
            } while (a == b && b == c); // Исключаем варианты 000 и 111 (нам важно попытаться построить модель, которая приближается к заданным условиям любым способом)
            First = new Particle(a, b, c);
            Second = new Particle(a, b, c); // Значение первой и второй частицы совпадают
        }
    }
    


    Es ist ersichtlich, dass die Werte jedes Partikels zum Zeitpunkt der Erzeugung eines Paars von verschränkten Partikeln eingestellt werden und die Parameter des zweiten Partikels den Parametern des ersten Partikels entsprechen (ohne diesen können wir den ersten Test nicht bestehen). Wir verwenden Zufallszahlen, aber gemäß dem Modell hängen die Parameter zum Zeitpunkt der Verschränkung von Faktoren ab (Roulette hängt daher zum Zeitpunkt des Abwickelns von einer Reihe von Faktoren ab).

    Vollständiger Beispielcode:

    Deterministischer C # -Modellcode (behoben)
    using System;
    public class Program
    {
        private static readonly Random Random = new Random();
        // Элементарная частица
    	public class Particle
    	{
    		private bool _measured = false;
    		public bool A { get; private set; } // Зафиксирует ли датчик в позиции переключателя 1
    		public bool B { get; private set; } // Зафиксирует ли датчик в позиции переключателя 2
    		public bool C { get; private set; } // Зафиксирует ли датчик в позиции переключателя 3
    		public Particle(bool a, bool b, bool c)
    		{
    			A = a;
    			B = b;
    			C = c;
    		}
    		// Получаем значение с учетом позиции переключателя на датчике (всего 3 позиции).
    		public bool GetValue(int sensorPosition)
    		{
    			if (_measured)
    				throw new InvalidOperationException("Измерить можно только один раз!");
    			_measured = true;
    			switch (sensorPosition)
    			{
    				case 1:
    					return A;
    				case 2:
    					return B;
    				case 3:
    					return C;
    				default:
    					throw new ArgumentOutOfRangeException();
    			}
    		}
    	}
        // Пара запутанных частиц
        public class EntanglementParticles
        {
            public Particle First { get; private set; } // Первая частица
            public Particle Second { get; private set; } // Вторая частица
            // Создание пары запутанных частиц (пока верим в детерминизм, считаем что с каждая частица уже имеет установленное значение)
            public EntanglementParticles()
            {
                // Вычисляем в какой позиции частицу потенциально зафиксирует датчик
    			bool a;
    			bool b;
    			bool c;
    			do
    			{
    				a = GetRandomBoolean(); // Зафиксирует ли в позиции 1
    				b =  GetRandomBoolean(); // Зафиксирует ли в позиции 2
    				c =  GetRandomBoolean();; // Зафиксирует ли в позиции 3
    			} while (a == b && b == c); // Исключаем варианты 000 и 111 (нам важно попытаться модель, которая приближается к заданным условиям любым способом)
                First = new Particle(a, b, c);
                Second = new Particle(a, b, c); // Значение первой и второй частицы совпадают
            }
        }
        public static void Main(string[] args)
        {
            Experiment1();
            Experiment2();
        }
        private static void Experiment1()
        {
            var totalAttempts = 10000; // всего измерений
    		var coincidenceCount = 0; // сколько значений совпало
    		for (int attemptNumber = 1; attemptNumber <= totalAttempts; attemptNumber++)
    		{
    			var entanglementParticles = new EntanglementParticles(); // Зарождение пары запутанных частиц
    			var position = GetRandomInteger(1, 3); // Выбираем позицию переключателя на датчике случайным образом
    			// Первый и второй датчик устанавливаем в одну и ту же позицию
    			int firstSensorPosition = position;
    			int secondSensorPosition = position;
    			bool firstValue = entanglementParticles.First.GetValue(firstSensorPosition); // Значение первой частицы с учетом позиции первого датчика
    			bool secondValue = entanglementParticles.Second.GetValue(secondSensorPosition); // Значение второй частицы с учетом позиции второго датчика
    			if (firstValue == secondValue) // подсчет количества совпавших значений
    				coincidenceCount ++;
    		}
    		Console.WriteLine("Эксперимент №1: {0}% значений совпало", (decimal)coincidenceCount / totalAttempts * 100); // все совпали
    	}
        private static void Experiment2()
        {
            var totalAttempts = 10000; // всего измерений
    		var coincidenceCount = 0; // сколько значений совпало
    		for (int attemptNumber = 1; attemptNumber <= totalAttempts; attemptNumber++)
    		{
    			var entanglementParticles = new EntanglementParticles(); // Зарождение пары запутанных частиц
    			int firstSensorPosition = GetRandomInteger(1, 3); // Случайным образом устанавливаем позицию датчика 1
    			int secondSensorPosition = GetRandomInteger(1, 3); // Случайным образом устанавливаем позицию датчика 2
    			bool firstValue = entanglementParticles.First.GetValue(firstSensorPosition); // Значение первой частицы с учетом позиции первого датчика
    			bool secondValue = entanglementParticles.Second.GetValue(secondSensorPosition); // Значение второй частицы с учетом позиции второго датчика
    			if (firstValue == secondValue) // подсчет количества совпавших значений
    				coincidenceCount ++;
    		}
    		Console.WriteLine("Эксперимент №2: {0}% значений совпало", (decimal)coincidenceCount / totalAttempts * 100);
        }
        private static bool GetRandomBoolean()
        {
            return GetRandomInteger(0, 1) == 1;
        }
        private static int GetRandomInteger(int from, int to)
        {
            return Random.Next(from, to + 1); // нам удобнее указывать с какого числа по какое включительно
        }
    }
    


    Sie können vom Browser aus starten (erneuter Link: dotnetfiddle.net/N5Xg18 ).

    Nach dem Start sind dies die Ergebnisse:

    Versuch Nr. 1: 100% der Werte stimmten überein.
    Versuch Nr. 2: 55,6700% der Werte stimmten überein.

    Der erste bestandene Test entspricht dem, was in der Realität passiert. Aber das zweite passt nicht zusammen, denn sie sollten 50% bekommen!

    Infolgedessen mussten die Physiker zu dem Schluss kommen, dass die Theorie der verborgenen Parameter falsch war. Damit wurde auch das Prinzip der Lokalität widerlegt und sogar das Prinzip der Kausalität erschüttert .

    Überlagerungsmodell


    Verknüpfen Sie sofort mit dem Code des Beispiels, wenn Sie spezifische Informationen wünschen (im Browser ausgeführt werden können): dotnetfiddle.net/Mb7JqU

    Um die Ergebnisse der Experimente zu erläutern, mussten wir komplexere Modelle verwenden. In modernen Modellen ist der Zustand der Teilchenparameter vor der Messung nicht definiert, und die verschränkten Teilchen selbst können sofort (über der Lichtgeschwindigkeit) den Zustand voneinander beeinflussen. So sieht unser Modell eines Elementarteilchens jetzt aus:

    // Элементарная частица
    public class Particle
    {
        private Particle _superluminalChannel; // Организация связи с второй запутанной частицей по сверхсветовому каналу.
        private int? _measuredPosition;
        public bool? A { get; private set; } // Зафиксирует ли датчик в позиции переключателя 1
        public bool? B { get; private set; } // Зафиксирует ли датчик в позиции переключателя 2
        public bool? C { get; private set; } // Зафиксирует ли датчик в позиции переключателя 3
        internal void CreateSuperluminalChannelWith(Particle particle)
        {
            _superluminalChannel = particle;
        }
        // Получаем значение с учетом позиции переключателя на датчике (всего 3 позиции).
        public bool GetValue(int sensorPosition)
        {
            if (null != _measuredPosition)
                throw new InvalidOperationException("Измерить можно только один раз!");
            _measuredPosition = sensorPosition;
            if (null != _superluminalChannel._measuredPosition) // если другая запутанная частица уже была измеряна
            {
                var measuredValue = _superluminalChannel.GetNakedValue();
                // Если измеряли тот же параметр у другой частицы (позиция переключателя на датчиках совпала), то возвращаем значение, противоположное значению уже измерянной частицы.
                if (sensorPosition == _superluminalChannel._measuredPosition)
                    return measuredValue;
                if (GetRandomInteger(1, 4) == 1)
                    return measuredValue;
                return !measuredValue;
            }
            // Установка значения. Происходит в момент измерения с нарушением принципа причинности, никакие причины на значение не влияли - чистый рандом.
            // Детерминизм терпит крах!
            var value = GetRandomBoolean();
            SetValue(sensorPosition, value);
            return value;
        }
        private bool GetNakedValue() // Запутанная частица получает значение частицы по сверхсветовому каналу уже после того, как было произведено измерение.
        {
            if (null == _measuredPosition)
                throw new InvalidOperationException();
            switch (_measuredPosition.Value)
            {
                case 1:
                    return A.Value;
                case 2:
                    return B.Value;
                case 3:
                    return C.Value;
                default:
                    throw new InvalidOperationException();
            }
        }
        private void SetValue(int position, bool value)
        {
            switch (position)
            {
                case 1:
                    A = value;
                    break;
                case 2:
                    B = value;
                    break;
                case 3:
                    C = value;
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
    }
    

    Erstens sind die Parameter des Stahls nullfähig (sie können keine Bedeutung haben), und wir legen sie nicht im Konstruktor fest. Zweitens schien das CreateSuperluminalChannelWith-Verfahren einen superluminalen Kanal zwischen Partikeln aufzubauen, d. H. Jetzt kann ein Partikel unabhängig von der Entfernung sofort einen anderen Zustand empfangen. Nun, und was am wichtigsten ist, der Zustand des Partikels wird erst zum Zeitpunkt der Messung festgestellt (rufen Sie die GetValue-Methode auf) und hängt davon ab, ob ein anderes mit ihm verbundenes Partikel gemessen wurde.

    Das Innere der GetValue-Methode ist eine reine Annahme. Wie ein Partikel im Inneren angeordnet ist - niemand weiß es, aber wir wissen, dass es genau so funktioniert: 100% ige Übereinstimmung bei der Messung desselben Parameters und 50% ige Abweichung bei der Messung von Parametern in zufälliger Reihenfolge.

    In meiner Version des Codes überprüft das Partikel über dem überluminalen Kanal, ob die Messung damit verschränkt ist, und verhält sich wie folgt:

    1. Wenn der gemessene Parameter eines anderen Partikels dem entspricht, den wir zu messen versuchen, ergibt sich derselbe Wert.
    2. Wenn der Parameter unterschiedlich ist, gibt er in 1/4 Fällen den gleichen Wert und in 3/4 Fällen den entgegengesetzten Wert (da wir 50/50 erhalten).

    Wenn die Messung nicht durchgeführt wurde - das Partikel verwendet den wahren Zufall, um seinen Wert einzustellen, das heißt, es liegt eine Verletzung der Kausalbeziehung vor (der Wert war vor der Messung nicht vorhanden und die Messung selbst hat ihren Wert nicht bestimmt).

    Übrigens! Sie können diese Funktion auf andere Weise umschreiben, die Testergebnisse sind jedoch gleich. Noch weiß niemand, wie das Elementarteilchen angeordnet ist und wie es für den zweiten Test zu 50% erreicht wird.

    Ein Paar verschränkter Partikel ist einfacher geworden, da zum Zeitpunkt der Verschränkung keine Werte eingestellt sind (die Werte sind noch nicht bestimmt):

    // Пара запутанных частиц
    public class EntanglementParticles
    {
        public Particle First { get; private set; } // Первая частица
        public Particle Second { get; private set; } // Вторая частица
        // Создание пары запутанных частиц (значения не установлены, находятся в суперпозиции)
        public EntanglementParticles()
        {
            First = new Particle(); // значения не установлены, находятся в суперпозиции
            Second = new Particle(); // значения не установлены, находятся в суперпозиции
            // Частицы имеют возможность общаться по сврехсветовому каналу связи
            First.CreateSuperluminalChannelWith(Second);
            Second.CreateSuperluminalChannelWith(First);
        }
    }
    

    Vollständiger Beispielcode:

    Überlagerungsmodell auf C #
    using System;
    public class Program
    {
        private static readonly Random Random = new Random();
        // Элементарная частица
        public class Particle
        {
            private Particle _superluminalChannel; // Организация связи с второй запутанной частицей по сверхсветовому каналу.
            private int? _measuredPosition;
            public bool? A { get; private set; } // Зафиксирует ли датчик в позиции переключателя 1
    		public bool? B { get; private set; } // Зафиксирует ли датчик в позиции переключателя 2
    		public bool? C { get; private set; } // Зафиксирует ли датчик в позиции переключателя 3
            internal void CreateSuperluminalChannelWith(Particle particle)
            {
                _superluminalChannel = particle;
            }
            // Получаем значение с учетом позиции переключателя на датчике (всего 3 позиции).
            public bool GetValue(int sensorPosition)
            {
                if (null != _measuredPosition)
                    throw new InvalidOperationException("Измерить можно только один раз!");
                _measuredPosition = sensorPosition;
                if (null != _superluminalChannel._measuredPosition) // если другая запутанная частица уже была измеряна
                {
                    var measuredValue = _superluminalChannel.GetNakedValue();
                    // Если измеряли тот же параметр у другой частицы (позиция переключателя на датчиках совпала), то возвращаем значение, противоположное значению уже измерянной частицы.
                    if (sensorPosition == _superluminalChannel._measuredPosition)
                        return measuredValue;
                    if (GetRandomInteger(1, 4) == 1)
                        return measuredValue;
                    return !measuredValue;
                }
                // Установка значения. Происходит в момент измерения с нарушением принципа причинности, никакие причины на значение не влияли - чистый рандом.
                // Детерминизм терпит крах!
                var value = GetRandomBoolean();
                SetValue(sensorPosition, value);
                return value;
            }
            private bool GetNakedValue() // Запутанная частица получает значение частицы по сверхсветовому каналу уже после того, как было произведено измерение.
            {
                if (null == _measuredPosition)
                    throw new InvalidOperationException();
                switch (_measuredPosition.Value)
                {
                    case 1:
                        return A.Value;
                    case 2:
                        return B.Value;
                    case 3:
                        return C.Value;
                    default:
                        throw new InvalidOperationException();
                }
            }
            private void SetValue(int position, bool value)
            {
                switch (position)
                {
                    case 1:
                        A = value;
                        break;
                    case 2:
                        B = value;
                        break;
                    case 3:
                        C = value;
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
        }
        // Пара запутанных частиц
        public class EntanglementParticles
        {
            public Particle First { get; private set; } // Первая частица
            public Particle Second { get; private set; } // Вторая частица
            // Создание пары запутанных частиц (значения не установлены, находятся в суперпозиции)
            public EntanglementParticles()
            {
                First = new Particle(); // значения не установлены, находятся в суперпозиции
                Second = new Particle(); // значения не установлены, находятся в суперпозиции
                // Частицы имеют возможность общаться по сврехсветовому каналу связи
                First.CreateSuperluminalChannelWith(Second);
                Second.CreateSuperluminalChannelWith(First);
            }
        }
        public static void Main(string[] args)
        {
            Experiment1();
            Experiment2();
        }
        private static void Experiment1()
        {
            var totalAttempts = 10000; // всего измерений
    		var coincidenceCount = 0; // сколько значений совпало
    		for (int attemptNumber = 1; attemptNumber <= totalAttempts; attemptNumber++)
    		{
    			var entanglementParticles = new EntanglementParticles(); // Зарождение пары запутанных частиц
    			var position = GetRandomInteger(1, 3); // Выбираем позицию переключателя на датчике случайным образом
    			// Первый и второй датчик устанавливаем в одну и ту же позицию
    			int firstSensorPosition = position;
    			int secondSensorPosition = position;
    			bool firstValue = entanglementParticles.First.GetValue(firstSensorPosition); // Значение первой частицы с учетом позиции первого датчика
    			bool secondValue = entanglementParticles.Second.GetValue(secondSensorPosition); // Значение второй частицы с учетом позиции второго датчика
    			if (firstValue == secondValue) // подсчет количества совпавших значений
    				coincidenceCount ++;
    		}
    		Console.WriteLine("Эксперимент №1: {0}% значений совпало", (decimal)coincidenceCount / totalAttempts * 100); // все совпали
    	}
        private static void Experiment2()
        {
            var totalAttempts = 10000; // всего измерений
    		var coincidenceCount = 0; // сколько значений совпало
    		for (int attemptNumber = 1; attemptNumber <= totalAttempts; attemptNumber++)
    		{
    			var entanglementParticles = new EntanglementParticles(); // Зарождение пары запутанных частиц
    			int firstSensorPosition = GetRandomInteger(1, 3); // Случайным образом устанавливаем позицию датчика 1
    			int secondSensorPosition = GetRandomInteger(1, 3); // Случайным образом устанавливаем позицию датчика 2
    			bool firstValue = entanglementParticles.First.GetValue(firstSensorPosition); // Значение первой частицы с учетом позиции первого датчика
    			bool secondValue = entanglementParticles.Second.GetValue(secondSensorPosition); // Значение второй частицы с учетом позиции второго датчика
    			if (firstValue == secondValue) // подсчет количества совпавших значений
    				coincidenceCount ++;
    		}
    		Console.WriteLine("Эксперимент №2: {0}% значений совпало", (decimal)coincidenceCount / totalAttempts * 100);
        }
        private static bool GetRandomBoolean()
        {
            return GetRandomInteger(0, 1) == 1;
        }
        private static int GetRandomInteger(int from, int to)
        {
            return Random.Next(from, to + 1); // нам удобнее указывать с какого числа по какое включительно
        }
    }
    


    Ergebnisse:

    Experiment Nr. 1: 100% der Werte stimmten überein
    Experiment Nr. 2: 49,7700% der Werte stimmten überein

    Im Browser ausführen : dotnetfiddle.net/Mb7JqU

    Schlussfolgerungen


    Ich hätte gerne verständlichere Interpretationen, wie sie von Mermin zum Ausdruck gebracht wurden. Basierend auf dieser Interpretation gelang es mir, visuelle Modelle bestehender Theorien zu erstellen und sogar ein alternatives Modell vorzuschlagen. Diese Modelle sind nicht allegorisch - Sie können sie ausführen und sehen, wie sie funktionieren.

    Leider habe ich keine zeitweiligen Ressourcen für ein tieferes Wissen über die Quantenphysik und ich hoffe, dass Kenner meinem Beispiel folgen und genauere Arbeitsmodelle geben können.

    UPDATE
    In der Erklärung von Mermin steht nichts über das Gerät der Detektoren. Aus eigener Initiative habe ich A, B und C eine Erklärung als Projektion des Spin auf der X-, Y- bzw. Z-Achse hinzugefügt. Das heißt, ich wollte den physikalischen Phänomenen in den Kommentaren des Codes eine Bindung hinzufügen, damit er nicht so trocken ist. Und darin habe ich mich geirrt ...

    Der Artikel wurde korrigiert und alle vergeblichen Versuche, Mermins Erklärung mit realen physikalischen Experimenten zu verknüpfen, wurden entfernt.