Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 从牌堆中抽出一张牌,进行扑克的蒙特卡罗模拟_Objective C_Random_Montecarlo_Poker - Fatal编程技术网

Objective c 从牌堆中抽出一张牌,进行扑克的蒙特卡罗模拟

Objective c 从牌堆中抽出一张牌,进行扑克的蒙特卡罗模拟,objective-c,random,montecarlo,poker,Objective C,Random,Montecarlo,Poker,目前,我正在开发一个iOS应用程序,在这个应用程序中,我需要从卡片组中随机抽取卡片。目前,我的代码如下所示: - (PlayingCard*) drawRandomCard { PlayingCard * randomCard = nil; NSUInteger index = arc4random_uniform(self.cards.count); randomCard = self.cards[index]; //self.cards is an NSArray

目前,我正在开发一个iOS应用程序,在这个应用程序中,我需要从卡片组中随机抽取卡片。目前,我的代码如下所示:

- (PlayingCard*) drawRandomCard
{
    PlayingCard * randomCard = nil;

    NSUInteger index = arc4random_uniform(self.cards.count);
    randomCard = self.cards[index]; //self.cards is an NSArray of PlayingCard's
    while (randomCard.isUsed) {
        index = arc4random_uniform(self.cards.count);
        randomCard = self.cards[index];
    }
    randomCard.used = YES;
    return randomCard;
}
这种方法被调用了很多次(一次蒙特卡罗模拟调用了50'000-1'000'000次)
目前,整个事情是缓慢的,我真的需要优化它。 我有一些想法:

  • 快速随机数发生器
  • 将牌组(Objective-C类,包括一系列玩牌)和牌(Objective-C类)的整个高级表示形式更改为普通C数组和结构中的表示形式
  • 将牌组和牌的整个表示更改为按位级别,然后在下面执行所有操作
你觉得怎么样?
你还有其他想法吗?
你知道更适合(更快)的随机数发生器吗


提前谢谢

我假设您多次调用此方法从牌组中抽牌,将抽牌的
used
属性设置为
YES
,以便不再抽牌

您不必设置属性,只需将卡从卡组中取出,并将其放入
usedCards
数组中,就可以在
循环时为您保存可能永不结束的


另一种方法是先洗牌,然后从数组的开头或结尾抽牌。

保持一个指向最后抽牌的静态索引(最初设置为-1)。每次调用该方法时,将索引模向前推进
self.cards.count
,如果结果为零,则洗牌组。然后在索引处返回卡片。因为像Fisher Yates/Knuth这样一个像样的洗牌是θ(
self.cards.count
),但是在
self.cards.count
)中只调用一次,所以每次平局的结果是摊销固定时间。这应该避免由于识别已绘制的值和拒绝而产生的任何开销。如果您想避免在重新洗牌之前处理整个牌组,可以添加重置方法。

通过随机查看循环中的整个牌组

while(randomCard.isUsed){

不仅是那些还在使用中的牌,当你到达牌组末端时,你会得到很多重试次数。最后一张牌(数字52)在average上的未命中次数超过25次。t将一张全牌组转换平均总共会有超过600次未命中

除此之外,您还需要在再次使用牌组之前重置牌组。我猜您有一种方法可以通过循环所有牌来重置牌组,并执行
used=NO
。这将在牌组上执行52次操作,即使您只需要处理一张牌

通过这个简单的解决方案,您可以避免这两个问题

将你所有的牌储存在一个阵列中。然后将一端用于尚未发放的牌,另一端用于已发放的牌:

                                                                                             <---------------------- not yet dealt ---------------------->
[ ah 2h 3h 4h 5h 6h 7h 8h 9h 10h jh qh kh ad 2d  ..... jk qk kk ]
                                                               ^
                                                            dealt 
                                                            cards
将其与最后一张尚未发牌的牌切换,并将发牌指针移到左侧

  <-------------------- not yet dealt --------------------->
[ ah 2h 3h 4h 5h 6h kk 8h 9h 10h jh qh kh ad 2d  ..... jk qk 7h ]
                                                            ^
                                                           dealt
                                                           cards

[ah 2h 3h 4h 5h 6h kk 8h 9h 10h jh qh kh ad 2d…..jk qk 7h]
^
处理
卡
根据需要重复以下步骤:

  <------------------ not yet dealt ----------------->
[ ah 2h qk 4h 5h 6h kk 8h 9h 10h jh jk kh ad 2d  ..... qh 3h 7h ]
                                                      ^
                                                    dealt 
                                                    cards

[ah 2h qk 4h 5h 6h kk 8h 9h 10h jh jk kh ad 2d…..qh 3h 7h]
^
处理
卡
当你需要新牌组时,只需将已发牌指针移回末端,牌组即可开始新的使用

  <----------------------- not yet dealt ---------------------->
[ ah 2h qk 4h 5h 6h kk 8h 9h 10h jh jk kh ad 2d  ..... qh 3h 7h ]
                                                               ^
                                                             dealt 
                                                             cards

[ah 2h qk 4h 5h 6h kk 8h 9h 10h jh jk kh ad 2d…..qh 3h 7h]
^
处理
卡

牌组的新顺序只是增加了随机性…

执行此操作的原因是,我必须从牌组中抽出一些(2-23)张牌,进行一些计算,然后重置牌组,并一次又一次地执行所有这些操作(50'000-1'000'000次)…所以我真的不知道你的建议是否会加快速度。因为我认为创建NSArray、处理某些元素、复制元素(重置)的开销比仅仅设置一些布尔值更大,然后将布尔值设置回重置…你能解释一下为什么你认为这会有帮助吗?似乎你的while循环并不像我想象的那样是一个瓶颈(除非抽到的牌的数量非常接近牌组的大小).我将我的实现更改为此,效果很好!谢谢!你有其他提高速度的想法吗?那么现在有多快?什么部分需要花费时间?因此,如果你使用解决方案,也许你可以接受答案?
  <----------------------- not yet dealt ---------------------->
[ ah 2h qk 4h 5h 6h kk 8h 9h 10h jh jk kh ad 2d  ..... qh 3h 7h ]
                                                               ^
                                                             dealt 
                                                             cards