【拜占庭将军问题】这一计谋,可以让诸葛丞相兴复汉室

news2024/11/14 22:48:25

我们都知道,诸葛亮第一次北伐是最可能成功的,魏国没有防备,还策反了陇西,陇西有大量的马匹可以装备蜀国骑兵,可惜街亭一丢,那边就守不住了

当时我不在,只能作诗一首~

image.png

如果穿越过去,我将会向丞相献上一计,别说街亭,直接拿下长安,先看地图

image-20230309115840165.png

从延安,洛阳,策反魏国州长,让他们出兵。然后再结盟孙权,让他从久攻不下的合肥调来800精兵从襄阳进攻,让魏延从宝鸡出兵,自己率领大军从汉中进发

五路攻击,光围都能把长安围死

但是这个时候你可能会说:天方夜谭,且不说孙权,你怎么能确保洛阳和延安的兵听你的,而不是反贼?

这个呢,就需要我们今天要讲的问题,也称为【拜占庭将军问题】,多节点场景,没有中心化的协调,而且其中可能出现不可靠结点的情况下,如何保证大家行动的统一性?

我们先约定一些共识:

  • 一个丞相发送指令,四个将军接收
  • 所有人都可能是反贼
  • 反贼回复的指令和丞相的相反

现在我们模拟一个场景,必须要五路进发才能够打下长安,其中有反贼。当主路——也就是诸葛亮的那一路发出“进攻”指令时,另外四路的将军会收到,同时会向其他三路求证,如果进攻指令数过半数,就会进攻。但是反贼会回复别的将军【撤退】指令

如果反贼过多,导致【撤退】指令过多,所有的将军都不会出动,丞相只能自己北伐了

  • 那么此时忠反比多少才合适呢?

    关键在于,即使有反贼存在,只要忠臣数量足够多,就可以保证最终的决策是正确的。
    这是因为反贼无法破坏所有将军之间的通信,因此忠臣可以通过相互交流,确定反贼的存在并排除他们的虚假消息。最终的决策取决于忠臣的数量,通常情况下,当忠臣数量超过总将军数量的三分之二时,算法可以保证正确性。

  • 那么为什么是三分之二呢?不是更多或者更少?

    假设发指令的是丞相,其他为将军,总数为n, 反贼数为m,

    其中每一个将军做判断的依据是接受到的指令取多数,

    每个将军自己在判断时,只会考虑别的将军和丞相的指令,排除自己,所以此时有n - 1个指令,那么会出现 m 个假指令和n - m - 1 个真指令

    只要保证 n - m - 1 > m,也就是 n > 2m + 1即可

    这是基本情况,当n = 3, m = 1时,满足n > 2m + 1,但是忠臣只会收到一个真指令和一个假指令,无法判断丞相或者另一个将军谁是反贼,所以为了确保取

    n > 3m,也就是忠臣占2/3多数

下面是一个简单的Java代码示例,演示了如何解决这个问题。

假设有6个将军,其中两个是反贼。每个将军都有一个唯一的ID和一个决策(attack或retreat)。这些将军之间通过消息传递来达成共识。

import java.util.Arrays;
import java.util.Random;public class ByzantineGenerals {private static final int NUM_GENERALS = 6;private static final int REPEAT = 5;
    static int traitor;
    static int traitor2;
    public static void main(String[] args) {String[] orders = new String[NUM_GENERALS]; // 命令集合
        for (int p = 0; p < REPEAT; p++) {
            traitor = new Random().nextInt(NUM_GENERALS - 1);
            traitor2 = new Random().nextInt(NUM_GENERALS);
            if (traitor == traitor2) traitor2 += 1;
            for (int i = 0; i < NUM_GENERALS; i++) {
                orders[i] = (i == traitor || i == traitor2) ? "retreat" : "attack";
            }System.out.println("orders" + Arrays.toString(orders));
            boolean finalDecision = computeFinalDecision(orders);
            System.out.println("Final decision: " + (finalDecision ? "attack" : "retreat"));
            System.out.println();
        }
    }private static boolean computeFinalDecision(String[] orders) {
        boolean[] decisions = new boolean[NUM_GENERALS];
        for (int i = 0; i < NUM_GENERALS; i++) {
            if (i == traitor || i == traitor2) {
                decisions[i] = (new Random().nextBoolean());
            } else {
                boolean[] receivedOrders = new boolean[NUM_GENERALS - 1];
                int index = 0;
                for (int j = 0; j < NUM_GENERALS; j++) {
                    if (j != i) {
                        receivedOrders[index++] = (orders[j].equals("attack")); // 每一位将军收集命令
                    }
                }
                decisions[i] = computeDecision(receivedOrders);
            }
        }
        return computeDecision(decisions);
    }private static boolean computeDecision(boolean[] decisions) {
        // Compute the majority decision
        int numTrue = 0;
        int numFalse = 0;
        for (boolean decision : decisions) {
            if (decision) {
                numTrue++;
            } else {
                numFalse++;
            }
        }
        return (numTrue > numFalse);
    }}

在上面的示例代码中,我们模拟了一个有6个将军的场景,并随机指定两个将军为反贼。每个将军都有一个决策,攻击或撤退。如果将军是反贼,他将发送虚假的命令,否则,将军将发送他真正的命令。在每个将军之间进行消息传递后,每个将军都会收到其他将军发送的命令。如果将军是反贼,他可能会给每个将军发送不同的命令,而忠臣将发送相同的命令。最后,每个将军都会将他们收到的命令和自己的命令一起计算出一个最终的决策,并将它们合并成一个共同的决策。

在计算决策的过程中,我们使用了一个简单的投票算法。我们将每个将军的决策转换为一个布尔值(attack为true,retreat为false),然后计算出这些布尔值中出现次数最多的值。如果attack出现的次数比retreat多,则我们最终的决策为attack,否则为retreat。

输出之一如下

orders[retreat, retreat, attack, attack, attack, attack]
Final decision: attack
​
orders[attack, attack, retreat, retreat, attack, attack]
Final decision: attack
​
orders[attack, attack, attack, retreat, retreat, attack]
Final decision: attack
​
orders[attack, attack, retreat, attack, retreat, attack]
Final decision: attack
​
orders[retreat, attack, attack, attack, attack, retreat]
Final decision: attack

可以看到在6个将军2个反贼下是符合 n > 2m + 1的场景,所以大家都是进攻

在n = 3, m = 1时,n > 2m + 1需要替换为 n > 3m

保险起见取 n > 3m即可

在我看来,这个问题是对投票解决问题的有效性和科学性很有力的佐证,比如选举,即使人民中藏了很多间谍或者是愚昧的人,但是只要正常人占了2/3以上,就可以确保这一制度的稳定与务实。

image.png

同时,如果诸葛亮使用我的计策,五路取长安,那么完全可以兴复汉室,还于旧都。剩下的只需要解决这一计策上面的两朵小乌云即可

  1. 如何防止孙权背刺
  2. 如何策反魏国两个地方的军队

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/399756.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot下的Spring——DAY04——动态代理总结、AOP、自定义注解进行拦截、动态获取注解参数、通知方法(内含源代码)

SpringBoot下的Spring——DAY04——动态代理总结、AOP、自定义注解进行拦截、动态获取注解参数、通知方法&#xff08;内含源代码&#xff09; 源代码下载链接地址&#xff1a;https://download.csdn.net/download/weixin_46411355/87549575 目录SpringBoot下的Spring——DAY0…

【点云学习】多时相激光雷达点云

多时相雷达数据&#xff08;multi-tempral LiDAR data&#xff09; 1 一种多时相激光雷达数据建筑物变化检测方法-汪承义&#xff08;2013&#xff09; 背景&#xff1a;空间分辨率的提高引入了“类内可分性”增加与“类间可分性”降低&#xff1b;遮挡与阴影的存在使问题变得…

pytorch权值初始化和损失函数

pytorch权值初始化和损失函数 权值初始化 梯度消失与爆炸 针对上面这个两个隐藏层的神经网络&#xff0c;我们求w2的梯度 可以发现&#xff0c;w2的梯度与H1&#xff08;上一层网络的输出&#xff09;有很大的关系&#xff0c;当h1趋近于0时&#xff0c;w2的梯度也趋近于0&am…

swoole的强大之处,你可能只是略知一二!

首先 swoole 是 php 的一个扩展程序swoole 是一个为 php 用 c 和 c 编写的基于事件的高性能异步 & 协程并行网络通信引擎swoole 是一个多进程模型的框架&#xff0c;当启动一个进程 swoole 应用时&#xff0c;一共会创建 2nm 个进程&#xff0c;n 为 worker 进程数&#xf…

maven将jar文件上传至本地仓库及私服

maven官方仓库有些依赖并不存在&#xff0c;现在项目都是maven直接获取jar&#xff0c;当maven获取不到时&#xff0c;需要我们把jar上传至maven仓库。已 ImpalaJDBC41.jar 文件为例&#xff0c;如&#xff1a;希望上传后&#xff0c;设置的依赖为&#xff1a;<dependency&g…

数字化工厂装配线生产管理看板系统

电力企业业务复杂&#xff0c;组织结构复杂&#xff0c;不同的业务数据&#xff0c;管理要求也不尽相同。生产管理看板系统针对制造企业的生产应用而开发&#xff0c;能够帮助企业建立一个规范准确即时的生产数据库。企业现状&#xff1a;1、计划不清晰&#xff1a;生产计划不能…

python程序设计基础 实验四

⭐python实验专栏&#xff0c;欢迎订阅与关注&#xff01; ★观前提示&#xff1a;本篇内容为python程序设计实验&#xff0c;代码内容经测试没有问题&#xff0c;但是可能会不符合每个人实验的要求&#xff0c;因此以下内容建议仅做思路参考。 一、实验目的 &#xff08;1&am…

2.webpack loader

webpack默认只能处理 以 .js 为后缀名的文件&#xff0c;其他的文件需要用loader&#xff0c;比如 css-loader 可以打包处理.css相关的文件less-loader 可以打包处理 .less相关的文件babel-loader 可以打包处理webpack无法处理的高级JS语法 目录 1 css-loader 1.1 安装 1…

[学习笔记] 2. 数据结构

数据结构视频地址&#xff1a;https://www.bilibili.com/video/BV1uA411N7c5 数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成。简单来说&#xff0c;数据结构就是设计数据以何种方式组织并存储在计算机中。 比如:列表、集合与字…

“小霞”黄绮珊绮望三十巡回演唱会将于3月18日杭州大剧院震撼开唱!

•中年成名 四十余载静待盛放 歌手黄绮珊&#xff0c;1991年正式进入歌坛&#xff0c;至今已满三十周年。黄绮珊前半生的歌手之路好像并不是那么顺畅。虽然一直有着华语乐坛的顶尖歌唱实力&#xff0c;但在45岁之前&#xff0c;黄绮珊一直处于“歌红人不红”的状态。不少人听过…

postgresql 自动备份 bat实现

postgres数据据备分,用cmd命令有些烦,写了个bat实现 BAT脚本中常用的注释命令有rem、@rem和:: rem、@rem和::用法都很简单,直接在命令后加上要注释的语句即可。例如下图,语言前加了rem,运行BAT时就会自动忽略这个句子。需要注释多行时,每行前面都要加上rem、@rem和::。…

Kalman Filter in SLAM (3) ——Extended Kalman Filter (EKF, 扩展卡尔曼滤波)

文章目录1. 线性系统的 Kalman Filter 回顾2. Extended Kalman Filter 之 DR_CAN讲解笔记2.1. 非线性系统2.2. 非线性系统线性化2.2.1. 状态方程f(xk)f(x_k)f(xk​)在上一次的最优估计状态x^k−1\hat{x}_{k-1}x^k−1​处线性化2.2.2. 观测方程h(xk)h(x_k)h(xk​)在这一次的预测…

企业知识管理应该怎么做?

企业知识管理是指企业利用各种信息技术手段&#xff0c;对企业内部的知识进行收集、整理、分析和传递&#xff0c;以提高企业的知识水平和竞争力。企业知识管理涉及到企业内部的各种知识&#xff0c;包括技术知识、专业知识、经验知识、市场知识等。 企业知识管理的方式可以分为…

DETR目标检测算法学习记录

引言 无论是One Stage中的YOLO还是Two-Stage中的Faster-RCNN&#xff0c;其虽然都在目标检测领域有着一席之地&#xff0c;但无一例外都是基于Anchor的模型算法&#xff0c;这就导致其在输出结果时不可避免的进行一些如非极大值抑制等操作来进一步选择最优解&#xff0c;这会带…

uniCloud基础使用

获取openID云函数use strict; exports.main async (event, context) > {//event为客户端上传的参数console.log(event : , event)// jscode2session 微信小程序登录接口&#xff0c;获取openidconst {code} event;// 云函数中如需要请求其他http服务&#xff0c;则使用uni…

Day912.多环境配置隔离 -SpringBoot与K8s云原生微服务实践

多环境配置隔离 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于多环境配置隔离的内容。 多环境支持&#xff0c;是现在互联网开发研发和交付的主流基本需求。通过规范多环境配置可以规范开发流程&#xff0c;并同时提示项目的开发质量和效率等。 一个公司应该规范…

网络使用情况监控

您的网络是否经常成为网络紧张或带宽瓶颈的牺牲品&#xff1f;瓶颈并不一定意味着带宽不足&#xff1b;它们可能是由占用带宽到严重网络威胁等任何因素造成的。密切监控您的网络并分析带宽使用情况和网络流量对于找到问题的根源非常重要。NetFlow Analyzer是最先进的网络使用情…

Simulink自动化-Matlab脚本自动创建Runnable及mapping

文章目录前言设计Excel模板编写matlab脚本自动添加Function到Simulink模型自动mapping Function与Runnable总结前言 在之前的一篇文章中&#xff0c;介绍了Autosar S/R接口的自动创建及mapping,传送门&#xff1a;Simulink自动化-Matlab脚本自动生成Autosar RTE S/R接口及mapp…

mujoco安装及urdf转xml方法记录

参考 mujoco210及mujoco-py安装 下载适用于Linux或 OSX的 MuJoCo 2.1 版二进制文件 。 将mujoco210的下载的目录解压到~/.mujoco/mujoco210路径下. 注意&#xff1a;如果要为包指定非标准位置&#xff0c;请使用环境变量MUJOCO_PY_MUJOCO_PATH。 验证是否安装成功&#xff08…