Введение: Мы все знаем, что многие компании обычно проводят оценку эффективности в середине/конце года.В данном случае мы предполагаем, что оценки эффективности являются A, B, C и D от высокого к низкому. Затем, поскольку результаты служебной аттестации напрямую связаны с продвижением сотрудника по службе и повышением заработной платы, а также со стандартами премирования в конце года (например, в классе А выплачивается месячная заработная плата в марте; в классе В выплачивается месячная заработная плата за 2,5 месяца; в классе С выплачивается месячная заработная плата за февраль. ; класс D не имеет премий в конце года и рискует быть уволенным), поэтому руководители компании установили негласное правило для оценки эффективности и прямо и тайно разделили пропорцию каждого уровня производительности заранее (например: A 10 %; Б 20%; С 65%; Д 5%). Итак, теперь вопрос в том, что в проектной команде, за исключением очень немногих выдающихся сотрудников, ту же работу выполняют другие, и у них будет свое мнение о том, кто выше, а кто ниже. время, как вы должны выполнить работу?Может ли оценка максимально сбалансировать мнения руководителей и членов команды?
Да, раз выбрать не просто, то пишите код для реализации алгоритма взвешенного случайного выбора.Если повезет, то можно получить хорошую производительность, а если не повезет, то низкую производительность. Алгоритм открытый и прозрачный, производительность зависит от удачи, предположительно члены команды могут его принять, наверное (◔◡◔)
Реализация алгоритма
Прежде чем писать конкретный код, мы можем подумать о том, как реализовать этот взвешенный случайный выбор.
Возьмем приведенное выше введение в качестве примера: вероятность появления A составляет 10%, вероятность появления B составляет 20%, вероятность появления C составляет 65%, а вероятность появления D составляет 5%. Мы преобразуем это в прогрессивное значение вероятности, которое выглядит следующим образом:
Идея алгоритма прояснилась, а логику алгоритма написать легко.Ниже я приведу пример написанного мною алгоритма для справки.
import org.junit.Test;
import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.Random;
/**
* 带权重的随机选择
*
* @author zifangsky
* @date 2020/5/15
* @since 1.0.0
*/
public class Problem_004_Weight_Random {
/**
* 测试代码
*/
@Test
public void testMethods(){
Item[] items = new Item[]{new Item("A", 0.1),
new Item("B", 0.2),
new Item("C", 0.65),
new Item("D", 0.05),};
WeightRandom weightRandom = new WeightRandom(items);
for(int i = 0; i < 10; i++){
System.out.println(MessageFormat.format("员工{0}的绩效得分:{1}",
(i + 1),weightRandom.nextItem()));
}
}
/**
* 带权重的随机选择
*/
static class WeightRandom{
/**
* 选项数组
*/
private Item[] options;
/**
* 权重的临界值
*/
private BigDecimal[] criticalWeight;
private Random rnd;
public WeightRandom(Item[] options) {
if(options == null || options.length < 1){
throw new IllegalArgumentException("选项数组存在异常!");
}
this.options = options;
this.rnd = new Random();
//初始化
this.init();
}
/**
* 随机函数
*/
public String nextItem(){
double randomValue = this.rnd.nextDouble();
//查找随机值所在区间
int index = this.searchIndex(randomValue);
return this.options[index].getName();
}
/**
* 查找随机值所在区间
*/
private int searchIndex(double randomValue){
BigDecimal rndValue = new BigDecimal(randomValue);
int high = this.criticalWeight.length - 1;
int low = 0;
int median = (high + low) / 2;
BigDecimal medianValue = null;
while (median != low && median != high){
medianValue = this.criticalWeight[median];
if(rndValue.compareTo(medianValue) == 0){
return median;
}else if(rndValue.compareTo(medianValue) > 0){
low = median;
median = (high + low) / 2;
}else{
high = median;
median = (high + low) / 2;
}
}
return median;
}
/**
* 初始化
*/
private void init(){
//总权重
BigDecimal sumWeights = BigDecimal.ZERO;
//权重的临界值
this.criticalWeight = new BigDecimal[this.options.length + 1];
//1. 计算总权重
for(Item item : this.options){
sumWeights = sumWeights.add(new BigDecimal(item.getWeight()));
}
//2. 计算每个选项的临界值
BigDecimal tmpSum = BigDecimal.ZERO;
this.criticalWeight[0] = tmpSum;
for(int i = 0; i < this.options.length; i++){
tmpSum = tmpSum.add(new BigDecimal(this.options[i].getWeight()));
this.criticalWeight[i + 1] = tmpSum.divide(sumWeights, 2, BigDecimal.ROUND_HALF_UP);
}
}
}
/**
* 需要随机的item
*/
static class Item{
/**
* 名称
*/
private String name;
/**
* 权重
*/
private double weight;
public Item(String name, double weight) {
this.name = name;
this.weight = weight;
}
public String getName() {
return name;
}
public double getWeight() {
return weight;
}
}
}
Вывод примера кода выглядит следующим образом:
员工1的绩效得分:C
员工2的绩效得分:B
员工3的绩效得分:B
员工4的绩效得分:C
员工5的绩效得分:C
员工6的绩效得分:B
员工7的绩效得分:C
员工8的绩效得分:C
员工9的绩效得分:B
员工10的绩效得分:C