Permutaciones, combinaciones, variaciones y particiones
Librería en Java para generar permutaciones, combinaciones, variaciones y particiones, con un programa para testearlas.
Permutador.java
package combinatoria;
public class Permutador {
private int fact;
private int cuenta;
private int[] vector;
public Permutador(int[] vec) {
vector = vec;
cuenta = 0;
}
// genera una nueva permutación del vector
// retorna true si aún quedan permutaciones
// o false si las ha generado todas
public boolean permutar() {
return permutar(0, vector.length);
}
boolean permutar(int inicio, int tam) {
if(tam > 1) {
if(!permutar(inicio + 1, tam - 1)) {
rotar(inicio);
}
fact *= tam;
} else {
cuenta++;
fact = 1;
}
return cuenta % fact != 0;
}
void rotar(int inicio) {
int i, primero;
primero = vector[inicio];
for(i = inicio + 1; i < vector.length; i++) {
vector[i-1] = vector[i];
}
vector[i-1] = primero;
}
}
Combinador.java
Permutador.java
package combinatoria;
public class Permutador {
private int fact;
private int cuenta;
private int[] vector;
public Permutador(int[] vec) {
vector = vec;
cuenta = 0;
}
// genera una nueva permutación del vector
// retorna true si aún quedan permutaciones
// o false si las ha generado todas
public boolean permutar() {
return permutar(0, vector.length);
}
boolean permutar(int inicio, int tam) {
if(tam > 1) {
if(!permutar(inicio + 1, tam - 1)) {
rotar(inicio);
}
fact *= tam;
} else {
cuenta++;
fact = 1;
}
return cuenta % fact != 0;
}
void rotar(int inicio) {
int i, primero;
primero = vector[inicio];
for(i = inicio + 1; i < vector.length; i++) {
vector[i-1] = vector[i];
}
vector[i-1] = primero;
}
}
Combinador.java
package combinatoria;
import java.util.ArrayList;
public class Combinador {
public static ArrayList<int[]> combinar(int[] vec, int tam) {
ArrayList<int[]> lista = new ArrayList<>();
if(tam > 0 && tam <= vec.length) {
Permutador p = new Permutador(vec);
int[] sub = new int[tam];
do {
for(int i = tam-1; i < vec.length; i++) {
int j = i;
int k = tam;
while(k > 0) {
sub[--k] = vec[j--];
}
ordenar(sub);
for(j = 0; j < lista.size() &&
!igual(sub, lista.get(j)); j++);
if(j == lista.size()) {
lista.add(sub.clone());
}
}
} while(p.permutar());
}
return lista;
}
static boolean igual(int[] p, int[] q) {
int i;
for(i = 0; i < p.length && p[i] == q[i]; i++);
return i == p.length;
}
static void ordenar(int[] v) {
boolean hayCambio;
int t = v.length;
do {
hayCambio = false;
for(int i = 1; i < t; i++) {
if(v[i-1] > v[i]) {
int x = v[i];
v[i] = v[i-1];
v[i-1] = x;
hayCambio = true;
}
}
t--;
} while(hayCambio);
}
}
Variador.java
package combinatoria;
import java.util.ArrayList;
public class Variador {
public static ArrayList<int[]> variar(int[] vec, int tam) {
ArrayList<int[]> lista = new ArrayList<>();
if(tam > 0 && tam <= vec.length) {
Permutador p = new Permutador(vec);
int[] sub = new int[tam];
do {
for(int i = tam-1; i < vec.length; i++) {
int j = i;
int k = tam;
while(k > 0) {
sub[--k] = vec[j--];
}
for(j = 0; j < lista.size() &&
!igual(sub, lista.get(j)); j++);
if(j == lista.size()) {
lista.add(sub.clone());
}
}
} while(p.permutar());
}
return lista;
}
// p.length == q.length
static boolean igual(int[] p, int[] q) {
int i;
for(i = 0; i < p.length && p[i] == q[i]; i++);
return i == p.length;
}
}
Particion.java
package combinatoria;
import java.util.ArrayList;
public class Particion implements Cloneable, Comparable<Particion> {
public final ArrayList<Integer> partes;
public int numero;
private Particion() {
partes = new ArrayList<>();
}
Particion(int num) {
this();
numero = num;
partes.add(num);
}
private void setNumero(int num) {
numero = num;
}
@Override
protected Particion clone() {
Particion nueva = new Particion();
nueva.setNumero(numero);
for(int i : partes) {
nueva.partes.add(i);
}
return nueva;
}
void extender() {
partes.add(0, partes.remove(0)-1);
partes.add(1);
}
void agrupar(int i) {
int val = partes.get(i) + partes.get(i+1);
partes.remove(i+1);
partes.remove(i);
partes.add(i, val);
}
int get(int i) {
return i < partes.size()? partes.get(i) : 0;
}
public int size() {
return partes.size();
}
public int[] toArray() {
int tam = 0;
for(int p : partes) {
tam += p;
}
return toArray(tam);
}
public int[] toArray(int tam) {
int[] vec = new int[tam];
int i = 0;
while(i < tam && i < partes.size()) {
vec[i] = partes.get(i);
i++;
}
while(i < tam) {
vec[i++] = 0;
}
return vec;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
for(int i : partes) {
sb.append(" " + i);
}
return sb.toString();
}
@Override
public int compareTo(Particion otra) {
int lim = size() < otra.size() ? size() : otra.size();
int dif = get(0) - otra.get(0);
int i = 0;
while(dif == 0 && ++i < lim) {
dif = get(i) - otra.get(i);
}
return dif;
}
}
Partidor.java
package combinatoria;
import java.util.ArrayList;
public class Partidor {
public final ArrayList<Particion> particiones;
public final int numero;
public Partidor(int num) {
this.numero = num;
particiones = new ArrayList<Particion>();
particiones.add(new Particion(num));
extender(0);
}
void extender(int i) {
Particion par = particiones.get(i);
if(par.get(0) > 1) {
Particion nueva = par.clone();
nueva.extender();
particiones.add(nueva);
extender(i+1);
} else {
agrupar(0, 1);
}
}
void agrupar(int i, int pos) {
Particion par = particiones.get(i);
if(pos < par.size() - 1) {
int anterior = par.get(pos-1);
int nuevo = par.get(pos) + par.get(pos+1);
if(nuevo <= anterior) {
Particion nueva = par.clone();
nueva.agrupar(pos);
particiones.add(nueva);
}
}
if(++i < particiones.size()) {
agrupar(i, pos);
} else if(++pos < numero-2) {
agrupar(0, pos);
}
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
int j = 0;
for(Particion p : particiones) {
sb.append(String.format("\n[%2d] ", ++j) + p);
}
return sb.toString() + "\n";
}
public void ordenar() {
boolean hayCambio;
int tam = particiones.size();
do {
hayCambio = false;
Particion p = particiones.get(0);
for(int i = 1; i < tam; i++) {
Particion q = particiones.get(i);
if(p.compareTo(q) < 0) {
particiones.set(i-1, q);
particiones.set(i, p);
hayCambio = true;
} else {
p = q;
}
}
tam--;
} while(hayCambio);
}
public ArrayList<Particion> get() {
return particiones;
}
public static ArrayList<int[]> partir(int num) {
ArrayList<Particion> particiones =
new Partidor(num).particiones;
ArrayList<int[]> lista = new ArrayList<>();
for(Particion p : particiones) {
lista.add(p.toArray());
}
return lista;
}
}
Comentarios
Publicar un comentario