Calcul efficace de la série Fibonacci

je travaille sur un projet Euler problème: celui de la somme des nombres même Fibonacci.

mon code:

def Fibonacci(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return Fibonacci(n-1) + Fibonacci(n-2)

list1 = [x for x in range(39)]
list2 = [i for i in list1 if Fibonacci(i) % 2 == 0]

la solution du problème peut être facilement trouvée en imprimant sum(list2). Cependant, il faut beaucoup de temps pour trouver la liste2, je suppose. Est-il possible de faire plus vite? Ou c'est ok même de cette façon...

(le problème: en considérant les Termes Fibonacci séquence dont les valeurs ne dépassent pas quatre millions, trouver la somme des termes à valeur égale.)

32
demandé sur iCodez 2013-08-11 17:11:22

19 réponses

Oui. La solution primitive récursive prend beaucoup de temps. La raison en est que pour chaque nombre calculé, il doit calculer tous les numéros précédents plus d'une fois. Jetez un oeil à l'image ci-dessous.

Tree representing fibonacci calculation

il représente le calcul de Fibonacci(5) avec votre fonction. Comme vous pouvez le voir, il calcule la valeur de Fibonacci(2) trois fois, et la valeur de Fibonacci(1) cinq fois. Que devient de pire en pire plus le numéro que vous voulez calculer.

ce qui le rend encore pire, c'est qu'avec chaque nombre de fibonacci que vous calculez dans votre liste, vous n'utilisez pas les nombres précédents dont vous avez connaissance pour accélérer le calcul – vous calculez chaque nombre "à partir de zéro."

il y a quelques options pour rendre cela plus rapide:


1. Créer une liste" de bas en haut "

la façon la plus simple est de créer une liste de nombres fibonacci jusqu'au nombre que vous voulez. Si vous le faites, vous construire "par le bas", ou pour parler, et vous pouvez réutiliser les numéros précédents pour créer le prochain. Si vous avez une liste des nombres de fibonacci [0, 1, 1, 2, 3] , vous pouvez utiliser les deux derniers numéros de cette liste pour créer le prochain numéro.

cette approche ressemblerait à quelque chose comme ceci:

>>> def fib_to(n):
...     fibs = [0, 1]
...     for i in range(2, n+1):
...         fibs.append(fibs[-1] + fibs[-2])
...     return fibs
...

alors vous pouvez obtenir les premiers 20 Numéros fibonacci en faisant

>>> fib_to(20)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765]

ou vous pouvez obtenir le 17ème numéro fibonacci d'une liste des 40 premiers en faisant

>>> fib_to(40)[17]
1597

2. Memoization (relativement technique avancée)

une autre alternative pour la rendre plus rapide existe, mais elle est aussi un peu plus compliquée. Depuis votre problème est que vous recalculez les valeurs que vous avez déjà calculées, vous pouvez choisir de sauvegarder les valeurs que vous avez déjà calculées dans un dict, et essayer de les récupérer avant de les recalculer. Cela s'appelle memoization . Il peut ressembler à quelque chose comme ceci:

>>> def fib(n, computed = {0: 0, 1: 1}):
...     if n not in computed:
...         computed[n] = fib(n-1, computed) + fib(n-2, computed)
...     return computed[n]

cela vous permet de calculer de grands nombres de fibonacci dans une brise:

>>> fib(400)
176023680645013966468226945392411250770384383304492191886725992896575345044216019675

C'est en fait une technique si commune que Python 3 inclut un décorateur pour le faire pour vous. Je vous présente, mémoization automatique!

import functools

@functools.lru_cache(None)
def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

Cela fait à peu près la même chose que la fonction précédente, mais avec tous les computed trucs manipulés par le lru_cache décorateur.


3. Juste compter jusqu' (un naïf solution itérative)

une troisième méthode, comme suggéré par Mitch, est de simplement compter sans enregistrer les valeurs intermédiaires dans une liste. Vous pourriez imaginez faire

>>> def fib(n):
...     a, b = 0, 1
...     for _ in range(n):
...         a, b = b, a+b
...     return a

Je ne recommande pas ces deux dernières méthodes si votre but est de créer une liste de numéros fibonacci. fib_to(100) va être beaucoup plus rapide que [fib(n) for n in range(101)] parce que avec ce dernier, vous obtenez toujours le problème de calculer chaque nombre dans la liste à partir de zéro.

69
répondu kqr 2014-10-30 10:20:05

il S'agit d'un algorithme très rapide et il peut trouver n-e Fibonacci nombre beaucoup plus rapide que l'approche itérative simple présentée dans d'autres réponses, il est assez avancé cependant:

def fib(n):
    v1, v2, v3 = 1, 1, 0    # initialise a matrix [[1,1],[1,0]]
    for rec in bin(n)[3:]:  # perform fast exponentiation of the matrix (quickly raise it to the nth power)
        calc = v2*v2
        v1, v2, v3 = v1*v1+calc, (v1+v3)*v2, calc+v3*v3
        if rec=='1':    v1, v2, v3 = v1+v2, v1, v2
    return v2

vous pouvez en savoir plus sur les mathématiques impliquées ici .


40
répondu Piotr Dabkowski 2015-04-21 18:20:00

Python n'optimise pas la récursion de la queue, donc la plupart des solutions présentées ici échoueront avec Error: maximum recursion depth exceeded in comparison si n est trop grand (et par grand, je veux dire 1000).

la limite de récursion peut être augmentée, mais cela fera planter Python sur le débordement de la pile dans le système d'exploitation.

notez la différence de performance entre fib_memo / fib_local et fib_lru / fib_local_exc : la cache LRU est beaucoup plus lente et n'a même pas complet, car il produit déjà une erreur d'exécution pour n = ~500:

import functools
from time import clock
#import sys
#sys.setrecursionlimit()

@functools.lru_cache(None)
def fib_lru(n):
    if n < 2:
        return n
    return fib_lru(n-1) + fib_lru(n-2)

def fib_memo(n, computed = {0: 0, 1: 1}):
    if n not in computed:
        computed[n] = fib_memo(n-1, computed) + fib_memo(n-2, computed)
    return computed[n]

def fib_local(n):
    computed = {0: 0, 1: 1}
    def fib_inner(n):
        if n not in computed:
            computed[n] = fib_inner(n-1) + fib_inner(n-2)
        return computed[n]
    return fib_inner(n)

def fib_local_exc(n):
    computed = {0: 0, 1: 1}
    def fib_inner_x(n):
        try:
            computed[n]
        except KeyError:
            computed[n] = fib_inner_x(n-1) + fib_inner_x(n-2)
        return computed[n]

    return fib_inner_x(n)

def fib_iter(n):
    a, b = 0, 1
    for i in range(n):
        a, b = b, a + b
    return a

def benchmark(n, *args):
    print("-" * 80)
    for func in args:
        print(func.__name__)
        start = clock()
        try:
            ret = func(n)
            #print("Result:", ret)
        except RuntimeError as e:
            print("Error:", e)
        print("Time:", "{:.8f}".format(clock() - start))
        print()

benchmark(500, fib_iter, fib_memo, fib_local, fib_local_exc, fib_lru)

Résultats:

fib_iter
Time: 0.00008168

fib_memo
Time: 0.00048622

fib_local
Time: 0.00044645

fib_local_exc
Time: 0.00146036

fib_lru
Error: maximum recursion depth exceeded in comparison
Time: 0.00112552

la solution itérative est de loin la plus rapide et ne corrompt pas la pile même pour n=100k (0,162 secondes). Il ne renvoie pas les nombres de Fibonacci intermédiaires en effet.

si vous voulez calculer le n que même le nombre de Fibonacci, vous pouvez adapter l'approche itérative comme ceci:

def fib_even_iter(n):
    a, b = 0, 1
    c = 1
    while c < n:
        a, b = b, a + b
        if a % 2 == 0:
            c += 1
    return a

ou si vous êtes intéressé par chaque nombre pair sur le chemin, utilisez un générateur :

def fib_even_gen(n):
    a, b = 0, 1
    c = 1
    yield a
    while c < n:
        a, b = b, a + b
        if a % 2 == 0:
            yield a
            c += 1
    return a

for i, f in enumerate(fib_even_gen(100), 1):
    print("{:3d}.  {:d}".format(i, f))

résultat:

  1.  0
  2.  2
  3.  8
  4.  34
  5.  144
  6.  610
  7.  2584
  8.  10946
  9.  46368
 10.  196418
 11.  832040
 12.  3524578
 13.  14930352
 14.  63245986
 15.  267914296
 16.  1134903170
 17.  4807526976
 18.  20365011074
 19.  86267571272
 20.  365435296162
 21.  1548008755920
 22.  6557470319842
 23.  27777890035288
 24.  117669030460994
 25.  498454011879264
 26.  2111485077978050
 27.  8944394323791464
 28.  37889062373143906
 29.  160500643816367088
 30.  679891637638612258
 31.  2880067194370816120
 32.  12200160415121876738
 33.  51680708854858323072
 34.  218922995834555169026
 35.  927372692193078999176
 36.  3928413764606871165730
 37.  16641027750620563662096
 38.  70492524767089125814114
 39.  298611126818977066918552
 40.  1264937032042997393488322
 41.  5358359254990966640871840
 42.  22698374052006863956975682
 43.  96151855463018422468774568
 44.  407305795904080553832073954
 45.  1725375039079340637797070384
 46.  7308805952221443105020355490
 47.  30960598847965113057878492344
 48.  131151201344081895336534324866
 49.  555565404224292694404015791808
 50.  2353412818241252672952597492098
 51.  9969216677189303386214405760200
 52.  42230279526998466217810220532898
 53.  178890334785183168257455287891792
 54.  757791618667731139247631372100066
 55.  3210056809456107725247980776292056
 56.  13598018856492162040239554477268290
 57.  57602132235424755886206198685365216
 58.  244006547798191185585064349218729154
 59.  1033628323428189498226463595560281832
 60.  4378519841510949178490918731459856482
 61.  18547707689471986212190138521399707760
 62.  78569350599398894027251472817058687522
 63.  332825110087067562321196029789634457848
 64.  1409869790947669143312035591975596518914
 65.  5972304273877744135569338397692020533504
 66.  25299086886458645685589389182743678652930
 67.  107168651819712326877926895128666735145224
 68.  453973694165307953197296969697410619233826
 69.  1923063428480944139667114773918309212080528
 70.  8146227408089084511865756065370647467555938
 71.  34507973060837282187130139035400899082304280
 72.  146178119651438213260386312206974243796773058
 73.  619220451666590135228675387863297874269396512
 74.  2623059926317798754175087863660165740874359106
 75.  11111460156937785151929026842503960837766832936
 76.  47068900554068939361891195233676009091941690850
 77.  199387062373213542599493807777207997205533596336
 78.  844617150046923109759866426342507997914076076194
 79.  3577855662560905981638959513147239988861837901112
 80.  15156039800290547036315704478931467953361427680642
 81.  64202014863723094126901777428873111802307548623680
 82.  271964099255182923543922814194423915162591622175362
 83.  1152058411884454788302593034206568772452674037325128
 84.  4880197746793002076754294951020699004973287771475874
 85.  20672849399056463095319772838289364792345825123228624
 86.  87571595343018854458033386304178158174356588264390370
 87.  370959230771131880927453318055001997489772178180790104
 88.  1571408518427546378167846658524186148133445300987550786
 89.  6656593304481317393598839952151746590023553382130993248
 90.  28197781736352815952563206467131172508227658829511523778
 91.  119447720249892581203851665820676436622934188700177088360
 92.  505988662735923140767969869749836918999964413630219877218
 93.  2143402371193585144275731144820024112622791843221056597232
 94.  9079598147510263717870894449029933369491131786514446266146
 95.  38461794961234640015759308940939757590587318989278841661816
 96.  162926777992448823780908130212788963731840407743629812913410
 97.  690168906931029935139391829792095612517948949963798093315456
 98.  2923602405716568564338475449381171413803636207598822186175234
 99.  12384578529797304192493293627316781267732493780359086838016392
100.  52461916524905785334311649958648296484733611329035169538240802

Time: 0.00698620

C'est le premier 100 numéros de Fibonacci pair dans ~7ms et inclut la tête de l'impression au terminal (facile à sous-estimer sur Windows).

7
répondu CoDEmanX 2015-08-25 23:35:38

basé sur le fait que fib(n) = fib(n-1)+fib(n-2) , la solution simple est

def fib(n):
    if (n <=1):
        return(1)
    else:
        return(fib(n-1)+fib(n-2))

cependant, le problème ici est que certaines valeurs sont calculées plusieurs fois, et donc il est très inefficace. La raison peut être vue dans ce croquis:

Fibonacci

essentiellement, chaque appel récursif à la fonction fib doit calculer tous les fibonacci précédents les numéros pour son propre usage. Ainsi, la valeur la plus calculée sera fib(1) puisqu'elle doit apparaître dans tous les noeuds de feuilles de l'arbre montré par la réponse de @kqr. La complexité de cet algorithme est le nombre de noeuds de l'arbre, qui est $O(2^n)$.

Maintenant une meilleure façon est de garder la trace de deux nombres, la valeur actuelle et la valeur précédente, de sorte que chaque appel n'a pas à calculer toutes les valeurs précédentes. C'est la deuxième algorithme dans l'esquisse, et peut être mis en œuvre comme suit

def fib(n):
   if (n==0):
       return(0,1)
   elif (n==1):
       return(1,1)
   else:
       a,b = fib(n-1)
       return(b,a+b)

la complexité de cet algorithme est linéaire $O (n)$, et quelques exemples seront

>>> fib(1)
(1, 1)
>>> fib(2)
(1, 2)
>>> fib(4)
(3, 5)
>>> fib(6)
(8, 13)
4
répondu Vahid Mir 2016-02-15 04:04:53

Solution dans R, benchmark calcule 1 à 1000ème série de Fibonacci nombre en 1.9 secondes. Serait beaucoup plus rapide en C++ ou Fortran, en fait, depuis l'écriture du post initial, j'ai écrit une fonction équivalente en C++ qui s'est terminée en une impressionnante 0.0033 secondes, même python terminé en 0.3 secondes.

#Calculate Fibonnaci Sequence
fib <- function(n){
  if(n <= 2)
    return(as.integer(as.logical(n)))
  k = as.integer(n/2)
  a = fib(k + 1)
  b = fib(k)
  if(n %% 2 == 1)
    return(a*a + b*b)
  return(b*(2*a - b))
}

#Function to do every fibonacci number up to nmax
doFib <- function(nmax = 25,doPrint=FALSE){
    res = sapply(0:abs(nmax),fib)
    if(doPrint)
        print(paste(res,collapse=","))
    return(res)
}

#Benchmark
system.time(doFib(1000))

#user  system elapsed 
#  1.874   0.007   1.892 
3
répondu Nicholas Hamilton 2016-03-31 23:18:29

j'ai basé cela sur un article sur les nombres de Fibonacci sur Wikipedia. L'idée est d'éviter la boucle et la récursion et de calculer simplement la valeur au besoin.

N'étant pas un génie des maths, a sélectionné une des formules et l'a rendu codé et l'a modifié jusqu'à ce que les valeurs sortent à droite.

import cmath

def getFib(n):
    #Given which fibonacci number we want, calculate its value
    lsa = (1 / cmath.sqrt(5)) * pow(((1 + cmath.sqrt(5)) / 2), n)
    rsa = (1 / cmath.sqrt(5)) * pow(((1 - cmath.sqrt(5)) / 2), n)
    fib = lsa-rsa
    #coerce to real so we can round the complex result
    fn = round(fib.real) 
    return fn 

#Demo using the function
s = ''
for m in range(0,30):
    s = s + '(' + str(m) + ')' + str(getFib(m)) + ' '

print(s)
3
répondu Dan Rhea 2016-09-19 22:20:47

kqr 's solution n ° 2 est mon définitive favori.

Toutefois, dans ce cas précis, nous perdons tous nos calculs entre les appels consécutifs dans la liste compréhension:

list2 = [i for i in list1 if fib(i) % 2 == 0]

, donc j'ai décidé d'aller un peu plus loin et de le memoize entre les pas de boucle comme suit:

def cache_fib(ff):
    comp = {0: 0, 1: 1}

    def fib_cached(n, computed=comp):
        return ff(n, computed)
    return fib_cached


@cache_fib
def fib(n, computed={0: 0, 1: 1}):
    if n not in computed:
        computed[n] = fib(n - 1, computed) + fib(n - 2, computed)
    return computed[n]
2
répondu Lukasz 2017-05-23 12:03:02

des problèmes comme cela va prendre un certain temps si il y a beaucoup de niveaux de récursivité. La définition récursive est bonne pour coder le problème d'une manière qui peut être facilement comprise, mais si vous en avez besoin pour exécuter plus rapidement une solution itérative comme la réponse dans ce fil sera beaucoup plus rapide.

1
répondu ChrisProsser 2017-05-23 12:18:17

Récursive de calcul de Fibonacci sera plus inefficace que de le faire de manière itérative. Ma recommandation est:

prendre le temps de créer une classe Fibonacci comme itérateur, et faire les calculs indépendamment pour chaque élément de l'indice, peut-être avec quelque @memoize décorateur (et aussi ici ) pour mettre en cache tous les calculs précédents.

Espérons que cette aide!

1
répondu Paulo Bu 2013-08-11 14:41:14

un moyen rapide est de calculer le nombre fib(n/2) récursivement:

fibs = {0: 0, 1: 1}
def fib(n):
    if n in fibs: return fibs[n]
    if n % 2 == 0:
        fibs[n] = ((2 * fib((n / 2) - 1)) + fib(n / 2)) * fib(n / 2)
        return fibs[n]
    else:
        fibs[n] = (fib((n - 1) / 2) ** 2) + (fib((n+1) / 2) ** 2)
        return fibs[n]

from time import time
s=time()
print fib(1000000)
print time()-s
1
répondu Stefan Gruenwald 2014-10-31 02:36:05

Haskell 1 liner: -

fibs = 0 : (f 1 1) where f a b = a : f b (a+b)

ce code est extrêmement efficace et calcule des nombres de Fibonacci jusqu'à ( 10^1000 ) en moins d'une seconde ! Ce code sera également utile pour ce problème dans le projet Euler.

1
répondu rohansumant 2014-11-14 05:17:48

pour trouver la somme du premier n nombres de fibonacci Pair-évalués directement, mettez 3n + 2 dans votre méthode préférée pour calculer efficacement un nombre de fibonacci simple, décrément par un et diviser par deux ( fib((3*n+2) - 1)/2) ). Comment les nuls en maths ont-ils survécu avant OEIS ?

1
répondu greybeard 2015-01-20 19:57:18

vous pouvez utiliser l'équation avec des racines carrées pour calculer ceci si vous n'utilisez pas l'arithmétique flottante, mais gardez la trace des coefficients d'une autre manière que vous allez. Cela donne un algorithme essentiellement constant de temps exact pour les nombres de Fibonacci:

def rootiply(a1,b1,a2,b2,c):
    ''' multipy a1+b1*sqrt(c) and a2+b2*sqrt(c)... return a,b'''
    return a1*a2 + b1*b2*c, a1*b2 + a2*b1

def rootipower(a,b,c,n):
    ''' raise a + b * sqrt(c) to the nth power... returns the new a,b and c of the result in the same format'''
    ar,br = 1,0
    while n != 0:
        if n%2:
            ar,br = rootiply(ar,br,a,b,c)
        a,b = rootiply(a,b,a,b,c)
        n /= 2
    return ar,br

def fib(k):
    ''' the kth fibonacci number'''
    a1,b1 = rootipower(1,1,5,k)
    a2,b2 = rootipower(1,-1,5,k)
    a = a1-a2
    b = b1-b2
    a,b = rootiply(0,1,a,b,5)
    # b should be 0!
    assert b == 0
    return a/2**k/5

if __name__ == "__main__":
    assert rootipower(1,2,3,3) == (37,30) # 1+2sqrt(3) **3 => 13 + 4sqrt(3) => 39 + 30sqrt(3)
    assert fib(10)==55
1
répondu Scott 2017-01-20 19:40:28

il s'agit d'une version améliorée de Fibonacci où nous calculons Fibonacci De Nombre une seule fois:

dicFib = { 0:0 ,1 :1 }
iterations = 0
def fibonacci(a):
    if  (a in dicFib):      
        return dicFib[a]    
    else :
        global iterations               
        fib = fibonacci(a-2)+fibonacci(a-1)
        dicFib[a] = fib
        iterations += 1
        return fib

print ("Fibonacci of 10 is:" , fibonacci(10))
print ("Fibonacci of all numbers:" ,dicFib)
print ("iterations:" ,iterations)

# ('Fibonacci of 10 is:', 55)
# ('Fibonacci of all numbers:', {0: 0, 1: 1, 2: 1, 3: 2, 4: 3, 5: 5, 6: 8, 7: 13, 8: 21, 9: 34, 10: 55})
# ('iterations:', 9)

ici nous stockons Fibonacci de chaque nombre dans le dictionnaire. Donc vous pouvez voir qu'il calcule seulement une fois pour chaque itération et pour Fibonacci(10) Il est seulement 9 fois.

1
répondu Girish Gupta 2017-04-09 07:42:21

Bien qu'une réponse tardive mais il pourrait être utile

fib_dict = {}

def fib(n): 
    try:
        return fib_dict[n]
    except:
        if n<=1:
            fib_dict[n] = n
            return n
        else:
            fib_dict[n] = fib(n-1) + fib (n-2)
            return fib(n-1) + fib (n-2)

print fib(100)

C'est beaucoup plus rapide que la voie traditionnelle

0
répondu Abx 2015-09-03 04:40:42

an O (1) solution

il s'avère qu'il existe une belle formule récursive pour la somme des nombres même Fibonacci. Le nième terme dans la séquence des sommes de même numéros de Fibonacci est S_{n} = 4*S_{n-1} + S_{n-2} + 2 preuve est laissée au lecteur, mais implique la preuve 1) même numéros de Fibo sont tous les trois un, 2) preuve de la formule ci-dessus avec induction en utilisant la définition de numéros de Fibo. En utilisant la logique de ici , nous pouvons dériver une formule fermée pour cela avec un petit effort:

S_{n} = -1/2 + (1/4 + 3*sqrt(5)/20)*(2+sqrt(5))**n + (1/4 - 3*sqrt(5)/20)*(2-sqrt(5))**n

malgré le sqrt , ceci est intégral pour intégrale n , de sorte que cela peut être commodément calculé en utilisant les fonctions pratiques de ma réponse précédente, ou en utilisant un paquet tel que sympy pour manipuler les racines exactement.

import sympy as sp
one = sp.sympify(1) #to force casting to sympy types
k1 = -one/2
k2 = one/4 + 3*sp.sqrt(5)/20
k3 = one/4 - 3*sp.sqrt(5)/20
r1 = one
r2 = 2 + sp.sqrt(5)
r3 = 2 - sp.sqrt(5)
def even_sum_fibo(n):
  #get the nth number in the sequence of even sums of Fibonacci numbers.  If you want the sum of Fibos up to some number m, use n = m/3 (integer division)
  return sp.simplify(k1*r1**n + k2*r2**n + k3*r3**n)
0
répondu Scott 2017-10-26 17:33:15

il y a une solution O(1): https://en.wikipedia.org/wiki/Fibonacci_number#Computation_by_rounding

import math

PHI = (1 + math.sqrt(5)) / 2
SQRT5 = math.sqrt(5)


def fast_fib(n):
    if n < 0:
        raise ValueError('Fibs for negative values are not defined.')
    return round(math.pow(PHI, n) / SQRT5)
0
répondu Bastian Venthur 2018-06-20 07:13:48

étant donné le nombre de départ et le nombre maximum; je pense que la solution suivante pour fibonacci serait intéressante. La bonne chose est qu'elle n'inclut pas la récursion - réduisant ainsi le fardeau de mémoire.

# starting number is a
# largest number in the fibonacci sequence is b

def fibonacci(a,b):
    fib_series = [a, a]

    while sum(fib_series[-2:]) <=b:
        next_fib = sum(fib_series[-2:])
        fib_series.append(next_fib)

    return fib_series

print('the fibonacci series for the range %s is %s'
      %([3, 27], fibonacci(3, 27)))

the fibonacci series for the range [1, 12] is [3, 3, 6, 9, 15, 24]
0
répondu everestial007 2018-06-28 01:28:29
int count=0;
void fibbo(int,int);

void main()

{

fibbo(0,1);

    getch();
}

void fibbo(int a,int b)

{

 count++;

 printf(" %d ",a);

if(count<=10)

     fibbo(b,a+b);

else

      return;

}
-4
répondu Manoj Nawathale 2014-04-09 13:27:25