【问题标题】:Time efficient implementation of generating probability tree and then sorting the results生成概率树然后对结果进行排序的高效实现
【发布时间】:2012-02-07 10:21:03
【问题描述】:

我有一些事件,其中每个事件都有发生的概率,如果发生的话,还有权重。我想用相应的权重创建事件概率的所有可能组合。最后,我需要按重量顺序对它们进行排序。这就像生成一个概率树,但我只关心生成的叶子,而不关心获取它们需要哪些节点。在创建最终结果的过程中,我不需要查找特定条目,只需创建所有值并按权重排序即可。

只有大约 5-15 个事件,但由于 n 个事件有 2^n 个结果可能性,而且这是经常进行的,我不希望它花费不必要的长时间。速度比使用的存储量重要得多。

我想出的解决方案可行,但速度很慢。有什么更快的解决方案或改进的想法吗?

   class ProbWeight {
        double prob;
        double eventWeight;

        public ProbWeight(double aProb, double aeventWeight) {
            prob = aProb;
            eventWeight = aeventWeight;
        }

        public ProbWeight(ProbWeight aCellProb) {
            prob = aCellProb.getProb();
            eventWeight = aCellProb.geteventWeight();
        }

        public double getProb(){
            return prob;
        }
        public double geteventWeight(){
            return eventWeight;
        }       

        public void doesHappen(ProbWeight aProb) {
            prob*=aProb.getProb();
            eventWeight += aProb.geteventWeight();                             
        }

        public void doesNotHappen(ProbWeight aProb) {
            prob*=(1-aProb.getProb());                         
        }

    }

    //Data generation for testing
    List<ProbWeight> dataList = new ArrayList<ProbWeight>();
    for (int i =0; i<5; i++){
        ProbWeight prob = new ProbWeight(Math.random(), 10*Math.random(), i);
        dataList.add(prob);
    }

    //The list where the results will end up
    List<ProbWeight> resultingProbList = new ArrayList<ProbWeight>();
    // a temporaty list to avoid modifying a list while looping through it
    List<ProbWeight> tempList = new ArrayList<ProbWeight>();

    resultingProbList.add(dataList.remove(0));
    for (ProbWeight data : dataList){ //for each event
        //go through the already created event combinations and create two new for each
        for(ProbWeight listed: resultingProbList){ 
            ProbWeight firstPossibility = new ProbWeight(listed);
            ProbWeight secondPossibility = new ProbWeight(listed);
            firstPossibility.doesHappen(data);
            secondPossibility.doesNotHappen(data);
            tempList.add(firstPossibility);
            tempList.add(secondPossibility);
        }
        resultingProbList = new ArrayList<ProbWeight>(tempList);
    }
    // Then sort the list by weight using sort and a comparator

【问题讨论】:

    标签: java algorithm probability execution-time


    【解决方案1】:

    选择合适的数据结构占 50%,算法占 50%。数据结构——我相信TreeBidiMap 会为你创造奇迹。您将需要实现 2 个比较器 - 1 个用于权重,另一个用于概率。 算法 - 微不足道。 祝你好运!

    【讨论】:

    • 谢谢,那我就专注于数据结构!但是,我对那个 TreeBidiMap 有点不确定。 “这会使 put 操作的成本增加一倍”是否意味着每次添加新节点时都需要两倍的时间?此外,我认为我不需要按概率查找节点,只需按权重对它们进行排序,然后它们会跳过所有节点以计算具有概率的东西。
    • @Siana,我认为考虑到您的数据大小(不重要)和您当前的实现,您不应该担心 put 操作的成本几乎翻倍——它会更有效率。如果您不需要双向映射,您可以使用简单的 TreeMap。
    • 谢谢,使用 TreeMap 算法现在快了大约 12 倍!
    【解决方案2】:

    尝试加快代码速度的一些技巧: - 尽量避免不必要的对象分配 - 尝试为您的集合使用正确的构造函数,在您的代码示例中,您似乎已经知道集合的大小,因此将其用作构造函数中的参数以防止无用的集合调整大小(和 gc 调用) 您可以尝试使用 Set 而不是 List 来查看动态排序.....

    HTH 杰罗姆

    【讨论】:

      猜你喜欢
      • 2021-08-27
      • 2022-11-25
      • 2015-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-11
      • 1970-01-01
      相关资源
      最近更新 更多