Semestrální práce z předmětu
Teoretická informatika.
36TI
Teoretická informatika.
36TI
Vypracoval: Jan Saidl
Datum: 28.12.2002
Datum: 28.12.2002
Úloha číslo 2 z českých úloh
Zadání:
Jsou dána čísla 1, 2, ... N. Tato čísla lze permutovat právě N! způsoby. Permutace lze seřadit v rostoucím lexikografickém pořadí:
0, 1, ... N-3, N-2, N-1
0, 1, ... N-3, N-1, N-2
0, 1, ... N-1, N-2, N-2
. . .
N-1, N-2,.... 0, 1
N-1, N-2,.... 1, 0
Navrhněte, popište a implementujte algoritmus, který pro zadané i vytvoří i-tou permutaci. Určete výpočetní složitost algoritmu v závislosti na hodnotě N.
Implementace (Applet JAVA):
Operační složitost:
Paměťová složitost je lineární, v každé části algoritmu je potřeba si pamatovat pouze N znakové pole členů permutace.
Paměťová složitost:
Algoritmus provádí N-1 dělení indexu I řádem, který se v každém cyklu snizuje N-krát. V nejhořím případě, kdy výsledkem je permutace
s indexem 0, dochází k n^2/2 presunům v poli dostupných členů permutace. Operační složitost algoritmu je O(N^2).
Tato kvadratická složitost by se dala odstranit, kdyby pole dostupných členů permutace bylo reprezentováno spojovým seznamem. Vypuštění jednoho členu by proběhlo s konstatní složisostí.
Operační složitost algoritmu by v tomto případě byla O(N).
Popis algoritmu:
Nejprve je vygenerováno pole dostupných členů permutace (max. 12) a spočítán nejvyšší řád N! permutace. V N-1 průchodech je určeno N-1 členů hledané permurtace, od nejvyššího řádu.
Index X-tého členu je výsledek celočíselného dělení indexu I X-tým řádem. Nový index je zbytek po tomto dělení a řád se snižuje na (X-1)!. Po N-1 cyklech je určeno N-1 členů permutace a poslední člen je na nultém indexu pole dostupných členů permutace.
Zdrojový text:
package permutace;
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class AppletPermutace extends Applet {
// implementace GUI
boolean isStandalone = false;
private Label lable_velikost;
private Label lable_index;
private Label vysledekLB;
private TextField velikost;
private TextField index;
private Button buttonGo;
private GridBagLayout gbl;
private GridBagConstraints gbc;
private class ButtonGoClick implements ActionListener {
public void actionPerformed(ActionEvent p) {
String result = countPerm(velikost.getText(),index.getText());
vysledekLB.setText(result);
}
}
private void vlozComponentu(Component c, int gridx, int gridy) {
gbc.gridx = gridx;
gbc.gridy = gridy;
gbl.setConstraints(c,gbc);
add(c);
}
private void initMetoda() {
// implementace GUI
lable_velikost = new Label("delka permutace N: ");
lable_index = new Label("index permutace I: ");
velikost = new TextField("");
vysledekLB = new Label("");
index = new TextField("");
buttonGo = new Button("Spocti");
buttonGo.addActionListener(new ButtonGoClick());
gbl = new GridBagLayout();
this.setLayout(gbl);
this.setBackground(Color.white);
gbc = new GridBagConstraints();
gbc.insets = new Insets(2,2,2,2);
gbc.anchor = gbc.WEST;
vlozComponentu(lable_velikost,0,0);
gbc.weightx = 1.0;
gbc.fill = GridBagConstraints.HORIZONTAL;
vlozComponentu(velikost,0,1);
gbc.anchor = gbc.WEST;
vlozComponentu(lable_index,0,2);
gbc.weightx = 1.0;
gbc.fill = GridBagConstraints.HORIZONTAL;
vlozComponentu(index,0,3);
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0.0;
gbc.anchor = gbc.CENTER;
vlozComponentu(buttonGo,0,4);
gbc.anchor = gbc.CENTER;
gbc.fill = GridBagConstraints.HORIZONTAL;
vysledekLB.setSize(200,20);
vlozComponentu(vysledekLB,0,5);
}
// Initialize appletu
public void init() {
try {
initMetoda();
}
catch(Exception e) {
e.printStackTrace();
}
}
// funkce pro vypocet I-te permutace
public static String countPerm(String NStr, String IStr) {
int NValue = 0; // N je delka permutace
int IValue = 0; // I je index hledane permutace
try { // pokus o prevedeni N na cislo
Integer N = new Integer(NStr);
NValue = N.intValue();
} catch(NumberFormatException ex) {
return "CHYBA N neni cislo nebo je mimo rozsah";
}
// kontrola rozsahu N maximum je N = 12 protoze 13! = 6227020800 > integer.MAX_VALUE = 2147483647
if ((NValue > 12) || (NValue < 1)) { return "CHYBA N mimo rozsah <1,12>"; }
try { // pokus o prevedeni I na cislo
Integer I = new Integer(IStr);
IValue = I.intValue();
} catch(NumberFormatException ex) {
return "CHYBA I neni cislo nebo je mimo rozsah";
}
int rad = 1; // vypocet maximalniho radu permutace = N!
for (int x = NValue; x > 0; x--) {
rad = rad * x;
}
// overeni zda I je v intervalu <0 ; N!-1>
if ((IValue >= rad) || (IValue < 0)) { return "CHYBA I mimo rozsah <0,"+(new Long(rad-1)).toString()+">"; }
rad = rad / NValue;
String chars = new String("0123456789AB"); // pojmenovani jednotlivych dostupnych clenu premutace
String perm = new String(""); // inicializace vysledne premutace
while (NValue > 1) { // pres vsechny cleny permutace
NValue--;
int divx = IValue / rad; // urci N-ty clen permutace
IValue = IValue % rad; // urci zbytek po N-tem clenu permutace
perm = perm + chars.charAt(divx); // pridej N-ty clen permutace do vysledne permutace
chars = chars.substring(0,divx) + chars.substring(divx+1); // a odstran ho z dostupnych clenu
rad = rad / NValue; // sniz rad permutace
}
perm = "Permutace = "+ perm + chars.charAt(0); // pouzij posledni dostupny clen permutace
return perm; // vrat vypoctenou permutaci
}
}
|