package permutation;
import java.util.Scanner;
class Digit {
int value;
String direction;
public Digit(){};
}
public class NeighbourExchangePermutation {
public int factorial(int n) {
int sum = 1;
while (n > 1) {
sum *= (n--);
}
return sum;
}
// get initialization permutation of scale is number
public Digit[] creatPermutation(int number) {
Digit[] permutation = new Digit[number];
for (int i = 0; i < number; ++i) {
// initialization of object
permutation[i] = new Digit();
permutation[i].value = i + 1;
permutation[i].direction = "left";
}
return permutation;
}
// get interNumber of permutation given;
public int[] getInterNumber(Digit[] permutation) {
// initialization for digit 2 direction is left
String digitDirection = "left";
int[] b = new int[permutation.length - 1];
//find interNumber[permutation.length - 1] to interNumber[2]
int j;
for(int i = 0 ; i < permutation.length - 1 ; ++ i) {
int digit = i + 2 ,count = 0;
boolean flag = true;//next digit has same direction with current digit
for(j = 0 ; j < permutation.length ; ++j) {
if(i > 0) {
//digit is odd then its direction decided by b[i-1]
if(digit % 2 == 1) {
if(b[i - 1] % 2 == 1) digitDirection = "right";
else digitDirection = "left";
}
//digit is even then its direction decided by sum b[i-1] with b[i-2]
if(digit % 2 == 0) {
if( (b[i - 1] + b[ i - 2]) % 2 == 1) digitDirection = "right";
else digitDirection = "left";
}
}
if(permutation[j].value == digit) {
if(digitDirection.endsWith("left")) {
for(int k = permutation.length - 1 ; k > j ;-- k ) {
if(permutation[k].value < digit) ++count;
}
}
else if(digitDirection.endsWith("right")) {
for(int k = 0 ; k < j ; ++ k) {
if(permutation[k].value < digit) ++count;
}
}
b[i] = count;break;
}
if(permutation[j].value == digit + 1) flag = false;
}
/**
System.out.println("digit = " + digit + "\t poistion = " + j +"\t direction = " + digitDirection );
*/
}
return b;
}
// next interNumber
public int[] nextInterNumber(int[] originalInterNumber) {
for (int i = originalInterNumber.length - 1; i >= 0; --i) {
int pow = i + 2;
if (++originalInterNumber[i] >= pow) {
originalInterNumber[i] -= pow;
} else {
return originalInterNumber;
}
}
return originalInterNumber;
}
// get permutation via interNumebr given
public Digit[] getPermutation(int[] b) {
Digit[] permutation = new Digit[b.length+1];
String direction = "";
for(int i = 0 ; i < b.length + 1 ; ++ i) {
permutation[i] = new Digit();
permutation[i].value = 0;
}
//there are b.length+1 digit to fill the spaces
for(int j = b.length - 1 ; j >=0 ; -- j ) {
int digit = j + 2;
//judge j odd or even
if(j>=1){
if(digit % 2 == 1){
if(b[j-1] % 2 == 1) direction = "right";
else direction = "left";
}else{
if((b[j-1] + b [j-2]) % 2 == 1) direction = "right";
else direction = "left";
}
}
if(digit == 2 ) direction = "left";
//set the digit in right position
int count = b[j];
if(direction.endsWith("left")) {
int pos = b.length +1 ;
while( count>=0 && (--pos)>=0){
if(permutation[pos].value == 0)--count;
if(count < 0){
permutation[pos].value = digit;
}
}
}
if(direction.endsWith("right")) {
int pos = - 1 ;
while( count>=0 && (++pos) <= b.length){
if(permutation[pos].value == 0)--count;
if(count < 0){
permutation[pos].value = digit;
}
}
}
}
int pos = -1;
while(permutation[++pos].value!=0);
permutation[pos].value = 1;
return permutation;
}
//public
public void neighbourExchangePermutation(Digit[] permutation){
for(int i = 0 ; i < factorial(permutation.length);++i) {
int[] original = getInterNumber(permutation);
for(int j = 0 ; j < permutation.length ; ++ j){
System.out.print(permutation[j].value);
}
System.out.print("\t");
for(int k = 0 ; k < original.length ; ++ k)
System.out.print(original[k]);
System.out.println();
original = nextInterNumber(original);
permutation = getPermutation(original);
}
}
// test
public static void main(String[] args) {
NeighbourExchangePermutation nep = new NeighbourExchangePermutation();
Scanner scan = new Scanner(System.in);
System.out.println("Please input scale of permutaion: ");
int scale = scan.nextInt();
nep.neighbourExchangePermutation(nep.creatPermutation(scale));
}
}
邻位互换法—全排列
最新推荐文章于 2022-04-05 13:00:50 发布
本文介绍了一种使用邻位互换法生成全排列的算法。通过创建初始排列,获取交换数,计算下一个排列以及从交换数还原排列,实现了全排列的遍历。算法基于Java实现,适用于组合数学和全排列问题的研究。
摘要由CSDN通过智能技术生成