0

x * yセルのグリッド(またはテーブル)が与えられます。各セルには値が含まれています。これらのセルのほとんどの値は0ですが、このグリッドのどこかに、高い値のセルがある「ホットスポット」が存在する可能性があります。この場合、このセルの隣接セルの値も0を超えます。ホットスポットから離れるほど、それぞれのグリッドセルの値を低くします。

したがって、このホットスポットは丘の頂上と見なすことができ、この丘から離れるほど値が小さくなります。特定の距離で、値は再び0に下がります。

次に、グリッドの重心を表すグリッド内のセルを決定する必要があります。上記の簡単な例では、この図心は単純に最も高い値を持つ1つのセルになります。ただし、必ずしもそれほど単純ではありません。

  1. ホットスポットセルの周囲の隣接セルの減少する値が均等に分散されていないか、「丘の側」が別の側よりも早く0に低下する可能性があります。

  2. グリッド内に値が0より大きい別のホットスポット/丘があります。

これは典型的な問題だと思います。残念ながら、私は数学の専門家ではないので、何を検索すればよいかわかりません(少なくともGoogleで答えは見つかりませんでした)。

この問題をどのように解決できますか?

前もって感謝します。

4

2 に答える 2

3

セル値の「加重平均」を探しています。各セルの値がz(x、y)であるとすると、次のことができます。

zx = sum( z(x, y) ) over all values of y
zy = sum( z(x, y) ) over all values of x

meanX = sum( x * zx(x)) / sum ( zx(x) )
meanY = sum( y * zy(y)) / sum ( zy(y) )

私はあなたがこれをあなたの選んだ言語に変換できると信じています...

例:Matlabを知っている場合、上記は次のように記述されます

zx = sum( Z, 1 ); % sum all the rows
zy = sum( Z, 2 ); % sum all the columns

[ny nx] = size(Z); % find out the dimensions of Z

meanX = sum((1:nx).*zx) / sum(zx);
meanY = sum((1:ny).*zy) / sum(zy);

これにより、1 .. nxの範囲のmeanXが得られます。真ん中にある場合、値は(nx + 1)/2になります。明らかに、これをニーズに合わせてスケーリングできます。

編集:もう一度、「ほぼ本物の」コードで:

// array Z(N, M) contains values on an evenly spaced grid
// assume base 1 arrays

zx = zeros(N);
zy = zeros(M);

// create X profile:
for jj = 1 to M
  for ii = 1 to N
    zx(jj) = zx(jj) + Z(ii, jj);
  next ii
next jj

// create Y profile:
for ii = 1 to N
  for jj = 1 to M
    zy(ii) = zy(ii) + Z(ii, jj);
  next jj
next ii

xsum = 0;
zxsum = 0;
for ii = 1 to N
  zxsum += zx(ii);
  xsum += ii * zx(ii);
next ii
xmean = xsum / zxsum;

ysum = 0;
zysum = 0;
for jj = 1 to M
  zysum += zy(jj);
  ysum += jj * zy(ii);
next jj
ymean = ysum / zysum;
于 2013-02-02T03:46:20.120 に答える
1

このウィキペディアのエントリが役立つ場合があります。「粒子のシステム」というタイトルのセクションが必要なすべてです。次元ごとに1回計算する必要があることを理解してください。そのうち、2つあるようです。

そして、これが完全なScala 2.10プログラムで、ランダムな整数でいっぱいのグリッドを生成し(コマンドラインで指定された次元を使用)、重心(行と列に1から始まる番号が付けられます)を見つけます。

object Ctr extends App {
  val Array( nRows, nCols ) = args map (_.toInt)
  val grid = Array.fill( nRows, nCols )( util.Random.nextInt(10) )
  grid foreach ( row => println( row mkString "," ) )
  val sum = grid.map(_.sum).sum
  val xCtr = ( ( for ( i <- 0 until nRows; j <- 0 until nCols )
    yield (j+1) * grid(i)(j) ).sum :Float ) / sum
  val yCtr = ( ( for ( i <- 0 until nRows; j <- 0 until nCols )
    yield (i+1) * grid(i)(j) ).sum :Float ) / sum
  println( s"Center is ( $xCtr, $yCtr )" )
}

関数を定義して計算をDRYerに保つこともできますが、できるだけわかりやすくしたかったのです。とにかく、ここでそれを数回実行します:

$ scala Ctr 3 3
4,1,9
3,5,1
9,5,0
Center is ( 1.8378378, 2.0 )

$ scala Ctr 6 9
5,1,1,0,0,4,5,4,6
9,1,0,7,2,7,5,6,7
1,2,6,6,1,8,2,4,6
1,3,9,8,2,9,3,6,7
0,7,1,7,6,6,2,6,1
3,9,6,4,3,2,5,7,1
Center is ( 5.2956524, 3.626087 )
于 2013-02-02T04:46:41.667 に答える