एक UI के लिए एल्गोरिथ्म जो एक्स प्रतिशत स्लाइडर्स दिखा रहा है जिनके जुड़े मूल्य हमेशा कुल 100% हैं


11

एक प्रणाली जो मैं बना रहा हूं उसमें 0-100 के पैमाने के साथ यूआई स्लाइडर्स का एक सेट (संख्या भिन्न होती है) शामिल है। स्लाइडर से मेरा मतलब है कि यूआई जहां आप एक तत्व को पकड़ते हैं और वॉल्यूम कंट्रोल की तरह इसे ऊपर और नीचे खींचते हैं। वे एक एल्गोरिथ्म से जुड़े हैं जो यह सुनिश्चित करता है कि वे हमेशा कुल 100 हों। इसलिए जब एक स्लाइडर को ऊपर ले जाया जाता है, तो बाकी सभी नीचे चले जाते हैं, अंततः शून्य पर। जब एक को नीचे ले जाया जाता है, तो दूसरे ऊपर चले जाते हैं। हर समय कुल 100 होना चाहिए। इसलिए यहां स्लाइडर के विभिन्न मूल्य हैं, लेकिन वे कुल 100% हैं:

----O------ 40
O----------  0
--O-------- 20
--O-------- 20
--O-------- 20

यदि पहला स्लाइडर फिर 40 से 70 तक उत्तर प्रदेश को स्थानांतरित करता है, तो अन्य को DOWN को मान में स्थानांतरित करना होगा (जैसा कि स्लाइडर को खींचा गया है)। नोट तीन स्लाइडर्स 20 से 10 में बदल गए, और एक शून्य पर रहा क्योंकि यह कम नहीं जा सकता है।

-------O--- 70
O----------  0
-O--------- 10
-O--------- 10
-O--------- 10

बेशक, जब कोई भी स्लाइडर 0 या 100 तक पहुंचता है, तो वह आगे नहीं बढ़ सकता है, जो कि मेरे सिर को वास्तव में चोट लगी है। इसलिए यदि कोई स्लाइडर अधिक गति करता है, तो अन्य नीचे की ओर जाते हैं, लेकिन जब उनमें से कोई भी शून्य तक पहुंचता है तो शेष जो शून्य तक नहीं पहुंचते हैं, वे कम स्थानांतरित हो सकते हैं।

मैं यह यहाँ पूछ रहा हूँ क्योंकि यह प्रश्न एल्गोरिथ्म के लिए विशिष्ट है कार्यान्वयन नहीं। FWIW मंच एंड्रॉइड जावा है, लेकिन यह विशेष रूप से प्रासंगिक नहीं है।

जिस दृष्टिकोण को मैंने अपने पहले स्टैब के साथ लिया था, वह स्थानांतरित किए गए स्लाइडर के प्रतिशत परिवर्तन की गणना करने के लिए था। मैंने तब उस परिवर्तन को विभाजित किया और इसे (दूसरी दिशा में) अन्य स्लाइडर मूल्यों पर लागू किया। हालांकि समस्या यह है कि प्रतिशत का उपयोग करके और गुणा करके, यदि कोई स्लाइडर शून्य हो जाता है, तो इसे फिर से शून्य से कभी नहीं बढ़ाया जा सकता है - इसका शुद्ध परिणाम यह है कि व्यक्तिगत स्लाइडर्स शून्य पर अटक जाते हैं। मैंने राउंडिंग समस्याओं से बचने के लिए 0 - 1,000,000 की सीमा के साथ स्लाइडर्स का उपयोग किया है और यह मददगार प्रतीत होता है, लेकिन मैंने अभी तक एक एल्गोरिथ्म तैयार किया है जो सभी परिदृश्यों को अच्छी तरह से संभालता है।


2
UX साइट पर इसी तरह के प्रश्न पूछे गए हैं, हालांकि IMHO का जवाब उन्हें विशेष रूप से संतोषजनक तरीके से नहीं दिया गया है। मैं यह देखने के लिए उत्सुक हूं कि क्या कोई अच्छा समाधान है। यद्यपि ईमानदार होने के लिए, मुझे पता है कि स्लाइडर्स एक दूसरे से जुड़े होने के कारण उपयोगकर्ता के लिए और भी अधिक परेशानी का कारण बनता है - यह आपके द्वारा दिए जाने वाले वितरण को समाप्त करने के लिए मुश्किल हो जाता है, क्योंकि आप अपने पहले से ही दर्ज किए गए मानों को बदलते रहते हैं। जाओ।
डैनियल बी

1
एक सुझाव यह होगा कि उपयोगकर्ता को दो मोडों के बीच स्विच करने की अनुमति दी जाए, अनिवार्य रूप से एक जहां स्लाइडर एक दूसरे से जुड़े होते हैं, और एक जहां वे नहीं हैं (और "सापेक्ष मोड" पर वापस स्विच करने से वितरण फिर से सामान्य हो जाएगा)। यह आपके द्वारा बताए गए कुछ मुद्दों को साइड-स्टेप करने देगा, लेकिन UI में इतनी जटिलता जोड़ देगा कि उपयोगकर्ता को मूल्यों को टाइप करने में आसानी हो सकती है।
डैनियल बी

आप निश्चित रूप से सही हैं कि इसके लिए उपयोगकर्ता की ओर से बहुत सी फ़िदालिंग की आवश्यकता होती है, लेकिन इस मामले में यह सर्वेक्षण ऐप का एक रूप है जहां स्लाइडर्स मुद्दों का प्रतिनिधित्व करते हैं, इसलिए सवाल सभी मूल्यों के सापेक्ष भार के बारे में है।
ओली सी

1
मैं समझता हूँ ... मेरा मुद्दा सिर्फ इतना है कि 60/30/10 के बंटवारे की तरह कुछ व्यक्त करने के लिए 3 से अधिक कार्यों की आवश्यकता होगी , क्योंकि जब 30/10 भाग के साथ फ़िडलिंग होती है, तो 60 घूमता रहता है। यह बड़ी सूचियों के साथ उत्तरोत्तर बदतर हो जाता है, और केवल अत्यंत अस्पष्ट इनपुट के लिए वास्तव में उपयुक्त है, क्योंकि आप इसे अपने सिर में होने वाली संख्या के लिए कभी नहीं प्राप्त करेंगे।
डैनियल बी

2
आप के एक UX बिंदु से, मेरा सुझाव है कि कुल स्कोर को स्लाइडर्स के पक्ष में बड़ी संख्या के रूप में प्रस्तुत किया जाए। जब आप एक स्लाइडर को ऊपर स्लाइड करते हैं, तो कुल स्कोर "100" से अधिक बढ़ जाता है और जब तक उपयोगकर्ता कुल स्कोर को कम करने के लिए किसी अन्य स्लाइडर को स्लाइड नहीं करता, तब तक आपका "अगला" बटन अक्षम हो जाता है। आप कभी नहीं जान पाएंगे कि एक स्लाइडर को ऊपर स्लाइड करने पर उपयोगकर्ता 4 अन्य स्लाइडर्स में से कौन सा कम करना चाहता है, इसलिए कोशिश भी न करें।
ग्राहम

जवाबों:


10

लालची एल्गोरिदम

जब एक स्लाइडर ऊपर (नीचे) चलता है, तो अन्य सभी को नीचे (ऊपर) जाने की आवश्यकता होती है। हर एक के पास कुछ स्थान हो सकते हैं (नीचे - उनकी स्थिति, ऊपर के लिए: 100-स्थिति)।

इसलिए जब एक स्लाइडर चलता है, तो अन्य स्लाइडर्स को ले जाएं, उन्हें उस स्थान से छांटें, जिसे वे स्थानांतरित कर सकते हैं, और बस उनके माध्यम से पुनरावृति कर सकते हैं।

प्रत्येक पुनरावृत्ति पर, स्लाइडर को आवश्यक दिशा में ले जाएं (कुल छोड़ दिया गया है (बाईं ओर स्लाइडर्स कतार में छोड़ दिया गया है) या वह दूरी जिसे वह स्थानांतरित कर सकता है, जो भी छोटा हो।

यह जटिलता में रैखिक है (चूंकि आप एक ही क्रमबद्ध कतार का उपयोग कर सकते हैं और एक बार, इसे हल कर दिया गया है)।

इस परिदृश्य में, कोई भी स्लाइडर फंस नहीं जाता है, सभी जितना संभव हो उतना आगे बढ़ने की कोशिश करते हैं, लेकिन केवल अपने उचित हिस्से तक।

भारित चाल

एक अलग दृष्टिकोण उस कदम को भारित करना होगा जो उन्हें करने की आवश्यकता है। मुझे लगता है कि यह वही है जो आपने करने की कोशिश की, आपके "स्लाइडर्स 0 पर अटक जाते हैं" बयान से। IMHO यह अधिक स्वाभाविक है, आपको बस अधिक ट्विकिंग करने की आवश्यकता है।

फिर से निर्दिष्ट करते हुए, मैं कहूंगा कि आप अलग-अलग स्लाइडर्स की चालों को उनके स्थान से वज़न करने की कोशिश करेंगे (यह सीधे 0 समस्या पर आपके अटके हुए अनुवाद में बदल जाएगा)। हालाँकि ध्यान दें कि आप स्लाइडर की स्थिति को विभिन्न दिशाओं से देख सकते हैं - शुरू से या अंत से। यदि आप घटते समय स्थिति से वजन लेते हैं और बढ़ते समय अंत से स्थिति, तो आपको अपनी समस्या से बचना चाहिए।

यह पिछले भाग की शब्दावली में काफी समान है - स्लाइडर्स की स्थिति के आधार पर करने के लिए कदम को उस दिशा में स्थानांतरित करने के लिए उनके द्वारा छोड़े गए स्थान से भारित न करें।


1
मैंने गहराई से देखा और यह पता चला कि "अटक" वाले अटक नहीं रहे हैं, लेकिन बस ऐसे कम मूल्यों का प्रतिशत परिवर्तन का लगभग कोई प्रभाव नहीं है - एक स्लाइडर चाल की मात्रा इसके मूल्य के सापेक्ष है। मुझे संदेह है कि आपके सुझाव के विपरीत मूल्य का उपयोग करने से बेहतर काम हो सकता है, मुझे केवल 100 पर मूल्य रखने की आवश्यकता है। कुछ स्पष्टता को इंजेक्ट करने के लिए धन्यवाद।
ओली सी

1

मेरे द्वारा लिया गया दृष्टिकोण थोड़ा अलग है, और प्रत्येक स्लाइडर के एक अलग आंतरिक प्रतिनिधित्व का उपयोग करना शामिल है।

  1. प्रत्येक स्लाइडर 0..100 (एक्स) से किसी भी मूल्य ले सकता है जो उस स्लाइडर के लिए एक भार कारक के रूप में उपयोग किया जाता है (एक% नहीं)

  2. कुल आंकड़ा पाने के लिए सभी स्लाइडर मान जोड़ें (T)

  3. प्रत्येक स्लाइडर के प्रदर्शित मूल्य को निर्धारित करने के लिए, ROUND (X * 100 / T) का उपयोग करें

  4. जब एक स्लाइडर को ऊपर या नीचे ले जाया जाता है, तो आप केवल एक स्लाइडर के मूल्य को बदलते हैं ; उस स्लाइडर के लिए वेटिंग अन्य सभी स्लाइडर्स के सापेक्ष बढ़ेगी या घटेगी, और उपरोक्त कैल्क यह सुनिश्चित करेगा कि अन्य सभी स्लाइडर्स में परिवर्तन समान रूप से फैल जाएगा।


यह एक अच्छा इंटरफ़ेस होगा यदि उपयोगकर्ता मुख्य रूप से कम या ज्यादा सटीक अंश बनाने के बारे में चिंतित है। हालाँकि, मैं यह नहीं देख सकता कि यह अन्य स्लाइड्स को उनकी स्थिति के लिए आनुपातिक बनाने से कार्यात्मक रूप से अलग कैसे है।
क्रमांक

1

मुझे लगता है कि आप 'स्थानांतरित' स्लाइडर के परिवर्तन के प्रतिशत से वर्तमान मूल्य को समायोजित करने की कोशिश करके चीजों को जटिल कर रहे हैं, जो आपको प्रतिशत प्रतिशत देता है, जो गोल त्रुटियों को पेश करता है।

चूंकि आप जानते हैं कि आप केवल 100 के कुल मूल्य के साथ काम कर रहे हैं, इसलिए मैं पूर्णांक के रूप में चीजों को रखूंगा और 100 से पीछे की ओर काम करूंगा, गोलाई के बारे में किसी भी गंभीर गड़बड़ी से बचें। (नीचे के उदाहरण में मैं अंत में पूरे पूर्णांक के रूप में किसी भी गोलाई को संभालता हूं)

मेरी तकनीक यह होगी कि स्लाइडर्स को 0-100 तक सरल तरीके से सेट किया जाए। 100 से 'नए' मूल्य को घटाएँ, यह पता लगाने के लिए कि उनके वजन के अनुसार अन्य स्लाइडर्स के बीच कितनी मात्रा में फिर से काम करना है, फिर साफ करें)

यह नहीं है, जहाँ तक मुझे पता है, मान्य Android कोड: p

// see how much is "left" to redistribute
amountToRedistribute = 100 - movedSlider.value

//What proportion of the original 100% was contained in the other sliders (for weighting)
allOtherSlidersTotalWeight = sum(other slider existing values)

//Approximately redistribute the amount we have left between the other sliders, adjusting for their existing weight
for each (otherSlider)
    otherSlider.value = floor(otherSlider.value/allOtherSlidersWeight * amountToRedistribute)
    amountRedistributed += otherSlider.value

//then clean up because the floor() above might leave one or two leftover... How much still hasn't been redistributed?
amountLeftToRedistribute -= amountRedistributed

//add it to a slider (you may want to be smarter and add in a check if the slider chosen is zero, or add it to the largest remaining slider, spread it over several sliders etc, I'll leave it fairly simple here)
otherSlider1.value += amountLeftToRedistribute 

यह आंतरिक रूप से किसी भी 0 या 100 मान को संभालना चाहिए


0

गोल रॉबिन दृष्टिकोण के बारे में क्या? एक लेनदेन बनाएं जो बीमा करता है कि एक स्लाइडर के लिए मूल्य जोड़ना उसके सहकर्मी से कम हो जाएगा। और इसके विपरीत।

फिर हर बार एक स्लाइडर परिवर्तन एक अलग सहकर्मी स्लाइडर के साथ लेन-देन को चलाता है (मैं एक पुनरावृत्त बनाऊंगा जो सहकर्मी स्लाइडर को बदल देता है)। यदि सहकर्मी स्लाइडर शून्य है तो अगले एक पर आगे बढ़ें।


0

बस @Ordous से महान लालची एल्गोरिथ्म जवाब पर विस्तृत करने के लिए। यहाँ कदमों का टूटना है।

  1. स्लाइडर को खिसकाएं
  2. सहेजें differenceAmount यह के रूप में ले जाया गया newValue - OLDVALUE (सकारात्मक मूल्य का मतलब यह ऊपर ले जाया गया और अन्य स्लाइडर्स नीचे जाने के लिए और इसके विपरीत)
  3. क्रमबद्ध दूसरों सूची में से कम से कम सबसे करने के लिए की दूरी वे स्थानांतरित कर सकते हैं दिशा के लिए आवश्यक में differenceAmount सकारात्मक या नकारात्मक किया जा रहा है।
  4. अमाउंट सेट करें = अंतर करें / अंतर करें या अन्य को छोड़ दें
  5. प्रत्येक स्लाइडर को उसके माध्यम से लूप करें और ले जाएं या तो वह राशि ले जा सकती है या राशि को हटा सकती है । जो भी छोटा हो
  6. राशि को घटाएं स्लाइडर स्लाइडर राशि से ले जाया गया और नए शेष दूसरों द्वारा विभाजित
  7. एक बार समाप्त होने के बाद, आपने अन्य स्लाइडर्स के बीच अंतर को सफलतापूर्वक वितरित किया है ।

शानदार जवाब यहाँ। stackoverflow.com/a/44369773/4222929
सीन

-3

एक सरल तकनीक स्लाइडर मूल्यों के योग के सापेक्ष स्लाइडर मूल्यों के प्रतिशत की गणना करना है और फिर संबंधित गणना प्रतिशत में स्लाइडर मूल्यों को फिर से असाइन करना है। इस तरह से स्लाइडर मानों को फिर से जांचा जाएगा

slider1.value = (slider1.value / sumOfSliderValues) * 100 ;
slider2.value = (slider2.value / sumOfSliderValues) * 100 ;
slider3.value = (slider3.value / sumOfSliderValues) * 100 ;

हालाँकि यह राउंड ऑफ एरर का परिचय देता है, लेकिन इसे तब तक संभाला जा सकता है, जब हमें स्लाइडर मानों की आवश्यकता हमेशा और हमेशा 100 तक की हो।

मैंने इसे angularjs का उपयोग करने के लिए एक फिडेल सेटअप किया है। कृपया डेमो देखें


2
... जो जेफरी का जवाब है। डुप्लिकेट को रोकने के लिए पहले अन्य उत्तरों को पढ़ें।
जन डोगेने
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.