我试图在不可靠的频道上找到协议协议。基本上两方(A和B)必须同意做某事,所以它是two generals' problem。
由于没有防弹解决方案,我正在尝试这样做。
我的问题。双方何时可以得出结论认为他们可以采取行动?显然我无法设置一个条件:“收到10条消息后执行此操作”,因为最后一位发件人不会确定消息10是否已到达 - 返回原点。
另一个想法怎么样:
答案 0 :(得分:3)
这个java代码表明,对于两个将军问题有一个合理的解决方案,可以最大限度地降低信使风险和转移消息所花费的时间。给定合理的时间量,达到99.9重复%的确定性。最糟糕的情况是,将军们花费无限时间向危险区域的另一方发送信使,表明他们尚未确定,所有信使都被拦截的可能性极小。在这种最糟糕的情况下,两位将军大多数时候都知道尚未达成协议。他们很不幸,一个普通人提交而另一个人犹豫不决。
算法有一个明确的终点,每个通用可以是99.(可变数量的9)确定另一个将提交。它基于选择沉默指示承诺的时间。信使生命的风险最小化。
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的机会通过危险区域。
答案 1 :(得分:2)
您可以通过保存已发送的所有序列ID的当前状态来增加可靠性(类似于计算哈希函数或3DES计算甚至每条消息的PKI证书 - 后者将花费很多......)。 2将军问题无法解决,但有关问题的更多信息,我想我可以给你一个更好的答案......
顺便说一下,无论你发送多少时间信息,可靠性问题都会在100小时后保持事件(但不良事件发生的可能性会降低)。这意味着你可能需要第三个对象C,它知道A和B,并且可以作为通信的见证人(就像我提到过的PKI)。