データ構造・15パズル・Algebraの意味とは?

このQ&Aのポイント
  • 通信大学でデータ構造を専攻中の質問者は、画像部分の意味がわからないと困っています。
  • 質問文章では、データ構造、15パズル、Algebraの関連性について触れられています。
  • 具体的には、15パズルのボードやタイル、位置、移動に関する要素が述べられています。
回答を見る
  • ベストアンサー

データ構造・15パズル・Algebra

通信大学で、データ構造を専攻中なのですが、 添付した画像部分が具体的に何を意味しているのかよく分かりません。 {(Ptile, blank), (Pblank, t)} ∪{(p',t') | (p',t') ∈ b ∧ p' ∉ {Ptile, Pblank}} この(p',t')は何を表しているんでしょうか。どうぞ宜しくお願い致します。 ----------------------------- Algebra puzzle 15 sorts tile, position, board, bool ops init: tile16 -> board move: board x tile -> board solved: board -> bool pos: board x tile -> position sets tile = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,blank} position = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,error} board = {c ⊂ (position \ {error}) x tile |c| = 16 ∧∀c = (p,t) ∈ c: c’ ≠ c -> p‘ ≠ p ∧ t‘ ≠ t } ∪ {error}

質問者が選んだベストアンサー

  • ベストアンサー
  • stomachman
  • ベストアンサー率57% (1014/1775)
回答No.3

ま、ま、一応、答も書いちゃいますか。 > {(Ptile, blank), (Pblank, t)} > ∪{(p',t') | (p',t') ∈ b ∧ p' ∉ {Ptile, Pblank}}

 (p',t')は数学の書き方なら順序対<p', t'>。ANo.1で説明した「タイルと空きの配置」cの要素である<マス, タイル>を指していて、p: position, t: tileである。ここで、   {(p',t') | (p',t') ∈ b ∧ p' ∉ {Ptile, Pblank}} とは、そのまま読めば、ある「タイルと空きの配置」bについて、(p',t') ∈ b かつ p'≠Ptileかつp'≠Pblank であるような(p',t')の集合、ということですね。  PtileとPblankは何かというと、ある「タイルと空きの配置」bにおいて、特定のマスPblankとマスPtileが指定されているんです。もちろんこれは、move(指し手)においてあるタイルと空きとを入れ替える、その場所を表しているに違いありません。ですから、   {(p',t') | (p',t') ∈ b ∧ p' ∉ {Ptile, Pblank}} とは、 bにおける16個の<マス, タイル>のペアの中で、PblankでもPtileでもないマスp'とそのマスにあるタイルt'のペア<p', t'>の集合 すなわち、(Pblankにある空きとPtileにあるタイルを入れ替えるという)指し手によって影響を受けない(変化しない)ペア全部の集合に他なりません。  となると、   {(Ptile, blank), (Pblank, t)} とは、タイルtと空きblankとを入れ替える指し手(move)において、moveの直前には<Ptile, t>, <Pblank, blank> (つまり、マスPtileにはタイルtがあり、マスPblankには空きがあった)のを、入れ替えた、という状態を表している。ですから、 > {(Ptile, blank), (Pblank, t)}
 > ∪{(p',t') | (p',t') ∈ b ∧ p' ∉ {Ptile, Pblank}}
 とは結局、 「タイルと空きの配置」bにおいて、空きがあるマスPblankと、それに隣接するマスPtile(そこにはタイルtがある)について、タイルtをマスPblankへ移動させる(従って、空きはマスPtileへ移動する)という指し手(move)を行ったあとに生じる「タイルと空きの配置」 に他なりません。

Aepfelchen
質問者

お礼

理解出来ました! 本当に丁寧に書いて下さりありがとうございました。 また分からない時には宜しくお願い致します。

その他の回答 (2)

  • stomachman
  • ベストアンサー率57% (1014/1775)
回答No.2

ANo.1、一番肝心なとこミスプリしました。 >> board ={ c ⊂ (position\{error})×tile ∧ |c|=16 ∧ ∀c=(p,t)∃c'=(p',t'): c’ ≠ c → p‘ ≠ p ∧ t‘ ≠ t } ∪ {error} じゃなくて、 board ={ c ⊂ (position\{error})×tile ∧ |c|=16 ∧ ∀c=(p,t)∀c'=(p',t'): c’ ≠ c → p‘ ≠ p ∧ t‘ ≠ t } ∪ {error} です。

  • stomachman
  • ベストアンサー率57% (1014/1775)
回答No.1

何かの高級プログラミング言語で書いてあるようで(何語ですか?もしかして「Algebra」という言語なんでしょうか。知らんけど。)、数学の表記としては「?」な部分も散見されます。が、ともあれ、 > Algebra puzzle 15 「15パズル」は大昔からあるけど今でもポピュラー。1~15の番号が付いた15個のタイルと空きひとつをボード上に4×4マスに並べておいて、空きに隣接しているマスにあるタイルを空きと交換する、という操作を繰り返して、1~15までのタイルが所定の配置になるようにする。ご質問では、ボード上のマスにも1~16の番号を付けてあるんですね。 > sorts tile, position, board, bool 分からんが、これらが順序集合だ、ということを言っているのかもしれないな。だとすると、15パズルにおいてはまるきりどうでもいい話ですね。 
> ops 知らんけど、以下関数の定義域と値域の話が来ますね。関数は実装を見なくちゃ正確なことは言えないわけですが、15パズルを解くためのプログラムだ、ということと名称から、何をする関数なのか見当がつきます。 
> init: tile16 -> board initは tile16からboardへの関数である。boardは「タイルと空きの配置」の集合ですね。この関数は、ある「タイルと空きの配置」、つまり解くべき問題をセットする関数なのでしょう。tile16が何の事かは分かりません。 > move: board x tile -> board 数学の記号としては"x"じゃなくて"×"であるべきでしょう。move(日本語なら「指し手」)はboardとtileからboardへの関数である。ある「タイルと空きの配置」において、「どのタイル」を空きと交換するか、を指定すると、(もし可能なら)次の「タイルと空きの配置」が得られる関数。もちろん、指定したタイルが空きに隣接していなければダメで、だからboardにはダメを表すerrorという要素が含まれている。 
> solved: board -> bool solvedはboardからbool(真偽値)への関数である。これは「解けた」ということを表す関数ですね。 
> pos: board x tile -> position posはboardとtileからpositionへの関数。positionはボード上のマスですね。ある「タイルと空きの配置」において、あるタイルがどのマスにあるか、を答えてくれる関数。 
> sets ここからは集合の定義ですな。 
> tile = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,blank} 1~15までの番号が付いたタイルと、空きひとつ。空きもタイルの一種と考えるわけですね。 
> position = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,error} ボード上の1~16までのマスの集合ですが、「error」というのも入れてありますね。(何に使うんだろ?) 
> board = {c ⊂ (position \ {error}) x tile |c| = 16 
> ∧∀c = (p,t) ∈ c:
 > c’ ≠ c -> p‘ ≠ p ∧ t‘ ≠ t
 > } ∪ {error}  ここはいろいろ変です。もう、かなりおかしいです。そこで、15パズルの「タイルと空きの配置」を表すためにはどうあればいいか、ということから逆に正しい記述を再構成してみると、おそらくこうでしょう:  boardという集合は、「集合positionから要素errorを除いたものとtileとの直積集合の部分集合」c(すなわち「集合positionから要素errorを除いたものの要素とtileの要素との対」を集めた集合c)の集合に、要素errorを加えた集合である。ただし、cの要素の個数は16であり、どのc(c=(p,t)とする)についても、c'(c'=(p',t')とする)が存在して、c'≠cならばp‘ ≠ p ∧ t‘ ≠ t である。  つまり、   board ={ c : c ⊂ (position\{error})×tile ∧ |c|=16 ∧ ∀c=(p,t)∃c'=(p',t'): c’ ≠ c → p‘ ≠ p ∧ t‘ ≠ t } ∪ {error} でしょ。どういう意味かというと、boardはボード上のタイルと空きの配置cのあらゆるものを集めたもの、およびerrorから成る集合である。さて、boardの要素である「タイルと空きの配置」cは<マス, そのマスにあるタイル>という対の集合である。ただし、cは、16個のマス全部について、また(空きを含めた)16個のタイル全部についての対を含んでいる。つまり、マスもタイルも重複してはダメ(これを表すのがc’ ≠ c → p‘ ≠ p ∧ t‘ ≠ t)、抜けていても駄目(|c|=16)。  添付写真にあるのは、どのマスが空きに隣接しているか(つまりどのタイルが動かせるか)という判定をやる部分ですね。

Aepfelchen
質問者

お礼

stomachmanさん、 早速のお返事ありがとうございます! とても詳しく書いてくださったお陰で、理解してきました。 あと一つ気になるのですが、画像の3行目、 ∪{(p',t') | (p',t') ∈ b ∧ p' ∉ {Ptile, Pblank}} にある、 p' ∉ {Ptile, Pblank} で ∉ となる点がよく分かりません。 度々申し訳ありませんが、どうぞ宜しくお願い致します。

関連するQ&A

  • 適切な変換関数が存在しない???

    C++の構造体で困っています 印刷領域のカレントポジションを原点に戻すとともに、それ以前のカレントポジションを知ろうと思い以下のようなプログラムを書きました typedef struct {       int x;       int y; }POINT ; POINT MyPoint; MyPoint.x = 9999; MyPoint.y = 9999; bool rtn = MoveToEx(hdc, 0, 0, MyPoint);  ・・・・・(1) MyPoint.xとMyPoint.y には9999ではなく、現在のカレントポジションが入るという単純なものです ところが(1)のMyPointで以下のような文法エラーが発生します ERROR "POINT"から"LPPOINT"への適切な変換関数が存在しません 色々調べましたらC++のコンパイラの設定に関連するエラーらしいです この辺りのことは不勉強で困っております どのように対処すれば良いかご指導願います

  • 微分方程式について

    以下の同次微分方程式をとく問題について質問です。お願いします。 1) (d^2x)/(d t^2)+6(dx)/(dt)+9x=0,x(0)=3,x^(1)(0)=-4という問題です。 ------- 僕は、x(t)=cε^(pt) (p^2+6p+9)cε^(pt)=0 特性方程式:H(p)=p^2+6p+9=(x+3)^2 特 性 根:p0=-3,p1=-3 まで分かりましたが、ここから分かりません。 解答に、ここからのつづきとして、 x(t)=c0 ε^(-3t)+c1 【t】 ε^(-3t)の【】でしてある’t’の意味が分かりません。なぜ、c1 ε^(-3t)じゃないんですか。 また、解答に書いてあるx’(t)=-3c0 ε^(-3t)+c1 ε^(-3t)-3c1 t ε^(-3t)に成るのでしょうか。教えてください。

  • 微分方程式について

    以下の微分方程式の問題が分かりません。お願いします。 ◎次の同次微分方程式を、与えられた初期値の下で解け。 (d^2 x)/(d t^2)-2(dx)/(dt)-3x=0,x(0)=3,x^(1)(0)=1 という問題です。 x(t)=cε^(pt)を上記の式の代入して、 (p^2-2p-3)cε^(pt)=0 特性方程式は、H(p)=p^2-2p-3=(p+1)(p-3) になり、 特性根は、p0=-1,p1=3になる x(t)=c0 ε^(-t)+c1 ε^(3t) x(t)’=-c0 ε^(-t)+3c1 ε^(3t) になります。ここで、x(0)とx(0)’を求めるのですがここからがわかりません。 x(0)=c0+c1=3,x(0)’=-c0+3c1=1 と立てれるそうですが、それぞれの左辺は、分かりますが、右辺の3と1の意味が分かりません。なぜ、こうなりますか。 あと、ここからどうしたらよいですが。 お教えください。

  • セグメンテーションエラーがでます

    今、cでオセロゲームを作っています。 コンピュータと対戦できるようにしたいのですが、セグメンテーション違反になってしまいます。 p[LEN*LEN]を大域変数にするとうまく動きますが、以下のように局所変数にして関数で受け渡しをすると、 数回ループさせたところでエラーで強制終了します。 おそらく関数find_legal_moveへのp[]の渡し方が悪いのだと思いますが、なぜか分かりません。 以下にプログラムの一部を載せますので、お手数ですが原因を教えていただけないでしょうか。 よろしくお願いします。 #define LEN 10 /* ボードの1辺 */ #define opponent(player) (3-(player)) /* 1の相手は2, 2の相手は1 */ typedef struct {  int row; /* 行 */  int col; /* 列 */  int dr, dc; /* 行, 列の向き */ } Position; // 裏返る石の個数 int count_turn_over(int board[][LEN], int player, Position p) {  int i;  for (i=1; board[p.row+i*p.dr][p.col+i*p.dc]==opponent(player); i++);  if (board[p.row+i*p.dr][p.col+i*p.dc] == player)   return i - 1;  else   return 0; } // playerが(row, col)に石を置けるかどうかをチェック int is_legal_move(int board[][LEN], int player, Position p) {  if ((p.row < 1 || p.row > 8) || (p.col < 1 || p.col > 8))   return 0;  if (board[p.row][p.col] != 0) return 0;  for (p.dr = -1; p.dr <= 1; p.dr++)   for (p.dc = -1; p.dc <= 1; p.dc++)    if (count_turn_over(board, player, p) != 0)     return 1;  return 0; } // playerがどこに石を置けるか int find_legal_move(int board[][LEN], int player, Position p[]) {  Position pos;  int i = 0;  for (pos.row = 1; pos.row < LEN - 1; pos.row++)   for (pos.col = 1; pos.col < LEN - 1; pos.col++)    if (is_legal_move(board, player, pos) != 0) {     p[i].row = pos.row;     p[i].col = pos.col;     i++;    }  return i; } // computerの入力 void computer(int board[][LEN], int player, Position *pos) {  int i, num, max;  Position p[LEN * LEN];  printf("コンピュータの番です\n");  // 一番多く取れるところを取る  num = find_legal_move(board, player, p);  max = count_turn_over(board, player, p[0]);  pos->row = p[0].row;  pos->col = p[0].col;  for (i = 1; i < num; i++) {   int tmp = count_turn_over(board, player, p[i]);   if (max < tmp) {    pos->row = p[i].row;    pos->col = p[i].col;   }  } }

  • 構造体vectorの入れ子のfillの使い方

    構造体vectorの入れ子のfillの使い方 vectorデータのメモリを確保する関数をテンプレート関数で作ったのですが、構造体の入れ子vectorのデータの時、ビルドが通りません。 構造体や入れ子vectorの時のfillの使い方が間違っているようですが、理由がわかりません。直し方を教えて下さい! ソースコード ------------------------------------------------------------- #include <vector> using namespace std; struct aa{  float x; float y;  aa& operator = (const aa& rhs)  {   if (this == &rhs) return *this;   x = rhs.x; y = rhs.y;   return *this;  }; }; template<typename T1, typename T2> bool getM(   vector<T1>& vDat, const T2 datN ) {  bool bRet = true;  try{   vDat.resize( datN );  }catch( bad_alloc ){   return false;  }  fill( vDat.begin(), vDat.end(), 0x0 );  return bRet; } template bool getM<aa, int> ( vector<aa>& vDat, const int datN ); template bool getM<vector<aa>, int> ( vector< vector<aa> >& vDat, const int datN ); int main() {  vector< vector<aa> > data;  data.clear();  if( false == getM( data, 10 ) ) return -1;  for( int i = 0; i < 10; i++ ){   if( false == getM( data.at(i), 20 ) ) return -1;   for( int j = 0; j < 20; j++ ){    data.at(i).at(j).x = 1.;    data.at(i).at(j).y = 1.;   }  }  return 0; } エラーメッセージ ------------------------------------------------------------- Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland main.cpp: エラー E2285 c:\Borland\Bcc55\include\algorith.cc 519: 'aa::operator =(const int )' に一致するものが見つからない(関数 fill<aa *,int>(aa *,aa *,const int &) ) 警告 W8057 c:\Borland\Bcc55\include\algorith.cc 520: パラメータ 'value' は一度も 使用されない(関数 fill<aa *,int>(aa *,aa *,const int &) ) エラー E2285 c:\Borland\Bcc55\include\algorith.cc 519: 'vector<aa,allocator<aa> >::operator =(const int)' に一致するものが見つからない(関数 fill<vector<aa,alloc ator<aa> > *,int>(vector<aa,allocator<aa> > *,vector<aa,allocator<aa> > *,const int &) ) 警告 W8057 c:\Borland\Bcc55\include\algorith.cc 520: パラメータ 'value' は一度も 使用されない(関数 fill<vector<aa,allocator<aa> > *,int>(vector<aa,allocator<aa> > *,vector<aa,allocator<aa> > *,const int &) ) *** 2 errors in Compile ***

  • 導関数と接線の問題なんですが・・・

    f(x)=x^3-5/3xとし、曲線y=f(x)をCとする。 C上の点P(t,f(t)) (t≠0)におけるCの接線lが、 P以外の点QでCと交わるとき、Qのx座標とtで表せ。 またこのとき、QにおけるCの接線の傾きをtで表せ。 という問題なんですが、一応自分でも解いてみてまず f´(x)=3x^2-5/3として、みたんですが、それさえも あっているか分からないのですが、ここまでしかわからないので 解き方を教えて下さい。お願いします。

  • Span setって?線形代数の問題が解けません

    P2を次数2の多項式の集合とする。 (1) ベクトルx1,x2,x3:は一次独立か? (2) ベクトルx1,x2,x3:はP2のspan setか? (3) P2の任意のベクトルはx1,x2,x3の一次結合で表せるか? x1:=1+t x2:=1-t x3:=1-t^2 (1)の解 ax1+bx2+cx3=0とおくと a(1+t)+b(1-t)+c(1-t^2)=0 -ct^2+(a-b)t+(a+b+c)=0. これはtについての恒等式になっているので -c=a-b=a+b+c=0でなければならない。 したがって、a=b=c=0で一次独立。 で正しいでしょうか? あと、(2),(3)の解き方をお教え下さい。

  • 確率変数の式変形について

    Z(t)=√ρ*X(t)+√(1-ρ)*ε(t) X(t),ε(t) は互いに独立に標準正規分布に従う。 Z(t)<C の時に事象Aが発生する。 X(t)=x の下での事象Aの条件付発生確率を以下のように表す。 p(x)=Pr[Z<C | X(t)=x] =Pr[√ρ*x+√(1-ρ)*ε(t)<C] =Pr[ε(t) < (C-√ρ*x)/√(1-ρ)] =G[(C-√ρ*x)/√(1-ρ)]    ※Gは標準正規分布の分布関数 このときに、 E[p(x)]=∫[-∞~∞]p(x)f(x)dx   ※fは標準正規分布の密度関数 =G(C) ←★       1つ前の式から★に至る式変形がわかりません。 よろしくお願いします。

  • 偏微分方程式

    ∂y(x,t)/∂t = α ∂^2y(x,t)/∂x^2 ただし、0≦t, 0≦x≦p, αは正の定数 を、以下の条件のもとで解け。 初期条件 t=0; y=A 境界条件 x=0; y=B      x=p; y=C ただし、A,B,Cは正の定数である。 この問題がわかりません。 y = η(x,t) + B + (C-B)/p x とおくと、ηについての境界条件がどちらもy=0になるので、 η=X(x)T(t)とおいて変数分離形で解いてみましたが、 途中にフーリエ級数もどきがでてきてしまい、 うまく解けません。 どなたか教えていただけないでしょうか。

  • C++について。

    現在”猫でもわかるプログラミング”のC++編をSDKと共に勉強している身です。 現在第22章、第23章を勉強中です。 22章 http://www.kumei.ne.jp/c_lang/cpp/cpp_22.htm 23章 http://www.kumei.ne.jp/c_lang/cpp/cpp_23.htm 作業環境はVisual Studio 2005.net C++です 22章でのプログラムを作成し、実行した結果エラーが出てしまいました。 ソースです #include <iostream> class xy_position { int x; int y; public: xy_position(int x = 0, int y = 0){ xy_position::x = x; xy_position::y = y; } int X() const {return x;} int Y() const {return y;} }; ostream& operator << (ostream& o, const xy_position& p) { return o << "(" << p.X() << "," << p.Y() << ")"; } int main(void) { xy_position a(50, 60), b; std::cout << a << b << std::endl; return 0; } (17):error C2143: 構文エラー : ';' が '&' の前にありません。 (17):error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません (17):error C2065: 'o' : 定義されていない識別子です。 (17):error C2059: 構文エラー : 'const' (18):error C2143: 構文エラー : ';' が '{' の前にありません。 (18):error C2447: '{' : 対応する関数ヘッダーがありません (旧形式の仮引数リスト?) (26):error C2679: 二項演算子 '<<' : 型 'xy_position' の右オペランドを扱う演算子が見つかりません (または変換できません)。 このようなエラーが出てしまいました。 もちろんソースは全て同様に書いています。 この”猫でも”で使用しているコンパイラと異なるために出たエラーでしょうか? それに単に cout << のように記述するとエラーが出てしまい、 std::cout << のように記述しなければ通りません。 また、エラーとは別の質問になってしまいますが、プログラム中に int X() const {return x;} という記述がありますが、このconstの意味が分かりません。 単純に return x が変更不可能という意味でしょうか? 次に23章についての質問です。 ここでもソースは同じなのに以下のようなエラーが出てしまいます。 ソースです。 #include <iostream> int main(void) { int x=10, y=15, z=20; std::cout << "16進表示" << std::endl; std::cout.setf(ios::hex); std::cout << x << std::endl; std::cout << y << std::endl; std::cout << z << std::endl; std::cout.unsetf(iostream::hex); std::cout << "8進数" << std::endl; std::cout.setf(ios::oct); std::cout << x << std::endl; std::cout << y << std::endl; std::cout << z << std::endl; return 0; } (8):error C2653: 'ios' : 識別子がクラス名でも名前空間名でもありません。 (8):error C2065: 'hex' : 定義されていない識別子です。 (13):error C2653: 'iostream' : 識別子がクラス名でも名前空間名でもありません。 (15):error C2653: 'ios' : 識別子がクラス名でも名前空間名でもありません。 (15):error C2065: 'oct' : 定義されていない識別子です。 これも何か設定をしなければいけないのでしょうか? なにぶんC++は・・・というかオブジェクト指向の言語は初心者なもので疑問も多いですorz