Bir Markov Sürecinin Yakınsaması


10

Meydan okuma

X olarak sınırın matrisin sonsuzluğuna x'in gücüne yaklaştığı sol veya sağ stokastik bir matris verildiğinde, tüm sonlu değerlere sahip bir matrise yaklaşır, matrisin birleştiği matrisi döndürür. Temel olarak, sonuç artık değişmeyene kadar matrisi kendi kendine çoğaltmaya devam etmek istersiniz.

Test Durumları

[[7/10, 4/10], [3/10, 6/10]] -> [[4/7, 4/7], [3/7, 3/7]]
[[2/5, 4/5], [3/5, 1/5]] -> [[4/7, 4/7], [3/7, 3/7]]
[[1/2, 1/2], [1/2, 1/2]] -> [[1/2, 1/2], [1/2, 1/2]]
[[1/3, 2/3], [2/3, 1/3]] -> [[1/2, 1/2], [1/2, 1/2]]
[[1/10, 2/10, 3/10], [4/10, 5/10, 6/10], [5/10, 3/10, 1/10]] -> [[27/130, 27/130, 27/130], [66/130, 66/130, 66/130], [37/130, 37/130, 37/130]]
[[1/7, 2/7, 4/7], [2/7, 4/7, 1/7], [4/7, 1/7, 2/7]] -> [[1/3, 1/3, 1/3], [1/3, 1/3, 1/3], [1/3, 1/3, 1/3]]

kurallar

  • Standart Loopholes Uygula
  • Sağ veya sol stokastik bir matris isteyip istemediğinizi seçebilirsiniz
  • Şamandıralar, gerekçeler, sonsuz duyarlıklı ondalık sayılar vb.Gibi makul bir sayı türü kullanabilirsiniz.
  • Bu , bu nedenle her dil için bayt cinsinden en kısa teslim, kendi dili için kazanan ilan edilir. Hiçbir cevap kabul edilmeyecek

@FryAmTheEggman daha önceki bazı yorumların silinmiş gibi görünüyor, bu yüzden bu gereksiz olabilir, ancak indirgenebilir ve periyodik matrisler zaten "x matrisin sonsuzluğuna iktidara yaklaştığında sol veya sağ stokastik bir matris verildiğinde x 'in tüm sonlu değerlere sahip bir matrise yaklaşması "ifadesini kullandı. (yani giriş matrisinin ergodik olması garanti edilir.)
Nathaniel

@Nathaniel Bu doğru değil, eğer zincir azaltılabilirmiş gibi söylediklerinize uyan bir sonuca (kimlik matrisi gibi) sahip olabilirsiniz, ancak tarif ettiği zincir indirgenemez değildir ve bu nedenle girdinin ergodik olun (pozitif tekrarlanmayacağı için). Ergodisiteyi garantilemek OP'nin istediği şeydir ve bence şimdi tüm satır değerlerinin ek kısıtlaması aynı olduğunda buna sahipler. Markov zincirlerinin bir açıklamasını eklemek zorunda kalmadan girişi kısıtlamanın daha iyi bir yolunu biliyorsanız, eminim HyperNeutrino bunu takdir edecektir! :)
FryAmTheEggman

1
@FryAmTheEggman ah, haklısın, üzgünüm. Matrisi bir güce yükseltmek yerine güç yinelemesini düşünüyordum. (Yani "benzersiz çözüm" demekle "yineleme sürecinin başlangıç ​​noktasından bağımsız" demekti, ama bu burada geçerli değil.) 'Tüm satırlar aynıdır' koşulunun işi yaptığını kabul ediyorum. Bence OP sadece “Markov zincirinin ergodik olması garantili” diyebilirdi ki bu bizim gibi endişe duyan insanları tatmin edecek!
Nathaniel

Aslında, B BA = B'ye bir çözüm ise , o zaman herhangi bir skaler sabit c için cB de olur . Bu nedenle, bir şekilde ölçeği düzeltmedikçe sıfır olmayan bir çözüm kesinlikle benzersiz olamaz . ( B'nin stokastik olmasını zorunlu kılar.) Ayrıca, açıkçası, B'nin satırlarının mı yoksa sütunlarının mı eşit olduğu A'nın sol veya sağ stokastik olmasına bağlı olacaktır .
Ilmari Karonen

2
Lisede Matematik dersinde matrisleri ve bunları nasıl çoğaltacağını hiç öğrenmeyen herkes için: mathsisfun.com/algebra/matrix-multiplying.html . Neyin sorulduğunu anlamak için bakmalıydım .. Belki de dünyanın başka yerlerinde yaygın olan bilgi ..: S
Kevin Cruijssen

Yanıtlar:


7

R ,  44  43 bayt

function(m){X=m
while(any(X-(X=X%*%m)))0
X}

Çevrimiçi deneyin!

Sabit bir matris bulana kadar çoğalmaya devam eder. Görünüşe göre X!=(X=X%*%m)karşılaştırma yapar, sonra yeniden atar X, bu yüzden bu temiz.

@Vlo'ya bir bayt tıraş ettiği için teşekkürler; çaprazlanmış olmasına rağmen 44 hala düzenli 44.


1
Acaba neden function(m){ while(any(m!=(m=m%*%m)))0 m}çalışmıyor? Sonlandırma koşulunun tetiklenmesini engelleyen sayısal yanlışlıklar?
CodesInChaos

@CodesInChaos büyük olasılıkla hassasiyet eksikliğidir. Rastgele bir hassas kütüphaneye geçmek de yardımcı olmaz - muhtemelen yanlış bir şey yapmama rağmen, ya zaman aşımı (Rmpfr) veya başarısız (gmp).
Giuseppe

@Giuseppe Sanırım önerilen yaklaşım artık değişene kadar kareler tekrarlanıyor? (R'yi okuyamıyorum)
user202729

@ user202729 evet öyle. R, 64 bit kayan nokta sayıları kullanır ve hataların oldukça hızlı bir şekilde yayıldığını biliyorum.
Giuseppe

Bence algoritma kararsız. Jelly'in de aynı sorunu var. (TODO bunu kanıtlıyor ve alternatif
buluyor

5

Oktav ,45 42 35 bayt

@(A)([v,~]=eigs(A,1))/sum(v)*any(A)

Çevrimiçi deneyin!

Giuseppe sayesinde 3 bayt ve Luis Mendo sayesinde 7 bayt tasarruf etti!

Bu, özdeğer 1'e (ayrıca maksimum özdeğer) karşılık gelen özvektörün, sınırlayıcı matrisin her değeri için tekrarlanan sütun vektörü olduğunu kullanır. Vektörü stokastik olması için toplam 1 olacak şekilde normalleştirmeliyiz, o zaman matrisi doldurmak için tekrarlarız. Golf Octave golf konusunda çok bilgili değilim, ancak tekrarlanan çarpma için işlevsel bir yol bulamadım ve tam bir program her zaman bundan daha uzun olacak gibi görünüyor.

any(A)Kısıtlamalardan matrisin indirgenemez bir Markov zincirini tanımlaması gerektiğini ve böylece her bir duruma diğer eyaletlerden erişilebilmesi gerektiğini bildiğimiz için kullanabiliriz . Bu nedenle, her sütundaki en az bir değer sıfır olmamalıdır.


eigsHer zaman karşılık gelen özvektörü nasıl döndürür 1? Markov zincirlerinin hafızam biraz bulanık.
Giuseppe


@Giuseppe Matris stokastik ve birkaç başka şey olduğundan, maksimum özdeğer değeri 1'dir ve eigsen büyük özdeğerden başlayarak geri döner. Ayrıca, golf için teşekkürler!
FryAmTheEggman

Ah doğru. Markov zincirleri bir sonraki sınavımda, ancak aktüerler için olduğundan, bazı detaylar tamamen eksik.
Giuseppe




3

k / q, 10 bayt

k / q çünkü program her iki dilde de aynı. Kod gerçekten sadece deyimsel k / q.

{$[x]/[x]}

açıklama

{..}xörtük bir parametre olarak lambda sözdizimi dışında

$[x] ikili matris çarpma operatörü olarak $ değerine sahiptir, yalnızca bir parametre sağlayarak Markov Matrix ile çarpılan tekli bir operatör oluşturur

/[x] x ile başlayan yakınsamaya kadar sol çarpımı uygular.


3

C (GCC) , 207 192 190 181 176 bayt + 2 bayrak bayt-lm

  • Kaydedilen onbeş onyedi -e doğru yirmi-iki bayt sayesinde ceilingcat .
  • Dokuz bayt kurtardı; kaldırılıyor return A;.
float*f(A,l,k,j)float*A;{for(float B[l*l],S,M=0,m=1;fabs(m-M)>1e-7;wmemcpy(A,B,l*l))for(M=m,m=0,k=l*l;k--;)for(S=j=0;j<l;)m=fmax(m,fdim(A[k],B[k]=S+=A[k/l*l+j]*A[k%l+j++*l]));}

Çevrimiçi deneyin!


@ ceilingcat Derleyici bayrak baytlarını sayarsak, bu yine 192 ile sonuçlanır. Yine de önerinizi dahil etti.
Jonathan Frech

@ ceilingcat Teşekkür ederim.
Jonathan Frech

2

Python 3 , 75 61 bayt

f=lambda n:n if allclose(n@n,n)else f(n@n)
from numpy import*

Çevrimiçi deneyin!

Test vakalarında şamandıra yanlışlıkları vardır, bu nedenle değerler kesin kesirlerden biraz farklı olabilir.

PS. uzun ve yanlışlıkları yüzmeye eğilimli numpy.allclose()olduğu için kullanılır numpy.array_equal().

-14 bayt Teşekkürler HyperNeutrino;) Oh evet @ operatörü unuttum; P


dotBunun yerine kullanın matmul: D
HyperNeutrino

Aslında, numpy dizilerini girdi olarak alın ve şunu yapın x=n@n: P tio.run/…
HyperNeutrino


f=Tekrar tekrar çağrıldığı için ön tarafa eklendi ;)
Shieru Asakoto

Oh evet haklısın :) iyi çağrı!
HyperNeutrino

2

Java 8, 356339 bayt

import java.math.*;m->{BigDecimal t[][],q;RoundingMode x=null;for(int l=m.length,f=1,i,k;f>0;m=t.clone()){for(t=new BigDecimal[l][l],i=l*l;i-->0;)for(f=k=0;k<l;t[i/l][i%l]=(q!=null?q:q.ZERO).add(m[i/l][k].multiply(m[k++][i%l])))q=t[i/l][i%l];for(;++i<l*l;)f=t[i/l][i%l].setScale(9,x.UP).equals(m[i/l][i%l].setScale(9,x.UP))?f:1;}return m;}

@Ceilingcat sayesinde -17 bayt .

Kesinlikle doğru dil değil .. Lanet kayan nokta hassasiyeti ..

Açıklama:

Çevrimiçi deneyin.

import java.math.*;     // Required import for BigDecimal and RoundingMode
m->{                    // Method with BigDecimal-matrix as both parameter and return-type
  BigDecimal t[][],q;   //  Temp BigDecimal-matrix
  RoundingMode x=null;  //  Static RoundingMode value to reduce bytes
  for(int l=m.length,   //  The size of the input-matrix
          f=1,          //  Flag-integer, starting at 1
          i,k;          //  Index-integers
      f>0;              //  Loop as long as the flag-integer is still 1
      m=t.clone()){     //    After every iteration: replace matrix `m` with `t`
    for(t=new BigDecimal[l][l],
                        //   Reset matrix `t`
        i=l*l;i-->0;)   //   Inner loop over the rows and columns
      for(f=k=0;        //    Set the flag-integer to 0
          k<l           //    Inner loop to multiply
          ;             //      After every iteration:
           t[i/l][i%l]=(q!=null?q:q.ZERO).add(
                        //       Sum the value at the current cell in matrix `t` with:
             m[i/l][k]  //        the same row, but column `k` of matrix `m`,
             .multiply(m[k++][i%l])))
                        //        multiplied with the same column, but row `k` of matrix `m`
        q=t[i/l][i%l];  //     Set temp `q` to the value of the current cell of `t`
    for(;++i<l*l;)      //   Loop over the rows and columns again
      f=t[i/l][i%l].setScale(9,x.UP).equals(m[i/l][i%l].setScale(9,x.UP))?
                        //    If any value in matrices `t` and `m` are the same:
         f              //     Leave the flag-integer unchanged
        :               //    Else (they aren't the same):
         1;}            //     Set the flag-integer to 1 again
  return m;}            //  Return the modified input-matrix `m` as our result

Ana işlev neden bu kadar ayrıntılı?
user202729

@ user202729 Çünkü float/ doubleuygun kayan nokta hassasiyetine sahip olmadığından, java.math.BigDecimalbunun yerine kullanılmalıdır. Ve yerine basitçe +-*/, BigDecimals kullanmak .add(...), .subtract(...), .multiply(...), .divide(...). Şey kadar basit bir şekilde Yani 7/10olur new BigDecimal(7).divide(new BigDecimal(10)). Ayrıca, 'sonsuz' ondalık değerlere ( varlık gibi ) sahip değerler ,scale,RoundingModeiçin dividede gereklidir . Ana yöntem elbette golf olabilir, ancak bir arama yaptım ve yüzenleri BigDecimals'e dönüştürmek için değiştirmedim. 1/30.333...
Kevin Cruijssen

@ ceilingcat Teşekkürler!
Kevin Cruijssen
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.