格努普特

格努普特

我目前正在研究冰雹序列(collat​​z 数字)。

我想创建一个这样的情节(来自维基百科):

在此处输入图片描述

但是我不知道这种图怎么叫(它既不是线图,也不是散点图或条形图或直方图,虽然看起来很相似)。

我想绘制从某个数字n到 需要多少步1。x 轴应为数字(从 1 到 M,M 尽可能大),y 轴应为步数。

由于我不知道上述那种图叫什么(而且我找不到名字),所以我使用了散点图:

在此处输入图片描述

遗憾的是,这似乎占用了大量内存。绘制 4100 (n,从 n 到 1 的步骤) 对成功了,但当我将其增加到 4150 对时,我得到了:

! TeX capacity exceeded, sorry [main memory size=3000000].
\endvarwidth ...\vbox \bgroup \unvcopy \@tempboxa 
                                                  \@tempdima -\maxdimen \let...
l.28 \end{document}

我认为以下内容最终可以解决我的问题:

  • 切换到 gnuplot(我不知道如何使用 gnuplot 读取 CSV 文件,而且我只使用过一次 gnuplot+LaTeX。有人有一个带有如何编译说明的最小工作示例吗?)
  • 将图表类型切换为上面的图表(怎么称呼?)
  • 实际上并没有在 csv 文件中写入数字 n,而是从行号中获取它(如何从下面代码中的 CSV 文件中获取 x 的行号?)
  • 切换到另一种情节就像这里(我想这会更复杂,而且好像我必须使用 gnuplot / R。有人知道如何将它应用于我的问题吗?)

我写的所有代码都是在 GitHub 上。这是我目前编写的 LaTeX 代码:

\documentclass[varwidth=true, border=2pt]{standalone}
\usepackage[utf8]{inputenc} % this is needed for umlauts
\usepackage[ngerman]{babel} % this is needed for umlauts
\usepackage[T1]{fontenc}    % this is needed for correct output of umlauts in pdf
\usepackage[margin=2.5cm]{geometry} %layout

\usepackage{pgfplots}

\begin{document}
\begin{tikzpicture}
    \begin{axis}[
            axis x line=middle,
            axis y line=middle,
            enlarge y limits=true,
            %xmin=0, xmax=2150,
            %ymin=0, ymax=600,
            width=15cm, height=8cm,     % size of the image
            grid = major,
            grid style={dashed, gray!30},
            ylabel=steps,
            xlabel=$n$,
            legend style={at={(0.1,-0.1)}, anchor=north}
         ]
          \addplot[scatter,only marks] table [x=n, y=steps, col sep=comma] {../steps.csv};
    \end{axis}
\end{tikzpicture}
\end{document}

我想绘制至少 100,000 个元素(如果可能的话最好是 10,000,000 个)。我该怎么做?

答案1

pgfplots,梳状图

感谢 Torbjørn T. 建议我看一下comb plots。这让我能够绘制 7150 个(但不是 7200 个)数据点:

在此处输入图片描述

格努普特

十字架

在此处输入图片描述

您必须创建一个文件来告诉 gnuplot 要做什么。我将其命名为plot.gnuplot

set terminal latex
set output "plot-tmp.tex"
set datafile separator "," 
set title "Collatz Number of steps"
plot '../steps.csv' every::1 

然后你必须运行 gnuplot:gnuplot plot.gnuplot 这将生成一个可以包含在你的 LaTeX 文档中的“plot-tmp.tex”:

\documentclass{standalone}

\usepackage{graphicx}

\begin{document}
\input plot-tmp
\end{document}

这使我能够绘制 22300 个数据点(但不是 22350 个)。

梳状图

要获得梳状图,您必须在 plot 命令中添加“with pulses”。因此您的 plot.gnuplot 文件应如下所示:

set terminal latex
set output "plot-tmp.tex"
set datafile separator "," 
set title "Collatz Number of steps"
plot '../steps.csv' every::1 with impulses

生成结果:

在此处输入图片描述

R

您可以(应该?)使用 R 将大数据绘制为 PDF 文件。R 可以处理包含 10,000,000 个数据点的 120 MB 文件。

为此,您必须安装 R 和 ggplot2(sudo apt-get install r-cran-ggplot2)。

现在您可以从命令行启动 R sudo R(必须是大写字母)来安装 hexbin install.packages("hexbin", dependencies=TRUE);:(来源

现在创建一个名为的文件analyze.R并复制以下内容:

library(ggplot2)

mydata = read.csv("/home/moose/Downloads/algorithms/collatz/steps.csv")

# Prepare data
p<-ggplot(mydata, aes ( x=n,y=steps ))

# Plus means you add those options to the plot
p + geom_hex( bins=30 ) + opts(panel.background = theme_rect(fill='white', colour='white'))

执行它:R -f analyze.R

您将获得:

在此处输入图片描述

答案2

在此处输入图片描述

问题的表述看起来有点混乱。首先,它讨论了Wikipedia链接中的图表,这是一个表示直方图的普通条形图:对于每个整数(从某个数字x达到的步数),都有一个整数(该间隔内具有相同步数的数字数量)。请注意,范围不是很大,只是小于从数字获得的统计数据的单个点。下一个问题更简单,同时也更困难:绘制范围内测试的每个数字的步数。它更简单,因为不需要累积具有相同步骤的数字数量,而困难是......要绘制这样的图形,例如,一个“谦虚的数字” ,每个点都必须绘制(否则它只是某种无用的随机混乱)。假设每个条只有一个点宽,打印如果在,-轴的总宽度大约为11..100000000yxx600100mlnx1000001200dpix两米宽

因此,此Asymptote代码(没有任何额外程序)用于绘制与链接相同的图形Wikipedia,这是从nMax=100000000(100mln)数字中获得的统计数据。它在一台不太先进的笔记本电脑上后台运行大约需要 20 分钟。直方图数据在整数数组中累积stepCount并打印到stdout。输出还包括:

  • n=100000000- 测试范围内的最大数量,
  • highest=2185143829170100- 整个测试期间达到的最大数量,
  • maxStep=949要达到的最大步数1
  • maxStepArg=63728127maxStep需要步数才能达到的数量1

因此,从63728127它开始就应该采取949措施来获得1

collatz.asy:

import graph;
int nMax=100000000;
int highest=1;
int maxStepArg=1;
int[] arStep=array(nMax,0); 

int stepMaxLimit=1000;
int[] stepCount=array(stepMaxLimit,0); 

int steps(int nn){
  int n=nn;
  int m=0;
  int nextn;
  while(n>1){
    if((n%2)==0){
      nextn=floor(n/2);
      ++m;
    }else{
      assert(n<floor((intMax-1)/3),"too big n="+string(n));
      nextn=3n+1;
      highest=max(highest,nextn);
      ++m;
    }
    if(nextn<arStep.length && arStep[nextn-1]>0){
      m+=arStep[nextn-1];
      n=1;
      return m;
    }else{
      n=nextn;
    }
  }
  return m;
}

int maxStep=1;
int j;
for(int i=1;i<=nMax;++i){
  j=steps(i);
  ++stepCount[j];
  if(j>maxStep){
    maxStep=j;
    maxStepArg=i;
  }
  arStep[i-1]=j;
}

write("n="+string(nMax)
+", highest="+string(highest)
+", maxStep = "+string(maxStep)
+", maxStepArg = "+string(maxStepArg)
);

size(256,256,IgnoreAspect);
int nj;
real t;

pen barPen=rgb(0,0,0.5608)+opacity(0.6)+0.8pt;
guide g=(0,0);
for(int i=1;i<=maxStep;++i){
  g=g--(i,stepCount[i])--(i+1,stepCount[i])--(i+1,0);
}
g=g--cycle;

fill(g,barPen);
xaxis(0,maxStep,RightTicks());
yaxis(0,max(stepCount),LeftTicks(beginlabel=false));

write(stepCount[0:maxStep+4]);

答案3

我通过 Asymptote 为这个 10 年前的问题制作了冰雹图。令人兴奋的是科拉兹猜想仍然开放。

为了绘制,我使用具有 3 个属性的struct名称Collatzchain表示链,len表示max_value链的长度(停止时间)和最大值。如果想要条形图,只需将其替换dot((i,d),2pt+red);draw((i,d)--(i,0),blue);

在线编译需要几秒钟n=10000。我还没有测试过离线运行。

在此处输入图片描述

在此处输入图片描述

// Collatz: the hailstone graph
// Run on http://asymptote.ualberta.ca/ 
    
struct Collatz {
    int[] chain;      // the Collatz chain
    int len;          // the length of the Collatz chain
    int max_value;    // the maximum of the Collatz chain
}

Collatz collatz_calculate(int n) {
    Collatz c;   
    c.chain.push(n);  // Initialise the chain with the first node n
    c.len = 1;        // Initialise the length chain as 1
    c.max_value = n;  // Initialise the maximum value as n
  
    while (n > 1) {
        n = (n % 2 == 0) ? (n # 2) : (3 * n + 1);
        c.chain.push(n);
        ++ c.len;
        c.max_value = max(n, c.max_value);
    }
    return c;
}

import graph;
size(12cm,8cm,IgnoreAspect);
int n = 10000;
for (int i=2; i < n; ++i) { 
    int d = collatz_calculate(i).len;
    //draw((i,d)--(i,0),blue);    // the bar graph
    dot((i,d),2pt+red);           // the hailstone graph
}

xaxis("$n$",BottomTop,LeftTicks);
yaxis("stopping time",LeftRight,RightTicks);
label("\bfseries Collatz conjecture: hailstone graph",point(N),2N);
shipout(bbox(5mm,invisible));

相关内容