Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

作业计分算法改造 #17

Open
r2099c2 opened this issue Nov 20, 2017 · 0 comments
Open

作业计分算法改造 #17

r2099c2 opened this issue Nov 20, 2017 · 0 comments

Comments

@r2099c2
Copy link

r2099c2 commented Nov 20, 2017

1.我们重新定义下名字:

prop 任务难度 
level 玩家等级
grade 评级
extraPoint 文章
coefficient 系数
Score 最终得分

2.旧的算法

score = prop * grade * coefficient * extraPoint / level
这里 coefficient = 100 / 3

这样的意义是: 玩家做相同等级的任务拿到3分不计算附加分的情况下就是100分
eg: 2 * 3 * 100 / (3 * 2 ) = 100

有哪些不好的点?

  1. 附加分过于重要,附加分的乘法规则使得系数的影响翻倍。

  2. 用户等级、任务难度所占比重过高、系数固定,倍数放大过于明显。
    1级玩家做1级题目拿到4分 == 2级玩家做2级题目拿到4分 没问题
    2级玩家做2级题目拿到4分 <<< 1级玩家做2级题目拿到4分
    其他不变的情况是只是1个任务等级差分数在combo的加持下差距变成266 << 533差距变化过大
    相同得分的情况下用户等级的变化或者任务难度的变化都会造成得分翻倍的变化

  3. 分数不应该是线性
    完成任务就是3分 所以3分是一个很容易拿到的分值
    3到4应该有小的加成;
    4到5分应该有一个大的加成;
    大概这样的图
    image

  4. 不同等级的玩家 获得同样的评分时 同样的任务难度变化造成的分数变化差距过大
    举例:同样的3级评分 1级玩家任务难度1是100分 2是200分 2级玩家难度2是100分但是3是150分
    也就是每次增长只有1级玩家的一半。
    同理 不同的任务难度下同样评分时玩家等级变化造成的分数变化差距过大
    这个就不举例了 和上面一样

3.思路:

分析过程:
首先源头在于144+combo = 1066分 但是 444+combo = 266分 差距太大
所以目的在于缩短这个差距 但是后面发现 4级玩家正常答题就是4分了 所以得分低是应该的
那么这个差距是不是可以缩小呢?
还是有必要缩小下的但是不能影响排名

我们属性一共有3个值 prop level grade
现在prop 和 level 都是线性的 一个个单独分析下
对于prop:是不是应该是线性的呢?
我们使用初中实验知识单一变量原则分析:假如grade和level都不变的情况下prop是不是应该线性增加
答案是可以是也可以不是 这个要看作业怎么出的 1-2 2-3 3-4 的差距是不是相同的?
现在的这几次的题目来看差不多是,举例:
同样是完成任务也就是3分:1-2的难度增长和2-3难度增长是差不多的
但是!这里有很大的不确定性因为可能对于一个玩家来说可能他的弱点刚好在于1星的某个题目而4星的那个题目他可以信手拈来。所以这其中还是有很大的随机性。
所以prop可以是线性 这个完全在于出题人和答题人的技能树的点法

举个例子:以藏马为例 他是服务端转前端的所以对他而言可能很多1星的前端题目难度是大于3星的某个服务端的题目的

对于level呢:是不是也是线性的呢
同样的单一变量分析:假如prop和grade都不变 level是不是应该线性的呢
举例:4级任务同样得4分 玩家等级越高越简单所以是个下降的图
(找不到图了就是 \ 这样)
那么1-2级玩家的下降高度是不是等于3-4级玩家呢?不是的
4级玩家答题出来就是4星了 所以这个曲线会是比线性更急促的下降方式就是是得分应该更低差距要大于1-2的得分差
所以这里对于4级玩家还要有一个降分的过程。

所以呢 综上2条得出一个蛋疼的结论就是 实际上144(也就是 1级玩家 4级任务 获得4评级)与 444的得分差距确实要大
但是和其他等级玩家差距不应该这么大 同时总体分值也太大了

所以最终的结论是什么呢?

1.combo改为extraPoint 改为加固定值。那么应该加多少呢?这个就要看他的重要性了
我感觉重要性是没问题的但是由于做作业的过程中一定会或多或少写点东西出来,所以乘法有点多了。
他的加分应该在一个和基础分差不多的分值我们最后再定。

2.我们现在动辄700 800 重新计算下分值 缩小下增长系数
首先我们基准分定义的是100分 意思是x等级的玩家做x等级任务拿到3分时的分数
那么上面也分析了分数的增长应该是什么样的呢?
prop的增长和level的增长应该是一样的
具体就是:等级1的玩家1级任务得3分 简写113
那么应该是
score(123) === score(233)

以1星为例

prop level grade score
1 1 3 100
2 1 3 120
3 1 3 140
4 1 3 160
prop level grade score
4 4 3 100
4 3 3 80
4 2 3 60
4 1 3 40

其他等级的推算过程差不多
也就是每个任务差距和每个等级差距都是一样的得分
1级玩家做2级任务和2级玩家做3级任务同样的评分时应该是同样的分数而不是像现在这样差距这么大
假设grade是3不变那么分数就是
100 + (prop - level) * 20 + extraPoint = score
这里为什么是20呢?100基础分的话 10分的差值不够大 20 * 4 = 80 差距接近基础分了而且也比25容易计算

3.最后来确定grade的问题
首先grade肯定不是加法 因为3分是完成任务分,但是1 2 就是完全没完成任务或者跑题了
4分需要大量的时间和精力 5分更是
所以应该是以一个系数的乘法方式计算
100 * (grade / 3)?
No
这样没有4分和5分的加成,而且另一个重点在于4级的玩家很容易得到4分!所以4级玩家的基准值并不是443而是444

所以首先这里变成的分段函数

if (level === 4) {
  return 120 * (grade / 4); 
}
return 120 * (grade / 3);
为了好计算取个公倍数 把基础分100改为120

那么5分的加成怎么算呢
定一个基准值
4级玩家代表着专家级,那么他们的答案4分是正常水平,但是拿五分还是需要做很多的工作或者耗很多的精力的
所以4 4 5这样的分数应该不至于过低
那么横向对比下 应该和什么难度相当呢?
最终觉得应该略大于1级玩家3级任务拿到4的分数
134 约等于 445
134 = 120 * 1 + (4 - 1)* 20 + extraPoint = 180 + extraPoint = score(445)
简单的一元一次方程170 & x > 180
那么这里的&用乘法?这个是我最初的想法 但是后来发现属性压缩到这个份上其实5分额外给个20的加分是最简单暴力又有效的
所以最终的结果就是

k() + m() + (prop - level) * 20 + extraPoint = score
k = () => 120 * grade / (level == 4 ? 4 : 3)
m = () => grade === 5 ? 20 : 0

剩下的附加分应该是多少呢
这个就比较随意了 他并不影响最终的排名
个人认为基础分的一半比较合适也就是 60

验算:

var list = [];
var level = [1 ,2 ,3, 4];
var prop = [1, 2, 3, 4];
var grade = [1, 2, 3, 4, 5];
var extraPoint = [0, 60];

level.forEach(function(le) {
  prop.forEach(function(p) {
    grade.forEach(function(gra) {
      var k = () => 120 * gra / (le == 4 ? 4 : 3);
      var score = k() + (p - le) * 20;
      if (!list[le]) {
        list[le] = [];
      }
      if (!list[le][p]) {
        list[le][p] = [];
      }
      if (gra === 5) {
        score = score + 20;
      }
      list[le][p].push(score);
      console.log(score);
    })
  })
})
console.log(list);

结果是:(不含附加分)
![image](https://user-images.githubusercontent.com/4426450/33022232-714e5e4a-ce3f-11e7-9165-bb85a0a55d87.png)

加上附加分60之后

var list = [];
var level = [1 ,2 ,3, 4];
var prop = [1, 2, 3, 4];
var grade = [1, 2, 3, 4, 5];
var extraPoint = [0, 60];
var basePoint = 120;
var coefficient = 20;
var fiveStar = 20;

level.forEach(function(le) {
  prop.forEach(function(p) {
    grade.forEach(function(gra) {
      extraPoint.forEach(function(ext) {
        var k = () => basePoint * gra / (le == 4 ? 4 : 3);
        var score = k() + (p - le) * coefficient + ext;
        if (!list[le]) {
          list[le] = [];
        }
        if (!list[le][p]) {
          list[le][p] = [];
        }
        if (gra === 5) {
          score = score + fiveStar;
        }
        list[le][p].push(score);
      })
    })
  })
})
console.log(list);
![image](https://user-images.githubusercontent.com/4426450/33022260-85cf3ab0-ce3f-11e7-9074-07f53baf4d89.png)

大家可以选几个点来试验下 个人觉得还是解决了最初的那4个问题
另外的一个好处是任务最重要的一点是学到新的东西所以任务深度应该是更重要的 现在这个算法下能把一个同级任务做到5分基本就第一了(4级玩家除外 因为他们起点是4分我们是3分)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant