#reminder #blake3 #global #rdv

randevu

官方 RANDEVU 算法的 Rust 实现

4 个稳定版本

2.0.0 2024年5月14日
1.0.2 2024年2月20日
1.0.0 2024年2月18日

332算法 中排名

Download history 101/week @ 2024-05-13 29/week @ 2024-05-20 1/week @ 2024-06-10 5/week @ 2024-07-08

394 每月下载量

Unlicense OR MIT OR Apache-2.0

19KB
169

RANDEVU

用于任何事物的通用概率性每日提醒协调系统

  • 通用 - 同一个对象的提醒对每个人都是一样的
  • 概率性 - 提醒是通过基于2的幂的简单概率算法计算的
  • 每日 - 提醒遵循每日日程/间隔(UTC)
  • 日内 - 无限可选的日内提醒时间(RDVT - 在版本2.0中作为现有系统的扩展添加)
  • 通用 - 适用于任何事物,字面意义上的(在合理的地方,见用例)
  • FOSS - 公共领域(Unlicense 或 MIT 或 Apache-2.0)
  • 离线 - 无需互联网连接
  • 便携 - 简单的代码,易于移植到任何有 blake3 的地方
  • 确定性 - 对于任何对象和任何日期都易于计算和预测
  • 伪随机 - 提醒均匀地随机分布
  • 可调整 - 用户可以决定他们希望多久看到每个对象的提醒

https://github.com/TypicalHog/randevu(Rust - 参考实现)
https://github.com/TypicalHog/randevu-ts(TypeScript)   https://github.com/TypicalHog/randevu-py(Python)
上述实现可在 Crates.io、PyPI 和 npm 上作为 randevu 获得。
请随时贡献,创建其他(缺失)语言的实现,甚至为 1(或更多)我已经创建了存储库和 crate/module/package 的 3 种语言中的任何一种的替代实现。

示例用法

use chrono::Utc;
use randevu::{rdv, rdvt};

fn main() {
    let object = "THE_SIMPSONS";
    let date = Utc::now();
    let rdv_value = rdv(object, &date);
    let rdvt_value = rdvt(0, object, &date);

    println!("Object {} has RDV{} today with RDVT0 at {:?}", object, rdv_value, rdvt_value);
}


我知道 README.md 是一个令人困惑的单词丛林,随意的想法和想法。 (将会改进)   我不太擅长解释事情和以有组织的方式组织文本。为此我感到抱歉。 :/
我已经尽力了,并将继续努力在未来改进它。
整个文档可能将被彻底翻新。内容将解释得更好,无关紧要的事情,旁白,想法和漫谈将被移除等。
我还想为 RANDEVU 算法/系统编写一个正式的规范。
我在想创建一个常见问题解答部分/文档,其中我将解释系统的各个方面,以及我想要更详细地说明或澄清的其他任何内容。
我还在考虑添加一些视觉类比(信息图表),如抛硬币等,我认为这在使系统更容易解释和理解方面具有巨大的潜力。


关键概念

  • 对象 - 表示任何可以用字符字符串表示的事物(游戏、电影、人、歌曲、地点、视频、主题、单词、书籍、数字、品牌、帖子、事件、物品、网站、应用、引语、行为、运动或实际上任何其他事物) 
  • 日期 - 我们想要计算RDV的日期(UTC) 
  • RDV - 表示在特定日期某个对象提醒的级别/重要性/稀有度的正整数  

(版本2.0的新功能)  

  • RDVT - 一天中无限多个随机时刻之一(0-24小时UTC),此时对象有当天的提醒,允许无限精度  
  • 排名 - RDVT排名,从0(最重要)到无穷大 - RDVT0,RDVT1...  

RDV计算

RDV = in blake3::keyed_hash(key: DATE, data: OBJECT)   注意:前一个版本(1.0)使用不同的算法,因此两个版本之间的RDV值已经改变,并且完全不相关。通过实施这一变化,我消除了2/3的blake3哈希计算,并提高了性能(但这并不重要)。但现在我可以在我的电脑上每秒计算大约1000万个RDV值。
我有充分的理由相信未来的重大变化不会发生,并且这是算法的最终版本。尽管RANDEVU除了我自己和一个小型社区之外几乎没有被采用,但进行这样的基本算法更改仍然是时候了。

工作原理和潜在用例

想象一个系统,每天为每个对象分配一个特殊的数字(RDV)。分配给每个对象的数字对每个对象都不同,并且每天都会变化。这个数字有50%的概率是0,25%的概率是1,12.5%的概率是2,依此类推(每个数字的稀有度是前一个的两倍)。我一切都是基于二进制(最简单的数值基数,之后是一元),这使得一切都非常完美(当你更多地了解系统的工作原理时,你可能会看到原因)。
通过使每个提醒级别稀有度加倍,我们可以有效地实现几乎无限频率的提醒,以及每天的提醒,以及各种频率的提醒之间的良好范围。
如果一个对象有RDV4的提醒,这也意味着RDV3、RDV2、RDV1和RDV0。用户可以为每个对象设置一个阈值值,如果特定对象的RDV值大于或等于该阈值,则用户可以决定对该对象采取某种行动。例如,有人可能决定在特定的视频的RDV值(该特定视频的RDV值)达到他们期望的阈值时观看该视频。阈值允许用户决定他们希望多频繁地“被提醒”某个对象。0 -> 每天,1 -> 每两天(平均而言 - 是随机的),2 -> 4天,3 -> 8天,依此类推(允许几乎无限的提醒频率,尽管高于10的频率发生得相当少 - 2^10 = 1024天)。如果多个人使用此系统来提醒相同的事情,他们都会在同一天提醒他们,因此可以协调与相关对象相关的会议/行动。这可以允许“已死亡”游戏的粉丝(没有或几乎没有在线玩家的游戏)在每256天聚在一起玩一次。
人们可以在同一天重新观看他们喜欢的电影或视频,并与其他粉丝讨论。   这个系统可以应用于任何事物。   它可以用来为你的最喜欢的书籍、歌曲、艺术家、事件或(正如我之前所说的)任何事物指定特殊的欣赏/纪念日。   一个人可以有一长串他们关心的对象,并且永远不会忘记其中任何一个——因为最终他们会想起它们(例如——书签)。  

RDVT 计算 和 用例

RDVT 是 RANDEVU 系统新增加的(2.0 版本)功能,也是 RDV 算法的可选扩展。   我们像计算 RDV 一样计算哈希,除了我们在键内的日期后面附加一个 RANK 整数,用下划线分隔。   我们不计入前导零位。   相反,我们遍历哈希中的位,并将增量添加到 RDVT 时间(从午夜 00:00h 开始)。   对于每个 1,我们添加一个增量,如果位是 0,则不执行任何操作。
增量从 12h 开始,处理完每个位后将其除以二。
例如,如果前 4 位是 0110,这将导致时间为 09:00h(0 * 12h + 1 * 6h + 1 * 3h + 0 * 1.5h...)。
请注意,有 256 位,我们会一直这样做,直到达到 1 ns(或根据实现方式为毫秒/微秒)。
这意味着我们为每个 RANK 获取一个不同的均匀伪随机时间(0-24h)。   如果用户发现每天的 RDV 提醒太宽泛,并希望有更具体的时间提醒——他们可以计算一个或多个 RDVT 时间并选择一个。
由于 RDVT0 是最重要的/主要时间,用户应该选择对他们来说最低排名的 RDVT——这增加了其他人也可能选择与他们相同的 RDVT 时间的可能性,从而增加了互动的可能性。   假设某个 YouTube 视频今天有 RDV10。我们可以有一个浏览器扩展或网站,为该视频安排直播(如视频首映)在第一个 10 个 RDVT 时间(RDVT0-9)。
该视频的粉丝都可以在某个 RDVT 时间与别人一起现场观看,也许还可以在直播聊天中(如果该功能存在)一起讨论。
这只是我想出的一个超级具体的假设用例。


对象命名约定(非详尽示例)

对象是一个字符串(最好是 A-Z,0-9 的大写)。不允许有空格。   空格和任何其他字符应替换为单个下划线 ('_')。   此集合之外的字符只能用于外部标识符,这些标识符区分大小写或包含其他符号,例如,YOUTUBE 视频 ID。

XONOTIC (all letters should be uppercase)

STAR_WARS (spaces and dashes in multi-word objects should be replaced with _)

THE_MATRIX_1999 (movies should have a year of release at the end)

GRAND_THEFT_AUTO_5 (objects should be referenced by their full name, Roman
numerals should be replaced with Arabic ones)

ASAP_ROCKY ($ should be replaced with S, same for other similar instances)

C_PLUS_PLUS (++ should be replaced with _PLUS_PLUS)

C_SHARP (# should be replaced with _SHARP, in other contexts it could be _HASH
or omitted)

YEAR_2000 (years should have a YEAR_ prefix)

FRIDAY (weekdays and months should not be abbreviated, same as all other
objects)

2023-08-25 (dates should be in ISO 8601 format, YYYY-MM-DD)

NO_MANS_SKY (apostrophe in MAN'S should be dropped)

HARRY_POTTER_SMOKES_WEED_Cdfkq2Nmb3c (video ID should be appended to the video
title, double underscore is fine if the ID starts with one, IDs are allowed to
use dashes and lowercase letters)

GETTING_BANGED_BY_GREEN_BOOMERS_MINECRAFT_BETA_1_7_3_SOLO_SURVIVAL_NO_COMMENTARY_OJzsmWBQE3I
(brackets, quotation marks, colons, and other punctuation should be dropped,
periods in version numbers like 1.7.3 should be replaced with _)

NUMBER_69 (numbers should have a NUMBER_ prefix)

为什么有如此具体和严格的约定呢?

为了确保每个人在同一天对同一件事物获得相同的提醒。

由于算法的工作方式——两个对象之间的单个字符差异都会导致系统为每个对象生成完全不同的提醒。   例如:WEED,weed,Weed,和 W33D 都会被视为不同且独立的对象,具有完全无关的提醒。   可以将对象视为密码——相同的密码会让使用该密码的每个人都获得相同的提醒。   如果有人想要为特定对象从其他人那里获得完全不同的提醒,他们可以在它后面附加额外的字符。   然而,这并不是系统的重点。   整个目的是帮助人们在同一时间与其他人协调提醒事项。

依赖项

~2.5MB
~57K SLoC