首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >高效的搜索和更新,数据表或稀疏矩阵-R

高效的搜索和更新,数据表或稀疏矩阵-R
EN

Stack Overflow用户
提问于 2020-05-17 08:43:07
回答 1查看 94关注 0票数 0

我正在尝试找到最有效的方法来重复搜索引用表中两个变量的组合。该问题基于具有退火步长的爬山算法的实现,因此增加了问题的复杂性。

为了解释,假设我有两个想要优化的变量AB。我从这些变量的100个组合开始,我将遍历这些组合

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
set.seed(100)
A_start <- sample(1000,10,rep=F)
B_start <- sample(1000,10,rep=F)
A_B_starts<-expand.grid(A = A_start,
                               B = B_start)

head(A_B_starts)
    A   B
1 714 823
2 503 823
3 358 823
4 624 823
5 985 823
6 718 823

对于这些开始组合中的每一个,我希望在预测模型中使用它们的近邻,如果它们的误差小于开始组合的误差,则继续沿着该方向进行。重复这一过程,直到达到最大迭代次数或误差增加(标准爬山)。但是,我不想重新检查我已经查看过的组合,为此,我想使用一个参考表来存储检查过的组合。然后,在运行预测模型之前,每次生成直接邻居时,我都会检查它们是否在参考表中。任何存在的内容都会被简单地删除。增加了更多的复杂性,因为我希望生成紧邻的步长是退火的;随着时间的推移变得更小。我已经使用data.tables实现了这一点

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
max_iterations <-1e+06
#Set max size so efficient to add new combinations, max size is 100 start points by max iterations allowed 
ref <-data.table(A=numeric(), 
                 B=numeric(),
                 key=c("A","B"))[1:(100*max_iterations)]

ref
            A  B
        1: NA NA
        2: NA NA
        3: NA NA
        4: NA NA
        5: NA NA
       ---      
 99999996: NA NA
 99999997: NA NA
 99999998: NA NA
 99999999: NA NA
100000000: NA NA

所以循环实际处理这个问题

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
step_A <- 5
step_B <- 5
visited_counter <- 1L
for(start_i in 1:nrow(A_B_starts)){
   initial_error <- get.error.pred.model(A_B_starts[1,])
   A <-A_B_starts[1,1]
   B <-A_B_starts[1,2]
   #Add start i to checked combinations
   set(ref, i=visited_counter, j="A", value=A)
   set(ref, i=visited_counter, j="B", value=B)
   visited_counter <- visited_counter+1L
   iterations <- 1
   while(iterations<max_iterations){
      #Anneal step
      decay_A = step_A / iterations
      decay_B = step_B / iterations
      step_A <- step_A * 1/(1+decay_A*iterations)
      step_B <- step_B * 1/(1+decay_B*iterations)
      #Get neighbours to check
      to_visit_A <- c(A+step_A,A-step_A)
      to_visit_B <- c(B+step_B,B-step_B)
      to_visit <- setDT(expand.grid("A"=to_visit_A,"B" = to_visit_B),
                        key=c("A","B"))
      #Now check if any combination have been checked before and remove if so
      #set key for efficient searching - need to reset in loop as you are updating values in datatable
      setkey(ref,A,B)
      prev_visited<-ref[to_visit,nomatch=0L]
      to_visit<-to_visit[!prev_visited]
      #Run model on remaining combinations and if error reducing continue
      best_neighbour <- get.min.error.pred.model(to_visit)
      if(best_neighbour$error<initial_error){
         initial_error <- best_neighbour_error
         A <- best_neighbour$A
         B <- best_neighbour$B
      }
      else{
         iterations <- max_iterations
      }
      #Add all checked to reference and also update the number of iterations
      for(visit_i in 1L:nrow(to_visit)){
         #This will reset the key of the data table
         set(ref, i=visited_counter, j="A", value=to_visit[visit_i,1])
         set(ref, i=visited_counter, j="B", value=to_visit[visit_i,2])
         visited_neighbour_counter <- visited_counter+1L
         iterations <- iterations+1
      }
   }
}

这种方法的问题是,我必须在每次循环迭代时重置键,因为已经向ref添加了一个新的组合,这使得它非常慢:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
setkey(ref,A,B)
prev_visited<-ref[to_visit,nomatch=0L]
to_visit<-to_visit[!prev_visited]

此外,我提到退火的原因是因为我有另一个想法,使用稀疏矩阵;Matrix保存已经检查的对的指示符,这将允许非常快速的检查

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
require(Matrix)
#Use a sparse matrix for efficient search and optimum RAM usage
sparse_matrix <- sparseMatrix(A = 1:(100*1e+06),
                              B = 1:(100*1e+06) )

然而,由于步长是可变的,即A/B可以以越来越小的间隔保持任何值,我不知道如何在稀疏矩阵中初始化A和B的适当值来捕获所有可能的组合。

EN

回答 1

Stack Overflow用户

发布于 2020-05-18 08:39:53

(不是真正的答案,但太长了,不能发表评论。)

如果可能的解决方案数量巨大,则可能不切实际或不可能将它们全部存储。更重要的是,查找单个解决方案的最快方法通常是哈希表;但是设置哈希表很慢,因此您可能不会获得太多(您的目标函数需要比这种设置/查找-oberhead更昂贵)。根据问题的不同,这种存储解决方案的大部分可能是一种浪费;算法可能永远不会重新访问它们。另一种建议可能是先进/先出数据结构,它只存储访问过的最后N个解决方案。(对于短列表,即使是线性查找也可能比使用重复设置的哈希表更快。)但在任何情况下,我都会从一些测试开始,测试算法是否以及重新访问特定解决方案的频率。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61849147

复制
相关文章
【C++】静态成员函数 ( 静态成员函数概念 | 静态成员函数声明 | 静态成员函数访问 | 静态成员函数只能访问静态成员 )
静态成员函数归属 : 在 C++ 类中 , 静态成员函数 是一种 特殊的函数 , 该函数属于类 , 而不是属于 类实例对象 ;
韩曙亮
2023/10/15
1.6K0
【C++】静态成员函数 ( 静态成员函数概念 | 静态成员函数声明 | 静态成员函数访问 | 静态成员函数只能访问静态成员 )
C++ 静态数据成员与静态成员函数
本文介绍了静态数据成员和静态成员函数的概念、特点以及用法,并给出了一个示例代码。静态数据成员和静态成员函数是C++中比较重要的概念,在开发中经常用到。
chaibubble
2018/01/02
1.5K0
C++类的静态数据成员和静态成员函数
一些类对象可能会具有一些相同的属性,如果用普通数据成员来描述这些相同的属性,这意味着我们需要给每个对象的这个数据成员设定相同的值,如果改变类对象相同的属性,那么意味着我们需要对它们统一操作,这就有可能出现它们的值会不一样的情况,如果用全局变量来描述它们相同的属性,就会破坏类的独立性。
叶茂林
2023/07/30
2060
c++系列之二 指向成员函数的指针(烧脑)
这是一篇翻译的文章,原文详细解释了C++中指向成员函数的指针,因为带有“教程”一词,所以比较通俗易懂。为了使文章读起来通俗有趣,翻译君并未一字一句一板一眼地翻译,并大量使用了诙谐的词汇(如“码农”)。另外,原文的某些地方分段不太合适(小学语文可能是体育老师教的。。),有些地方也稍嫌啰嗦,所以翻译君自己作了一些调整。如果对翻译君的翻译质量有意见,建议前往 原地址 围观。
早起的鸟儿有虫吃
2019/05/05
3.1K0
c++系列之二 指向成员函数的指针(烧脑)
C++ this指针:用于在成员函数中指向调用该函数的对象
C++中this指针是一个指向当前对象的指针。在成员函数中,可以使用this指针来访问调用该函数的对象的成员变量和成员函数。
很酷的站长
2023/08/25
2680
C++ this指针:用于在成员函数中指向调用该函数的对象
静态成员函数和非静态成员函数的区别?
一个静态成员函数不与任何对象相联系,故不能对非静态成员进行默认访问。 它们的根本区别在于静态成员函数没有this指针,而非静态成员函数有一个指向当前对象的指针this。 例如: 1 class Sc 2 { 3 public: 4 void nsfn(int a); //像声明Sc::nsfn(Sc *this , int a); 5 static void sfn(int a); // 无this指针 6 //.... 7 }; 8 9 void f(Sc
猿人谷
2018/01/17
1.9K0
C++中的const成员变量和成员函数
在类中,如果你不希望某些数据被修改,可以使用const关键字加以限定。const 可以用来修饰成员变量和成员函数。
芯动大师
2023/10/14
3350
C++中的const成员变量和成员函数
【C++】C++ 类中的 this 指针用法 ② ( 常量成员函数 | const 修饰成员函数分析 )
在 C++ 类中 , 普通的非静态成员函数 , 可以使用 const 进行修饰 ,
韩曙亮
2023/10/15
2360
【C++】C++ 类中的 this 指针用法 ② ( 常量成员函数 | const 修饰成员函数分析 )
C++类的成员函数 | 成员函数
在C++中,类的成员函数是函数的一种,它有返回值和函数类型,它与一般函数的区别只是:
小林C语言
2021/01/18
1.9K0
C++类的成员函数 | 成员函数
静态成员函数访问非静态数据成员【C++】
详解:由于静态数据成员属于本类的所有对象共享,不属于特定类对象,因此在未产生类对象时作用域就可见,即:在未产生类的实例时,就可以对它进行操作。
攻城狮杰森
2022/06/03
1.3K0
C++静态成员变量和静态成员函数小结
静态类成员包括静态数据成员和静态函数成员两部分。 一 静态数据成员: 类体中的数据成员的声明前加上static关键字,该数据成员就成为了该类的静态数据成员。和其他数据成员一样,静态数据成员也遵守public/protected/private访问规则。同时,静态数据成员还具有以下特点: 1.静态数据成员的定义。 静态数据成员实际上是类域中的全局变量。所以,静态数据成员需要在类外定义(初始化),而不应该被放在类声明中。 原因是类声明中只是描述如果分配内存并不会真正的分配内存,而定义是一定要分配
用户1215536
2018/02/05
1.9K0
c++中的静态成员
静态成员变量特点: 1.所有对象共享一份数据 2.在编译阶段分配内存(程序还没运行前就分配内存) 3.类内声明,类外初始化(不初始化,无法使用)
大忽悠爱学习
2021/02/22
7210
c++中的静态成员
指向类成员的指针
关注点在于 count_fruit 的第三个参数,这样就省去了单独编写 count_apples 和 count_oranges 函数的麻烦。
ClearSeve
2022/02/10
8190
指向类数据成员的指针
在C++中,可以定义一个指针,使其指向类成员或成员函数,然后通过指针 来访问类的成员。这包括指向属性成员的指针和指向成员函数的指针。它类似与static成员函数或成员变量,具有共享的属性。每一个实例化的对象都可以借助指向类数据成员的指针来访问指向的数据。它的结构图如下:
我与梦想有个约会
2023/10/20
1860
指向类数据成员的指针
C++类的this指针,静态成员,友元函数友元类
在上篇讲C++中类,对象,封装,继承(派生),多态的时候,this指针出现在成员函数中,并使用->成员提取符操作成员变量。
花狗Fdog
2021/03/02
1.5K0
C++之静态成员变量和静态成员函数学习总结
平时我们在写类的时候,类中的成员变量,我们一般是通过对象名来访问public成员变量的,一般private(私有)的成员变量,对象是不能直接访问的;同时我们要明白每个对象的成员变量都是专属的,而且成员变量是不能在对象之间共享的,这就是专属性。下面我们来做一个小的程序需求来慢慢引出静态成员变量:
用户6280468
2022/03/21
6040
c++之空指针访问成员函数
#include<iostream> using namespace std; class Person { public: int age; void showClass() { cout << "这是Person类" << endl; } void showAge() { //解决方法,如果是空就直接返回 if (this == NULL) { return; } co
西西嘛呦
2020/08/26
6190
C++指向函数的指针
函数指针是指向函数而非指向对象的指针。与其他类型的指针一样,函数指针也指向某个特定的类型。函数类型由其返回类型以及形参表确定,而与函数名无关。(类似C#中的代理)
卡尔曼和玻尔兹曼谁曼
2019/01/25
1.5K0
使用指向函数的指针
/**输入2个整数,然后让用户选择1或2,选1时调用max函数,输出2者中的大数, 选2时调用min函数,输出2者中的小数**/ #include <stdio.h> #include <stdlib.h> int main() { int max(int x,int y); int min(int x,int y); int (*p)(int ,int ); int n,a,b; scanf("%d%d",&a,&b); scanf("%d",&n);
谙忆
2021/01/19
8090
C++中的static成员函数以及static成员变量详解「建议收藏」
static成员变量,在编程中我们时常都会遇到,那么你是否对static变量以及static成员函数有一定深入的认识呢?
全栈程序员站长
2022/07/11
8410

相似问题

Docker:项目中有多个Dockerfile

466

在.Net核心项目中引用Asp.Net核心类库项目的问题

10

.net 5.0核心web项目的docker文件问题

12

在“自我”中有多个项目?

42

Docker .NET核心-解决方案中的多个项目

20
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文