Соглашение двух генералов

Я пытаюсь составить протокол соглашения по ненадежному каналу. По сути, две стороны (А и Б) должны договориться о чем-то, так что это проблема двух генералов< /а>.

Поскольку нет пуленепробиваемого решения, я пытаюсь сделать это.

  • A постоянно отправляет сообщение с последовательностью 1
  • Когда B получает последовательность 1, он постоянно отвечает последовательностью 2.
  • В этот момент A получает последовательность 2, поэтому он начинает отправлять последовательность 3.
  • ...

Мой вопрос. Когда обе стороны могут прийти к выводу, что они могут предпринять действия? Очевидно, я не могу поставить условие: "сделать это после получения 10 сообщений", поскольку у последнего отправителя не будет никакой уверенности в том, что сообщение 10 пришло - вернуться к исходной точке.

А как насчет другой идеи:

  • Продолжайте общаться таким образом в течение заранее определенного периода времени. По истечении этого периода обе стороны имеют представление о надежности канала. Было бы это приемлемо?

person user1079062    schedule 03.12.2011    source источник
comment
Возможно, вы получите лучшие ответы на security.stackexchange.com.   -  person Jacco    schedule 03.12.2011
comment
@Jacco Я не думаю, что дело в безопасности, а в надежности.   -  person user1079062    schedule 03.12.2011
comment
Это тот же ход мыслей. А протокол согласования по ненадежному каналу — это а) общее требование к протоколам безопасности, б) то, что уже решалось ранее.   -  person Jacco    schedule 03.12.2011
comment
@Jacco Кажется, у тебя есть решение для этого. Вы бы ответили, если бы я перенес это на security.se :-)?   -  person user1079062    schedule 03.12.2011
comment
Что они согласны делать?   -  person James    schedule 03.12.2011
comment
@ Джеймс Это может быть что угодно. В этом случае оба должны отправить две сущности, которые должны встретиться.   -  person user1079062    schedule 03.12.2011
comment
Как насчет того, чтобы A продолжал отправлять свою сущность B. Затем B обрабатывает обе сущности или отправляет их в конечный пункт назначения. Затем B повторно отправляет сообщение «ОК» обратно в A в течение t секунд. Если по истечении этого времени B снова получает тот же объект (т. е. сообщение OK никогда не дошло до A), B отправляет «OK» еще на t секунд. И так далее. Это будет работать до тех пор, пока объект не будет дорогим для отправки.   -  person James    schedule 03.12.2011
comment
@James Эта сущность может быть чем-то вроде ракеты.   -  person user1079062    schedule 03.12.2011
comment
В концептуальной «Проблеме Генерала» — да. Я не пытаюсь это решить, потому что мы не можем. Поэтому нам нужно знать, в чем заключается ваша настоящая проблема.   -  person James    schedule 03.12.2011
comment
@James На самом деле тебе не нужно ничего знать/делать. Я просто спрашиваю, как добавить надежности связи.   -  person user1079062    schedule 03.12.2011
comment
@James Мой последний комментарий мог показаться резким. Пожалуйста, поймите, я ищу общее (sic) решение. Кроме того, голосование против кого-то с 3 повторениями довольно бесполезно :-)   -  person user1079062    schedule 03.12.2011
comment
Без проблем. Я надеюсь, что кто-то может помочь вам.   -  person James    schedule 03.12.2011


Ответы (2)


Этот Java-код демонстрирует, что существует разумное решение проблемы двух генералов, которое сводит к минимуму риск для жизни мессенджера и время, затрачиваемое на передачу сообщения. При разумном количестве времени достигается 99,9-процентная достоверность повторения. Наихудший случай — это бесконечно малая вероятность того, что генералы тратят бесконечное время на отправку гонцов друг другу через опасную зону, показывая, что они еще не уверены, что все гонцы перехвачены. В этом наихудшем случае два генерала в большинстве случаев знают, что соглашение не достигнуто. Есть крошечный шанс, что им не повезло, и один генерал совершает, а другой колеблется.

У алгоритма есть определенная конечная точка, в которой каждый генерал может быть на 99,0 (переменное число девяток) процентов уверен, что другой совершит его. Он основан на том, сколько времени выделено для молчания, указывающего на обязательство. Количество жизней курьеров, подвергающихся риску, сведено к минимуму.

import java.util.*;
public class Runner{
    public static void main(String[] args) {
        ArrayList<String> coordinated = new ArrayList<String>();
        int fails = 0;

        for(int x = 0; x < 1; x++){
            General a = new General("Patton");
            General b = new General("Bradley");
            a.coordinateAttack(b, "9:00");

            System.out.println("livesRisked = '" + (a.livesRisked + b.livesRisked) + "'");
            System.out.println("" + a.attackIsCoordinated  + b.attackIsCoordinated);

            if (a.attackIsCoordinated == false || b.attackIsCoordinated == false)
                fails++;
        }

        System.out.println("failed " + fails + " times");
    }
}

class General{
    public String name;
    public boolean attackIsCoordinated;
    public int livesRisked;
    public General(String name){
        this.name = name;
        livesRisked = 0;
        attackIsCoordinated = false;
    }
    public void coordinateAttack(General otherGeneral, String time){
        System.out.println("General " + name + " intends to coordinate the attack with General " + otherGeneral.name + " at " + time);
        System.out.println("");

        int tryThisManyTimes = 100;
        for(int x = 1; x <= tryThisManyTimes; x++){

            if (attackIsCoordinated == false){
                System.out.println(name + " will try " + tryThisManyTimes + " times, we still arn't sure, this is attempt number " + x);
                sendAMessageTo(otherGeneral, time);
            }
            else{
                System.out.println("General " + name + " has received a confirmation from " + otherGeneral.name + " and we are 100% certain the battle is coordinated");
                break;
            }
        }
        System.out.println("Patton is 100% sure Bradley is notified of the " + time + " attack.");
        System.out.println("Bradley is 100% sure Patton is notified of the " + time + " attack.");
        System.out.println("");
        System.out.println("This algorithm will always result in 100% assurance that each general commits to the attack and , ");
        System.out.println("is sure the other will join them.  The only way it can fail is if all messengers are always intercepted ");
        System.out.println("and the two generals spend infinite time sending messengers across an impassable dangerzone");
        System.out.println("");
        System.out.println("Given infinite time, it will always result in complete accuracy.");
        attackIsCoordinated = true;
    }
    public void sendAMessageTo(General general_to_send_to, String time){
        Random r = new Random();
        boolean madeItThrough = r.nextBoolean();
        livesRisked++;
        System.out.println("General " + name + " sends a soldier with a message across the dangerzone to " + general_to_send_to.name);
        if (madeItThrough)
            general_to_send_to.receiveMessage(this, time);
        else
            System.out.println(name + "'s messenger was intercepted!  Blast!  Life used up with no results!");
    }

    public void sendConfirmation(General general_to_send_to, String time){
        Random r = new Random();
        System.out.println(name + " is risking a life to tell " + general_to_send_to.name + " we will comply.");
        boolean madeItThrough = r.nextBoolean();
        livesRisked++;
        if (madeItThrough)
            general_to_send_to.receiveConfirmation(this, time);
        else
            System.out.println(name + "'s confirmation messenger was intercepted, but we don't know that, we know " + general_to_send_to.name + " will continue to send us messengers until he is 100% sure.");
    }
    public void receiveMessage(General general_who_sent_it, String time){
        attackIsCoordinated = true;
        System.out.println("Messenger made it!!  As agreed, General " + name + " is notified and commits 100% to the attack at " + time);
        sendConfirmation(general_who_sent_it, time);
    }
    public void receiveConfirmation(General general_who_sent_it, String time){
        System.out.println("Messenger made it!!  General " + name + " has received confirmation from " + general_who_sent_it.name + ", therefore we know he's committed 100% to the attack and we don't need to keep sending messengers.");
        attackIsCoordinated = true;
    }
}

Результат и своего рода псевдокод:

General Patton intends to coordinate the attack with General Bradley at 9:00

Patton will try 100 times, we still arn't sure, this is attempt number 1
General Patton sends a soldier with a message across the dangerzone to Bradley
Patton's messenger was intercepted!  Blast!  Life used up with no results!
Patton will try 100 times, we still arn't sure, this is attempt number 2
General Patton sends a soldier with a message across the dangerzone to Bradley
Messenger made it!!  As agreed, General Bradley is notified and will commit to
    the attack when he is certain, Bradley is not certain yet.
Bradley is risking a life to tell Patton we will comply.
    Bradley Messenger made it!!  General Patton has received confirmation from Bradley, 
    therefore Patton knows he's committed 100% to the attack and we don't need 
    to keep sending messengers.  Silence means I'm 100% sure.
General Patton has received a confirmation from Bradley and we are 100% 
    certain the battle is coordinated
    Bradley receives no additional messages from Patton, and the silence is used to
    mean Patton is 100% certain, the amount of time passed is so great that the
    odds of all messengers being intercepted approaches zero.

Patton is 99.9 repeated % sure Bradley is committed to the 9:00 attack.
Bradley is 99.9 repeated % sure Patton is committed of the 9:00 attack.

Этот алгоритм всегда будет возвращать 99 (определенное количество девяток) повторяющихся процентов для каждого генерала, уверенного, что другой будет там. Единственный способ, которым это может потерпеть неудачу, - это если все гонцы всегда перехватываются, и два генерала тратят бесконечное время, отправляя гонцов через непроходимую опасную зону.

Все, что требуется, — это чтобы один мессенджер прошел и загудел, было получено уведомление, а тишина используется в качестве двунаправленного подтверждения для обеих сторон.

Количество активов или «жизней», которым рискуют, составляет от 3 до 8, учитывая шансы 50/50 пройти через опасную зону.

person Eric Leschinski    schedule 16.11.2012
comment
Кажется, что это не удастся в том случае, если мессенджер Паттона пройдет до того, как все последующие мессенджеры потерпят неудачу. Брэдли не может знать, что его посланник не смог связаться с Паттоном, и ошибочно полагает, что последующее молчание означает подтверждение. Паттон так и не получает подтверждения от Брэдли и отправит еще 99 сообщений, которые не дойдут до Брэдли. Паттон не привязан, а Брэдли. - person Justin C; 11.04.2018

Вы можете повысить надежность, сохранив текущее состояние всех отправленных идентификаторов последовательностей (что-то вроде вычисления хеш-функции или вычисления 3DES или даже сертификата PKI для каждого сообщения - последнее будет стоить дорого...). Проблема двух генералов не может быть решена, но, имея больше информации о проблеме, я думаю, что смогу дать вам лучший ответ...

Кстати, независимо от того, сколько времени вы отправляете сообщение, проблема надежности останется событием через 100 часов (хотя вероятность плохого события уменьшится). Это означает, что, возможно, вам нужен третий объект C, который знает A и B и может быть своего рода свидетелем связи (что-то вроде PKI, о котором я упоминал).

person lionheart    schedule 03.12.2011
comment
Если информации больше нет, то приведу анализ: для каждого удачного сообщения вероятность неудачи уменьшается, так как вероятность неудачи 0,5^t (хорошо/плохо), t - количество сообщений прошло через указанный период. И еще: вы можете установить разумный тайм-аут между A и B, и это повысит вероятность обнаружения хорошего события (то есть уменьшит вероятность плохого события). Из ваших данных я не знаю, можете ли вы использовать тайм-аут. Если тайм-аут проходит, это означает инициализацию связи. - person lionheart; 04.12.2011