2009-10-11 29 views
12

Tôi có các ô mà giá trị số có thể là bất kỳ giá trị nào giữa 0 và Integer.MAX_VALUE. Tôi muốn mã màu các tế bào này tương ứng.Số tỷ lệ là <= 255?

Nếu giá trị = 0, thì r = 0. Nếu giá trị là Integer.MAX_VALUE, thì r = 255. Nhưng còn giá trị ở giữa thì sao?

Tôi nghĩ rằng tôi cần một hàm có giới hạn là x =>Integer.MAX_VALUE là 255. Chức năng này là gì? Hoặc là có một cách tốt hơn để làm điều này?

Tôi chỉ có thể thực hiện (value/(Integer.MAX_VALUE/255)) nhưng điều đó sẽ khiến nhiều giá trị thấp bằng không. Vì vậy, có lẽ tôi nên làm điều đó với một chức năng đăng nhập.

Hầu hết các giá trị của tôi sẽ nằm trong khoảng [0, 10.000]. Vì vậy, tôi muốn làm nổi bật sự khác biệt ở đó.

+4

Không chắc chắn tại sao phiếu bầu đóng lại. Nó có vẻ như là một câu hỏi thực sự (và tốt) đối với tôi. –

+4

Làm thế nào điều này có thể được gắn thẻ java ** và ** ngôn ngữ bất khả tri? –

+0

Tôi nghĩ bạn có thể gắn thẻ cả hai vì có thể có giải pháp chung (tốt hơn) và java (cụ thể) – warren

Trả lời

5

I figured một sự phù hợp log sẽ là tốt cho điều này, nhưng nhìn vào kết quả, tôi không như vậy chắc chắn.

Tuy nhiên, Wolfram|Alpha là rất tốt cho experimenting with this sort of thing:

tôi bắt đầu với điều đó, và kết thúc với:

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

Điều thú vị là, nó chỉ ra rằng điều này sẽ cho kết quả gần giống với câu trả lời của Artelius của:

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

IMHO, bạn sẽ được phục vụ tốt nhất với chức năng chia cho 0-10000 và 10000-2^31.

+0

Sau khi đơn giản hóa đại số của tôi dưới đây, tôi nghĩ rằng điều này có thể phục vụ tốt cho bạn: 'r (x) = floor ((256./31) * log (x)/log (2))' – PaulMcG

+0

Yup, đó chắc chắn đơn giản hơn, mặc dù nó vẫn bị vấn đề phù hợp xấu so với các giá trị mong muốn. –

-1

Tôi chỉ có thể làm (giá trị/(Integer.MAX_VALUE/255)) nhưng điều đó sẽ làm cho nhiều giá trị thấp bằng không.

Một cách tiếp cận bạn có thể thực hiện là sử dụng toán tử modulo (r = value%256;). Mặc dù điều này sẽ không đảm bảo rằng Integer.MAX_VALUE hóa ra là 255, nó sẽ đảm bảo một số từ 0 đến 255. Nó cũng sẽ cho phép các số thấp được phân phối trên phạm vi 0-255.

EDIT:

Funnily, như tôi đã kiểm tra điều này, Integer.MAX_VALUE % 256 không dẫn đến 255 (Ban đầu tôi đã nhầm lẫn thử nghiệm chống lại %255, mà mang lại kết quả sai). Điều này có vẻ như một giải pháp khá thẳng về phía trước.

+0

Nó không được tuyên bố rõ ràng, nhưng dường như ẩn trong câu hỏi rằng các màu phải nhóm các giá trị tương tự - tức là nếu hai ô chia sẻ một màu thì giá trị của chúng sẽ tương đương nhau. Trong câu trả lời của bạn, màu sắc không liên quan đến độ lớn của giá trị. –

+0

Cái gì? Đây thậm chí không phải là một ý tưởng tốt từ xa. – rlbond

+0

Kirk, tôi đồng ý rằng ý tưởng phân phối vào các nhóm có giá trị tương tự là * một ý tưởng. Nó cũng xuất hiện rằng OP đã được mở cho các giải pháp khác. Có vẻ như, tuy nhiên, hầu hết những người trả lời đã lấy nhóm các giá trị tương tự như giải pháp duy nhất. – akf

1

Giá trị bạn đang tìm kiếm là: r = 255 * (giá trị/Integer.MAX_VALUE). Vì vậy, bạn sẽ phải biến điều này thành một đôi, sau đó quay trở lại một int.

+1

-1. Hoàn toàn sai, xin lỗi. – Artelius

+0

Ugh, bạn nói đúng, tôi đã gõ quá nhanh. Bạn có thể đã xác định sự điều chỉnh, nhưng tôi đã lấy manh mối tinh tế của bạn và chạy với nó. –

+0

Ngu ngốc SO. Tôi không thể đảo ngược downvote bây giờ. – Artelius

2

Nói chung (vì nó không phải là rõ ràng với tôi nếu đây là một Java hoặc ngôn ngữ-Agnostic câu hỏi), bạn sẽ chia giá trị mà bạn có bởiInteger.MAX_VALUE, nhân với 255 và chuyển đổi sang một số nguyên.

+0

Cách duy nhất để làm điều đó là để đúc thành một đôi tại một thời điểm, nó là hiệu quả hơn để làm điều đó theo cách khác xung quanh. – Erich

+0

@Erich, Nhưng sau đó bạn có cơ hội tràn. – strager

+0

Bạn sẽ không tràn nếu bạn chia đầu tiên! – Erich

2

Công trình này! r= value /8421504;

8421504 thực sự là số 'ma thuật', bằng MAX_VALUE/255. Do đó, MAX_VALUE/8421504 = 255 (và một số thay đổi, nhưng toán học số nguyên đủ nhỏ sẽ loại bỏ nó.

nếu bạn muốn một số không có số ma thuật, nó sẽ hoạt động (và hiệu suất ngang nhau) từ bất kỳ trình biên dịch tốt sẽ thay thế nó với giá trị thực tế:

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

phần tốt đẹp là, điều này sẽ không yêu cầu bất kỳ giá trị dấu chấm động

+0

Không phân phối chính xác bằng nhau, nhưng đủ tốt. – strager

+0

Làm thế nào? Các giá trị từ 0-Int.Max sẽ được phân phối đồng đều qua 0-255, phải không? – Erich

16

các "công bằng" mở rộng quy mô tuyến tính được thực hiện như thế nào. này:

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

Lưu ý rằng đây chỉ là mã giả và giả định tính toán dấu phẩy động.

Nếu chúng tôi giả định rằng Số nguyên.MAX_VALUE + 1 là 2^31, và đó/sẽ cho chúng ta phân chia số nguyên, sau đó nó đơn giản hoá để

value/8388608 

Tại sao câu trả lời khác là sai

Một số câu trả lời (cũng như các câu hỏi chính nó) suggsted một biến thể của (255 * value/Integer.MAX_VALUE). Có lẽ điều này phải được chuyển đổi thành một số nguyên, hoặc sử dụng round() hoặc floor().

Nếu sử dụng floor(), chỉ value sản xuất 255 chính là Integer.MAX_VALUE. Phân phối này không đồng đều.

Nếu sử dụng round(), 0 và 255 mỗi người sẽ nhận được một nửa số lần lặp lại 1-254. Cũng không đồng đều.

Sử dụng phương pháp chia tỷ lệ tôi đã đề cập ở trên, không xảy ra sự cố nào.

phương pháp

Non-linear

Nếu bạn muốn sử dụng các bản ghi, hãy thử này:

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

Bạn cũng có thể chỉ lấy căn bậc hai của giá trị (điều này sẽ không đi tất cả các đường đến 255, nhưng bạn có thể mở rộng nó lên nếu bạn muốn).

+0

hoạt động tốt hơn khi nó là 'log (Integer.MAX_VALUE)' thay vì 'log (Integer.MAX_VALUE + 1)'. Nếu không, mọi kết quả là 0 vì 'log (Integer.MAX_VALUE)' là 'NaN'. –

+2

Có lẽ các nhà phê bình bây giờ có thể thấy nó là ngôn ngữ bất khả tri như thế nào, mặc dù người lập trình đang làm việc trong THE ONE TRUE LANGUAGE –

+0

@Rosarch: Điểm tốt. Tôi có thể đã thử nghiệm mã của tôi trước khi đăng bài, nhưng tại sao tôi sẽ phá vỡ lời thề của tôi không bao giờ sử dụng Java trên một cái gì đó tầm thường? ;) Tuy nhiên, với tư cách là lập trình viên C, tôi nên biết rõ hơn ... – Artelius

0

Câu trả lời hay nhất thực sự phụ thuộc vào hành vi bạn muốn.

Nếu bạn muốn mỗi ô chỉ nhìn chung có màu khác với hàng xóm, hãy đi theo những gì akf cho biết trong đoạn thứ hai và sử dụng modulo (x% 256).

Nếu bạn muốn màu sắc có giá trị thực tế (như "xanh lam nghĩa là giá trị nhỏ hơn" tất cả các cách "đỏ có nghĩa là giá trị lớn"), bạn sẽ phải đăng nội dung về giá trị phân phối dự kiến ​​của mình. Vì bạn lo lắng về nhiều giá trị thấp bằng không, tôi có thể đoán rằng bạn có rất nhiều giá trị trong số đó, nhưng đó chỉ là phỏng đoán.

Trong trường hợp thứ hai này, bạn thực sự muốn phân phối câu trả lời có khả năng của bạn thành 256 "phần trăm" và gán màu cho mỗi phần (trong đó số câu trả lời có khả năng tương ứng sẽ rơi vào từng phần trăm).

3

Đối với ánh xạ tuyến tính trong khoảng 0-2^32 đến 0-255, chỉ cần lấy byte thứ tự cao. Dưới đây là làm thế nào mà sẽ trông sử dụng nhị phân & và bit-chuyển:

r = value & 0xff000000 >> 24 

Sử dụng mod 256 chắc chắn sẽ trả về một giá trị 0-255, nhưng bạn sẽ không thể vẽ bất kỳ ý nghĩa nhóm từ kết quả - 1, 257 , 513, 1025 tất cả sẽ ánh xạ tới giá trị được chia tỷ lệ 1, mặc dù chúng cách xa nhau.

Nếu bạn muốn trở thành sáng suốt hơn giữa giá trị thấp, và hợp nhất các giá trị nhiều lớn hơn với nhau, sau đó là một biểu hiện log sẽ làm việc:

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

EDIT: Yikes, giáo viên đại số trường trung học của tôi bà Buckenmeyer sẽ ngất đi! log(pow(2,32)) giống với 32*log(2)nhiều hơn rẻ hơn để đánh giá.Và bây giờ chúng ta cũng có thể yếu tố tốt hơn này, vì 256/32 là một tốt đẹp thậm chí 8:

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

log(value)/log(2) thực sự là log-base-2 of value, mà đăng nhập làm cho chúng ta rất gọn gàng:

r = 8 * log(value,2) 

Ở đó, bà Buckenmeyer - nỗ lực của bạn không hoàn toàn lãng phí!

+0

Rất tiếc, xin lỗi, tôi đã chuyển sang Python ở đó. java.math.đăng nhập không mất một arg thứ hai, vì vậy bạn đang mắc kẹt với log (value)/log (2). – PaulMcG

0

Nếu bạn đang phàn nàn rằng các số thấp đang trở thành số không, sau đó bạn có thể muốn bình thường hóa các giá trị 255 hơn là toàn bộ phạm vi của các giá trị.

Công thức sẽ trở thành:

currentValue/(tối đa giá trị của tập)

1

Lưu ý rằng nếu bạn muốn sáng hơn và sáng hơn, độ sáng mà không tuyến tính do đó, một bản đồ trực tiếp từ giá trị cho màu sắc sẽ không cho kết quả tốt.

Lớp Màu có phương pháp tạo màu sáng hơn. Có một cái nhìn vào đó.

1

Việc triển khai tuyến tính được thảo luận trong hầu hết các câu trả lời này và câu trả lời của Artelius có vẻ là tốt nhất. Nhưng công thức tốt nhất sẽ phụ thuộc vào những gì bạn đang cố gắng đạt được và phân phối giá trị của bạn. Không biết rằng rất khó để đưa ra một câu trả lời lý tưởng.

Nhưng chỉ để minh họa, bất kỳ những có thể là tốt nhất cho bạn:

  • phân phối tuyến tính, mỗi bản đồ vào một phạm vi đó là 1/266 của dãy tổng thể.
  • Phân phối lôgarít (lệch theo giá trị thấp) sẽ làm nổi bật sự khác biệt ở độ cao thấp hơn và giảm sự khác biệt ở độ cao lớn hơn
  • Phân phối lôgarit ngược (lệch về giá trị cao). ở độ cao thấp hơn.
  • Phân bố thường xuyên về tỷ lệ màu sắc, trong đó mỗi màu xuất hiện cùng một số lần với mọi màu khác.

Một lần nữa, bạn cần xác định những gì bạn đang cố gắng đạt được & dữ liệu nào sẽ được sử dụng. Nếu bạn đã được giao nhiệm vụ xây dựng điều này thì tôi khuyên bạn nên làm rõ điều này để đảm bảo rằng nó hữu ích nhất có thể - và tránh phải tái phát triển nó sau này.

1

Tự hỏi mình câu hỏi, "Giá trị nào cần ánh xạ tới 128?" Nếu câu trả lời là khoảng một tỷ (tôi nghi ngờ rằng nó là) sau đó sử dụng tuyến tính. Nếu câu trả lời nằm trong khoảng 10-100 nghìn, sau đó xem xét căn bậc hai hoặc nhật ký.

Một câu trả lời khác đã đề xuất điều này (tôi chưa thể nhận xét hoặc bỏ phiếu). Tôi đồng ý.

r = log (giá trị)/log (pow (2,32)) * 256

1

Dưới đây là một loạt các thuật toán để mở rộng quy mô, bình thường, đứng vv số bằng cách sử dụng phương pháp mở rộng trong C#, mặc dù bạn có thể áp dụng chúng vào các ngôn ngữ khác:

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

Có giải thích và đồ họa giải thích khi nào bạn có thể muốn sử dụng một phương pháp này hay cách khác.