12

数値が 0 ~ の間の任意のセルがありますInteger.MAX_VALUE。これらのセルをそれに応じて色分けしたいと思います。

値が 0 の場合、r = 0 です。値が の場合、Integer.MAX_VALUEr = 255 です。しかし、その間の値はどうでしょうか?

Integer.MAX_VALUEx =>が 255である関数が必要だと考えています。この関数は何ですか? または、これを行うより良い方法はありますか?

私はそれ(value / (Integer.MAX_VALUE / 255))を行うこともできますが、それにより多くの低い値がゼロになります。おそらく、ログ機能でそれを行う必要があります。

ほとんどの値は [0, 10,000] の範囲になります。そこで、違いを強調したいと思います。

4

13 に答える 13

16

「最も公平な」線形スケーリングは、実際には次のように行われます。

floor(256 * value / (Integer.MAX_VALUE + 1))

これは単なる疑似コードであり、浮動小数点計算を想定していることに注意してください。

Integer.MAX_VALUE + 1 が 2^31 であり、/ で整数除算が得られると仮定すると、次のように簡略化されます。

value / 8388608

他の答えが間違っている理由

一部の回答 (および質問自体) は、(255 * value / Integer.MAX_VALUE). round()おそらく、これはまたはを使用して整数に変換する必要がありfloor()ます。

を使用する場合、 255 を生成するのは Integer.MAX_VALUE 自体floor()だけです。valueこの分布は不均一です。

を使用するround()と、0 と 255 はそれぞれ 1-254 の半分の回数ヒットします。ムラもあります。

上記のスケーリング方法を使用すると、そのような問題は発生しません。

非線形法

ログを使用したい場合は、これを試してください:

255 * log(value + 1) / log(Integer.MAX_VALUE + 1)

値の平方根を取ることもできます (これは 255 までは行きませんが、必要に応じてスケールアップできます)。

于 2009-10-11T03:17:47.590 に答える
5

これには対数適合が適していると考えましたが、結果を見るとよくわかりません。

ただし、Wolfram|Alphaは、この種の実験には最適です。

私はそれから始めて、次のようになりました:

r(x) = floor(((11.5553 * log(14.4266 * (x + 1.0))) - 30.8419) / 0.9687)

興味深いことに、これはアルテリウスの次の回答とほぼ同じ結果をもたらすことがわかりました。

r(x) = floor(255 * log(x + 1) / log(2^31 + 1)

IMHO、0-10000 と 10000-2^31 の分割関数を使用するのが最適です。

于 2009-10-11T19:48:35.113 に答える
3

0-2^32 から 0-255 の範囲の線形マッピングの場合は、上位バイトのみを取得します。バイナリ&とビットシフトを使用すると、次のようになります。

r = value & 0xff000000 >> 24

mod 256 を使用すると、確かに値 0 ~ 255 が返されますが、結果からグループ化の意味を引き出すことはできません。1、257、513、1025 はすべて、互いに離れていても、スケーリングされた値 1 にマップされます。 .

低い値をより識別し、より多くの大きな値をマージしたい場合は、対数式が機能します。

r = log(value)/log(pow(2,32))*256

編集: うーん、私の高校の代数の先生、バッケンマイヤー夫人は失神するでしょう! log(pow(2,32))は と同じで32*log(2)、評価がはるかに安価です。256/32 はちょうどいい 8 であるため、これを因数分解することもできます。

r = 8 * log(value)/log(2)

log(value)/log(2)実際にはlog-base-2 of value、ログは非常にきれいに処理されます。

r = 8 * log(value,2)

バッケンマイヤーさん、あなたの努力は無駄ではありませんでした!

于 2009-10-11T04:04:03.737 に答える
2

一般に (これが Java なのか言語に依存しない質問なのかはっきりしないため)、値を Integer.MAX_VALUE割り、 を掛けて255、整数に変換します。

于 2009-10-11T03:04:39.207 に答える
2

これはうまくいきます! r= value /8421504;

8421504 は実際には「マジック」ナンバーであり、MAX_VALUE/255 に相当します。したがって、MAX_VALUE/8421504 = 255 (および、多少の変更はありますが、十分に小さい整数計算ではそれが取り除かれます。

マジックナンバーを含まないものが必要な場合は、これが機能するはずです(優れたコンパイラーは実際の値に置き換えるため、同等のパフォーマンスになります:

r= value/ (Integer.MAX_VALUE/255);

良い点は、これには浮動小数点値が必要ないことです。

于 2009-10-11T03:16:50.697 に答える
1

より明るくしたい場合、その光度は線形ではないため、値から色への直線的なマッピングでは良い結果が得られないことに注意してください。

Colorクラスには、より明るい色を作成するためのメソッドがあります。それを見てください。

于 2009-10-11T06:43:48.533 に答える
1

線形実装はこれらの回答のほとんどで説明されており、Arteliusの回答が最良のようです。しかし、最良の公式は、あなたが達成しようとしていることとあなたの価値観の分布に依存します。理想的な答えを出すのは難しいことを知らずに。

ただし、説明のために、これらのいずれかが最適な場合があります。

  • 線形分布。各範囲は、全体の範囲の1/266です。
  • 対数分布(低い値に向かって歪んでいる)は、低いマグニチュードの違いを強調し、高いマグニチュードの違いを減らします
  • 逆対数分布(高い値に向かって歪んでいる)。これにより、高いマグニチュードの違いが強調表示され、低いマグニチュードの違いが減少します。
  • 色の発生率の正規分布。各色は他のすべての色と同じ回数表示されます。

繰り返しになりますが、何を達成しようとしているのか、データは何に使用されるのかを判断する必要があります。これを構築するタスクを課されている場合は、これを明確にして、可能な限り有用であることを確認し、後で再開発する必要がないようにすることを強くお勧めします。

于 2009-10-11T06:47:25.577 に答える
1

C# で拡張メソッドを使用して数値をスケーリング、正規化、ランク付けなどするための一連のアルゴリズムを次に示しますが、他の言語に適用することもできます。

http://www.redowlconsulting.com/Blog/post/2011/07/28/StatisticalTricksForLists.aspx

ある方法または別の方法をいつ使用するかを説明する説明と図があります。

于 2011-07-30T14:04:31.630 に答える
1

「どの値を 128 にマップする必要があるか」という質問を自問してください。答えが約 10 億の場合 (そうであるとは思えません)、linear を使用します。答えが 1 万から 10 万の範囲にある場合は、平方根または対数を検討してください。

別の回答がこれを示唆していました(まだコメントも投票もできません)。同意します。

r = ログ (値)/ログ (pow(2,32))*256

于 2009-10-11T07:17:51.397 に答える
1

探している値は次のとおりです: r = 255 * (値 / Integer.MAX_VALUE)。したがって、これを double に変換してから、int にキャストする必要があります。

于 2009-10-11T03:03:11.927 に答える
0

最良の答えは、実際に必要な動作によって異なります。

各セルに隣接するセルとは異なる色を一般的に持たせたい場合は、2 番目の段落でakfが述べたことに従い、モジュロ (x % 256) を使用します。

色が実際の値に関係するようにしたい場合 (「青は小さい値を意味する」から「赤は大きな値を意味する」まで)、予想される値の分布について何かを投稿する必要があります。多くの低い値がゼロになることを心配しているので、それらがたくさんあると推測するかもしれませんが、それは推測にすぎません。

この 2 番目のシナリオでは、可能性の高い回答を 256 の「パーセンタイル」に分散し、それぞれに色を割り当てたいと考えています (各パーセンタイルに同数の可能性のある回答が含まれる場合)。

于 2009-10-11T03:32:21.913 に答える
0

低い数値がゼロになっていることに不満がある場合は、値の範囲全体ではなく、値を 255 に正規化することをお勧めします。

式は次のようになります。

currentValue / (セットの最大値)

于 2009-10-11T04:54:35.773 に答える
-1

(value / (Integer.MAX_VALUE / 255)) を実行することもできますが、それでは多くの低い値がゼロになります。

1 つの方法として、モジュロ演算子 ( ) を使用することができますr = value%256;これはInteger.MAX_VALUE255 になることを保証しませんが、0 から 255 の間の数値を保証します。また、0 から 255 の範囲に小さい数値を分散させることもできます。

編集:

おかしなことに、これをテストすると、Integer.MAX_VALUE % 256結果は255 (最初に誤って に対してテストし%255たため、間違った結果が得られました)。これはかなり簡単な解決策のようです。

于 2009-10-11T03:02:29.167 に答える