2014-09-12 84 views
-2

我必须根据它们的重量比调用方法。按比例运行方法

id  methodname  weight 
1   method1   10 
1   method2   20 
1   method3   20 

这些id将循环在for中。 方法的重量比是10:20:20 每当我们遇到id为1- 所以方法1必须运行20%的时间,方法2 40%的时间和方法3 40%的时间。

无论何时调用id,都必须保持此比例。 需要使用数据结构来做到这一点。请帮助!

+6

如果你想这样做,你几乎肯定会做错事。你试图解决的实际问题是什么? – 2014-09-12 14:21:54

+0

[Thread#setPriority](http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#setPriority(int))是否足够?否则,它听起来像你需要你自己的调度。 – 2014-09-12 14:24:35

+0

这是我试图解决的确切问题。我可以使用的唯一存储是属性文件。 – Learner 2014-09-12 14:25:00

回答

1

我会使用一个列表的Runnable,并挑选随机从列表中有一定比例的偏见:

static int method1Calls = 0; 
static int method2Calls = 0; 
static int method3Calls = 0; 

static final void method1() { 
    System.out.println("method1"); 
    method1Calls += 1; 
} 

static final void method2() { 
    System.out.println("method2"); 
    method2Calls += 1; 
} 

static final void method3() { 
    System.out.println("method3"); 
    method3Calls += 1; 
} 

Runnable call1 = new Runnable() { 

    @Override 
    public void run() { 
     method1(); 
    } 

}; 

Runnable call2 = new Runnable() { 

    @Override 
    public void run() { 
     method2(); 
    } 

}; 

Runnable call3 = new Runnable() { 

    @Override 
    public void run() { 
     method3(); 
    } 

}; 

public void test() { 
    // Put the three objects in a list. 
    List<Runnable> methods = Arrays.asList(call1, call2, call3); 
    // Call them in proportion. 
    int[] proportion = {0, 1, 1, 2, 2}; 
    Random r = new Random(); 
    for (int i = 0; i < 100; i++) { 
     // Pick one. 
     int n = r.nextInt(proportion.length); 
     // Run it. 
     methods.get(proportion[n]).run(); 
    } 
    System.out.println("method1 called " + method1Calls + " times."); 
    System.out.println("method2 called " + method2Calls + " times."); 
    System.out.println("method3 called " + method3Calls + " times."); 
} 

打印结尾:

method1 called 26 times. 
method2 called 40 times. 
method3 called 34 times. 

要拨打电话的次数完全可预测但随机需要使用洗牌机制:

public void testShuffle() { 
    System.out.println("Using shuffle"); 
    // Put the three objects in a list. 
    List<Runnable> methods = new ArrayList<>(); 
    // Call them in proportion 
    Runnable[] runners = {call1, call2, call3}; 
    int[] proportion = {10, 20, 20}; 
    // Grow my list. 
    for (int i = 0; i < proportion.length; i++) { 
     for (int j = 0; j < proportion[i]; j++) { 
      methods.add(runners[i]); 
     } 
    } 
    // Shuffle it. 
    Collections.shuffle(methods); 
    // Call them. 
    for (Runnable r : methods) { 
     r.run(); 
    } 
    System.out.println("method1 called " + method1Calls + " times."); 
    System.out.println("method2 called " + method2Calls + " times."); 
    System.out.println("method3 called " + method3Calls + " times."); 
} 

This print:

method1 called 10 times. 
method2 called 20 times. 
method3 called 20 times. 
0

如果你想一套方法之间均匀分布的方法调用,然后有一个非常简单的方法:

Math.random 

为什么?因为它提供了保证,它将返回从统一分布范围[0, 1)中抽取的一个数字。这意味着随机中的任何数字都可能返回。

这当然是随机的,所以理论上0.0可以从现在开始直到时间结束 - 这就是随机性的本质。但是你提到了“百分比机会”,这正是这个。

因此,我们需要的范围内划分成5段,然后如果该号码是:

    在第一段呼叫 method1 在第二或第三区段呼叫 method2 在第四
  • 或第五区段呼叫method3

这相当于:

final double random = Math.random() 
if(random < 0.2) { 
    method1(); 
} else if (random < 0.6) { 
    method2(); 
} else { 
    method3(); 
} 
+0

它是一个很好的解决方案鲍里斯。无论如何要使它具有通用性,因为比例可以是1:10或10:10:10:10或15:5等随机数,并且对于一个id可以有多种方法。 – Learner 2014-09-12 14:42:47

+0

我会把这个作为练习留给@Learner。提示:在这个例子中,我是如何计算出数字的? – 2014-09-12 14:43:15

+0

在这个解决方案中,如果我循环id 10次,method1必须被调用2次,method2 4次,method3 4次。如果小于0.2的随机数出现3次,则方法1将被调用3次。这是nt可以接受的wt我正在尝试做。 – Learner 2014-09-12 14:47:38