K12数学应用题批改步骤设计与实现

750 阅读4分钟

背景

从产品角度看,K12应用题批改是应用题求解的进一步功能拓展,正确批改建立在应用题正确求解的基础之上。 本文用于记录在实现求解后的应用题批改的设计与实现。

问题定义

批改范围定义

应用题求解输入存在两种情况:

  1. 应用相同的公式,即求解结果相同,但列式的顺序或组合不同
  2. 应用不同的公式求解,即求解结果相同,不同求解方法的的列式也不同

从实现的逻辑上看,情况2其实可由不同解法输入的情况1求解获得,因此解决情况1即可生成应用题的所有求解(批改标准)

关键问题

(1)如何通过最简求解算式集合判断学生不同形式、顺序的求解算式集合正确与否?
因为批改的最简求解算式集合是确定的,而学生求解的算式集合形式是不确定的,举例如下。

求解的最简集合为:
a. 合并算式(a + b)* (d + e)= g
b. 分解算式 a + b = c;d + e = f;c * f = g

而学生求解可能为:
a. 部分合并,顺序不同,如a+b=c;c * (d + e)= gd+e=f ;(a + b)* f = g
b. 四则运算法则应用不同,或数字的表示形式不同,如a是b的一半可表示为a = b * 0.5,也可以表示为a = b * 1/2
【注意】乘除变换待定,如 3 / 5 => 3 xx  1/5

(2)批改匹配算法设计:目前实现为方案设计(1)

设计与实现

已否定的方案

根据算式直接比较的方案(忽略算式上下文,即单纯比较算式):

  1. 应用最简式直接循环匹配用户输入式子,如
匹配序号最简求解式集合用户可能的输入算式
初始输入a + b = c;d + e = f;c * f = g(a + b)* (d + e) = g
1d + e = f;c * f = gc * (d + e) = g
2c * f = gc * f = g

无法处理得数相同,意义不同的算式冲突问题,【舍弃】。具体举例为:(1+2)/(1+2), 两个1+2的含义不同,应用的公式也不同。

2. 根据用户输入纯数学解题算式集合反推最简式集合

因用户输入算式无上下文,同样无法处理上文指出的问题。

方案设计

(1)根据生成最简式集合生成上下文相关的所有求解路径,暂定方案

节点(参数)与算式关系:
区分两种情况,左为已知一参数(h)的情况,右为两个参数都要求解而得的情况

image.png

生成算式路径集(对应上图) image.png

数据结构设计

image.png

算法实现

由上观察可得需要记录每个算式的参数的前继算式,通过参数变换即可求得所有的变换式(抽象为算法实际是回溯生成全路径问题)

// 根据求解式的生成逻辑,求解式集必然是拓扑顺序输出算式,所以可以直接for循环求解
_根据求解式集生成全批改路径(求解式集) {
  const 对象map = new Map()
  for (let 求解式 of 求解式集) {
      if (求解式的参数是通过另一求解式求得) {
          // 每种求解进行一次回溯
          for (let m of part) {
              // 合并求解变换方程(区分“生成算式路径集”的左右两种情况)
              let base = new Map()
              for (let [key, obj] of m.entries()) {
                  base.set(key, obj)
               }
              // 回溯替换 求解式的参数 求解
              dps(0, res, base, 求解式)
          }
          对象map.set(求解式.待求参数实例, res)
      } else {
          // 设置变换集
          对象map.set(求解式.待求参数实例, [对象变换map])
      }
  }
  // map转求解数组
  const 批改路径集 = 对象map.get(last).map(m => [...m].map(([key, val]) => val))
  return 批改路径集
}

(2)根据用户输入算式及题目上下文,反推所有算式的元素组成,即可根据用户输入算式反推 参数关系集,而后通过与解题得到的最简式集合比较判断
【注】上下文相关,即参数含有意义。如“1分钟“ 是某算式“时间 * 速度 = 路程” 的时间

存在问题

  1. 算法优化:
    a. 在生成算式时判断该表达式能否进行乘除变换、数字表示形式变换、四则运算法则变换
    b. 在生成可能的算式时生成全变换(效率很低)进行匹配
  2. 存在单位转换时,求解式子(表示形式)将完全不同,需要对单位换算进行判别和优化
  3. 合成算式时,存在计算优先级(乘除、加减),如何根据不同情况添加括号 并与用户输入进行比较?再生成运算树?