计算一次比较两个事物的比较等级



当输入数据如下时,如何计算表达一个人相对偏好的10件事的权重:

10件事的列表是随机成对呈现的(忽略顺序,所以可能会显示A对B,或者B对A,但不是两者都显示;并且不是一个项目本身);

A is better than B
D is better than F
H is better than B
C is better than J

等等。

有没有办法从这样的数据中对10个项目进行排名或加权?有没有办法将序列从10缩短!/(2!(10-2)!)=45个问题。

你在这里做了一个危险的心理假设:你假设"好于"关系是可传递的,所以从

A > B
B > C

直接跟随

A > C

也就是说,在不失普遍性的情况下,人类的偏好并非如此。因此,这让你的整个方法受到质疑。

然而,如果你能证明这个假设是正确的,这就归结为排序问题。有很多排序算法,它们只依赖于排序关系">"的存在。你的体重就是排序列表中的位置。

每一种现实世界的编程语言都可能有一个库,其中至少包含一种分类器算法;大多数语言都有一种方法来指定调用哪个函数来比较两个元素,所以这实际上可以归结为使用未排序列表调用排序器函数,以及在比较两个东西时要调用的函数。

如果不能假设"优于"关系是可传递的,事情就会变得复杂得多。基本上,你可以构建一个有向图,并试图找到通过它的路径,但该图可能不是无循环的,并且可能没有确定的可能性来分配任何权重。

关于如何测试这些东西,有几十年的心理学方法研究;我建议找一所提供心理学课程的大学,并询问那里的人。

为了使用这样的规则对数据进行排序,关系"better"必须是传递性

因此可能显示A与B,或B与A,但不能同时显示

这是朝着正确方向迈出的一步,但这不是完全可传递的。你仍然可以这样做:

A is better than B
B is better than C
C is better than A

现在你有了一个循环,所以上面的三条规则不能用来对物品进行排名。

当没有周期时,您可以使订单符合规则。但是,排序不一定是唯一的。例如,如果你的规则看起来像这个

A is better than B
C is better than B

并且您需要订购{A,B,C}"ACB"one_answers"CAB"都符合您的规则。

如果您正在寻找基于规则的任何一致排序,您可以首先构建一个由"X优于Y"规则诱导的树,然后使用该树来决定您的十个项目的相对排序。

TL;DR: 将列表中的每个元素与其他元素进行比较,并为获胜的选项指定权重或值。然后根据每个元素的"数量"对每个元素进行排序;获胜";它实现了

这些确实是很好的有效回应,指出了需要提出的限制,但它们没有提供解决方案。我提供一个。。。

在进行相对比较时,在本例中,根据主观偏好进行排名,毫无疑问,会缺乏一致性,从而破坏传递性的完整性。但是,你可以克服这一点。怎样好吧,使用问题中的建议:权重。

将列表中的每个元素与其他元素进行比较,并为获胜的选项指定权重或值。然后根据每个元素的"数量"对每个元素进行排序;获胜";它实现了。

每一场胜利都不必有相同的分量。例如,如果一个元素击败了排名很高或排名最靠前的元素,它就会获得额外的分数或其他什么。Idk,疯了!

所以,这不是一个科学明确的排名系统(如果没有客观的衡量,你永远不会得到),但我认为用这种方法,你可以非常接近。

我写了一个简单的java命令行程序来比较水果。下面是我的解决方案;足够好";因为我在寻找什么。我希望其他人能够发现这有帮助。

package com.example;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;
import com.google.common.collect.Lists;
import lombok.Getter;
import lombok.Setter;
public class ComparativeRanking {
public static void main(String[] args) throws Exception {
ComparativeRanking instance = new ComparativeRanking();
final List<Fruit> fruits = Lists.newArrayList(
new Fruit("banana"),
new Fruit("apple"),
new Fruit("kiwi"),
new Fruit("strawberry"),
new Fruit("mango"));
Fruit[] fruitArray = fruits.toArray(new Fruit[0]);
instance.compute(fruitArray);
}
void compute(Fruit[] fruitArray) throws Exception {
for (int i = 0; i < fruitArray.length; i++) {
for (int k = i + 1; k < fruitArray.length; k++) {
Fruit choice1 = fruitArray[i];
Fruit choice2 = fruitArray[k];
System.out.println(String.format("Enter '1' for %s and '2' for %s", choice1.name, choice2.name));
Scanner scanner = new Scanner(System.in);
int selection = scanner.nextInt();
switch (selection) {
case 1:
choice1.addWin();
break;
case 2:
choice2.addWin();
break;
default:
throw new Exception("Hey idiot, pick 1 or 2.");
}
}
}
List<Fruit> fruitsRankedByWins = Lists.newArrayList(fruitArray)
.stream()
.sorted(Comparator.comparing(Fruit::getWins).reversed())
.collect(Collectors.toList());
System.out.println("Result:");
for (Fruit fruit : fruitsRankedByWins) {
System.out.println(String.format("Fruit: %s | Wins: %s", fruit.getName(), fruit.getWins()));
}
}
@Getter
@Setter
static class Fruit {
String name;
int wins;
public Fruit(String name) {this.name = name;}
void addWin() {
wins++;
}
}
}

最新更新