【问题标题】:Version control for medications药物版本控制
【发布时间】:2022-01-06 22:26:14
【问题描述】:

我需要一些算法方面的帮助。

我正在跟踪患者服用的药物。我最终会得到这样的条目:

1/1/22 DrugA 5mg Started DrugA
1/1/22 DrugB 5mg Started DrugB
1/3/22 DrugA 10mg Increased dosage of DrugA
1/5/22 DrugB 0mg Stopped taking DrugB

因此,我需要能够生成以下内容:

1/1/22 DrugA 5mg; DrugB 5mg
1/2/22 DrugA 5mg; DrugB 5mg
1/3/22 DrugA 10mg; DrugB 5mg
1/4/22 DrugA 10mg; DrugB 5mg
1/5/22 DrugA 10mg
1/6/22 DrugA 10mg

换句话说,从描述药物剂量变化的条目中,我需要能够准确地显示在任何一天服用了哪些药物和剂量。

这有点像源代码控制版本控制,您可以跟踪更改,但可以在任何时间点重现整个版本。

为了清楚起见,我会将这些信息存储在数据库或其他东西中。将其存储在内存中会更简单。

谁能建议一种可以处理这种情况的算法?我需要在 C# 中实现它。

【问题讨论】:

  • 这会吸引意见。这是我的:使用状态机。每个事件(药物治疗方案的变化)都会产生一个新的状态对象。状态对象在其被查询的每一天都回显当前状态下的药物。改变到一个新的状态,第二天就会有不同的反应。
  • 所以在开始时,State state = State.New(); state = state.Add(drugA); state = state.Add(drugB); 会在 22 年 1 月 1 日为您提供一个包含药物 A 和 B 的状态对象。在 22 年 1 月 3 日,state = state.ReplaceDrug(drugBWithHigherDosage); 或类似的东西。 22 年 1 月 5 日,state = state.RemoveDrug(drugB);
  • 这就是更好地将其比作银行帐户注册的地方。帐户中的当前金额始终是重放整个交易列表的结果,而不是某个缓存的金额(这是对此类家庭作业的常见批评)。因此,无论何时查询,都应该从更改事件中生成您想要的输出(第二个块)。这适用于您是否通过时间迭代来报告应该服用的药物,或者通过药物管理记录来说明在特定日期服用了什么。
  • 如果您需要知道服用了多少药物/应该服用多少药物,那么您将查询状态并汇总。它是正交的。
  • 我的建议是为患者加载所有数据,然后在内存中进行处理。这是一个非常直接的查询,它不受服用药物数量的影响。这听起来更像是您不确定如何将其实现为内存算法,我建议我们将持久性细节留到以后

标签: c# algorithm version-control versioning


【解决方案1】:

你只给了我们纯文本输入,所以我要组成一个类来表示数据。

public class Prescription
{
    public DateTime Date { get; set; }
    public long PatientNumber { get; set; }
    public string DrugName { get; set; }
    public decimal DrugAmount { get; set; }
    public string Notes { get; set; }
}

假设您有一个针对一位特定患者的这些记录的列表,并且您想要生成输出文本。为了建模,我们需要更多的类:

public class Administration
{
    public DateTime Date { get; set; }
    public List<Dosage> Dosages { get; set; }
}

public class Dosage
{
    public string DrugName { get; set; }
    public decimal DrugAmount { get; set; }
}

您的算法可能如下所示:

var prescriptions = GetPrescriptions(); // Load the list of prescriptions from the database
var administrations = new List<Administration>();
if (prescriptions.Count == 0)
    return administrations;

var start = prescriptions[0].Date;
var end = prescriptions[prescriptions.Count - 1].Date;

var date = start;
var dosages = new Dictionary<string, decimal>();
var index = 0;
while (date <= end)
{
    // Iterate through all the prescriptions that happened on this day, and update the dosage amounts
    while (index < prescription.Count)
    {
        var prescription = prescriptions[index];
        if (prescription.Date != date)
            break;

        if (prescription.DrugAmount == 0)
            dosages.Remove(prescription.DrugName);
        else
            dosages[prescription.DrugName] = prescription.DrugAmount;

        index++;
    }

    administrations.Add(new Administration
    {
        Date = date,
        Dosages = dosages.Select(pair => new Dosage
        {
            DrugName = pair.Key,
            DrugAmount = pair.Value,
        }).ToList(), 
    });

    date += TimeSpan.FromDays(1);
}

return administrations;

【讨论】:

  • 是的。我可以做这样的事情。如果您的剂量数据在您报告的开始日期之前开始,则需要进行额外的工作。但这可以使用钝力以相同的方式完成。猜猜我在寻找更聪明的东西。但这可以工作。
  • 避免暴力破解的最简单方法是每天进行计算,并保存结果。另一种方法是不那么频繁地保存完整状态,例如每月一次,或者每次所有有效处方都用完,然后暴力破解剩余的处方。但是,如果人们输入历史数据或必须更正现有条目,这两种方法都会遇到问题。我想说每位患者的处方数量总是足够低,您真的不需要担心蛮力方法的成本
【解决方案2】:

为了进一步参考,在高级视图中,可接受的解决方案可以看作是CQRS 模式与event sourcing 模式的组合。 链接中还有一些 C# 代码示例。

【讨论】:

    猜你喜欢
    • 2013-09-30
    • 1970-01-01
    • 2010-10-01
    • 2023-04-03
    • 1970-01-01
    • 2011-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多