আনুমানিক সমতা সহ ফ্লোট হ্যাশিং কীভাবে কার্যকর করা যায়


15

ধরা যাক আমাদের নীচের পাইথন ক্লাস রয়েছে (জাভাতে সমস্যাটি একই সাথে বিদ্যমান equalsএবং hashCode)

class Temperature:
    def __init__(self, degrees):
        self.degrees = degrees

degreesভাসা হিসাবে কেলভিনের তাপমাত্রা কোথায় ? এখন, আমি সেই Temperatureউপায়ে সাম্যতা পরীক্ষা এবং হ্যাশিং বাস্তবায়ন করতে চাই

  • সরাসরি সমতা পরীক্ষার পরিবর্তে একটি এপসিলন পার্থক্য পর্যন্ত ভাসমানের তুলনা করে,
  • এবং চুক্তিটি a == bবোঝায় যা সম্মান করে hash(a) == hash(b)
def __eq__(self, other):
    return abs(self.degrees - other.degrees) < EPSILON

def __hash__(self):
    return # What goes here?

পাইথন ডকুমেন্টেশনগুলি হ্যাশিং সংখ্যা সম্পর্কে কিছুটা কথা বলে তা নিশ্চিত করে hash(2) == hash(2.0)তবে এটি বেশ একই সমস্যা নয়।

আমি কি সঠিক পথে রয়েছি? এবং যদি তা হয় তবে এই পরিস্থিতিতে হ্যাশিং বাস্তবায়নের মানক উপায় কী?

আপডেট : এখন আমি বুঝতে পারি যে ফ্লোটগুলির জন্য এই ধরণের সমতা পরীক্ষার ফলে ==এবং এর ট্রানজিটিভিটি দূর হয় equals। তবে কীভাবে এটি "সাধারণ জ্ঞান" এর সাথে একসাথে যায় যা ভাসমানদের সরাসরি তুলনা করা উচিত নয়? আপনি যদি ফ্লোটগুলির সাথে তুলনা করে একটি সাম্য অপারেটর প্রয়োগ করেন তবে স্থির বিশ্লেষণ সরঞ্জামগুলি অভিযোগ করবে। তারা কি তাই করার অধিকার আছে?


9
প্রশ্নটি জাভার ট্যাগ কেন?
লাইভ

8
আপনার আপডেট সম্পর্কে: আমি বলব যে হ্যাশ ফ্লোটগুলি সাধারণত একটি প্রশ্নযুক্ত জিনিস। কী হিসাবে বা সেট উপাদান হিসাবে ভাসমান ব্যবহার এড়াতে চেষ্টা করুন।
জে ফাবিয়ান মিয়ার

6
@ নীল: একই সময়ে, পূর্ণসংখ্যার মতো গোল হয় না? এর দ্বারা আমার অর্থ: আপনি যদি হাজার হাজার ডিগ্রি গোল করতে পারেন, তবে আপনি কেবল একটি নির্দিষ্ট পয়েন্ট উপস্থাপন ব্যবহার করতে পারেন - একটি পূর্ণসংখ্যা যা হাজারে ডিগ্রি তাপমাত্রা প্রকাশ করে। ব্যবহারের স্বাচ্ছন্দ্যের জন্য, আপনি চান একজন গেটর / সেটার স্বচ্ছভাবে / থেকে ফ্লোটে রূপান্তর করতে পারেন যদি আপনি চান ...
ম্যাথিউ এম।

4
কেলভিনগুলি আর ডিগ্রি থাকে না। ডিগ্রিগুলিও অস্পষ্ট। কেন শুধু এটিকে ডাকবে না kelvin?
সলোমন উকো

উত্তর:


41

তাপমাত্রার জন্য সাম্যতা পরীক্ষা এবং হ্যাশিং এমনভাবে বাস্তবায়ন করুন যা সরাসরি সাম্যতার পরীক্ষার পরিবর্তে এপসিলন পার্থক্যের সাথে ভাসমান তুলনা করে,

ঝাপসা সমতা প্রয়োজনীয়তা লঙ্ঘন করে জাভা স্থান equalsপদ্ধতি, যথা transitivity , অর্থাত্ যদি x == yএবং y == zতারপর, x == z। তবে আপনি যদি একটি अस्पष्ट সাম্যটি উদাহরণস্বরূপ, 0.1 এর একটি অ্যাপসিলন দিয়ে থাকেন, তবে 0.1 == 0.2এবং 0.2 == 0.3তবে 0.1 == 0.3তা ধরে রাখে না।

পাইথন যদিও এ জাতীয় কোনও প্রয়োজনীয়তা নথিভুক্ত করে না, তবুও অ-ট্রান্সজিটিভ সমতা থাকার বিষয়টি এর ফলে খুব খারাপ ধারণা তৈরি করে; এই ধরণের সম্পর্কে যুক্তি হ'ল মাথা ব্যথা-প্ররোচিত করা।

সুতরাং আমি দৃ strongly়ভাবে সুপারিশ করছি আপনি এটি করবেন না।

হয় সঠিক সাম্যতা সরবরাহ করুন এবং আপনার হ্যাশটিকে সুস্পষ্ট উপায়ে তৈরি করুন এবং अस्पष्ट মিলটি করার জন্য একটি পৃথক পদ্ধতি সরবরাহ করুন, বা কেইনের প্রস্তাবিত সমতুল্য শ্রেণির পদ্ধতির সাথে যেতে পারেন। যদিও পরবর্তী ক্ষেত্রে, আমি আপনাকে পরামর্শ দিচ্ছি যে আপনি নির্মাতার সমতুল্য শ্রেণির একজন প্রতিনিধি সদস্যের কাছে আপনার মানটি ঠিক করুন, এবং তারপরে বাকীগুলির জন্য সাধারণ সঠিক সমতা এবং হ্যাশিংয়ের সাথে যান; প্রকারগুলি সম্পর্কে এভাবে যুক্তি করা অনেক সহজ।

(তবে আপনি যদি এটি করেন তবে আপনি ভাসমান পয়েন্টের পরিবর্তে স্থির বিন্দু উপস্থাপনাও ব্যবহার করতে পারেন, অর্থাত আপনি একটি ডিগ্রীর হাজারতম গণনা করতে ইন্টিজার ব্যবহার করেন বা আপনার প্রয়োজনীয় নির্ভুলতা যা প্রয়োজন।)


2
আকর্ষণীয় চিন্তা। সুতরাং কয়েক মিলিয়ন এপসিলন সংগ্রহ করে এবং ট্রানজিটিভিটি সহ আপনি এই সিদ্ধান্তে পৌঁছাতে পারেন যে যে কোনও কিছুর সমান :-) তবে এই গণিতের সীমাবদ্ধতা কি ভাসমান পয়েন্টগুলির পৃথক ভিত্তিকে স্বীকৃতি দেয়, যা বেশিরভাগ ক্ষেত্রে তারা প্রতিনিধিত্ব করার উদ্দেশ্যে সংখ্যার প্রায়?
ক্রিস্টোফ

ক্রিস্টোফের আকর্ষণীয় প্রশ্ন আপনি যদি এটির বিষয়ে চিন্তা করেন তবে আপনি দেখতে পাবেন যে এই পদ্ধতির ফলে একক বৃহত সমতুল্য শ্রেণি তৈরি হবে যার রেজোলিউশনটি এপিসিলনের চেয়ে বড় (অবশ্যই এটি 0 তে কেন্দ্রীকৃত) এবং তাদের অন্যান্য ক্লাসগুলিতে প্রতিটি তাদের ছেড়ে দেবে। তবে এটি বিন্দু নয়, আসল সমস্যাটি হ'ল এটি যদি এই সিদ্ধান্তে পৌঁছায় যে 2 টি সংখ্যা সমান হয় কি না তার সাথে তুলনা করা হয় যে কোনও তৃতীয়টি আছে কিনা এবং যে ক্রমে এটি করা হয়েছে on
সাধারণ

@ ওপি'র সম্পাদনায় সম্বোধন করে, আমি যুক্ত করব যে ভাসমান-পয়েন্টের ==ভুলটি ==তাদের ধারণকারী ধরণের "সংক্রামিত" হওয়া উচিত । এটি হ'ল যদি তারা আপনার সঠিক সাম্যতা সরবরাহ করার পরামর্শ অনুসরণ করে তবে সাম্যতা কখন ব্যবহৃত হয় তা সতর্ক করার জন্য তাদের স্থির বিশ্লেষণ সরঞ্জামটি আরও কনফিগার করা উচিত Temperature। এটিই কেবল আপনি করতে পারেন, সত্যই।
HTNW

@ এইচটিএনডাব্লু: এটি খুব সহজ হবে। অনুপাত শ্রেণীর একটি float approximationক্ষেত্র থাকতে পারে যা এতে অংশ নেয় না ==। তদ্ব্যতীত, স্থায়ী বিশ্লেষণ সরঞ্জামটি ==ক্লাসগুলির প্রয়োগের ভিতরে ইতিমধ্যে একটি সতর্কতা দেবে যখন তুলনামূলকভাবে সদস্যদের মধ্যে একটি floatপ্রকার হয়।
এমসাল্টারস

@ এসএমএলটার? সম্ভবত, পর্যাপ্ত কনফিগারযোগ্য স্থির বিশ্লেষণ সরঞ্জামগুলি আমি ঠিক সূক্ষ্মের প্রস্তাব হিসাবে যা করতে পারি তা করতে পারে। কোনও শ্রেণীর যদি এমন একটি floatক্ষেত্র থাকে যা এতে অংশ নেয় না ==, তবে সেই সরঞ্জামটি সম্পর্কে সতর্ক করার জন্য আপনার সরঞ্জামটি কনফিগার করবেন না ==। যদি ক্লাসটি করে, তবে সম্ভবত শ্রেণীরটিকে =="খুব নির্ভুল" হিসাবে চিহ্নিত করার ফলে সরঞ্জামটি প্রয়োগের মধ্যে এই ধরণের ত্রুটিটিকে উপেক্ষা করবে। যেমন জাভাতে, যদি @Deprecated void foo()তবে void bar() { foo(); }একটি সতর্কতা হয় তবে তা @Deprecated void bar() { foo(); }হয় না। হয়তো অনেক সরঞ্জাম এটিকে সমর্থন করে না, তবে কিছু সম্ভবত।
HTNW

16

শুভকামনা

আপনি হ্যাশগুলির সাথে বোকা হয়ে বা এপসিলনের ত্যাগ ছাড়াই তা অর্জন করতে সক্ষম হবেন না।

উদাহরণ:

ধরে নিন যে প্রতিটি পয়েন্টের নিজস্ব অনন্য হ্যাশ মান রয়েছে।

যেহেতু ভাসমান পয়েন্ট সংখ্যা ক্রমিক হয় সেখানে প্রদত্ত ভাসমান বিন্দু মানের পূর্বে কে সংখ্যা পর্যন্ত এবং প্রদত্ত ভাসমান বিন্দু মানের পরে k সংখ্যা পর্যন্ত থাকে যা প্রদত্ত বিন্দুর কিছু অংশের মধ্যে থাকে।

  1. একে অপরের ইপসিলনের মধ্যে প্রতিটি দুটি পয়েন্টের জন্য যা একই হ্যাশ মান ভাগ করে না।

    • হ্যাশিং স্কিমটি সামঞ্জস্য করুন যাতে এই দুটি পয়েন্ট হ্যাশ একই মান হয়।
  2. এই জাতীয় সমস্ত জোড়ের জন্য ভাসমান পয়েন্ট সংখ্যার পুরো ক্রমকে সংযুক্ত করে মানটির একটির দিকে ধস নেমে আসবে।

এমন কয়েকটি মামলা রয়েছে যেখানে এটি সত্য হবে না:

  • ইতিবাচক / নেতিবাচক অনন্ত
  • NaN
  • কয়েকটি ডি-নরমালাইজড রেঞ্জ যা প্রদত্ত অ্যাপসিলনের জন্য মূল পরিসরের সাথে লিঙ্কযোগ্য নাও হতে পারে।
  • সম্ভবত কয়েকটি অন্যান্য ফর্ম্যাট নির্দিষ্ট দৃষ্টান্ত

তবে> =================================================================================================================================================================================================== না>

ফলাফল

হয়> = 99% সম্পূর্ণ ফ্লোটিং পয়েন্ট পরিসীমা হ্যাশ মান (এবং যে কোনও ডিভাইস / ধারক মোটামুটি বিতরণ করা কম-সংঘর্ষের হ্যাশের উপর নির্ভর করে) এর অভিপ্রায়কে গুরুত্ব সহকারে সংশ্লেষ করে একক মানের to

বা এপসিলন এমন যে কেবল সঠিক ম্যাচের অনুমতি দেওয়া হয়।

ঝুরা

আপনি অবশ্যই পরিবর্তে দানাদার পদ্ধতির জন্য যেতে পারেন।

এই পদ্ধতির অধীনে আপনি নির্দিষ্ট রেজোলিউশনে নিখুঁত বালতিগুলি সংজ্ঞায়িত করেন। অর্থাৎ,

[0.001, 0.002)
[0.002, 0.003)
[0.003, 0.004)
...
[122.999, 123.000)
...

প্রতিটি বালতির একটি স্বতন্ত্র হ্যাশ রয়েছে এবং বালতির মধ্যে যে কোনও ভাসমান বিন্দু একই বালতিতে অন্য কোনও ভাসমানের সমান তুলনা করে।

দুর্ভাগ্যক্রমে দুটি ফ্লোটের পক্ষে এখনও দূরে এপসিলন হওয়া এবং দুটি পৃথক হ্যাশ থাকা সম্ভব।


2
আমি সম্মত যে এখানে দানাদার পদ্ধতির সম্ভবত ওপেনের প্রয়োজনীয়তা মাপসই করা সবচেয়ে ভাল হবে। যদিও আমি ভয় পাই যে ওপিতে +/- 0.1% ধরণের প্রয়োজনীয়তা রয়েছে যার অর্থ এটি দানাদার হতে পারে না।
নীল

4
@ ডকব্রাউন "সম্ভব নয়" অংশটি সঠিক। যদি এপসিলন ভিত্তিক সাম্যতা হ্যাশ কোডগুলি সমান হয় তা বোঝানো উচিত, তবে আপনার কাছে স্বয়ংক্রিয়ভাবে সমস্ত হ্যাশ কোড সমান, তাই হ্যাশ ফাংশনটি আর কার্যকর হয় না। বালতিগুলির পদ্ধতির ফলস্বরূপ হতে পারে তবে বিভিন্ন হ্যাশ কোডের সাথে আপনার সংখ্যা রয়েছে যা নির্বিচারে একে অপরের নিকটে থাকে।
জে ফাবিয়ান মিয়ার

2
সঠিক হ্যাশ কী দিয়ে বালতিটিই নয়, পাশাপাশি প্রতিবেশী দুটি বালতি (বা তাদের মধ্যে কমপক্ষে একটি) পাশাপাশি তাদের সামগ্রীর জন্য বালতি পদ্ধতির পরিবর্তন করা যেতে পারে। এটি সর্বাধিক দুটি (যখন সঠিকভাবে প্রয়োগ করা হয়) এর একটি ফ্যাক্টর দ্বারা চলমান সময় বাড়ানোর ব্যয়ের জন্য those প্রান্তের সমস্যাগুলি দূর করে। তবে এটি সাধারণ চলমান সময়ের ক্রম পরিবর্তন করে না।
ডক ব্রাউন 15

আপনি চেতনায় ঠিক থাকলেও সমস্ত কিছু ধসে পড়বে না। একটি নির্দিষ্ট ছোট এপসিলন সহ, বেশিরভাগ সংখ্যা কেবল তাদের সমান হবে। অবশ্যই, তাদের জন্য এপসিলন অকেজো হবে, সুতরাং আবার আত্মায় আপনি সঠিক।
কার্স্টেন এস

1
@ কার্স্টেনস হ্যাঁ, আমার বক্তব্য যে 99% রেঞ্জের একটি একক হ্যাশে হ্যাশগুলি আসলে পুরো ভাসমান পরিসীমাটিকে আবরণ করে না। অনেকগুলি উচ্চ স্তরের মান রয়েছে যারা এপসিলনের চেয়ে আলাদা হয়ে থাকে যা তাদের নিজস্ব অনন্য বালতিতে হ্যাশ করবে।
Kain0_0

7

আপনি আপনার তাপমাত্রাকে হুডের নীচে পূর্ণসংখ্যা হিসাবে মডেল করতে পারেন। তাপমাত্রার একটি প্রাকৃতিক নিম্ন সীমা থাকে (-273.15 সেলসিয়াস)। সুতরাং, দ্বিগুণ (-273.15 আপনার অন্তর্নিহিত পূর্ণসংখ্যার জন্য 0 এর সমান)। দ্বিতীয় যে উপাদানটি আপনার প্রয়োজন তা হ'ল আপনার ম্যাপিংয়ের গ্রানুলারিটি। আপনি ইতিমধ্যে এই গ্রানুলারিটি স্পষ্টভাবে ব্যবহার করছেন; এটা আপনার EPSILON।

আপনার তাপমাত্রাকে কেবল ইপিএসলন দ্বারা বিভক্ত করুন এবং এর মেঝেটি নিন, এখন আপনার হ্যাশ এবং আপনার সমান সিনক্রমে আচরণ করবে। পাইথন 3-তে পূর্ণসংখ্যা সীমাহীন হয়, আপনি চাইলে ইপসিলন আরও ছোট হতে পারে।

সতর্কতা অবলম্বন করুন যদি আপনি ইপিএসিলনের মান পরিবর্তন করেন এবং আপনি বস্তুটি সিরিয়ালাইজ করেছেন তবে সেগুলি উপযুক্ত হবে না!

#Pseudo code
class Temperature:
    def __init__(self, degrees):
        #CHECK INVALID VALUES HERE
        #TRANSFORM TO KELVIN HERE
        self.degrees = Math.floor(kelvin/EPSILON)

1

একটি ভাসমান-পয়েন্ট হ্যাশ টেবিল প্রয়োগ করে যা প্রদত্ত কীটির সাথে "প্রায় সমান" জিনিসগুলি খুঁজে পেতে পারে তার জন্য কয়েকটি পদ্ধতির বা এর সংমিশ্রণ প্রয়োজন:

  1. প্রতিটি মানকে একটি ইনক্রিমেন্টে রাউন্ড করুন যা হ্যাশ টেবিলের মধ্যে সংরক্ষণের আগে "ফাজি" রেঞ্জের চেয়ে কিছুটা বড় এবং কোনও মান খুঁজে পাওয়ার চেষ্টা করার সময়, খুঁজে পাওয়া মানটির উপরে এবং নীচে গোলাকার মানগুলির জন্য হ্যাশ টেবিলটি চেক করুন।

  2. প্রতিটি আইটেম হ্যাশ টেবিলের মধ্যে কীগুলি ব্যবহার করা হচ্ছে যা নীচের চেয়ে নীচে এবং নীচের দিকে চাওয়া হচ্ছে using

নোট করুন যে কোনও পদ্ধতির ব্যবহারের জন্য সম্ভবত হ্যাশ টেবিল এন্ট্রিগুলি আইটেমগুলি সনাক্ত করতে পারে না, বরং তালিকা তৈরি করবে, যেহেতু প্রতিটি চাবির সাথে একাধিক আইটেম যুক্ত থাকতে পারে। উপরের প্রথম পদ্ধতির প্রয়োজনীয় হ্যাশ টেবিলের আকারটি হ্রাস করবে, তবে টেবিলটিতে নেই এমন একটি আইটেমের জন্য প্রতিটি অনুসন্ধানের জন্য দুটি হ্যাশ-টেবিল লুকআপের প্রয়োজন হবে। দ্বিতীয় পদ্ধতিটি দ্রুত সনাক্ত করতে সক্ষম হবে যে আইটেমগুলি টেবিলের মধ্যে নেই, তবে সাধারণত টেবিলটির দ্বিগুণ এনট্রি রাখার প্রয়োজন হবে অন্যথায় প্রয়োজনের তুলনায়। যদি কেউ 2 ডি স্পেসে অবজেক্টগুলি সন্ধান করার চেষ্টা করে তবে এক্স দিকের জন্য একটি এবং ওয়াই দিকনির্দেশের জন্য একটি পদ্ধতি ব্যবহার করা কার্যকর হতে পারে, যাতে প্রতিটি আইটেম একবারে সঞ্চিত না করে প্রতিটি অনুসন্ধানের জন্য চারটি অনুসন্ধানের প্রয়োজন হয়, বা হচ্ছে একটি আইটেম সন্ধানের জন্য একটি লক্চু ব্যবহার করতে সক্ষম তবে প্রতিটি আইটেমটি চারবার সঞ্চয় করতে হবে,


0

আপনি অবশ্যই ম্যান্টিসার শেষ আটটি বিট এবং তারপরে তুলনা বা হ্যাশ করে মুছে ফেলে "প্রায় সমান" সংজ্ঞা দিতে পারেন can সমস্যাটি হ'ল একে অপরের খুব কাছাকাছি নম্বরগুলিও থাকতে পারে ভিন্ন পারে।

এখানে কিছু বিভ্রান্তি রয়েছে: দুটি ভাসমান পয়েন্ট সংখ্যা সমান তুলনা করলে তারা সমান। সেগুলি সমান কিনা তা পরীক্ষা করতে আপনি "==" ব্যবহার করেন। কখনও কখনও আপনি সাম্যতা পরীক্ষা করতে চান না, তবে আপনি যখন করেন, "==" যাওয়ার উপায়।


0

এটি কোনও উত্তর নয়, তবে একটি বর্ধিত মন্তব্য যা সহায়ক হতে পারে।

আমি এমপিএফআর (জিএনইউ এমপি ভিত্তিক) ব্যবহার করার সময় একই ধরণের সমস্যায় কাজ করছি have @ কেইন ০.০ দ্বারা বর্ণিত "বালতি" পদ্ধতিটি গ্রহণযোগ্য ফলাফল বলে মনে হচ্ছে তবে সেই উত্তরে সীমাবদ্ধতার বিষয়ে সচেতন থাকুন be

আমি এটি যুক্ত করতে চেয়েছিলাম - আপনি যা করতে চাইছেন তার উপর নির্ভর করে - ম্যাথমেটিকার মতো একটি "নির্ভুল" ( ক্যাভিয়েট এমপোটার ) কম্পিউটার বীজগণিত সিস্টেমটি একটি অনর্থক সংখ্যার প্রোগ্রামের পরিপূরক বা যাচাই করতে সহায়তা করতে পারে। এটি আপনাকে রাউন্ডিং সম্পর্কে চিন্তা না করে ফলাফলগুলি গণনা করার অনুমতি দেবে, উদাহরণস্বরূপ, পরিবর্তে বা অনুরূপ 7*√2 - 5*√2ফলন করবে । অবশ্যই, এটি অতিরিক্ত জটিলতাগুলি প্রবর্তন করবে যা এটির পক্ষে উপযুক্ত বা নাও হতে পারে।22.00000001

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.