关怀系统不该止步于关怀学生

千万不必去打听丧钟为谁而鸣;
丧钟为你而鸣。

约翰·堂恩

从其他同学那里得知学校要启用学生关怀系统了。我以前没有了解过什么是学生关怀系统,了解之后我发现这种关怀系统真是一个好东西,它太好了以至于不应该局限于校园,局限于学生,这种关怀系统如果推广到全社会将发挥更大的作用。

学生关怀系统的主要功能有:异常学生提醒、消费情况查看、行为轨迹追踪、上网信息监控、成绩变化波动提醒、用餐出勤归宿情况计算、相似轨迹同行者推荐。根据介绍,异常学生提醒能够分析学生的消费、行为轨迹、成绩波动数据,计算出消费异常、疑似不在校、成绩波动大等等异常情况。消费情况查看功能可以分析学生的消费数据,精准发现贫困学生,通过数据解决贫困生认定困难或碍于自尊不愿主动申请困难认定的问题。行为轨迹追踪可以通过学生网络接入情况分析学生的活动热区,发现学生的动向,防止学生失联。上网信息监控也是根据学生的网络接入情况工作,它能找到网络成瘾的问题学生,它还能对学生在网络上浏览的信息和发布的言论进行敏感监控来及早发现问题学生。成绩变化波动提醒支持查看学生每个学年学期的成绩和排名波动情况,对波动较大的学生及时标注提醒。用餐出勤归宿情况计算可以通过对数据进行综合分析得到学生的用餐、出勤、归宿情况,用数据说话。相似轨迹同行者推荐结合学生的活动范围和时间区间来寻找与某个学生轨迹相似、行为相近的人,进一步了解学生。

学生关怀系统正常工作的一个条件就是有数据供其进行分析,这一条件在大多数学校都已经得到满足。以我所在的学校为例,可以提供给学生关怀系统的数据就包括:校园网使用情况、教务系统成绩数据、校园一卡通使用情况、各处的人脸识别门禁数据。至于遍布四处的校园视频监控探头,我认为我所在的学校还不具备对其信息进行大规模分析处理的能力,但不排除其被使用的可能。

为什么我说关怀系统不该止步于关怀学生?这有两个方面的原因。一方面,关怀系统作为一种数据分析工具能通过已经搜集的数据发现更多信息,为管理者更详尽的内容来帮助管理被管理者。在校园里它只能用来管理学生,最多只是让学校朝着更好的方向发展,有些委屈它的才能了。如果推广到社会,它将在脱贫、反腐、疫情防控、犯罪预防、经济管理、舆情监控等多个领域发挥更大的作用,让社会朝着更好的方向发展。另一方面,现在的社会已经具备这种关怀系统工作所需的最基本的客观条件,即数据。银行卡的数据可以充当校园一卡通的数据,运营商基站接入数据可以充当校园网使用情况数据,信用分、所得收入、社会贡献等数据可以充当教务系统的成绩数据,手机定位数据可以充当校园里各处的人脸识别门禁数据。可以看到,我们的社会已经有足够的数据支撑这样一个关怀系统的正常工作,它能为管理者带来的好处也是显而易见的,所以我说关怀系统不该止步于关怀学生,它完全可以发挥更大的作用。

根据软件公司的介绍,2016年9月西安交通大学就已经试用了学生关怀系统,而中山大学从2017年3月开始使用学生关怀系统。现在是2022年9月,我的学校才跟上名校的步伐,这种好东西应该更早引入我们的校园。现在是2022年9月,我看社会上还没有大规模使用这种关怀系统,这种好东西应该更快推广到我们的社会。

提升公开讲话自信的三个技巧

“自”信

在进行其他训练之前,每个人都能做到的最简单的事情就是“自”信。

当出现小失误的时候,不要一直“抱歉”、“对不起”说个不停。当感觉大家都没有跟上思维时,不要说“可能大家都没听懂我在说什么”。自己发现问题后,自己把问题解决就好。出现失误,更正即可;表述不清,换种方式重新说清即可。

无论是接连不断的道歉还是反复强调自己没有让大家听懂,都不会帮助你解决问题,更不会帮助你的听众,反而会让你更加紧张或者自我否定,所以在公开讲话时不要这样做,要“自”信。

听众并非时刻注意你的一举一动

当进行公开讲话时,你可能以为听众都会把100%的注意力投入到你身上,以为听众会注意到你说的每一个字,以为听众会注意到你做的每一个动作。事实是,听众更可能会在自己的头脑里构建自己的理解,而忽略了你演讲的细节。

很多对你而言非常明显的细节,对听众而言,甚至会被全部忽略。这也是人们会反复强调重点的原因——为了不让听众错过重点——听众总是在忽略信息。知道了这一点,下次公开讲话时你会更加自信。

训练克服恐惧

正常情况下,每个人从小到大都在讲话,经过这么多年的练习,一个人的语言能力已经足以支撑其自如地讲话。每个人都至少能和某个人自然舒适地讲话,这个人可能是家人、朋友或伴侣,甚至可以是自己。

在公开讲话时不自信,更多的情况是思想没有跟上能力,具体一点就是不相信自己能在压力之下把话讲好。这种压力往往来自于对尴尬的恐惧。让自己多尴尬几次是一种解决办法。

可以这样训练:在一个安全的环境里——比如找上一些志同道合的朋友,大家都是一起进行训练的,所以并不会真的产生实质性损失——让自己处于各种可能出现的尴尬场景之中。可以让“听众”问你一些尖锐的问题;可以让“听众”“强迫”你把话讲明白,把句子说完整;还可以让“听众”在你讲话时打断你,使你不得不在讲话正中间冷场很长一段时间。总之,让“听众”想方设法使你尴尬难堪。多次进行这种训练,日积月累你会发现自己能处理好各种情况,在压力之下也能自信从容地完成自己的公开讲话。

Python PuLP 简单求解线性规划问题

一般步骤

  1. 导入 PuLP
  2. 使用 LpProblem 定义问题(名称、类型)
  3. 使用 LpVariable 定义变量(名称、下限、上限、类型)
  4. 添加目标表达式
  5. 添加约束条件
  6. 求解
  7. 输出结果

简单实例

问题

要用最低成本生产一种猫粮,同时使这种猫粮的营养成分满足一定的要求。生产者希望通过改变每种原料的添加量来实现这一目标。

每份猫粮为100克,其营养成分要求为:蛋白质不少于8克,脂肪不少于6克,纤维不多于2克,盐不多于0.4克。

猫粮的主要原料和其每克成本为:鸡肉($0.013)、牛肉($0.008)、羊肉($0.010)、大米($0.002)、小麦($0.005)、凝胶($0.001)。

每克原料对最终猫粮的营养贡献如下表所示:

原料蛋白质脂肪纤维
鸡肉0.1000.0800.0010.002
牛肉0.2000.1000.0050.005
羊肉0.1500.1100.0030.007
大米0.0000.0100.1000.002
小麦0.0400.0100.1500.008
凝胶0.0000.0000.0000.000
每克原料对最终猫粮的营养贡献,以克为单位。

求成本最低的原料添加量方案。

简化版问题

先考虑简化后的问题,假设只有鸡肉和牛肉两种原料。原料的添加量不能为负值。

简化版问题求解

导入 PuLP

from pulp import *

使用 LpProblem 定义问题

prob = LpProblem("The Cat Food Problem", LpMinimize)

LpProblem 第一个参数为问题的名称,可自定义。第二个参数为问题类型,可在 LpMinimizeLpMaximize 中选择。本题求成本最小值。

使用 LpVariable 定义变量

x1 = LpVariable("ChickenPercent", 0, None, LpContinuous)
x2 = LpVariable("BeefPercent", 0)

LpVariable 第一个参数为变量的名称,可自定义。第二个参数为变量的下限,本题为 0。第三个参数为变量的上限,None 在上下限处表示正无穷或负无穷。第四个参数为变量的类型,可选的值有 LpContinuous, LpIntegerLpBinary,意思即为字面意思,默认为 LpContinuous

添加目标表达式

prob += 0.013 * x1 + 0.008 * x2, "Cost per can"

"Cost per can" 为标识符,可自定义也可省略。注意使用 += 而不是 =

添加约束条件

prob += x1 + x2 == 100, "PercentSum"
prob += 0.100 * x1 + 0.200 * x2 >= 8.0, "Protein"
prob += 0.080 * x1 + 0.100 * x2 >= 6.0, "Fat"
prob += 0.001 * x1 + 0.005 * x2 <= 2.0, "Fibre"
prob += 0.002 * x1 + 0.005 * x2 <= 0.4, "Salt"

同样,引号中的内容为标识符,可自定义也可直接省略整个引号。注意使用 += 而不是 =

求解

prob.solve()

使用默认求解器进行求解。

输出结果

print("Status:", LpStatus[prob.status])
for v in prob.variables():
    print(v.name, "=", v.varValue)
print("Cost per can = ", value(prob.objective))

prob.status 是求解的状态,为整数型,有 LpStatusOptimal LpStatusNotSolved, LpStatusInfeasible, LpStatusUnboundedLpStatusUndefined 这四种返回,意思即为字面意思。该值是整数型,可以通过 LpStatus[prob.status] 来获取字符串类型的状态。

prob.objective 是求解后目标表达式的值,在本题中即为所求的最低成本。

完整问题求解

求解的基本步骤是一样的,不过在使用 LpVariable 定义变量、添加目标表达式和添加约束条件时可以使用一些方法来减少需要编写的代码。

导入 PuLP

from pulp import *

定义问题中的数据

Ingredients = ["CHICKEN", "BEEF", "MUTTON", "RICE", "WHEAT", "GEL"]

costs = {
    "CHICKEN": 0.013,
    "BEEF": 0.008,
    "MUTTON": 0.010,
    "RICE": 0.002,
    "WHEAT": 0.005,
    "GEL": 0.001,
}

proteinPercent = {
    "CHICKEN": 0.100,
    "BEEF": 0.200,
    "MUTTON": 0.150,
    "RICE": 0.000,
    "WHEAT": 0.040,
    "GEL": 0.000,
}

fatPercent = {
    "CHICKEN": 0.080,
    "BEEF": 0.100,
    "MUTTON": 0.110,
    "RICE": 0.010,
    "WHEAT": 0.010,
    "GEL": 0.000,
}

fibrePercent = {
    "CHICKEN": 0.001,
    "BEEF": 0.005,
    "MUTTON": 0.003,
    "RICE": 0.100,
    "WHEAT": 0.150,
    "GEL": 0.000,
}

saltPercent = {
    "CHICKEN": 0.002,
    "BEEF": 0.005,
    "MUTTON": 0.007,
    "RICE": 0.002,
    "WHEAT": 0.008,
    "GEL": 0.000,
}

为了简化后续所需编写的代码,在此把问题中需要使用的数据先进行定义。

使用 LpProblem 定义问题

prob = LpProblem("The Cat Food Problem", LpMinimize)

使用 LpVariable 定义变量

ingredient_vars = LpVariable.dicts("Ingredients", Ingredients, 0)

在这里我们直接使用先前定义的 Ingredients 列表来定义变量。

添加目标表达式

prob += (
    lpSum([costs[i] * ingredient_vars[i] for i in Ingredients]),
    "Cost per can",
)

同样,在这里我们直接使用先前定义的 costs, ingredient_vars, Ingredients 来定义变量。

其中,lpSum 会把其参数列表的各项相加。

添加约束条件

prob += lpSum([ingredient_vars[i] for i in Ingredients]) == 100, "PercentSum"
prob += (
    lpSum([proteinPercent[i] * ingredient_vars[i] for i in Ingredients]) >= 8.0,
    "Protein",
)
prob += (
    lpSum([fatPercent[i] * ingredient_vars[i] for i in Ingredients]) >= 6.0,
    "Fat",
)
prob += (
    lpSum([fibrePercent[i] * ingredient_vars[i] for i in Ingredients]) <= 2.0,
    "Fibre",
)
prob += (
    lpSum([saltPercent[i] * ingredient_vars[i] for i in Ingredients]) <= 0.4,
    "Salt",
)

同上,使用预先定义的数据来简化代码。

求解

prob.solve()

输出结果

print("Status:", LpStatus[prob.status])
for v in prob.variables():
    print(v.name, "=", v.varValue)
print("Cost per can = ", value(prob.objective))

参考资料

Optimization with PuLP(外部链接)