我无可救药地试图在collatz序列中生成所有数字的无限循环。 该程序应该从一个开始并打印所有可能的collatz,直到用户停止,或者我们得到内存溢出。所以我们必须是一个反向collatz功能。 逻辑将是这样的:(如果n甚至是重复它,如果n / 3是整数,我们进行逆运算,奇数运算。)
import java.math.BigInteger;
public class InverseColatz {
public static void main(String args[]) throws InterruptedException{
BigInteger n = BigInteger.valueOf(2);
System.out.println(1);
while(true){
if(n.mod(BigInteger.valueOf(3)).equals(BigInteger.ZERO)){
n = n.divide(BigInteger.valueOf(3));
n = n.subtract(BigInteger.ONE);
System.out.println(n);
Thread.sleep(500);
}
if(n.mod(BigInteger.valueOf(2)).equals(BigInteger.ZERO)) {
n = n.multiply(BigInteger.valueOf(2));
System.out.println(n);
Thread.sleep(500);
}
}
}
}
问题是我只是生成偶数序列(n * 2),但我无法生成奇数((n / 3)-1),因为此代码永远不会达到奇数条件,因为生成的所有数字都与第一个条件不匹配。有人可以给我一些启示吗? 提前谢谢。
答案 0 :(得分:0)
首先,请原谅我的格式,我不能用图像来显示方程式,因为这是我的第一篇文章。
让我们先来看看Collatz Conjecture。我们知道所涉及的系列被称为Halestone系列,参考所有数字2 n 的行为,其中n是正整数。系列的定义是根据值是奇数还是偶数来递归修改值。
- 如果数字是偶数,则除以2。
- 如果数字为奇数,则将其加倍并添加一个。
要扭转此过程,一个数字可能会有两个结果。例如,5和32都评估为16。
- 5是奇数,(3 * 5)+ 1 = 16
- 32是偶数,32/2 = 16
要找到反函数,我们需要考虑每个数字可以有两个答案。我们还需要定义一个有效的答案。反函数的有效答案必须为正整数。
现在我们做一些代数来得到反转。将 a 定义为Halestone系列的一次迭代的结果。
解决n:
的 名词 强>
3n + 1 = a 2 = a
a - 1
n = 3 n = 2a
所以现在我们有了新的规则。我们知道 n = 2a 总会评估为正整数,因此该表达式始终为true。但是,如果 a - 1 可被3整除,则另一个等式仅计算为正整数。每个其他实例不会返回整数,而是会被追踪通过无限数量的三或六。这些十进制数是不可接受的,将被抛弃。注意4的输入值如何作为答案之一返回1
要开始考虑代码,我们应该将提议的树分解为多个层。与this image的水平分层相似。对于每次迭代,每个分支都有可能分成两个独立的分支。这意味着我们需要在迭代树时存储未知数量的数字。
这就是我想出的。从本质上讲,它仍然只是一个数据流,需要格式化为可读的东西。当堆栈大小用完或并发分支数超过2 31 时,它应该失败 - 这是由于数组的性质。
public static void main(String args[]) throws InterruptedException {
ArrayList<BigInteger> tree = new ArrayList<BigInteger>();
tree.add(BigInteger.valueOf(2));
System.out.println(1);
while (true) {
// Store a snapshot of the current tree so new branches created don't mess with
// the iteration process.
BigInteger[] originalTree = tree.toArray(new BigInteger[tree.size()]);
// Keep track of new branches added during each step for index alignment in
// the stepping method.
int newBranchCount = 0;
// Iterate over the values of the original tree.
for(int i = 0; i < originalTree.length; i++) {
// Evaluate branch
stepBranch(tree, originalTree[i], i + newBranchCount);
// Update branch count after step.
newBranchCount = tree.size() - originalTree.length;
}
}
}
/*
* Given the tree to mutate, a value from a mutation free version of the tree,
* and the current working index of the tree:
* Evaluate whether or not to add a new odd valued branch and report new value(s).
*/
public static void stepBranch(ArrayList<BigInteger> tree, BigInteger branch, int index) throws InterruptedException {
// If (n + 1) is divisible by three, do so and create a new branch to store the new value
if (branch.subtract(BigInteger.ONE).mod(BigInteger.valueOf(3)).equals(BigInteger.ZERO)) {
// If the input is 4, the output is 1 which appears earlier, therefore requires no attention.
if(!branch.equals(BigInteger.valueOf(4))) {
// Create new value.
BigInteger odd = branch.subtract(BigInteger.ONE).divide(BigInteger.valueOf(3));
// If the output is even, it doesn't fit the requirements for an odd cell.
if(!odd.mod(BigInteger.valueOf(2)).equals(BigInteger.ZERO)) {
tree.add(index + 1, odd);
System.out.println(tree.get(index + 1));
}
} else {
System.out.println(1);
}
Thread.sleep(500);
}
// The original branch, not considering a new branch if one was created, is
// multiplied by 2 so as to check for a new odd node in the next iteration.
tree.set(index, branch.multiply(BigInteger.valueOf(2)));
System.out.println(tree.get(index));
Thread.sleep(500);
}
希望这有帮助!