使用其他投票在JavaScript中进行即时径流投票

如何解决使用其他投票在JavaScript中进行即时径流投票

我试图在JavaScript中实现IRV,但是每5秒只能获得10对投票(仅用于开发测试),因此,每当有新的一对投票添加到数组时,将其添加到数组中是不切实际的客户。因此,我想知道在接收到数据时是否有任何方法可以处理这些数据,并与将要接收的新数据保持一致。

const candidates = ['candidate1','candidate2','candidate3'];

// I Will Receive more Votes after 5 secs (or any in prod) that will replace this
let Votes = [['candidate1','candidate3','candidate2'],['candidate2','candidate1','candidate3'] /* etc*/];

// I Want to calculate the winner at the time
// But after 5 secs the array won't have the prevIoUs Votes

我要问当时是否有任何计算IRV Winner的算法,知道几秒钟后以前的值都消失了,因此无法以正常方式进行计算。

我们有什么办法可以根据他们的位置给他们,可以增加他们的价格,但仍然可以赢得赢家?

这是我想出的,但是没有按预期运行。但这应该可以让您了解我的需求。

// The Base Votes (only one for the demo)
let Votes = [['candidate1','candidate2']];

// Stores the Ranks Per Candidate
let ranked = [0,0];

// Calculates the IRV
function irv() {
    Votes.forEach(Vote => {
        let points = Vote.length;

        Vote.forEach((candidate,i) => {
            ranked[i] += points;
            points--;
        });
    });
}

// Calculate the Winner at the time
irv();

// Add new Votes
Votes = [['candidate2','candidate3']];

// ReCalculate the Winner
irv();

// Show the Winner
console.log(ranked);

在IRV之后,应在候选1和候选2之间建立平局,此方法将候选1作为获胜者。您能帮我解决这个问题还是给我一个更好的算法来解决这个问题?

解决方法

这是一个IRV实现(可能过于简单):

const irv = (ballots) => {
  const candidates = [... new Set (ballots .flat())]
  const votes = Object .entries (ballots .reduce (
    (votes,[v]) => {votes [v] += 1; return votes},Object .assign (... candidates .map (c => ({[c]: 0})))
  ))
  const [topCand,topCount] = 
    votes .reduce (([n,m],[v,c]) => c > m ? [v,c] : [n,['?',-Infinity])
  const [bottomCand,bottomCount] = 
    votes .reduce (([n,c]) => c < m ? [v,Infinity])

  return topCount > ballots .length / 2 
    ? topCand
    : irv (ballots .map (ballot => ballot .filter (c => c != bottomCand)) .filter (b => b.length > 0))
}

const ballots = [
  ['A','C','B','E','D'],['B','D','A','F','G'],['C','H'],['A','G','H','F'],['G',['E','B'],['D',['F','C'],'E'],]

console .log (irv (ballots))

(请注意,根据我的评论,我不会尝试在两次调用之间保持任何特定状态。如果您需要累积选票,我建议您单独进行此操作,然后在这些选票到达时运行此功能。如果太贵了,那么可以根据到目前为止收到的选票按固定的时间表运行。)

我们的选票只是候选人选择的有序列表。最后,我们选择候选人B,方法是依次淘汰第一名得票最少的候选人,并将其余选票上的候选人再上移一位。

代码首先通过拉平选票列表并选择集合的所有唯一成员来收集候选人。然后,我们计算每个候选人的第一票。格式为[["A",4],["C",1],["B",3],["E",["D",["F",2],["G",["H",0]],这使得在接下来的两个步骤中,使用基于reduce的最小选择器和最大选择器,最容易找到顶部和底部候选人。

这里的算法很幼稚,只需选择具有该值的第一个即可打破平局,该值取决于投票顺序。完整的IRV系统将具有比这更好的机制。

然后,最后,如果排名靠前的候选人的总数超过总数的一半,我们将退还该候选人。如果没有,我们将从所有选票中删除最底层的候选人,然后使用其余候选人重新运行该功能。

此版本是递归的,因为它可以使代码更简洁。但请注意,除非您与成千上万的候选人竞争,否则递归深度不太可能成为问题,因为每个递归步骤都会减少候选人的数量。

演练

在第一轮中,我们进行了以下投票:

ACBED,BDAFG,CBD,BDEAH,ABGHF,GEBHD,ECDBG,AB,DG,FEC,FCGAE,BCGAE,ABFG

具有以下第一名的投票计数:

{A: 4,B: 3,C: 1,D: 1,E: 1,F: 2,G: 1,H: 0}

我们还没有多数表决。由于H的计数最低,因此我们将其从每次投票中删除:


ACBED,BDEAH,ABGHF,GEBHD,ABFG
ACBED,BDEA,ABGF,GEBD,ABFG

这些第一名的投票数:

{A: 4,G: 1}

我们随机选择首位计数最低的一个C,然后将其删除:

ABED,BD,EDBG,FE,FGAE,BGAE,ABFG
{A: 4,B: 4,G: 1}

然后我们删除E

ABD,BDA,GBD,DBG,F,FGA,BGA,D: 2,G: 1}

然后G

ABD,BDAF,ABF,DB,D,FA,BA,ABF
{A: 4,B: 5,F: 2}

还有D

AB,BAF,B,B: 6,F: 2}

然后是F

AB,A,AB
{A: 5,B: 6}

在这里,我们终于有了多数,然后返回B

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?