コンピュータの最近のブログ記事

折角なので、マンデルブロ集合の彩色のところに、

TColor ColorN(int n)   {
 int i;
 i = (n%7);
 
 switch(i)           {
  case 0:
   return clRed;
  case 1:
   return clYellow;
  case 2:
   return clGreen;
  case 3:
   return clLime;
  case 4:
   return clPurple;
  default:
   return clSkyBlue;
 }
 return clWhite;
}
というカラーリング・スキームを適用してみた。

これの画像は、


だが、依然としていまいちか。

参考までに以前の画像も示すと、


ううん。こちらの方がまだましか。

異言語習得

user-pic
0

LME288エラーの対応に書いたように、懸命の努力でC++ Builder XE4が使えるようにしたのだが、そこからWindows Updateを一度経ると、またLME288エラーが再現した。

がっかりしながら、いつもどおり、パソコンをシャットダウンして、電源を入れ直してみたが、やはりエラーが解消されない。仕方なくそこからシャットダウンでなく再起動させると、なんとかLME288エラーが解消されたが、最早怪訝な気持ちは晴れない。

そこまでどうしてC++ Builder XE4に拘るのかというと、C++ Builder XE4が素晴らしいのではなく、その代替のVisual Studioが実に使いにくいからである。使いにくいというのは実は必ずしも正しくなくて、新しくVisual Studioを習得する手間が嫌なのである。

そういえば私は長年Perlを使っていて、未だに中級者以下やんけと思っているうちに、Perlに時代遅れ感が漂い始めて、Rubyかな、Pythonかなと横目でみるのだが、まったく浮気する勇気がない。

でも人間に大事なのは、異言語を学ぶときの強烈な違和感に酔うことなのであって、それが嫌ならこの王国を去れ、と言われてしまう。私は以前、強烈な違和感を求めて、アラビア語を勉強して、文字の書き方をある程度勉強した段階で挫折したが、なかなか有意義な体験であった。

なので、以前気まぐれで買って、なぜかずっと私の本棚のセンターを占める、大学書林の「ハンガリー語四週間」など恰好の違和感のソースなのだが、手を出せないでいるとはなんと情けない。

そう考えたら、Visual Studioの違和感など知れていないだろうか。

USBケーブル

user-pic
0

私は極めてメンテナンスな人間で、なのでパソコンのデータを頻繁にポータブルHDDに保存する。そのとき活躍するのは、USBケーブルなのであるが、あるときどうしてもポータブルHDDが認識されないという問題が起きた。これは実に困ったことなのだが、困ることはポータブルHDDだけでなく、パソコン本体に及び、パソコンの動作も不安定になってしまう。多分であるが、USBケーブルで接続した段階でパソコンはポータブルHDDからの応答を待機する状態になるのだが、何かの不具合で応答する信号が届かないからだろう。

で、考えてみて、これはUSBケーブルの不具合ではないかと予備のUSBケーブルに取り換えてみたらうまくいった。ううん、USBケーブルも微妙だねと思い、近所のローソン100で予備のUSBケーブルを買ってみた。

そして自宅に帰ってポータブルHDDに接続を試みると、適合しない。どうも微妙にコネクタの形状が違う。調べてみるとこれは、タイプCとかいうUSBケーブルで、スマホ充電用に使われたりするようで、よく調べてみたら、私が必要なのはミニBのUSBケーブルなのだった。確認してみると、最近はタイプCや独自のUSBケーブルを使うポータブルHDDもあって、私がもっているバッファローのHD-PCT500U2-BKJという500GBのポータブルHDDは、かなり古いタイプなのだった。

そこで自宅近くのコジマ電気にいってみたところ、なんとも多種のUSBケーブルがあって当惑した。特に最近の外付けHDDは相当に特殊なUSBケーブルを使うようである。データ転送速度を向上させるためそうなっていらしい。ともかく多種のUSBケーブルの中から、なんとかエレコムのミニBのUSBケーブルを探し出して買い、予備とした。たかがUSBケーブルなのに600円程度もかかった。百均一のミニBのUSBケーブルだといまいち信頼性に欠けるかもしれないので、仕方ない。

ともかく言いたいことは、USBケーブルには種類が多すぎて、間違えて買う可能性が高すぎるということである。製品ごとにきちんとタイプを明示してほしいのだが、そのあたりがいまいち曖昧なのだった。

レスラー系のアトラクタについては、レスラー系のアトラクタの更なる続きで一応完結したつもりだが、断片の寄せ集めのようになってしまったので、cを3.0から12.0まで広く動かして、一応、以下のようなまとめのアトラクタを生成してみた。

ここでは、折角なので、赤字で示すスケールと、その下の座標値を入れてみた。そこで座標値の表示は、TextOut()という関数を使うのだが、C++ Builderの標準の関数だけではTextOut()が表示する色をつけることができず、仕方なくその色は黒のままである。

ともかく、以下にソースコードを示しておく。

//---------------------------------------------------------------------------

#include <vcl.h>
#include <stdio.h>
#include <math.h>
#pragma hdrstop

#include "Main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
double fnx(double y,double z); 
double fny(double a,double x,double y);
double fnz(double b,double c,double x,double z);
void SCALE(int x1, int x2, int y, int N, double b, double step);

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Close1Click(TObject *Sender)
{
 Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Draw1Click(TObject *Sender)
{
const double H = 0.0001;
const pi = 3.14156;
double x,y,z;
double a = 0.2, b = 0.2, c;
double a1,a2,a3,a4;
double b1,b2,b3,b4;
double c1,c2,c3,c4;
double px, py;
int p_sgn, c_sgn;
int i,N;

 SCALE(30,830,500,9,3.0,1.0);

for ( i = 0; i < 800; i++ )      {

 N = 0;
 c = 3.0 + 9.0*i/800.0;
 x = 2.0; y = 2.0; z = 13.0;
 if ( x + y >= 0 )
 p_sgn = c_sgn = 1;
else
 p_sgn = c_sgn = -1;
 
 while (N++ < 30000000 )  {
  a1 = fnx(y,z); 
  b1 = fny(a,x,y);
  c1 = fnz(b,c,x,z);
  a2 = fnx(y+H*b1/2.0,z+H*c1/2.0);
  b2 = fny(a,x+H*a1/2.0,y+H*b1/2.0);
  c2 = fnz(b,c,x+H*a1/2.0,z+H*c1/2.0);
  a3 = fnx(y+H*b2/2.0,z+H*c2/2.0);
  b3 = fny(a,x+H*a2/2.0,y+H*b2/2.0);
  c3 = fnz(b,c,x+H*a2/2.0,z+H*c2/2.0);
  a4 = fnx(y+H*b3,z+H*c3);
  b4 = fny(a,x+H*a3,y+H*b3);
  c4 = fnz(b,c,x+H*a3,z+H*c3);
  x += H*(a1+2.0*a2+2.0*a3+a4)/6.0;
  y += H*(b1+2.0*b2+2.0*b3+b4)/6.0;
  z += H*(c1+2.0*c2+2.0*c3+c4)/6.0;
  if ( x + y >= 0 )
   c_sgn = 1;
   else
   c_sgn = -1;
  if ( N > 10000 )                {
   if ( p_sgn != c_sgn )            {
     px = 30 + i;
     if ( y >= 0 )
	   py = 150.0 - 30.0*x;

     Canvas->Pixels[px][py] = clBlack;
   }
  }
  p_sgn = c_sgn;
 } // end of while
}
 // end of for
 SCALE(30,830,500,9,3.0,1.0);
}
//---------------------------------------------------------------------------
double fnx(double y,double z)  {
 return -y-z;
}

double fny(double a,double x,double y)  {
 return x + a*y;
}

double fnz(double b,double c,double x,double z)  {
 return b + x*z - c*z;
}

void SCALE(int x1, int x2, int y, int N, double b, double step)  {
 int i,t;
 String NUM;
 char temp[10];
 double s = (x2 - x1)/N;
 Form1->Canvas->Pen->Color = clRed;
 Form1->Canvas->MoveTo(x1,y);
 Form1->Canvas->LineTo(x2,y);
 
 for ( i = 0; x2 >= s*i + x1; i++ )    {
   t = s*i + x1;
   Form1->Canvas->MoveTo(t,y);
   Form1->Canvas->LineTo(t,y - 600);
   sprintf(temp,"%2.1f",b + step*i);
   NUM = (String) temp;
   Form1->Canvas->TextOut(t, y+5,NUM);
 }
}

汎用AI

user-pic
0

以前に書籍広告で、文春新書の井上智洋著「人工知能と経済の未来 2030年雇用大崩壊」というのを見かけて、私は、こういうのはとりあえず買って目を通すのだが、なぜか買わないでいる。トンデモ本ぽいから、というのは私には理由にならない。なぜなら、霊だの異次元空間など、私は平気で口にする輩なのだから。

そう思っていたら、読売新聞に、井上智洋氏の汎用AIの記事があったので、読んでみた。すると、違和感を感じたのは、いきなり、2030年頃、人と同程度の知性である汎用AIが実現されて、それは人間にかなり近い作業ができ、どんな仕事にも適用できる、という件である。

確かにそういうことを唱えている人工知能学者もいるのかもしれないが、それはあくまでも希望的観測であり、具体的な技術的ロードマップは見えていないはずである。

そういう、ものすごく議論が分かれる汎用AIであるが、井上氏は、それが近未来に実現するという前提で、どんどん話を進めていく。確かに、汎用AIができれば、ほとんどの仕事はAIよって置き換えられるという議論はありえるだろう。

しかし、汎用AIの存在を前提としても、考えてほしいのは、我々が住んでいるのは、コンピュータによって作り出された仮想空間ではなく、重々しい穢土というか、非線形な情念が渦巻く物質世界である。そこで、計算や情報処理しかできないAIがどう物質世界とインターフェースするのか。

汎用AIというとき、多分であるが、最近の将棋AIや囲碁AIの過度の成功を考慮に入れているのだろう。きっと、井上氏も含め、世間の多くの人は、将棋と囲碁を完全情報の盤上ゲームとして一括りにして考えているのだろう。しかし、将棋と囲碁という比較的近いゲームであっても、そこに必要とされる解決のためのアルゴリズムや手法は、相当に本質的に違う。例えば、ディープラーニングは囲碁には著効があったが、将棋ではそれほどでもない、などである。おっと、AlphaZeroの手法はどうなのか分からないが。

ともかく、汎用AIとなると、要求される手法が多様すぎる、信じられないほどの広い分野に個々に対応していかなくてはならない。なので、汎用AIは実は、多数の専用AIの寄せ集めなのであり、いくら多数の専用AIを寄せ集めても、カバーする範囲は隙間だらけだろう。

戻って、物質世界とのインターフェースの問題がある。電王戦で人間のプロ棋士対将棋AIの対戦になったとき、当初、将棋AIのために駒を動かすのは人間だった。駒の移動一つをとってみても、マニュピュレータには大変である。高度なマニュピュレータである、半導体製造装置のステッパは極微細の線を半導体ウェーハ上に描けるが、駒を盤上で操作するのはまた別問題で大変で、デンソーはなんとか電王手君を開発したが、その動きは到底人間のようにエレガントではない。

そういう物質世界とのインターフェースのところは、人間が担当し続けるだろう。ただ逆に、会計や経理のような数字をメインに扱う仕事は、弁護士や法務の仕事と違って、比較的AIが蚕食しやすいような気がする。

物理学などでも、コンピュータ・シミュレーションが重要になってきた。なので、例えば京大数理解析研でさえ、計算機科学を重視する。

なので、人々が要求されるスキルは変容するが、あまり仕事は失わないで済むのではないか。というよりも、誰も失職したくないから努力するだろう。

井上氏は、今後は思考力が大事で、思考の「形」作るのに哲学が必要なのです、みたいに説かれているが、少なくとも汎用AIを前提として、粗雑に議論を進めていく人が、哲学を云々するのはいかがなものか。それがSFというならそれでもいいが、だとしても、もう少し個別分野の議論を盛り込んでほしいものである。

ソースネクストのスーパーセキュリティ・ゼロについては、その防御能力と、更新料がゼロであることで使い続けてきたが、最近、その信頼感が揺らぐことが起きたので、以下に記してみる。

まず、スーパーセキュリティ・ゼロには、決済ブラウザというアプリが付属していて、要するにネットバンキングなどのサイトをアクセスすると自動的に立ち上がって、セキュアな通信経路を確立するというものだが、最近、困った問題が起きた。すなわち、ネットバンキングで普通にログインしたり、送金したりする分には英数半角入力で足りるが、例えば、ある出版社の定期購読料を払うときなど、送金人の名前の前に、全角文字で購読者コードを数字で入れたりする必要があり、要するに全角入力が必須である。これは今までできていたはずなのに、いくら操作しても全角入力に切り替えられない。そこで困って、自宅のもう一台の、ウイルスバスターが入っているWindows 10パソコンで手続きしたら、あっさりできた。

ソースネクストのサポートサイトに連絡したら、Fall Creators Updateのあと、この問題が発生するようになったという。そんな、Fall Creators Updateとウイルスバスターでみたように、トレンドマイクロは直ちに対応したのに、ソースネクストは対応が遅いではないか、と怒りたくなった。

それからしばらくして、天頂の囲碁7 Zenが発売されているというので、おっ、これで囲碁の方もプロ並の強さが楽しめると、迷わず注文して、届いたらすぐにパソコンに導入しようとした。ところが何度導入を試みてもエラーになってしまう。なんでも、スーパーセキュリティ・ゼロが身代金ウイルスであると判定して、導入を拒否しているらしい。えっ、と思って早速天頂の囲碁7の名前でウェブ検索してみた。もし本当にそうなら、ウェブ上で問題になっているはずであるが、そういう記事は全くみかけない。それで、自宅のもう一台の、ウイルスバスターが入っているWindows 10パソコンで手続きしたら、あっさりできた。ウイルスバスターが許可するのだから、身代金ウイルスというのは違うだろうと思った。

そこでスーパーセキュリティ・ゼロが入っているパソコンに戻って、何度も試みたがその都度拒否されてしまう。すなわち、導入を試みると、何かis-fn038.tmp\setup.tmpのようなファイルが拒否され、それは操作によって許可リストに入れられるのだが、導入を試みる度に生成されるファイルの名前が変わり、それがその都度拒否されるのでどうしようもなく、とりあえず導入を諦めることにした。

これより軽い症状であるが、電紋で報告したようなことや、リカバリーで書いたTeXWorksの誤認逮捕事件もあった。

こうなるとどうしても、ウイルスバスターへの乗り換えを考えてしまうのだった。

と思いつつ、ソースネクストのサポート・サイトに問い合わせのメールを出したら、比較的早く返事が来た。ウイルスバスターだとうまくいったんですよ、みたいな意地悪なメッセージを入れたのがよかったのかもしれない。その回答によると、要するに当該アプリのexeのファイル名を、スーパーセキュリティ・ゼロの「信頼できるアプリケーション」のリスト、すなわちホワイトリストに入れればいいというのだが、ええっ、そんなこと言っても天頂の囲碁7 Zenのプログラムが導入されていないではないかと思って、念のためディスクを確認したら、C:\Program Files(x86)\Mynaviというフォルダに、天頂の囲碁6 Zenというフォルダに並んで、天頂の囲碁7 Zenというフォルダというフォルダがあり、そこを開くと、Zenith.exeとunins000.exeがあったので、この両方を「信頼できるアプリケーション」に加えた。

ただ、この段階ではZenith.exeのショートカットをデスクトップに貼り付けようとすると、スーパーセキュリティ・ゼロにブロックされてしまう。実はパソコンを再起動させることでホワイトリストがconfirmされるのだった。

あとは、Zenith.exeのショートカットをデスクトップに貼り付けて、そのショートカットを天頂の囲碁7 Zenと手書きでrenameすることで、普通にインストーラで導入したのと同じになった。ということで、とりあえずウイルスバスターへの乗り換えは見送ることにした。

LME288エラーについて、リンク・エラーの問題解決のあと、パソコンを何度も再起動したりして、騙し騙しC++ Builder XE4を使ってきて、なんだかすっきりしない状態が続いていたが、Fall Creators Updateを適用した後はLME288エラーが起きなくなった。

おお、ついにWindows 10の側でバグが解消されたかと気をよくしていたら、あるWindows Updateのあと、またLME288エラーが頻発するようになった。これはいよいよ、Visual Studioに移行するしかないかと覚悟を決めそうになったが、そうだ、最後にあの手を試してみようと、記憶を辿ってGoogle検索した。それはまさに、Visual Studioに付属のeditbinを使うもので、検索した情報に従い、次のようにした。

まず、例えばC:\tempというフォルダを作成し、C:\Program Files(x86)\Embarcadero\RAD Studio\11.0\bin\のフォルダからそこに、bcc32.exeとilink32.exeをコピーする。そしてそのフォルダ内で、バックアップのため、bcc32.exeとilink32.exeをそれぞれ、bcc32_old.exeとilink321_old.exeとコピーしておく。

次に、Windows 10のスタートメニューを開く。そこで、特に文字入力ボックスがあるわけではないが、"dev"とキーインすると、"Developer Command Prompt for VS2017"など、いくつか"dev"で始まるメニューがあらわるので、"Developer Command Prompt for VS2017"を選ぶと、C:\Users\xxx\source< というコマンドラインがあらわれる。

そこで、そのコマンドラインで、C:\tempにディレクトリを変更し、次のように、入力して改行キーを押す。

editbin /LARGEADDRESSAWARE bcc32.exe
要するに、"Developer Command Prompt for VS2017"では、editbinに対するパスが通っているということである。

次に同様に、editbin /LARGEADDRESSAWARE ilink32.exeとする。これらの操作により、ファイルサイズは変わらないが、bcc32.exeとilink32.exeのどこかのバイトが書き換えられ、タイプスタンプも書き換えた時点のものに置き換えられる。

そこで、exitで"Developer Command Prompt for VS2017"を抜け、書き換えたC:\temp上のbcc32.exeとilink32.exeを、C:\Program Files(x86)\Embarcadero\RAD Studio\11.0\bin\に書き戻す。このとき、管理者権限でないと上書きできない、みたいにプロンプトされるが、強制的に上書きするというボタンをクリックすると、上書きされる。

ここでほっと一息で、C++ Builder XE4上で任意のプログラムをコンパイル&リンクしてみると、あらっ、依然としてLME288エラーが出る。そこで、あっそうかと気づいて、システムを再起動したら、今度はちゃんとコンパイル&リンクできた。

しかし私は今まで散々、手段を尽くしてLME288エラーが出なくなったと思ったら、しばらくしてまた出たという目に遭ってきたので、まだ信じられない。しばらく様子をみるとしよう。しかし、editbinを使う方法はおそらく最終手段なので、もうこれ以上打つ手はないのだった。

そういえば、C++ Builder XE4のよくわからないエラーでは、HAMarker.exeというEmbarcaderoが提供したツールを使い、HAMarker -M -Filink32.exeのように、機能的にはeditbin /LARGEADDRESSAWAREと同様と思われる処理をしたが、それが結局功を奏さなかったのは、bcc32.exeにもHAMarkerを適用しなかったからいけなかったのか、それともHAMarkerが、editbinと違ってWindows 10とは互換性がなかったのか、そのあたり不明である。しかし最早そんなことを追及してみる気もおきないので、このまま様子をみることにする。

AlphaZero

user-pic
0

12月6日にISSEIさんからコメント戴いた、AlphaZeroについて、ねとらぼの記事に基づきまとめてみる。

その記事によると、以下のとおり:

世界最強の囲碁AI「AlphaGo Zero」を開発したDeepMind(Google関連会社)が、チェスと将棋のAIに関する論文を発表しました。AlphaGo Zeroと同様の手法を使い、24時間で既存の最強AIを超える実力に至ったとのこと。
AlphaGoは2017年5月、世界トップ棋士である中国の柯潔(かけつ)九段に3戦全勝した囲碁AI。もともと人間同士の棋譜(対局データ)を学習させていましたが、進化したAlphaGo Zeroでは人間の棋譜を用いず、AIによる自己対戦のみで強くする「強化学習」が用いられました。

何度読んでも、ほんまかいなと思ってしまう。しかし、いくらなんでも天下のDeepMindが、ガセの内容を発表するわけがない。具体的には以下のとおり:

今回の論文では、AlphaGo Zeroで用いられた手法を「AlphaZero」という名称で一般化し、チェスと将棋にも適用。24時間の学習の結果、チェスでは既存の最強AIとして知られる「Stockfish」相手に100戦して28勝0敗72引き分け、将棋でも同じく最強AIである「elmo」相手に90勝8敗2引き分けという戦績を残しました。

それにしても、ポナンザで、

ただ、AIの手法も駆使したからといって、ポナンザが単調増加で強くなるわけではない。むしろ強くなればなるほど、棋力の向上は大変である。現在では、前の版と3000局指して、52%以上の勝率になることを目指している。こういう棋力の向上策は、いまのところ暗中模索である。
と書いたこととは全くパラタイムが違うということである。

そういえば、AlphaZeroのアナウンスは、ISSEIさんのコメントのように、私が永世七冠を投稿した日だったが、その朝私は、まだAlphaZeroのことは全く知らず、通勤の行きの電車で、深層学習の専門書のボルツマン・マシンの章を一心不乱に読んでいた。あまりに没入したので、電車を降りて、昼食用のパンとおにぎりを例によって三鷹のローソン100で買うとき、ポンタカードを一度出したのを忘れて、二度目も出そうとし、また支払いのPASMOを読み取り機に置き忘れて、そのまま立ち去ろうとして店員から注意された。いくら私が粗忽だからといって、こんな経験は今まで一度もない。多分、AlphaZeroの衝撃が無意識のうちに私に伝わってきていたのだろう。

ほとんどのシステムのログインは、ユーザーIDとパスワードの組み合わせを入れるようになっているが、パスワードは、セキュリティ要件を満たすため、定期的に変更することが必要だったりする。すると、その都度新しいパスワードを考える必要があるが、セキュリティ仕様として、パスワードの長さや、含むべき文字種などが決まっていることがあり、適当に作ったパスワードがセキュリティ仕様を満たさないとして拒絶されてしまい、はたと困った経験がある。そこで、簡単ながら、任意の仕様を満たすパスワードを生成できる、以下のようなパスワード・ジェネレータをPerlで書いてみた。

このプログラムは以下の機能をもつ。

  1. 一度に生成してみるパスワードの個数を示す$n
  2. 生成されるパスワードの長さの範囲を指定する変数$L
  3. 使用可能な(あるいは使用すべき)特殊記号を一文字生成するサブルーチンCC()
  4. Upper caseのアルファベットを一文字生成するサブルーチンCA()
  5. Lower caseのアルファベットを一文字生成するサブルーチンCa()
  6. 数字を一文字生成するサブルーチンCn()

Perlのソースコードの例は、以下のとおりである。

for ( $n = 0; $n < 10; $n++ )     {
  $L = sprintf "%d",rand(6);
  $L += 8;
  $q = sprintf "%d",rand(4);
  for ($i = 0; $i < $L; $i++ )  {
  $q = ($q % 4);
  if ( $q == 0 )       {
    printf "%s",Ca();
  } elsif ( $q == 1 )       {
    printf "%s",CC();
  } elsif ( $q == 2 )       {
    printf "%s",CA();
  } else                    {
    printf "%s",Ca();
  } 
    $q++;
  }
  printf "\n";
}

sub CC     {
my @ZZ = qw/61 45 46 47 95 35 43 63 64/; # 使ってよい特殊文字を10進表示した
my $j = sprintf "%d",rand(9);
my $S = sprintf "%s".chr($ZZ[$j]);
return $S;
}

sub CA     {
my $b = 65;
my $j = sprintf "%d",rand(26);
my $S = sprintf "%s".chr($b + $j);
return $S;
}

sub Ca     {
my $b = 97;
my $j = sprintf "%d",rand(26);
my $S = sprintf "%s".chr($b + $j);
return $S;
}

sub Cn     {
my $b = 48;
my $j = sprintf "%d",rand(10);
my $S = sprintf "%s",chr($b + $j);
return $S;
}

ちなみに、実際に生成したパスワードは以下のとおりである。10個生成したのは、この中から気に入ったパスワードを選ぶためである。なお、Perl処理系にランダマイズ機能が含まれているので、実行する度に異なるパスワードが生成される。

2g_L5u.B5f?W7
g_W3p@W4e
#W5n.Q8b=
X4i.H4g=K
+T8h@U7g_
1t.N5r#H4k_
v/X4m_Y2b?
=L4f#G8j/A4e
9b=I4s?S5g
0y-B7n-W8

2次方程式が整数解をもつ割合に続き、蛇足とは思ったが、3次方程式が整数解をもつ割合についてもみてみた。

単なる直感で、3次方程式が整数解をもつ割合は2次方程式が整数解をもつ割合より少ないかと思ったら、確かに3次方程式が整数解をもつ割合は2次方程式が整数解をもつ割合の0.64倍程度であるが、案外大きい。

ただ、107の試行で、2つ以上を解をもつ場合というのは5回しか観察できなかった。

あまり豊穣ではないかもしれないが、どうもよく分からない世界である。ともかくプログラムのソースコードをリストする。少なくとも、高次になるほど複数の解をもちにくくなるということはいえるかもしれない。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

long long int QD(int a, int b, int c, int d, int x);

int main()     {
 int i,j,a,b,c,d;
 int e,f;
 srand(time(NULL));
 
 for ( i = 0; i < 10000000; i++ )  {
	a = rand() % 1000 + 1;
	if (( rand() % 2 + 1) == 1 ) a = -a;
 	b = rand() % 1000 + 1;
	if (( rand() % 2 + 1) == 1 ) b = -b;
 	c = rand() % 1000 + 1;
	if (( rand() % 2 + 1) == 1 ) c = -c;
 	d = rand() % 1000 + 1;
	if (( rand() % 2 + 1) == 1 ) d = -d;
 	e = 0; // 解の数
 	if ( d < 0 )
 	  f = -d;
 	else
 	  f = d;
 	for ( j = -f; j <= f; j++ )    {
		if ( j != 0 && (f % j) == 0 ) {
		  if ( QD(a,b,c,d,j) == 0 )       {
			if ( e == 0 )
		      printf("a = %4d,b = %4d,c = %4d, d = %4d, 解1:%d\n",a,b,c,d,j);
		    else if ( e == 1 )
		      printf("a = %4d,b = %4d,c = %4d, d = %4d, 解2:%d\n",a,b,c,d,j);
		    else
		      printf("a = %4d,b = %4d,c = %4d, d = %4d, 解3:%d\n",a,b,c,d,j);
		     e++;
		    }
		}
	}
 }
 
 return 1;

}

long long int QD(int a, int b, int c, int d, int x)  {
 return a*x*x*x + b*x*x + c*x + d;
}

このアーカイブについて

このページには、過去に書かれたブログ記事のうちコンピュータカテゴリに属しているものが含まれています。

次のカテゴリはスピリチュアルです。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。