简介
神经网络能否模拟阶乘分解(或其他方法)来提供给定排列唯一索引的列表排列?
应用
我有一份包含10个项目的列表,这些项目是什么并不重要。重要的是我的10个项目可以被排列成3628800种(或10!)独特的顺序,这样我就可以使用无符号整数和阶乘分解来表达我的10个项目的任何列表顺序:
顺序0:0, 1, 2, 3, 4, 5, 6, 7, 8, 9顺序1:0, 1, 2, 3, 4, 5, 6, 7, 9, 8顺序....顺序3628799:9, 8, 7, 6, 5, 4, 3, 2, 1, 0
这允许对我的10个项目的不同列表顺序进行并行分析分配。
一个常见的例子是旅行商问题:
1. 我给500台不同的计算机分配了一系列无符号整数: 0 -> 7257 用于计算机0, 7257 -> 14516 用于计算机1, 等等。2. 每台计算机首先通过使用阶乘分解从其无符号整数索引计算列表顺序。 例如,顺序1 -> 0, 1, 2, 3, 4, 5, 6, 7, 9, 83. 计算按所描述顺序排列的城市之间的距离。4. 收集每台计算机的最短距离,并从中选出最短的距离。这样我们就得到了一个单一的无符号整数索引,它描述了城市的最短可能排列。
同样的过程可以用来解决几乎任何可界定的误差表面,通常需要远超可行的计算能力。
递归算法解决方案
我们可以使用阶乘分解计算任何固定大小列表的第N个排列(当然,对于较大的列表,我们需要大整数支持)(这里用php描述),并在这里用javascript提供以便于理解:
function ithPermutationOfNElements (n, i){ var j, k = 0; var fact = []; var perm = []; // 计算阶乘数 fact[k] = 1; while (++k < n) fact[k] = fact[k - 1] * k; // 计算阶乘代码 for (k = 0; k < n; ++k) { perm[k] = Math.floor(i / fact[n - 1 - k]); i = i % fact[n - 1 - k]; } // 调整值以获得排列 // 从末尾开始,检查前面的值是否较低 for (k = n - 1; k > 0; --k) for (j = k - 1; j >= 0; --j) if (perm[j] <= perm[k]) perm[k]++; return perm;}console.log(ithPermutationOfNElements(4, 23)); // [ 3, 2, 1, 0 ]
神经网络解决方案?
任何神经网络架构和训练组合能否模拟这个函数,仅以i作为其输入神经元,并以n个输出神经元表示排列的每个元素?
回答:
一个神经元可以作为逻辑门操作,因此神经网络可以执行计算机可以执行的任何计算。然而,从这个意义上说,它只是低效地模拟逻辑门,使用高级代码,因此对于这个问题来说不是一个好的解决方案。
一般来说,神经网络擅长处理“真实”或“自然”数据。它们通常也使用浮点数而不是整数操作。所以如果有模式要学习,神经网络可能会学会,但你得到的输出答案将是例如0.783267。你可以将其去归一化为89743,但不太可能完全正确。对于你的需求,偏离正确答案一个整数完全是错误的。
相比之下,对于人脸识别神经网络,对于特定图像返回0.787或0.786,都可以被认为是正确的。
你的问题更适合传统的、过程性代码解决方案,每个输入只有一个正确答案。一般来说,在人工智能中,你是在寻找某个范围或概率分布内的正确答案。
关于用神经网络实现算法:
你可以有很多神经元作为逻辑门操作,所以现在你有神经元nand门/触发器等作为加法器/乘法器/锁存器等,直到你基本上构建了一台图灵机,但明确使用高级代码。这将完全不像大多数AI世界中使用的神经网络。此外,你面前已经有一台完美的图灵机了。
这是Matlab中神经网络AND门的代码。不需要训练。我使用了configure
而不是train
,并手动设置了权重。所以你可以制作其他逻辑类型,你可以构建一个完整的图灵机。
and = feedforwardnet(1);truthTable = [0 0 1 1; 0 1 0 1];and_out = [0 0 0 1];and = configure(and, truthTable, and_out);vals = [-2 -2 -1 2 0];and.IW{1} = vals(1:2); % input1 to hidden, input2 to hiddenand.LW{2,1} = vals(3); % hidden to outputand.b{1} = vals(4); % bias to hiddenand.b{2} = vals(5); % bias to outputy = sim(and, truthTable)round (y)mse = mean ((y - and_out) .^ 2)y = 0.0000 0.0180 0.0180 0.9820ans = 0 0 0 1mse = 2.4263e-04