【问题标题】:Programming structure style when writing probablistic algorithms编写概率算法时的编程结构风格
【发布时间】:2014-07-10 17:43:39
【问题描述】:

我有这种程序结构用于随机选择程序执行。 然而,这种风格不可扩展、不可维护且非常容易出错。如您所见,if 语句的条件越来越长且不可读

你能推荐一种更好的编程风格/结构吗?

double aProb = 0.4;

double bProb = 0.2;

double cProb = 0.2;

double dProb = 0.2;

double chance = random.nextDouble();

if ( chance < aProb ) {
    a();
}

if ( chance < bProb + aProb ) {
    b();
}

if ( chance < cProb + bProb + aProb ) {
    c();
}

if ( chance < dProb + cProb + bProb + aProb ) {
    d();
}

【问题讨论】:

  • 怎么样....数组!而且,如果你想过火,可能会加上前缀总和(可能是 fenwick 树)。
  • 一个小代码示例?
  • 通过逐步遍历概率数组来累积值。 currentProb += probs[i]。我没有更好的方法来附加函数,因为函数指针在 java 中并不存在。

标签: java design-patterns coding-style probability


【解决方案1】:

我认为很清楚。

如果你想要更短,

double chance = random.nextDouble();

if ((chance -= 0.4) < 0) {
    a();
} else if ((chance -= 0.2) < 0) {
    b();
} else if ((chance -= 0.2) < 0) {
    c();
} else {
    d();
}

(我假设你想要else if。)

【讨论】:

  • 好主意,简而言之,如果在中间添加另一个没问题
【解决方案2】:

您可以创建一个新变量来存储 aProb + bProb,因为它在除第一个语句之外的每个 if 语句中使用,这样会使其更短。

【讨论】:

    【解决方案3】:

    你可以创建类abstract class IntervalAction:

    public abstract class IntervalAction {
    
        private final double minBound;
        private final double maxBound;
    
        public IntervalAction(double minBound, double maxBound) {
            if (minBound < 0) throw new IllegalArgumentException("minBound >= 0");
            if (maxBound > 1) throw new IllegalArgumentException("maxBound <= 0");
            if (minBound > maxBound) throw new IllegalArgumentException("maxBound >= minBound");
    
            this.minBound = minBound;
            this.maxBound = maxBound;
        }
    
        public abstract void execute();
    
        @Override
        public String toString() {
            return "IntervalAction{" +
                    "minBound=" + minBound +
                    ", maxBound=" + maxBound +
                    '}';
        }
    }
    

    以及将具有所有可用操作的注册表类:

    public class ActionRegistry {
    
        public void register(IntervalAction action) {
            if (intersectsWithExistingRange(action))
                throw new IllegalArgumentException("Already have action in that range: " + action);
    
            // todo registration in internal data structure
        }
    
        private boolean intersectsWithExistingRange(IntervalAction action) {
            // todo
            return true;
        }
    
        public void execute(double input) {
            IntervalAction action = find(input);
            if (action == null) throw new IllegalArgumentException("No action found for " + input);
            action.execute();
        }
    
        private IntervalAction find(double input) {
            // todo
            return null;
        }
    }
    

    还有一个驱动类:

    public class ActionDriver {
        private final ActionRegistry registry;
        private final Random random;
    
    
        public ActionDriver() {
            random = new Random(System.currentTimeMillis());
    
            registry = new ActionRegistry();
            registry.register(new IntervalAction(0, 0.1) {
                @Override
                public void execute() {
                    System.out.println(this);
                }
            });
            registry.register(new IntervalAction(0.1, 0.2) {
                @Override
                public void execute() {
                    System.out.println(this);
                }
            });
            // so on
        }
    
    
        public void act() {
            registry.execute(random.nextDouble());
        }
    }
    

    现在,最有趣的部分是如何在ActionRegistry 中实现内部数据结构来保存(和搜索)您的操作——所有这些todos 都在上面的代码示例中。为此,我将向您推荐this SO 问题。

    【讨论】:

    • @PaulDraper 不要难过。使用 Java 有更简单的方法,例如 TreeSet&lt;Double&gt;,或者更好的是 TreeSet&lt;BigDecimal&gt;
    • @LuiggiMendoza 我认为Map 更适合这一点,因为在 OP 问题中间隔和动作之间存在联系。所以我链接的问题完全使用Map
    • @VictorSorokin 那么你应该投票结束这个问题作为重复......
    • @LuiggiMendoza 恕我直言,这不是重复的,因为这个问题是关于给定任务的“代码设计”的主要问题,而链接问题是关于实现细节的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-13
    • 1970-01-01
    • 2011-02-22
    • 2021-01-05
    • 1970-01-01
    相关资源
    最近更新 更多