置换代数运算主要是化简和将代数变量替换为数值转为数值运算。举个例子哈,比如计算(a b c)(a b d)(a b e)(a b f)(a b g)。这手算就比较慢,计算机计算马上就出来了,结果为(a d f b c e g)。其核心类的类图和数值运算相似:
EmptyAlgebraDisplaceExpression代表恒等置换
CompositeAlgebraDisplaceExpression代表置换组合
CyclicAlgebraDisplaceExpression代表轮换
接口核心方法有三个:
/**
* 变量表
* @param variables 变量表
* @return
*/
DisplaceExpression apply(Map<String,Integer> variables);
/**
* 被移动到哪个位置
* @param position 位置
* @return 下一个位置
*/
String next(String position);
/**
* 变量表
* @return 所有变量
*/
Set<String> variables();
核心实现方法如下:
循环置换代数运算实现类
@Override
public DisplaceExpression apply(Map<String, Integer> variables) {
int[] positions = new int[cyclic.length];
for (int i = 0; i < cyclic.length; i++) {
positions[i] = variables.get(cyclic[i]);
}
return new CyclicDisplaceExpression(positions);
}
@Override
public String next(String position) {
for (int i = 0; i < this.cyclic.length; i++) {
if (Objects.equals(cyclic[i], position)) {
return cyclic[(i + 1) % this.cyclic.length];
}
}
return null;
}
@Override
public Set<String> variables() {
return new HashSet<>(Arrays.asList(cyclic));
}
组合置换代数运算实现类:
@Override
public DisplaceExpression apply(Map<String, Integer> variables) {
final ArrayList<DisplaceExpression> expressions = new ArrayList<>();
for (AlgebraDisplaceExpression e : this.expressions) {
expressions.add(e.apply(variables));
}
return new CompositeDisplaceExpression(expressions);
}
@Override
public String next(String position) {
String next = position;
for (AlgebraDisplaceExpression e : this.expressions) {
final String n = e.next(next);
if (n != null) {
next = n;
}
}
return next;
}
@Override
public Set<String> variables() {
final HashSet<String> strings = new HashSet<>();
for (AlgebraDisplaceExpression e : expressions) {
strings.addAll(e.variables());
}
return strings;
}
组合运算化简方法:
public AlgebraDisplaceExpression simplify() {
// 代数运算的化简
final TreeMap<String, String> positionMap = new TreeMap<>();
// 第一步是要获取所有的变量
final Set<String> variables = this.variables();
for (String variable : variables) {
// 过滤掉自己映射到自己的特殊情况
final String next = this.next(variable);
if (!Objects.equals(variable, next)) {
positionMap.put(variable, next);
}
}
List<AlgebraDisplaceExpression> result = new ArrayList<>();
// 组成最简表达式
while (!positionMap.isEmpty()) {
List<String> cyclic = new ArrayList<>();
final Map.Entry<String, String> firstEntry = positionMap.firstEntry();
for (String k = firstEntry.getKey(), v = firstEntry.getValue();
!cyclic.contains(k);
k = v, v = positionMap.get(k)) {
cyclic.add(k);
}
cyclic.forEach(positionMap::remove);
result.add(new CyclicAlgebraDisplaceExpression(cyclic.toArray(new String[0])));
cyclic.clear();
}
if (result.isEmpty()) {
return EmptyAlgebraDisplaceExpression.INSTANCE;
}
if (result.size() == 1) {
return result.get(0);
}
return new CompositeAlgebraDisplaceExpression(result);
}
恒等置换,依旧使用枚举实现单例模式,代码比较简单:
public enum EmptyAlgebraDisplaceExpression implements AlgebraDisplaceExpression{
INSTANCE;
@Override
public DisplaceExpression apply(Map<String, Integer> variables) {
return EmptyDisplaceExpression.INSTANCE;
}
@Override
public String next(String position) {
return position;
}
@Override
public Set<String> variables() {
return Collections.emptySet();
}
@Override
public String toString() {
return "e";
}
}
Git地址: https://e.coding.net/buildt/math/displace.git