Jadual Kandungan
Memoisasi 1-D
Contoh
Output
n=5 ialah: 5
Nilai Fibonacci untuk n=5 ialah: 5
Hafazan 2-D
Kaedah
Memoisasi tiga dimensi
Rumah Java javaTutorial Memoisasi (1D, 2D dan 3D) Pengaturcaraan Dinamik di Jawa

Memoisasi (1D, 2D dan 3D) Pengaturcaraan Dinamik di Jawa

Aug 23, 2023 pm 02:13 PM
java Menghafal pengaturcaraan dinamik

Memoisasi ialah teknik berdasarkan pengaturcaraan dinamik yang digunakan untuk meningkatkan prestasi algoritma rekursif dengan memastikan kaedah tidak berjalan beberapa kali pada set input yang sama, dengan merekodkan keputusan (disimpan dalam tatasusunan) input yang disediakan. Memoisasi boleh dicapai melalui pendekatan atas ke bawah yang melaksanakan kaedah rekursif.

Mari kita fahami situasi ini melalui contoh jujukan asas Fibonacci.

Memoisasi 1-D

Kami akan mempertimbangkan algoritma rekursif dengan hanya satu parameter bukan malar (hanya satu perubahan nilai parameter), jadi kaedah ini dipanggil memoisasi 1-D. Kod berikut adalah untuk mencari Nth (semua sebutan sehingga N) dalam jujukan Fibonacci.

Contoh

public int fibonacci(int n) {
   if (n == 0)
      return 0;
   if (n == 1)
      return 1;
   System.out.println("Calculating fibonacci number for: " + n);
   return (fibonacci(n - 1) + fibonacci(n - 2));
}
Salin selepas log masuk

Output

Jika kita menjalankan kod di atas dengan n=5, output berikut akan dijana. Nilai Fibonacci untuk

Calculating fibonacci number for: 5
Calculating fibonacci number for: 4
Calculating fibonacci number for: 3
Calculating fibonacci number for: 2
Calculating fibonacci number for: 2
Calculating fibonacci number for: 3
Calculating fibonacci number for: 2
Salin selepas log masuk

n=5 ialah: 5

Perhatikan bahawa nombor Fibonacci untuk 2 dan 3 dikira berbilang kali. Marilah kita memahami dengan lebih baik dengan melukis pepohon rekursi di atas untuk keadaan n=5.

Dua anak nod akan mewakili panggilan rekursif yang dibuatnya. Anda boleh melihat bahawa F(3) dan F(2) dikira berbilang kali, yang boleh dielakkan dengan menyimpan cache hasil selepas setiap langkah.

Kami akan menggunakan pembolehubah contoh Tetapkan memoize untuk cache keputusan. Mula-mula semak sama ada n sudah wujud dalam Set memoize, jika ya, kembalikan nilai jika tidak, hitung nilai dan tambahkannya pada set.

Contoh

import java.util.HashMap;
import java.util.Map;
public class TutorialPoint {
   private Map<Integer, Integer> memoizeSet = new HashMap<>(); // O(1)
   public int fibMemoize(int input) {
      if (input == 0)
         return 0;
      if (input == 1)
         return 1;
      if (this.memoizeSet.containsKey(input)) {
         System.out.println("Getting value from computed result for " + input);
         return this.memoizeSet.get(input);
      }
      int result = fibMemoize(input - 1) + fibMemoize(input - 2);
      System.out.println("Putting result in cache for " + input);
      this.memoizeSet.put(input, result);
      return result;
   }
   public int fibonacci(int n) {
      if (n == 0)
         return 0;
      if (n == 1)
         return 1;
      System.out.println("Calculating fibonacci number for: " + n);
      return (fibonacci(n - 1) + fibonacci(n - 2));
   }
   public static void main(String[] args) {
      TutorialPoint tutorialPoint = new TutorialPoint();
      System.out.println("Fibonacci value for n=5: " + tutorialPoint.fibMemoize(5));
   }
}
Salin selepas log masuk

Output

Jika kita menjalankan kod di atas, output berikut akan dijana

Adding result in memoizeSet for 2
Adding result in memoizeSet for 3
Getting value from computed result for 2
Adding result in memoizeSet for 4
Getting value from computed result for 3
Adding result in memoizeSet for 5
Salin selepas log masuk

Nilai Fibonacci untuk n=5 ialah: 5

Seperti yang anda lihat dari atas, nilai Fibonacci ​​2 dan 3 Nombor surat ikatan tidak akan dikira lagi. Di sini, kami memperkenalkan HashMap menghafal untuk menyimpan nilai yang dikira Sebelum setiap pengiraan Fibonacci, semak sama ada nilai input telah dikira dalam koleksi Jika tidak, tambah nilai input tertentu.

Hafazan 2-D

Dalam program di atas, kita hanya mempunyai satu parameter bukan tetap. Dalam atur cara berikut, kami akan mengambil contoh atur cara rekursif yang mempunyai dua parameter yang mengubah nilainya selepas setiap panggilan rekursif dan kami akan melaksanakan penghafalan pada dua parameter bukan malar untuk pengoptimuman. Ini dipanggil penghafalan 2-D.

Sebagai contoh: kami akan melaksanakan Urutan Sepunya Terpanjang yang standard (LCS). Jika satu set jujukan diberikan, masalah jujukan sepunya terpanjang ialah mencari jujukan sepunya kepada semua jujukan yang mempunyai panjang terbesar. Akan ada 2^n kombinasi yang mungkin.

Contoh

class TP {
   static int computeMax(int a, int b) {
      return (a > b) ? a : b;
   }
   static int longestComSs(String X, String Y, int m, int n) {
      if (m == 0 || n == 0)
         return 0;
      if (X.charAt(m - 1) == Y.charAt(n - 1))
         return 1 + longestComSs(X, Y, m - 1, n - 1);
      else
         return computeMax(longestComSs(X, Y, m, n - 1), longestComSs(X, Y, m - 1, n));
   }
   public static void main(String[] args) {
      String word_1 = "AGGTAB";
      String word_2 = "GXTXAYB";
      System.out.print("Length of LCS is " + longestComSs(word_1, word_2, word_1.length(),word_2.length()));
   }
}
Salin selepas log masuk

Output

Jika kita menjalankan kod di atas, output berikut akan dijana

Length of LCS is 4
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Memoisasi (1D, 2D dan 3D) Pengaturcaraan Dinamik di Jawa

Dalam pepohon rekursi di atas, lcs("AXY", "AYZ") diselesaikan beberapa kali.

Disebabkan sifat masalah ini dengan substruktur yang bertindih, pengiraan berulang bagi submasalah yang sama boleh dielakkan dengan menggunakan memoisasi atau penjadualan.

Kaedah memoisasi kod rekursif dilaksanakan seperti berikut.

Contoh

import java.io.*;
import java.lang.*;
class testClass {
   final static int maxSize = 1000;
   public static int arr[][] = new int[maxSize][maxSize];
   public static int calculatelcs(String str_1, String str_2, int m, int n) {
      if (m == 0 || n == 0)
         return 0;
      if (arr[m - 1][n - 1] != -1)
         return arr[m - 1][n - 1];
      if (str_1.charAt(m - 1) == str_2.charAt(n - 1)) {
         arr[m - 1][n - 1] = 1 + calculatelcs(str_1, str_2, m - 1, n - 1);
         return arr[m - 1][n - 1];
      }
      else {
         int a = calculatelcs(str_1, str_2, m, n - 1);
         int b = calculatelcs(str_1, str_2, m - 1, n);
         int max = (a > b) ? a : b;
         arr[m - 1][n - 1] = max;
         return arr[m - 1][n - 1];
      }
   }
   public static void main(String[] args) {
      for (int i = 0; i < 1000; i++) {
         for (int j = 0; j < 1000; j++) {
            arr[i][j] = -1;
         }
      }
      String str_1 = "AGGTAB";
      String str_2 = "GXTXAYB";
      System.out.println("Length of LCS is " + calculatelcs(str_1, str_2, str_1.length(),str_2.length()));
   }
}
Salin selepas log masuk

Output

Jika kita menjalankan kod di atas, output berikut akan dijana

Length of LCS is 4
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Kaedah

Diperhatikan bahawa terdapat 4 parameter dalam kaedah (calculatelcs), yang mana tidak terdapat 2 pemalar mempengaruhi penghafalan), dan terdapat 2 parameter bukan malar (m dan n), yang nilainya akan berubah setiap kali kaedah dipanggil secara rekursif. Untuk mencapai hafalan, kami memperkenalkan tatasusunan dua dimensi untuk menyimpan nilai terkira lcs(m,n), yang disimpan dalam arr[m-1][n-1]. Apabila memanggil fungsi dengan parameter yang sama m dan n sekali lagi, kami tidak lagi melakukan panggilan rekursif, tetapi terus mengembalikan arr[m-1][n-1], kerana lcs(m, n) yang dikira sebelum ini telah disimpan dalam arr [m-1][n-1], dengan itu mengurangkan bilangan panggilan rekursif.

Memoisasi tiga dimensi

Ini ialah kaedah menghafal untuk program rekursif dengan 3 parameter bukan tetap. Di sini, kami mengambil pengiraan panjang LCS bagi tiga rentetan sebagai contoh.

Pendekatan di sini adalah untuk menjana semua kemungkinan susulan bagi rentetan tertentu (terdapat 3ⁿ kemungkinan susulan kesemuanya) dan memadankan urutan sepunya terpanjang di antaranya.

Kami akan memperkenalkan jadual tiga dimensi untuk menyimpan nilai yang dikira. Pertimbangkan susulan.

  • A1[1...i] i < N

  • A2[1...j] j <

  • Jika kita menemui aksara biasa (X[i]==Y[j]==Z[k]), kita perlu memproses aksara yang tinggal secara rekursif. Jika tidak, kami akan mengira maksimum kes berikut
  • Simpan

Jadi, jika kita menukar idea di atas kepada fungsi rekursif, maka
  • f(N,M,K)={1+f(N -1,M-1,K-1)jika (X[N] ==Y[M]==Z[K]maksimum(f(N-1,M,K),f(N,M-1, K),f(N,M,K-1))}

  • f(N-1,M,K) = Simpan X[i] untuk memproses aksara lain secara rekursif

  • f(N,M- 1,K) = Simpan Y[j] untuk memproses aksara lain secara rekursif

f(N,M,K-1) = Simpan Z[k] Memproses aksara lain secara rekursif

Contoh
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.*;
    class testClass {
       public static int[][][] arr = new int[100][100][100];
       static int calculatelcs(String str_1, String str_2, String str_3, int m, int n, int o) {
             for (int i = 0; i <= m; i++) {
                for (int j = 0; j <= n; j++) {
                   arr[i][j][0] = 0;
                }
             }
             for (int i = 0; i <= n; i++) {
                for (int j = 0; j <= o; j++) {
                   arr[0][i][j] = 0;
                }
             }
             for (int i = 0; i <= m; i++) {
                for (int j = 0; j <= o; j++) {
                   arr[i][0][j] = 0;
                }
             }
             for (int i = 1; i <= m; i++) {
                for (int j = 1; j <= n; j++) {
                   for (int k = 1; k <= o; k++) {
                      if (str_1.charAt(i - 1) == str_2.charAt(j-1) && str_2.charAt(j1) == str_3.charAt(k-1)) {
                         arr[i][j][k] = 1 + arr[i - 1][j - 1][k - 1];
                      }
                      else {
                         arr[i][j][k] = calculateMax(arr[i - 1][j][k], arr[i][j - 1][k], arr[i][j][k - 1]);
                      }
                   }
                }
             }
             return arr[m][n][o];
       }
       static int calculateMax(int a, int b, int c) {
          if (a > b && a > c)
             return a;
             if (b > c)
             return b;
             return c;
       }
       public static void main(String[] args) {
          String str_1 = "clued";
          String str_2 = "clueless";
          String str_3 = "xcxclueing";
          int m = str_1.length();
          int n = str_2.length();
          int o = str_3.length();
          System.out.print("Length of LCS is " + calculatelcs(str_1, str_2, str_3, m, n, o));
       }
    }
    Salin selepas log masuk
  • Output

    Jika kita menjalankan kod di atas, output berikut akan dihasilkan

    Length of LCS is 4
    Salin selepas log masuk
    Salin selepas log masuk
    Salin selepas log masuk

    Atas ialah kandungan terperinci Memoisasi (1D, 2D dan 3D) Pengaturcaraan Dinamik di Jawa. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Nombor Sempurna di Jawa Nombor Sempurna di Jawa Aug 30, 2024 pm 04:28 PM

Panduan Nombor Sempurna di Jawa. Di sini kita membincangkan Definisi, Bagaimana untuk menyemak nombor Perfect dalam Java?, contoh dengan pelaksanaan kod.

Weka di Jawa Weka di Jawa Aug 30, 2024 pm 04:28 PM

Panduan untuk Weka di Jawa. Di sini kita membincangkan Pengenalan, cara menggunakan weka java, jenis platform, dan kelebihan dengan contoh.

Nombor Smith di Jawa Nombor Smith di Jawa Aug 30, 2024 pm 04:28 PM

Panduan untuk Nombor Smith di Jawa. Di sini kita membincangkan Definisi, Bagaimana untuk menyemak nombor smith di Jawa? contoh dengan pelaksanaan kod.

Soalan Temuduga Java Spring Soalan Temuduga Java Spring Aug 30, 2024 pm 04:29 PM

Dalam artikel ini, kami telah menyimpan Soalan Temuduga Spring Java yang paling banyak ditanya dengan jawapan terperinci mereka. Supaya anda boleh memecahkan temuduga.

Cuti atau kembali dari Java 8 Stream Foreach? Cuti atau kembali dari Java 8 Stream Foreach? Feb 07, 2025 pm 12:09 PM

Java 8 memperkenalkan API Stream, menyediakan cara yang kuat dan ekspresif untuk memproses koleksi data. Walau bagaimanapun, soalan biasa apabila menggunakan aliran adalah: bagaimana untuk memecahkan atau kembali dari operasi foreach? Gelung tradisional membolehkan gangguan awal atau pulangan, tetapi kaedah Foreach Stream tidak menyokong secara langsung kaedah ini. Artikel ini akan menerangkan sebab -sebab dan meneroka kaedah alternatif untuk melaksanakan penamatan pramatang dalam sistem pemprosesan aliran. Bacaan Lanjut: Penambahbaikan API Java Stream Memahami aliran aliran Kaedah Foreach adalah operasi terminal yang melakukan satu operasi pada setiap elemen dalam aliran. Niat reka bentuknya adalah

TimeStamp to Date in Java TimeStamp to Date in Java Aug 30, 2024 pm 04:28 PM

Panduan untuk TimeStamp to Date di Java. Di sini kita juga membincangkan pengenalan dan cara menukar cap waktu kepada tarikh dalam java bersama-sama dengan contoh.

Program Java untuk mencari kelantangan kapsul Program Java untuk mencari kelantangan kapsul Feb 07, 2025 am 11:37 AM

Kapsul adalah angka geometri tiga dimensi, terdiri daripada silinder dan hemisfera di kedua-dua hujungnya. Jumlah kapsul boleh dikira dengan menambahkan isipadu silinder dan jumlah hemisfera di kedua -dua hujungnya. Tutorial ini akan membincangkan cara mengira jumlah kapsul yang diberikan dalam Java menggunakan kaedah yang berbeza. Formula volum kapsul Formula untuk jumlah kapsul adalah seperti berikut: Kelantangan kapsul = isipadu isipadu silinder Dua jumlah hemisfera dalam, R: Radius hemisfera. H: Ketinggian silinder (tidak termasuk hemisfera). Contoh 1 masukkan Jejari = 5 unit Ketinggian = 10 unit Output Jilid = 1570.8 Unit padu menjelaskan Kirakan kelantangan menggunakan formula: Kelantangan = π × r2 × h (4

Bagaimana untuk menjalankan aplikasi boot musim bunga pertama anda di Spring Tool Suite? Bagaimana untuk menjalankan aplikasi boot musim bunga pertama anda di Spring Tool Suite? Feb 07, 2025 pm 12:11 PM

Spring Boot memudahkan penciptaan aplikasi Java yang mantap, berskala, dan siap pengeluaran, merevolusi pembangunan Java. Pendekatan "Konvensyen Lebih Konfigurasi", yang wujud pada ekosistem musim bunga, meminimumkan persediaan manual, Allo

See all articles