Harmonyos应用实例225: 数学建模案例分析
·
7. 数学建模案例分析
功能简介:提供常见数学建模案例,如人口增长模型、传染病模型、经济增长模型等,通过参数调整观察模型变化,计算模型预测值。帮助学生理解数学建模的基本步骤和应用价值。
ArkTS代码:
@Entry
@Component
struct MathematicalModeling {
@State private model: string = 'population'
@State private parameters: number[] = [100, 0.1, 0.001]
@State private predictions: string = ''
@State private modelResults: number[] = []
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
build() {
Column() {
Text('🔍 数学建模案例分析')
.fontSize(24).fontWeight(FontWeight.Bold)
.margin({ bottom: 20 })
Text('模型类型')
.fontSize(18).fontWeight(FontWeight.Bold)
.margin({ bottom: 10 })
Row() {
Button('人口增长')
.width(100)
.onClick(() => { this.model = 'population'; this.updateModel() })
Button('传染病')
.width(100)
.onClick(() => { this.model = 'epidemic'; this.updateModel() })
Button('经济增长')
.width(100)
.onClick(() => { this.model = 'economic'; this.updateModel() })
}
.margin({ bottom: 20 })
Text('模型参数')
.fontSize(18).fontWeight(FontWeight.Bold)
.margin({ bottom: 10 })
ForEach([0, 1, 2], (index: number) => {
Row() {
Text(this.getParameterLabel(index))
.width(80)
Slider({
value: this.parameters[index],
min: this.getParamMin(index),
max: this.getParamMax(index),
step: this.getParamStep(index)
})
.width(200)
.onChange((val: number) => {
this.parameters[index] = val
this.updateModel()
})
Text(this.parameters[index].toFixed(this.getParamDecimals(index)))
.width(60)
}
.margin({ bottom: 10 })
})
Button('运行模型')
.width(100)
.margin({ top: 10, bottom: 20 })
.onClick(() => this.runModel())
Canvas(this.context)
.width(400).height(300)
.backgroundColor('#f5f5f5')
.onReady(() => this.drawModel())
Text('模型预测')
.fontSize(18).fontWeight(FontWeight.Bold)
.margin({ top: 20, bottom: 10 })
Text(this.predictions)
.fontSize(14).fontColor('#666')
Text('模型说明')
.fontSize(18).fontWeight(FontWeight.Bold)
.margin({ top: 20, bottom: 10 })
Text(this.getModelDescription())
.fontSize(14).fontColor('#666')
}
.padding(20)
}
private getParameterLabel(index: number): string {
switch (this.model) {
case 'population': return ['初始人口: ', '增长率: ', '死亡率: '][index]
case 'epidemic': return ['初始感染: ', '传播率: ', '恢复率: '][index]
case 'economic': return ['初始GDP: ', '增长率: ', '投资率: '][index]
default: return ''
}
}
private getParamMin(index: number): number {
switch (this.model) {
case 'population':
return [1, 0.01, 0.001][index]
case 'epidemic':
return [1, 0.01, 0.01][index]
case 'economic':
return [1, 0.01, 0.01][index]
default:
return 0.01
}
}
private getParamMax(index: number): number {
switch (this.model) {
case 'population':
return [1000, 0.5, 0.1][index]
case 'epidemic':
return [100, 1, 0.5][index]
case 'economic':
return [1000, 0.3, 0.5][index]
default:
return 1
}
}
private getParamStep(index: number): number {
switch (this.model) {
case 'population':
return [1, 0.01, 0.001][index]
case 'epidemic':
return [1, 0.01, 0.01][index]
case 'economic':
return [10, 0.01, 0.01][index]
default:
return 0.01
}
}
private getParamDecimals(index: number): number {
switch (this.model) {
case 'population':
return [0, 2, 3][index]
case 'epidemic':
return [0, 2, 2][index]
case 'economic':
return [0, 2, 2][index]
default:
return 2
}
}
private updateModel() {
// 根据模型类型调整参数范围
switch (this.model) {
case 'population':
this.parameters[0] = Math.max(1, Math.min(1000, this.parameters[0]))
this.parameters[1] = Math.max(0.01, Math.min(0.5, this.parameters[1]))
this.parameters[2] = Math.max(0.001, Math.min(0.1, this.parameters[2]))
break
case 'epidemic':
this.parameters[0] = Math.max(1, Math.min(100, this.parameters[0]))
this.parameters[1] = Math.max(0.01, Math.min(1, this.parameters[1]))
this.parameters[2] = Math.max(0.01, Math.min(0.5, this.parameters[2]))
break
case 'economic':
this.parameters[0] = Math.max(1, Math.min(1000, this.parameters[0]))
this.parameters[1] = Math.max(0.01, Math.min(0.3, this.parameters[1]))
this.parameters[2] = Math.max(0.01, Math.min(0.5, this.parameters[2]))
break
}
}
private runModel() {
this.modelResults = []
let predictions = ''
switch (this.model) {
case 'population':
this.modelResults = this.runPopulationModel()
predictions = `人口增长模型预测:\n`
predictions += `初始人口: ${this.parameters[0].toFixed(0)}\n`
predictions += `增长率: ${this.parameters[1].toFixed(2)}\n`
predictions += `死亡率: ${this.parameters[2].toFixed(3)}\n`
predictions += `10年后人口: ${this.modelResults[9].toFixed(0)}\n`
predictions += `20年后人口: ${this.modelResults[19].toFixed(0)}\n`
break
case 'epidemic':
this.modelResults = this.runEpidemicModel()
predictions = `传染病模型预测:\n`
predictions += `初始感染人数: ${this.parameters[0].toFixed(0)}\n`
predictions += `传播率: ${this.parameters[1].toFixed(2)}\n`
predictions += `恢复率: ${this.parameters[2].toFixed(2)}\n`
predictions += `第10天感染人数: ${this.modelResults[9].toFixed(0)}\n`
predictions += `第20天感染人数: ${this.modelResults[19].toFixed(0)}\n`
break
case 'economic':
this.modelResults = this.runEconomicModel()
predictions = `经济增长模型预测:\n`
predictions += `初始GDP: ${this.parameters[0].toFixed(0)}\n`
predictions += `增长率: ${this.parameters[1].toFixed(2)}\n`
predictions += `投资率: ${this.parameters[2].toFixed(2)}\n`
predictions += `10年后GDP: ${this.modelResults[9].toFixed(2)}\n`
predictions += `20年后GDP: ${this.modelResults[19].toFixed(2)}\n`
break
}
this.predictions = predictions
this.drawModel()
}
private runPopulationModel(): number[] {
const initial = this.parameters[0]
const growth = this.parameters[1]
const death = this.parameters[2]
const results: number[] = []
let population = initial
for (let t = 0; t < 20; t++) {
results.push(population)
population = population * (1 + growth - death)
}
return results
}
private runEpidemicModel(): number[] {
const initial = this.parameters[0]
const beta = this.parameters[1]
const gamma = this.parameters[2]
const results: number[] = []
let infected = initial
const totalPopulation = 1000 // 假设总人口为1000
for (let t = 0; t < 20; t++) {
results.push(infected)
const newInfections = beta * infected * (totalPopulation - infected) / totalPopulation
const recoveries = gamma * infected
infected = Math.max(0, infected + newInfections - recoveries)
}
return results
}
private runEconomicModel(): number[] {
const initial = this.parameters[0]
const growth = this.parameters[1]
const investment = this.parameters[2]
const results: number[] = []
let gdp = initial
for (let t = 0; t < 20; t++) {
results.push(gdp)
gdp = gdp * (1 + growth + investment * 0.5)
}
return results
}
private drawModel() {
const ctx = this.context
const width = 400
const height = 300
const padding = 50
// 清空画布
ctx.clearRect(0, 0, width, height)
// 绘制坐标轴
ctx.beginPath()
ctx.moveTo(padding, height - padding)
ctx.lineTo(width - padding, height - padding)
ctx.moveTo(padding, padding)
ctx.lineTo(padding, height - padding)
ctx.strokeStyle = '#000'
ctx.lineWidth = 1
ctx.stroke()
// 绘制模型预测曲线
if (this.modelResults.length > 0) {
// 计算最大值用于缩放
let maxValue = 0
for (let i = 0; i < this.modelResults.length; i++) {
if (this.modelResults[i] > maxValue) {
maxValue = this.modelResults[i]
}
}
maxValue = maxValue || 1
// 绘制曲线
ctx.beginPath()
ctx.strokeStyle = '#2196F3'
ctx.lineWidth = 2
for (let t = 0; t < this.modelResults.length; t++) {
const x = padding + (t / (this.modelResults.length - 1)) * (width - 2 * padding)
const y = height - padding - (this.modelResults[t] / maxValue) * (height - 2 * padding)
if (t === 0) {
ctx.moveTo(x, y)
} else {
ctx.lineTo(x, y)
}
}
ctx.stroke()
// 绘制数据点
for (let t = 0; t < this.modelResults.length; t++) {
const x = padding + (t / (this.modelResults.length - 1)) * (width - 2 * padding)
const y = height - padding - (this.modelResults[t] / maxValue) * (height - 2 * padding)
ctx.beginPath()
ctx.arc(x, y, 3, 0, 2 * Math.PI)
ctx.fillStyle = '#2196F3'
ctx.fill()
ctx.strokeStyle = '#000'
ctx.stroke()
}
// 绘制标签
ctx.font = '12px Arial'
ctx.fillStyle = '#000'
ctx.fillText('时间', width / 2 - 10, height - padding + 20)
ctx.save()
ctx.translate(padding - 20, height / 2)
ctx.rotate(-Math.PI / 2)
ctx.fillText(this.getVerticalAxisLabel(), 0, 0)
ctx.restore()
// 绘制刻度
for (let i = 0; i <= 4; i++) {
const x = padding + (i / 4) * (width - 2 * padding)
ctx.beginPath()
ctx.moveTo(x, height - padding - 5)
ctx.lineTo(x, height - padding + 5)
ctx.stroke()
ctx.fillText((i * 5).toString(), x - 5, height - padding + 15)
}
for (let i = 0; i <= 4; i++) {
const y = height - padding - (i / 4) * (height - 2 * padding)
ctx.beginPath()
ctx.moveTo(padding - 5, y)
ctx.lineTo(padding + 5, y)
ctx.stroke()
ctx.fillText(((i / 4) * maxValue).toFixed(0), padding - 40, y + 4)
}
}
}
private getVerticalAxisLabel(): string {
switch (this.model) {
case 'population': return '人口数量'
case 'epidemic': return '感染人数'
case 'economic': return 'GDP'
default: return '值'
}
}
private getModelDescription(): string {
switch (this.model) {
case 'population':
return '人口增长模型:基于指数增长模型,考虑出生率和死亡率的影响。适用于预测人口变化趋势,帮助制定人口政策。'
case 'epidemic':
return '传染病模型:基于SIR模型的简化版本,考虑感染率和恢复率的影响。适用于预测传染病的传播趋势,制定防控策略。'
case 'economic':
return '经济增长模型:考虑经济增长率和投资率的影响。适用于预测经济发展趋势,制定经济政策。'
default:
return ''
}
}
}
更多推荐


所有评论(0)