- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试在 javascript 中内存一个函数,以便在客户端的浏览器中运行。用 R(我最习惯使用的语言)编写此函数。在 R 中,我看到使用记忆化的显着好处(P_n(7/10, 20, 15, 6, 1) 的运行时间从 4 分钟缩短到 0.02 秒)。当我用 javascript 重写函数时,我几乎看不到任何好处。我的 javascript 代码有什么问题(或者我完全以错误的方式解决这个问题)?
下面分别是R和javascript中的memoized函数。与朴素的递归相比,R 函数(两者中的第一个)运行得非常快,而 javascript 基本上看不出有什么区别。然而,一些记忆化正在发生,因为如果我运行完全相同的函数调用两次,即 P_memo(7/10, 20, 15, 6, 1) 然后是 P_memo(7/10, 20, 15, 6, 1 ) ,第二次调用花费 0 时间。由于在递归中重复使用中间调用,第一次调用应该会快得多。
P_n <- (function() {
# Memoization handled through the use of cache
cache <- NULL
cache_reset <- function() {
cache <<- new.env(TRUE, emptyenv())
}
cache_set <- function(key, value) {
assign(key, value, envir = cache)
}
cache_get <- function(key) {
get(key, envir = cache, inherits = FALSE)
}
cache_has_key <- function(key) {
exists(key, envir = cache, inherits = FALSE)
}
# Initialize the cache
cache_reset()
# This is the function that gets returned by the anonymous function and
# becomes P_n
function(rho, n, i, k, s) {
nc <- paste(rho, n, i, k, s)
# Handle "vectors" by element
if(length(n) > 1){
return(lapply(n, function(n) sapply(n, P_n, rho = rho, i = 1:(n+k), k = k, s = s)))
}
if (length(i) > 1) {
return(sapply(i, P_n, rho = rho, n = n, k = k, s = s))
}
# Cached cases
if (cache_has_key(nc))
return(cache_get(nc))
# Everything else
#proposition 1
if(i == (n+k)){
#print('Proposition 1')
if(k >= s){
return((rho / (rho + 1))^n)
}else if( (k+n) <= s){
product_iter = 1
for(j in 1:n){
product_iter = product_iter * ( rho + (k + j - 1)/s )
}
out = rho^n / product_iter
cache_set(nc, out)
return(out)
}else if( k < s & s < (k + n)){
product_iter2 = 1
for(j in 1:(s-k)){
product_iter2 = product_iter2 * ( rho + (k + j - 1)/s )
}
product_denom = ((rho + 1)^(n-s+k)) * product_iter2
out = rho^n / product_denom
cache_set(nc, out)
return(out)
}
}
#proposition 2
else if(k == 0 & n == i){
#print('Proposition 2')
if(n <= s){
product_iter11 = 1
for(j in 1:n){
product_iter11 = product_iter11 * (rho + (j - 1)/s)
}
return(rho^n / product_iter11)
}else if(n > s){
product_iter12 = 1
for(j in 1:s){
product_iter12 = product_iter12 * ( rho + (j - 1)/s )
}
product_denom12 = ((rho + 1)^(n-s)) * product_iter12
out = rho^n / product_denom12
cache_set(nc, out)
return(out)
}
}
#if i = 1
else if(i == 1){
upsum = 0
for(j in 2:(n + k)){
upsum = upsum + P_n(rho, n, j, k, s)
}
out = 1 - upsum
cache_set(nc, out)
return(out)
}
#proposition 3
else if(n == 1 & 2 <= i & i <= k){
#print('Proposition 3')
if(k <= s){
begin = rho / (rho + (i - 1)/s)
product_iter13 = 1
for(j in 1:(k-i+1)){
product_iter13 = product_iter13 * (1 - rho / (rho + (k - j + 1)/s) )
}
out = begin * product_iter13
cache_set(nc, out)
return(out)
}else if(k > s & i > s){
out = rho / (rho+1)^(k-i+2)
cache_set(nc, out)
return(out)
}else if(i <= s & s <= k){
begin2 = rho / (( rho + 1 )^(k - s + 1) * ( rho + (i - 1)/s))
product_iter14 = 1
for(j in 1:(s-i)){
product_iter14 = product_iter14 * (1 - rho / (rho + (s - j)/s) )
}
out = begin2 * product_iter14
cache_set(nc, out)
return(out)
}
}
#proposition 4
else if( n >= 2 & 2 <= i & i <= (k + n - 1)){
#print('Proposition 4')
if(i>s){
begin11 = rho/(rho+1)
product_iter21 = 0
for(j in (i-1):(k+n-1)){
product_iter21 = product_iter21 + (1 / (rho+1))^(j-i+1) * P_n(rho, n-1, j, k, s)
}
out = begin11 * product_iter21
cache_set(nc, out)
return(out)
}else if(i <= s){
begin12 = rho / (rho + (i-1)/s)
summer1 = 0
for(j in (i-1):(s-1)){
product_iter22 = 1
for(h in 1:(j-i+1)){
product_iter22 = product_iter22 * (1 - rho / (rho + (j - h + 1) / s))
}
summer1 = summer1 + product_iter22 * P_n(rho, n-1, j, k, s)
}
product_iter23 = 1
for(h in 1:(s-i)){
product_iter23 = product_iter23 * (1 - rho / (rho + (s-h) / s))
}
summer2 = 0
for(j in s:(k+n-1)){
summer2 = summer2 + ((1 / (rho + 1))^(j-s+1) * P_n(rho, n-1, j, k, s))
}
bottom = product_iter23 * summer2
inner = summer1 + bottom
out = begin12 * inner
cache_set(nc, out)
return(out)
}
}
#check if missed all propositions
else{
stop("No proposition detected")
}
}
})()
var P_memo = (function() {
var memo = {};
var slice = Array.prototype.slice;
function f(rho, n, i, k, s){
var args = slice.call(arguments);
var value;
if (args in memo) {
return(memo[args]);
}else{
// NOTES ON THE UNITS OF INPUTS
//rho: ratio of lambda / tau
// n: arrival of nth customer
// i: are i customers in queue
// k : number of customers at t = 0
// s: machines in use
//proposition 1
if(i == (n+k)){
//print('Proposition 1')
if(k >= s){
return(Math.pow(rho / (rho + 1), n));
}else if( (k+n) <= s){
var product_iter = 1;
for(var j=1; j<= n; j++){
product_iter = product_iter * ( rho + (k + j - 1)/s );
}
return(Math.pow(rho, n) / product_iter);
}else if( k < s && s < (k + n)){
var product_iter2 = 1;
for(var j=1; j<= s-k; j++){
product_iter2 = product_iter2 * ( rho + (k + j - 1)/s );
}
product_denom = Math.pow((rho + 1), (n-s+k)) * product_iter2;
return(Math.pow(rho, n) / product_denom);
}
}
//proposition 2
else if(k == 0 && n == i){
if(n <= s){
var product_iter11 = 1;
for(var j=1; j<= n; j++){
product_iter11 = product_iter11 * (rho + (j - 1)/s);
}
return(Math.pow(rho, n) / product_iter11);
}else if(n > s){
var product_iter12 = 1;
for(var j=1; j<= s; j++){
product_iter12 = product_iter12 * ( rho + (j - 1)/s );
}
product_denom12 = Math.pow((rho + 1), (n-s)) * product_iter12;
return(Math.pow(rho, n) / product_denom12);
}
}
//if i = 1
else if(i == 1){
var upsum = 0;
for(var j=2; j<= (n+k); j++){
upsum = upsum + f(rho, n, j, k, s);
}
return(1 - upsum);
}
//proposition 3
else if(n == 1 && 2 <= i && i <= k){
if(k <= s){
begin = rho / (rho + (i - 1)/s);
var product_iter13 = 1;
for(var j=1; j<= (k-i+1); j++){
product_iter13 = product_iter13 * (1 - rho / (rho + (k - j + 1)/s) );
}
return(begin * product_iter13);
}else if(k > s && i > s){
return(rho / Math.pow((rho+1), (k-i+2)));
}else if(i <= s && s <= k){
begin2 = rho / (Math.pow( (rho + 1), (k - s + 1)) * ( rho + (i - 1)/s));
var product_iter14 = 1;
for(var j=1; j<= (s-i); j++){
product_iter14 = product_iter14 * (1 - rho / (rho + (s - j)/s) );
}
return(begin2 * product_iter14);
}
}
//proposition 4
else if( n >= 2 && 2 <= i && i <= (k + n - 1)){
if(i>s){
begin11 = rho/(rho+1);
var product_iter21 = 0;
for(var j=(i-1); j<= (k+n-1); j++){
product_iter21 = product_iter21 + Math.pow((1 / (rho+1)),(j-i+1)) * f(rho, n-1, j, k, s);
}
return(begin11 * product_iter21);
}else if(i <= s){
begin12 = rho / (rho + (i-1)/s);
var summer1 = 0;
for(var j=(i-1); j<= (s-1); j++){
var product_iter22 = 1;
for(var h=1; h<=(j-1+1); h++){
product_iter22 = product_iter22 * (1 - rho / (rho + (j - h + 1) / s));
}
summer1 = summer1 + product_iter22 * f(rho, n-1, j, k, s);
}
var product_iter23 = 1;
for(var h=1; h<=(s-i); h++){
product_iter23 = product_iter23 * (1 - rho / (rho + (s-h) / s));
}
var summer2 = 0;
for(var j=s; j<= (k+n-1); j++){
summer2 = summer2 + (Math.pow((1 / (rho + 1)), (j-s+1)) * f(rho, n-1, j, k, s)) ;
}
bottom = product_iter23 * summer2;
inner = summer1 + bottom;
return(begin12 * inner);
}
}
}
}
//Closure of f(), self-executing anonymous function
return f;
})();
最佳答案
你的内存有两个缺陷:
(1) 您永远不会将结果添加到 memo
。
(2) args in memo
将args
转换为字符串。这适用于一组数字,但可能无法用于其他输入。
我会像这样写一个通用版本的memo
:
const memo = fn => {
const cache = {};
return (...args) => {
const key = JSON.stringify(args);
if(key in memo) return memo[key];
return memo[key] = fn(...args);
};
};
const memoizedF = memo(f);
关于浏览器中的 Javascript Memoization 没有看到加速,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57478785/
如何获取特定 UTF-8 字符串的字节序列?我看到正则表达式引擎中的某些错误仅在某些边缘情况下才会触发,我想确切地知道它正在处理哪些数据。 最佳答案 也许 charToRaw ? > charToRa
考虑一个具有许多变量的 java 程序,其中一些是循环计数器,我希望看到这些变量随时间变化的值,而不是在代码中到处放置 print 语句。 为什么?我认为它可以帮助我轻松调试。 Example- in
有没有办法查看 JavaScript 正在创建的“线程”?例如,如果我有一个附加到 DOM 元素的事件处理程序,我假设 JavaScript 会隐式地创建一个新线程来在后台运行该代码?如果是这样,有没
我正在使用反射 API 来调用类运行时并调用其方法。但我看到 java.lang.reflect.InitationTargetException 异常。 我需要调用一个名为 - TestClass
考虑一个名为 t.cmd 的命令脚本,它只包含以下两行: @exit /b 123 @echo If you see this, THEN EXIT FAILED.. 因此,该脚本只是将脚本执行过程的
我最近一直在努力学习编程语言实用学第 3 版,以了解更多关于语言在底层如何工作的信息,并且通过查看由真正基本的 GCC 编译的 C 代码生成的程序集,我获得了很多进展.我开始对 C 系列的静态语言越来
最简单的制作方法是什么QWebView识别并正确加载网页上的 Flash? 最佳答案 似乎只需两行即可实现(当然,假设目标系统上安装了闪存): QWebSettings *settings = QWe
我想通过编程(使用VBA)访问其他人与我共享的日历。它们在我的Outlook中的“人民日历”下列出。我在网上搜索了此内容,所有建议所做的仅使我感到困惑。如何从“人的日历”中获取共享给我的所有日历的
使用MongoDB Compass,可以看到数据库用户或创建新用户吗? 最佳答案 香港专业教育学院在命令行上使用以下命令进行管理: mongo use (my database name) db.cr
我正在CentOS 7.4.1708(核心),Java(TM)SE运行时环境(内部版本1.8.0_152-b16)上运行eXist-db 3.6.1。我希望能够在person.xml中的最后一个记录之
我需要确认。 客户端 1 在事务内的表中插入行。 客户端 2 使用 SELECT 请求该表。如果在此客户端上隔离级别设置为 READ COMMITTED,您能否确认 SELECT 不会返回客户端 1
我刚刚安装了 python-dev: $ sudo apt-get install python-dev 这样我就可以开始使用 P4Python 了。但是当我尝试导入 P4 时,我得到: Traceb
我正在使用 msys 和 mingw 编译 libtorrent-rasterbar-0.16.16。./configure 运行良好,直到它进入 boost 库检查。我有 boost 1.51,我设
我在 GO 项目的 Travis CI 上有一个奇怪的行为。 [这里] 失败了,提示一个函数只接受 1 个参数并用 2 个参数调用。 src/finances-service/main.go:45:1
这个问题已经有答案了: What are enums and why are they useful? (27 个回答) 已关闭 4 年前。 作为 Java 初学者,我接触到了枚举,这让我对类型声明感
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 11 年前。 Improve thi
我正在使用 preactjs 创建我的应用程序。最重要的是,我正在使用剑道网格。在网格内,我想显示一个超链接。如果用户点击链接,它应该改变路线。为了呈现链接,我使用了 preact-router。 这
有没有办法只查看 Node.js 中的函数签名?我知道 fn.toString() 但不需要所有代码,只需要签名。 最佳答案 var source = fn.toString(); var signa
如何设置 vim 以查看我在 ubuntu 上安装的 ruby rvm。 rvm 已安装,ruby 从终端返回。 renshaw@renshaw-TravelMate-5740G:~$ ruby
我试图在我的 Android 应用程序中防止 OutOfMemoryError。我已经阅读了很多帖子,但我仍然无法解决。 该应用程序有后台 Activity ,所以我认为这是主要问题。 OutOfMe
我是一名优秀的程序员,十分优秀!