Cvičení 6: Pole, matice

Inicializace a kopírování 2D polí

  • Projdeme si inicializaci a kopírování 1D a více-D polí. Spusťte následující kód a na konci si vytiskněte jednotlivá pole. Co pozorujeme?

# Inicializace pole
a = [0] * 5
 
# Jak správně zkopírovat pole?
b = a
c = a[:]
d = list(a)
 
a[3] = 3
b[0] = -5
c[4] = 4

  • Spusťte následující kód a opět si na konci vypište jednotlivá pole.

# Inicializace 2D pole přímo
a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
 
# Inicializace po řádcích
f = []
for i in range(3):
    f.append([i] * 3)
 
# Inicializace po řádcích ve zkráceném zápisu
g = [[i] * 3 for i in range(3)]
 
# Jak správně zkopírovat pole?
b = a
c = a[:]
d = list(b)
e = [ r[:] for r in a ]
f = [ list(a[i]) for i in range(len(a))]
 
a[0][0] = -1
b[0][1] = -2 
c[0],c[1]=c[1],c[0]
d[1][0] = -3
e[1][1] = -4

  • Pokud chceme opravdovou kopii vícedimenzionálního pole, tvz. deep copy, můžeme použít modul copy a funkci deepcopy. Doplňte import a kopírování do předchozí ukázky a porovnejte výsledky.

import copy
 
d = copy.deepcopy(b)

Life

  • Hru Life navrhl v roce 1970 matematik John Horton Conway.
  • Pravidla hry jsou jednoduchá:
    • pokud jsou v okolí jedné buňky živé právě 3 buňky, pak v této buňce život vznikne (nebo zůstane)
    • pokud je buňka živá a v jejím okolí jsou právě 2 živé buňky, pak tato buňka bude žít i nadále
    • v ostatních případech buňka zahyne buď na osamění, nebo přemnoženost
  • Uvažujte osmiokolí: 8 sousedních buněk.
  • Uvažujte uzavřený svět, tedy sousední políčko pro první pole řádku je poslední pole řádku, sousední pole pro první řádek je poslední řádek
  • Napište program, který bude simulovat 40 kroků hry life pro toto počáteční pole:

a = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0, 1, 1, 1, 0],
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     [0, 0, 1, 0, 1, 0, 0, 0, 0, 0],
     [0, 0, 0, 1, 1, 0, 0, 0, 0, 0],
     [0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
   ]

  • Vygenerování prázdného pole

[[0]*len(a[0]) for i in a]

  • Pro lepší zobrazení udělejte po každém kroku pauzu

import time
time.sleep(0.5)

  • Také můžete vylepšit zobrazení tak, že místo 1 budete tisknout X a místo 0 mezeru

''.join('X' if i!=0 else ' ' for i in x)

Prohození řádků matice

  • Napište program, který načte matici a následně permutaci, která definuje prohození řádků matice. Na výstup program vytiskne matici s řádky prohozenými podle zadané permutace.

Gaussova eliminační metoda

  • Gaussova eliminační metoda je metodou řešení soustavy lineárních algebraických rovnic. GEM lze využít pro výpočet inverzní matice nebo determinantu matice.

Krok 1: Nalezení největšího prvku ve sloupci

  • Napište funkci maximum(M, i), která pro zadanou matici M a index (číslo) i najde takový index řádku j v rozsahu range(i, len(M)) jehož absolutní hodnota M[j][i] je maximální. Využijte vestavěnou funkci abs.

Krok 2: Prohození řádku

  • Napište funkci swap_rows(M, i), která prohodí řádek i a řádek s indexem j = maximum(M, i), pokud i != j.

Krok 3: Úprava řádku

  • Napište funkci do_line(M, i), která zavolá funkci swap_rows(M, i) a pokud:
    • M[i][i] != 0:
      • celý řádek i matice M vydělí hodnotou M[i][i]
      • od všech řádků r v rozsahu range(i + 1, len(M)) odečte M[r][i]-násobek řádku i
      • vrátí hodnotu True
    • jinak vrátí False

Krok 4: Gausova eliminace

  • Napište funkci GEM(M), která pro všechna i z rozsahu range(len(m)) zavolá funkci do_line(M, i)
  • Pokud je návratová hodnota funkce do_line() alespoň 1x False, metoda GEM() vrací False. V opačném případě vrací True.

Příklad

  • Spusťte funkci GEM() pro matici:

m=[[12,-7,3, 26],
   [4 ,5,-6, -5],
   [-7 ,8,9, 21]]

Použití modulu fraction

Využijte ve výpočtu úkolu 3 zlomků namísto reálných čísel. K tomu využijte Python modul fraction (from fractions import Fraction) pomocí kterého přemapujte prvky matice M na typ Fraction (zlomek):

M_fr = [list(map(Fraction, v)) for v in M]
GEM(M_fr)

Výsledek GEM lze transformovat zpět na reálná čísla pomocí:

result = [list(map(float, v)) for v in M_fr]

Domácí úkol

courses/b3b33alp/cviceni/t06.txt · Last modified: 2024/11/12 17:06 by vonasvoj