【农气项目】基于适宜度的产量预报
直接上干货(复制到开发工具即可运行的代码)
1. 适宜度模型及作物適宜度计算方法
2. 产量分离
3. 基于适宜度计算产量预报
1. 适宜度模型及作物適宜度计算方法
// 三基点温度配置private final double tempMin;private final double tempOpt;private final double tempMax;// 降水/日照理想值private final double idealPrecipitation;private final double idealSunshineRatio;// 权重配置private final double tempWeight;private final double precWeight;private final double sunWeight;public SimpleCropSuitability(double tempMin, double tempOpt, double tempMax,double idealPrecipitation, double idealSunshineRatio,double tempWeight, double precWeight, double sunWeight) {// 参数校验if (tempMin >= tempOpt || tempOpt >= tempMax) {throw new IllegalArgumentException("温度参数必须满足: tMin < tOpt < tMax");}if (idealPrecipitation <= 0 || idealSunshineRatio <= 0) {throw new IllegalArgumentException("降水和日照理想值必须大于0");}this.tempMin = tempMin;this.tempOpt = tempOpt;this.tempMax = tempMax;this.idealPrecipitation = idealPrecipitation;this.idealSunshineRatio = idealSunshineRatio;this.tempWeight = tempWeight;this.precWeight = precWeight;this.sunWeight = sunWeight;}// 温度适宜度(三基点模型)private double calculateTempScore(double meanTemp) {if (meanTemp <= tempMin || meanTemp >= tempMax) {return 0;}return (meanTemp < tempOpt)? (meanTemp - tempMin) / (tempOpt - tempMin) // 低温区间线性增长: 1 - (meanTemp - tempOpt) / (tempMax - tempOpt); // 高温区间线性衰减}// 降水适宜度(新线性模型)private double calculatePrecipitationScore(double precipitation) {return Math.min(precipitation / idealPrecipitation, 1.0);}// 日照适宜度(新线性模型)private double calculateSunshineScore(double sunshineRatio) {return Math.min(sunshineRatio / idealSunshineRatio, 1.0);}/*** 综合适宜度计算** @param meanTemp 旬平均温度(℃)* @param precipitation 旬累计降水(mm)* @param sunshineRatio 旬日照比率(实际日照/理论最大日照)* @return 0-1标准化适宜度*/public double evaluate(double meanTemp, double precipitation, double sunshineRatio) {double tScore = calculateTempScore(meanTemp);double pScore = calculatePrecipitationScore(precipitation);double sScore = calculateSunshineScore(sunshineRatio);// 加权求和(权重自动归一化)double totalWeight = tempWeight + precWeight + sunWeight;return (tScore * tempWeight + pScore * precWeight + sScore * sunWeight) / totalWeight;}public static void main(String[] args) {// 配置小麦抽穗期参数SimpleCropSuitability wheatModel = new SimpleCropSuitability(10, 22, 35, // 温度三基点(℃)60, // 旬理想降水(mm)0.65, // 理想日照比率0.4, 0.4, 0.2 // 温度、降水、日照权重);// 测试不同场景testCase(wheatModel, 22, 60, 0.65); // 理想条件testCase(wheatModel, 15, 30, 0.5); // 各项不足testCase(wheatModel, 25, 80, 0.7); // 降水日照超额}private static void testCase(SimpleCropSuitability model,double temp, double prec, double sun) {double suitability = model.evaluate(temp, prec, sun);System.out.printf("温度=%.1f℃ 降水=%.1fmm 日照=%.2f → 适宜度=%.2f\n",temp, prec, sun, suitability);}
这里的降水和日照都是只有适宜值,如果也类似气温一样有最高最低气温和适宜值,那么按照气温修改一下即可使用
2. 产量分离
根据历年的产量计算出趋势产量和气象产量
public enum SmoothingOption {THREE_YEAR(3), FIVE_YEAR(5);public final int windowSize;SmoothingOption(int size) { this.windowSize = size; }}public static class YieldData {private final int year;private final double yield;public YieldData(int year, double yield) {this.year = year;this.yield = yield;}public int getYear() { return year; }public double getYield() { return yield; }}public static class DecomposedYield {private final int year;private final Double socialYield;private final Double trendYield;private final Double weatherYield;private final Double relativeYield;public DecomposedYield(int year, Double social, Double trend,Double weather, Double relative) {this.year = year;this.socialYield = social;this.trendYield = trend;this.weatherYield = weather;this.relativeYield = relative;}@Overridepublic String toString() {return String.format("%d\t%s\t%s\t%s\t%s",year,socialYield != null ? String.format("%.2f", socialYield) : "",trendYield != null ? String.format("%.2f", trendYield) : "",weatherYield != null ? String.format("%.2f", weatherYield) : "",relativeYield != null ? String.format("%.1f%%", relativeYield) : "");}}public static void main(String[] args) {// 示例数据(2011-2020)List<YieldData> yields = Arrays.asList(new YieldData(2011, 5.2), new YieldData(2012, 5.5),new YieldData(2013, 5.1), new YieldData(2014, 5.8),new YieldData(2015, 6.0), new YieldData(2016, 5.7),new YieldData(2017, 6.2), new YieldData(2018, 6.5),new YieldData(2019, 6.3), new YieldData(2020, 6.4));// 预报年份设置Integer forecastYear = null;// 3年滑动窗口分析System.out.println("=== 3年滑动窗口分析 ===");process(yields, SmoothingOption.THREE_YEAR, forecastYear);// 5年滑动窗口分析System.out.println("\n=== 5年滑动窗口分析 ===");
// process(yields, SmoothingOption.FIVE_YEAR, forecastYear);}private static void process(List<YieldData> yields, SmoothingOption option, Integer forecastYear) {// 1. 产量分解List<DecomposedYield> decomposition = decomposeYield(yields, option);// 2. 获取建模有效数据(排除窗口期不足的年份)List<YieldData> modelData = yields.subList(option.windowSize - 1, yields.size());// 3. 打印趋势产量公式printTrendFormula(modelData);// 4. 预报指定年份if (forecastYear != null){double forecast = calculateTrendForecast(modelData, forecastYear);System.out.printf("预报 %d 年趋势产量: %.2f\n", forecastYear, forecast);}// 5. 打印分解结果printDecompositionResults(decomposition);}private static List<DecomposedYield> decomposeYield(List<YieldData> yields, SmoothingOption option) {List<DecomposedYield> results = new ArrayList<>();int windowSize = option.windowSize;// 计算趋势产量(仅使用有效数据)List<YieldData> modelData = yields.subList(windowSize - 1, yields.size());Map<Integer, Double> trendYields = calculateTrendYield(modelData);for (int i = 0; i < yields.size(); i++) {YieldData current = yields.get(i);Double social = (i >= windowSize - 1) ?calculateMovingAverage(yields, i, windowSize) : null;if (social == null) {results.add(new DecomposedYield(current.year, current.yield, null, null, null));} else {Double trend = trendYields.get(current.year);Double weather = trend != null ? current.yield - social : null;Double relative = weather != null ? (weather / social) * 100 : null;results.add(new DecomposedYield(current.year, social, trend, weather, relative));}}return results;}private static double calculateMovingAverage(List<YieldData> yields, int endIndex, int windowSize) {return yields.subList(endIndex - windowSize + 1, endIndex + 1).stream().mapToDouble(YieldData::getYield).average().orElse(0);}private static Map<Integer, Double> calculateTrendYield(List<YieldData> yields) {double[] coeff = calculateRegressionCoefficients(yields);int baseYear = yields.get(0).getYear();return yields.stream().collect(Collectors.toMap(YieldData::getYear,yd -> coeff[0] + coeff[1] * (yd.getYear() - baseYear)));}private static double[] calculateRegressionCoefficients(List<YieldData> yields) {int n = yields.size();int baseYear = yields.get(0).getYear();double sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0;for (YieldData yd : yields) {double x = yd.getYear() - baseYear;double y = yd.getYield();sumX += x;sumY += y;sumXY += x * y;sumX2 += x * x;}double b = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);double a = (sumY - b * sumX) / n;return new double[]{a, b};}private static double calculateTrendForecast(List<YieldData> yields, int year) {double[] coeff = calculateRegressionCoefficients(yields);return coeff[0] + coeff[1] * (year - yields.get(0).getYear());}private static void printTrendFormula(List<YieldData> yields) {double[] coeff = calculateRegressionCoefficients(yields);System.out.printf("趋势产量公式: y = %.4f + %.4f * (年份 - %d)\n",coeff[0], coeff[1], yields.get(0).getYear());}private static void printDecompositionResults(List<DecomposedYield> results) {System.out.println("\n产量分解结果:");System.out.println("年份\t社会产量\t趋势产量\t气象产量\t相对产量");results.forEach(System.out::println);}
一般都会进行滑动操作如果不需要删除相关代码即可
3. 基于适宜度计算产量预报
/*** 基于适宜度的产量预报,根据适宜度和产量,计算一元一次回归方程,并计算其相关系数和Significance F值* @param args*/public static void main(String[] args) {// 历史数据:适宜度(X)和产量(Y)double[] suitability = {0.714202, 1.2389059999999996, 0.9274519999999999, 1.175564, 1.150908, 0.9320140000000001, 1.207076, 1.012762, 1.321816};double[] yield = {272.288, 119.1564, 27.4286, 217.9705, 58.2261, 9.9326, -83.3608, -101.6542, -115.4477};// 创建并拟合回归模型SimpleRegression regression = new SimpleRegression();for (int i = 0; i < suitability.length; i++) {regression.addData(suitability[i], yield[i]);}// 获取回归系数double intercept = regression.getIntercept();double slope = regression.getSlope();// 计算F统计量double ssr = regression.getRegressionSumSquares();double sse = regression.getSumSquaredErrors();int n = suitability.length;int k = 1;double fStatistic = (ssr / k) / (sse / (n - k - 1));// 计算Significance F (p值)FDistribution fDist = new FDistribution(k, n - k - 1);double significanceF = 1 - fDist.cumulativeProbability(fStatistic);// 设置4位小数格式DecimalFormat df = new DecimalFormat("0.0000");// 处理极小的p值String formattedPValue;if (significanceF < 0.0001) {formattedPValue = "<0.0001";} else {formattedPValue = df.format(significanceF);}// 输出结果System.out.println("回归方程: Y = " + slope + " * X + " + intercept);System.out.println("相关系数(R): " + regression.getR());System.out.println("决定系数(R²): " + regression.getRSquare());System.out.println("F统计量: " + fStatistic);System.out.println("Significance F (p值): " + formattedPValue);// 模型显著性判断double alpha = 0.05;if (significanceF < alpha) {System.out.println("结论: 回归模型显著 (p < " + alpha + ")");} else {System.out.println("结论: 回归模型不显著 (p ≥ " + alpha + ")");}}
根据方法三我们可以拿到气象产量公式,结合方法二的趋势产量公式代入年份进行计算即可计算出基于适宜度的产量预报
相关文章:
【农气项目】基于适宜度的产量预报
直接上干货(复制到开发工具即可运行的代码) 1. 适宜度模型及作物適宜度计算方法 2. 产量分离 3. 基于适宜度计算产量预报 1. 适宜度模型及作物適宜度计算方法 // 三基点温度配置private final double tempMin;private final double tempOpt;private f…...
1、AI及LLM基础:Python语法入门教程
Python语法入门教程 这是一份全面的Python语法入门教程,涵盖了注释、变量类型与操作符、逻辑运算、list和字符串、变量与集合、控制流和迭代、模块、类、继承、进阶等内容,通过详细的代码示例和解释,帮助大家快速熟悉Python语法。 文章目录 Python语法入门教程一、注释二…...

3台CentOS虚拟机部署 StarRocks 1 FE+ 3 BE集群
背景:公司最近业务数据量上去了,需要做一个漏斗分析功能,实时性要求较高,mysql已经已经不在适用,做了个大数据技术栈选型调研后,决定使用StarRocks StarRocks官网:StarRocks | A High-Performa…...
服务器上安装node
1.安装 下载安装包 https://nodejs.org/en/download 解压安装包 将安装包上传到/opt/software目录下 cd /opt/software tar -xzvf node-v16.14.2-linux-x64.tar.gz 将解压的文件夹移动到安装目录(/opt/nodejs)下 mv /opt/software/node-v16.14.2-linux-x64 /opt/nodejs …...
精益数据分析(20/126):解析经典数据分析框架,助力创业增长
精益数据分析(20/126):解析经典数据分析框架,助力创业增长 在创业和数据分析的学习道路上,每一次深入探索都可能为我们带来新的启发。今天,依旧带着和大家共同进步的想法,我们一起深入研读《精…...
9.策略模式:思考与解读
原文地址:策略模式:思考与解读 更多内容请关注:7.深入思考与解读设计模式 引言 你是否曾遇到过这样的情况:在一个系统中,有许多算法或策略,每种策略的实现逻辑相似,但在某些情况下需要进行替换和扩展&am…...

【HCIA】简易的两个VLAN分别使用DHCP分配IP
前言 之前我们通过 静态ip地址实现了Vlan间通信 ,现在我们添加一个常用的DHCP功能。 文章目录 前言1. 配置交换机2. 接口模式3. 全局模式后记修改记录 1. 配置交换机 首先,使用DHCP,需要先启动DHCP服务: [Huawei]dhcp enable I…...
【设计模式-4】深入理解设计模式:工厂模式详解
在软件开发中,对象的创建是一个基础但至关重要的环节。随着系统复杂度的增加,直接使用new关键字实例化对象会带来诸多问题,如代码耦合度高、难以扩展和维护等。工厂模式(Factory Pattern)作为一种创建型设计模式&#…...
Spring Boot 整合 JavaFX 核心知识点详解
1. 架构设计与集成模式 1.1 Spring Boot 与 JavaFX 的分层架构设计 Spring Boot 与 JavaFX 的整合需要精心设计的分层架构,以充分利用两个框架的优势。 标准分层架构 ┌────────────────────────────────────────────────…...
Spring MVC DispatcherServlet 的作用是什么? 它在整个请求处理流程中扮演了什么角色?为什么它是核心?
DispatcherServlet 是 Spring MVC 框架的绝对核心和灵魂。它扮演着前端控制器(Front Controller)的角色,是所有进入 Spring MVC 应用程序的 HTTP 请求的统一入口点和中央调度枢纽。 一、 DispatcherServlet 的核心作用和职责: 请…...
亚马逊英国站FBA费用重构:轻小商品迎红利期,跨境卖家如何抢占先机?
一、政策背景:成本优化成平台与卖家共同诉求 2024年4月,亚马逊英国站(Amazon.co.uk)发布近三年来力度最大的FBA费用调整方案,标志着英国电商市场正式进入精细化成本管理时代。这一决策背后,是多重因素的叠…...
Redis在.NET平台中的各种应用场景
关键点总结 连接管理:所有示例都使用ConnectionMultiplexer来管理Redis连接,它是线程安全的,应该在整个应用程序中重用。 键设计:良好的键命名规范很重要,通常使用冒号分隔的层次结构(如page:home:pv)。 数据序列化&…...
近几年字节测开部分面试题整理
文章目录 前言一、面试问题1. 在浏览器url上写一个地址,请描述一下网络方面有哪些变化2. 堆栈数据存储位置3. HTTP POST请求支持的数据格式4. 缩容要注意些什么?5. Python中元组、数组、list和数组的区别6. Python中is和的区别7. HTTP与HTTPS8. 已知两个…...

艾蒙顿桌面app下载-Emotn UI下载安装-emotn ui官方tv版安卓固件
在智能电视桌面应用的领域里,Emotn UI 凭借其简洁无广告、可自定义等特点,赢得了不少用户的关注。然而,小编深入了解后发现了一款更好用的电视桌面——乐看家桌面在诸多方面更具优势,能为你带来更优质的大屏体验。 乐看家桌面内置…...

3、ArkTS语言介绍
目录 基础知识函数函数声明可选参数Rest参数返回类型箭头函数(又名Lambda函数)闭包 类字段字段初始化getter和setter继承父类访问方法重写方法重载签名可见性修饰符(Public、Private、protected) 基础知识 ArkTS是一种为构建高性…...

修改了Element UI中组件的样式,打包后样式丢失
修改了Element UI中组件的样式,在本地运行没有问题,但是打包到线上发现样式丢失(样式全部不生效、或者有一部分生效,一部分不生效),问题在于css的加载顺序导致代码编译后样式被覆盖了, 解决办法…...
Linux GPIO驱动开发实战:Poll与异步通知双机制详解
1. 引言 在嵌入式Linux开发中,GPIO按键驱动是最基础也最典型的案例之一。本文将基于一个支持poll和异步通知双机制的GPIO驱动框架,深入剖析以下核心内容: GPIO中断与防抖处理环形缓冲区设计Poll机制实现异步通知(SIGIO)实现应用层交互方式 …...

【springsecurity oauth2授权中心】jwt令牌更换成自省令牌 OpaqueToken P4
前言 前面实现了授权中心授权,客户端拿到access_token后就能请求资源服务器接口 权限的校验都是在资源服务器上进行的,授权服务器颁发的access_token有限期是2小时,也就是说在2小时之内,不管授权服务器那边用户的权限如何变更都…...

诱骗协议芯片支持PD2.0/3.0/3.1/PPS协议,支持使用一个Type-C与电脑传输数据和快充取电功能
快充是由充电器端的充电协议和设备端的取电协议进行握手通讯进行协议识别来完成的,当充电器端的充电协议和设备端的取电协议握手成功后,设备会向充电器发送电压请求,充电器会根据设备的需求发送合适的电压给设备快速供电。 设备如何选择快充…...

变量在template里不好使,在setup好使?
问题: 自定义的一个函数 ,import导入后 setup里面使用正常 ,在template里面说未定义 作用域问题 在 Vue 的模板语法中,模板(template )里能直接访问的是组件实例上暴露的属性和方法。从代码看,…...

OpenCV 图形API(53)颜色空间转换-----将 RGB 图像转换为灰度图像函数RGB2Gray()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 将图像从 RGB 色彩空间转换为灰度。 R、G 和 B 通道值的常规范围是 0 到 255。生成的灰度值计算方式如下: dst ( I ) 0.299 ∗ src…...

Trae+DeepSeek学习Python开发MVC框架程序笔记(四):使用sqlite存储查询并验证用户名和密码
继续通过Trae向DeepSeek发问并修改程序,实现程序运行时生成数据库,用户在系统登录页面输入用户名和密码后,控制器通过模型查询用户数据库表来验证用户名和密码,验证通过后显示登录成功页面,验证失败则显示登录失败页面…...

超详细mac上用nvm安装node环境,配置npm
一、安装NVM 打开终端,运行以下命令来安装NVM: curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash 然后就会出现如下代码: > Profile not found. Tried ~/.bashrc, ~/.bash_profile, ~/.zprofile, ~/.…...
STM32 串口通信
引言 在嵌入式系统开发中,串口通信是最基础且重要的通信方式之一。无论是设备调试、模块对接还是远程通信,串口都扮演着关键角色。本文将从通信协议原理出发,结合STM32F4系列MCU,深入讲解串口通信的硬件实现和软件配置࿰…...

hi3516cv610构建音频sample工程代码步骤
hi3516cv610构建音频sample工程代码步骤 sdk版本:Hi3516CV610_SDK_V1.0.1.0 硬件:非es8388 工程代码: 通过网盘分享的文件:audio_easy.zip 链接: https://pan.baidu.com/s/1gx61S_F3-pf6hPyfbGaRXg 提取码: 4gbg --来自百度网盘…...

12.QT-Combo Box|Spin Box|模拟点餐|从文件中加载选项|调整点餐份数(C++)
Combo Box QComboBox 表⽰下拉框 核⼼属性 属性说明currentText当前选中的⽂本currentIndex当前选中的条⽬下标.从0开始计算.如果当前没有条⽬被选中,值为-1editable是否允许修改设为true时, QComboBox 的⾏为就⾮常接近 QLineEdit ,也可以 设置 validatoriconSize下拉框图标…...

UML 顺序图:电子图书馆管理系统的交互之道
目录 一、初识 UML 顺序图 二、电子图书馆管理系统顺序图解析 (一)借阅流程 (二)归还流程 三、顺序图绘画 四、顺序图的优势与价值 五、总结 UML 顺序图是描绘系统组件交互的有力工具。顺序图直观展示消息传递顺序与对象协…...
分布式架构设计与应用:从理论到实践
在云计算、大数据与高并发场景的驱动下,分布式架构已成为现代软件系统的核心技术。它通过将计算、存储与业务逻辑分散到多台机器上,解决了单体架构的扩展性瓶颈与单点故障问题。本文将从设计原则、核心组件到典型应用场景,深入剖析分布式架构…...
Uniapp:view容器(容器布局)
目录 一、基本概述二、属性说明三、常用布局3.1 横向布局3.2 纵向布局3.3 更多布局3.3.1 纵向布局-自动宽度3.3.2 纵向布局-固定宽度3.3.3 横向布局-自动宽度3.3.4 横向布局-居中3.3.5 横向布局-居右3.3.6 横向布局-平均分布3.3.7 横向布局-两端对齐3.3.8 横向布局-自动填充3.3…...

访问者模式:分离数据结构与操作的设计模式
访问者模式:分离数据结构与操作的设计模式 一、模式核心:将操作从数据结构中分离,支持动态添加新操作 在软件开发中,当数据结构(如树、集合)中的元素类型固定,但需要频繁添加新的操作…...