गणित - संख्या मानचित्रण


98

मैं c और d के बीच जाने के लिए, a और b के बीच, रैखिक रूप से, संख्याओं को कैसे मैप करूं।

यही है, मैं 2 और 6 के बीच की संख्या को 10 और 20 के बीच की संख्या के लिए मैप करना चाहता हूं ... लेकिन मुझे सामान्यीकृत मामले की आवश्यकता है।

मेरा दिमाग तला हुआ है।


4
दो सूत्रीय रूप। en.wikipedia.org/wiki/Linear_equation#Two-point_form
kennytm

जवाबों:


210

यदि आपका नंबर X A और B के बीच में है, और आप Y को C और D के बीच में गिरना चाहते हैं, तो आप निम्नलिखित रैखिक परिवर्तन लागू कर सकते हैं:

Y = (X-A)/(B-A) * (D-C) + C

आपको वह देना चाहिए जो आप चाहते हैं, हालांकि आपका सवाल थोड़ा अस्पष्ट है, क्योंकि आप रिवर्स दिशा में अंतराल को भी मैप कर सकते हैं। बस शून्य से विभाजन के लिए बाहर देखो और तुम ठीक होना चाहिए।


47
तो शायद इस उत्तर को "स्वीकृत" के रूप में चिह्नित करें, इसके बगल में टिक मार्क पर क्लिक करें।
कोनराड रुडोल्फ

16
स्पष्टता के लिए, मुझे new_value = (old_value - old_bottom) / (old_top - old_bottom) * (new_top - new_bottom) + new_bottom पसंद है;
फुटट्रेटर

1
क्या इस समीकरण के लिए कहीं व्युत्पत्ति है?
21:39

@shaveenk यह एक पंक्ति का समीकरण होना चाहिए Y=f(X)=m*X+b, जहां एम और बी को एक साथ निम्नलिखित दो बाधा समीकरणों से निर्धारित किया गया है, जो आवश्यक समापन बिंदुओं पर एक्स और वाई के मूल्यों को प्रतिस्थापित करने से उत्पन्न होता है: C=m*A+bऔरD=m*B+b
क्रिस चियासैस

मैंने X=A+(A-B)*tइस दृष्टिकोण और पीटर के बीच समानता साबित करने के लिए उपयोग करने की आवश्यकता भी समाप्त कर दी। t मूलतः X. ( t=(X-A)/(A-B)) का एक nondimensionalization है
क्रिस चियासन

21

दो श्रेणियों के आकार के बीच का अनुपात प्राप्त करने के लिए विभाजित करें, फिर अपनी inital रेंज के शुरुआती मूल्य को घटाएं, अनुपात से गुणा करें और अपनी दूसरी श्रेणी के शुरुआती मूल्य को जोड़ें। दूसरे शब्दों में,

R = (20 - 10) / (6 - 2)
y = (x - 2) * R + 10

यह समान रूप से संख्याओं को पहली श्रेणी से दूसरी श्रेणी में फैलाता है।


यह काम नहीं करता है। मेरी सीमा १००००००००००० से ९९९९९९९९९ है और संख्या १ से ९९९९९९९९ हो सकती है।
देजेल

@ बेशक यह काम करता है। यह एक सरल पर्याप्त गणितीय परिवर्तन है। आपको बस एक बड़े पर्याप्त संख्या प्रकार (bignum या समान) का उपयोग करने की आवश्यकता है। 32 बिट पूर्णांक के लिए आपकी संख्या बस बहुत बड़ी है - लेकिन उदाहरण के लिए 64 बिट पूर्णांक काम करेंगे।
कोनराड रुडोल्फ

वे टाइप डबल के हैं। डबल आर = (20 - 10) / (6 - 2); डबल वाई = (एक्स - 2) * आर + 10;
देजेल

@Odelya वही समस्या हालांकि। आपको फ्लोटिंग-पॉइंट सटीक पर पढ़ना चाहिए। वास्तव में, यह पढ़ने की आवश्यकता है: फ्लोटिंग-पॉइंट अंकगणित के बारे में हर कंप्यूटर वैज्ञानिक को क्या पता होना चाहिए - यदि आपको ऐसे बड़ी संख्याओं के साथ फ्लोटिंग-पॉइंट प्रकार की आवश्यकता है, तो आपको एक मनमाना-सटीक संख्या प्रकार का उपयोग करना पड़ सकता है ।
कोनराड रुडोल्फ

क्या आप एक जावा प्रकार की सिफारिश कर सकते हैं जो मैं कर सकता हूं?
देजेल

7

इस कार्यक्षमता को java.lang.Mathकक्षा में रखना अच्छा होगा , क्योंकि यह एक ऐसा व्यापक रूप से आवश्यक कार्य है और अन्य भाषाओं में उपलब्ध है। यहाँ एक सरल कार्यान्वयन है:

final static double EPSILON = 1e-12;

public static double map(double valueCoord1,
        double startCoord1, double endCoord1,
        double startCoord2, double endCoord2) {

    if (Math.abs(endCoord1 - startCoord1) < EPSILON) {
        throw new ArithmeticException("/ 0");
    }

    double offset = startCoord2;
    double ratio = (endCoord2 - startCoord2) / (endCoord1 - startCoord1);
    return ratio * (valueCoord1 - startCoord1) + offset;
}

मैं इस कोड को भविष्य के संदर्भ के रूप में यहाँ रख रहा हूँ और हो सकता है कि यह किसी की मदद करे।


4

एक तरफ के रूप में, यह एक ही समस्या है क्योंकि क्लासिक सेलेकस को फ़ारेनहाइट में परिवर्तित करते हैं जहां आप एक संख्या सीमा को मैप करना चाहते हैं जो 0 - 100 (C) से 32 - 212 (F) के बराबर है।


यह कैसा उत्तर है?
शिंज़ौ

यह प्रश्न के अनुप्रयोग का एक उदाहरण है। कई लोगों को परिचय सीएस कक्षाओं में यह सरल समस्या है और यह विचार नहीं करते हैं कि समाधान को अन्य समस्याओं के लिए सामान्यीकृत किया जा सकता है। मैं मूल प्रश्न के संदर्भ को जोड़ने की कोशिश कर रहा था। मूल प्रश्न का पहले ही पर्याप्त उत्तर दिया जा चुका था।
मेट्रो

1

पहली सीमा पर प्रत्येक इकाई का अंतराल दूसरी सीमा पर (dc) / (ba) "स्पेस" लेता है।

छद्म:

var interval = (d-c)/(b-a)
for n = 0 to (b - a)
    print c + n*interval

आप कैसे संभालते हैं गोलाई आपके ऊपर है।


1
int srcMin = 2, srcMax = 6;
int tgtMin = 10, tgtMax = 20;

int nb = srcMax - srcMin;
int range = tgtMax - tgtMin;
float rate = (float) range / (float) nb;

println(srcMin + " > " + tgtMin);
float stepF = tgtMin;
for (int i = 1; i < nb; i++)
{
  stepF += rate;
  println((srcMin + i) + " > " + (int) (stepF + 0.5) + " (" + stepF + ")");
}
println(srcMax + " > " + tgtMax);

शून्य से विभाजित पर चेक के साथ, बिल्कुल।


1

यदि आपकी सीमा [a से b] तक है और आप इसे [c से d] में मैप करना चाहते हैं जहाँ x वह मान है जिसे आप मैप करना चाहते हैं, तो इस सूत्र (रैखिक मानचित्रण) का उपयोग करें

double R = (d-c)/(b-a)
double y = c+(x*R)+R
return(y)


0

@PeterAllenWebb उत्तर के अलावा, यदि आप परिणाम का उपयोग करने के लिए पीछे हटना चाहेंगे:

reverseX = (B-A)*(Y-C)/(D-C) + A
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.