2017-01-05 4 views
5

मैं एक (दो आयामी) डेटासेट पर clustering करने के लिए एक सी # पुस्तकालय में कोड लिख रहा हूँ - अनिवार्य रूप से समूह या समूहों में डेटा को तोड़ दिया। उपयोगी होने के लिए, लाइब्रेरी को "जेनेरिक" या "कस्टम" डेटा लेने की आवश्यकता है, इसे क्लस्टर करें, और क्लस्टर डेटा लौटाएं। (- मैं समन्वय के साथ काम कर रहा हूँ मेरे मामले Lat, Lng में)कस्टम डेटा में प्रवेश करना और वापस करना - सही दृष्टिकोण को इंटरफेस कर रहे हैं?

ऐसा करने के लिए, मुझे लगता है कि करने के लिए डेटासेट में हर गृहीत पारित किया जा रहा में इसके साथ जुड़े एक 2D वेक्टर है की जरूरत है।

मेरी पहली सोचा सामान्य प्रकार का उपयोग करने, और दो सूचियों, सामान्य डेटा (यानी List<T>) में से एक सूची है और एक ही लंबाई 2 डी वैक्टर (यानी List<Coordinate>, जहां Coordinate निर्दिष्ट करने के लिए मेरी कक्षा है निर्दिष्ट करने के किसी अन्य रूप में पारित किया गया था एक लैट, एलएनजी जोड़ी), जहां सूचियां इंडेक्स द्वारा एक-दूसरे से मेल खाते हैं। लेकिन यह काफी कठिन है क्योंकि इसका मतलब है कि एल्गोरिदम में मुझे इन इंडेक्स का किसी भी तरह से ट्रैक रखना है।

मेरा अगला सोचा inferfaces, जहां मैं एक इंटरफेस को परिभाषित

public interface IPoint 
{ 
    double Lat { get; set; } 
    double Lng { get; set; } 
} 

का उपयोग करें और यह सुनिश्चित डेटा है कि मैं औजार में इस इंटरफेस पारित (यानी मैं मान सकते हैं कि प्रत्येक गृहीत में पारित कर दिया है कि करने के लिए था एक Lat और एक Lng)।

लेकिन यह वास्तव में या तो मेरे लिए बाहर काम नहीं कर रहा। मैं अपने सी # पुस्तकालय का उपयोग ट्रांजिट नेटवर्क (एक अलग परियोजना में) में क्लस्टर स्टॉप करने के लिए कर रहा हूं। कक्षा को Stop कहा जाता है, और यह कक्षा बाहरी पुस्तकालय से भी है, इसलिए मैं उस वर्ग के लिए इंटरफ़ेस को कार्यान्वित नहीं कर सकता।

क्या मैं तो Stop से विरासत गया था था, एक वर्ग ClusterableStop कहा जाता है जो इस तरह दिखता है बनाने:

public class ClusterableStop : GTFS.Entities.Stop, IPoint 
{   

    public ClusterableStop(Stop stop) 
    { 
     Id = stop.Id; 
     Code = stop.Code; 
     Name = stop.Name; 
     Description = stop.Description; 
     Latitude = stop.Latitude; 
     Longitude = stop.Longitude; 
     Zone = stop.Zone; 
     Url = stop.Url; 
     LocationType = stop.LocationType; 
     ParentStation = stop.ParentStation; 
     Timezone = stop.Timezone; 
     WheelchairBoarding = stop.WheelchairBoarding; 
    } 
    public double Lat 
    { 
     get 
     { 
      return this.Latitude; 
     } 
    } 

    public double Lng 
    { 
     get 
     { 
      return this.Longitude; 
     } 
    } 
} 

के रूप में आप देख सकते हैं जो लागू IPoint इंटरफ़ेस। अब मैं ClusterableStop के लिए निर्माता का उपयोग पहले ClusterableStop रों को डाटासेट में सभी Stop रों परिवर्तित तो एल्गोरिथ्म चलाने के लिए और ClusterableStop रों के रूप में परिणाम प्राप्त करने के।

यह वास्तव में मैं क्या चाहते हैं, क्योंकि मैं क्या क्लस्टर वे में गिरावट के आधार पर Stop रों को काम करने के लिए चाहते हैं नहीं है। मैं नहीं कर सकता है कि क्योंकि मैं वास्तव में नई बंद हो जाता है, अर्थात् ClusterableStop instantiated किया है एस !!

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

उत्तर

2

आप tuples का उपयोग कर विचार काम करने के लिए है - कभी कभी यह एक नया वर्ग बनाने के बिना दो वर्गों जोड़ का एक उपयोगी तरीका है।

List<Tuple<Point, Stop>>

जहां प्वाइंट बात आप पर क्लस्टर है: आप tuples की एक सूची बना सकते हैं।

3

के बाद से सभी की जरूरत 2 डी सरणी के प्रत्येक तत्व के लिए एक (अक्षांश, देशांतर) जोड़ी संबद्ध करने के लिए है, तो आप एक विधि है कि एक प्रतिनिधि लेता है, जो, प्रत्येक गृहीत के लिए एक संबद्ध स्थिति पैदा करता है इस तरह बना सकते हैं:

ClusterList Cluster<T>(IList<T> data, Func<int,Coordinate> getCoordinate) { 
    for (int i = 0 ; i != data.Count ; i++) { 
     T item = data[i]; 
     Coordinate coord = getCoord(i); 
     ... 
    } 
} 

यह कैसे Coordinate डेटा के प्रत्येक तत्व के साथ जोड़ा जाता तय करने के लिए फोन करने वाले अब तक है।

ध्यान दें कि सूची स्थिति से संघ ही एकमात्र विकल्प आप के लिए उपलब्ध नहीं है।एक अन्य विकल्प एक प्रतिनिधि है कि आइटम लेता है पारित करने के लिए है, और रिटर्न अपने समन्वय:

ClusterList Cluster<T>(IEnumerable<T> data, Func<T,Coordinate> getCoordinate) { 
    foreach (var item in data) { 
     Coordinate coord = getCoord(item); 
     ... 
    } 
} 

हालांकि इस दृष्टिकोण सूचकांक आधारित एक से बेहतर है, मामलों में जब निर्देशांक वस्तु ही है, उस पर उपलब्ध नहीं हैं कॉलर को T पर किसी प्रकार का एक सहयोगी कंटेनर रखने की आवश्यकता होती है, जिसे या तो हैश-आधारित कंटेनर के साथ अच्छी तरह से खेलना चाहिए, या IComparable<T> होना चाहिए। पहला दृष्टिकोण T पर कोई प्रतिबंध नहीं रखता है।

आपके मामले में, दूसरा दृष्टिकोण बेहतर है:

var clustered = Cluster(
    myListOfStops 
, stop => new Coordinate(stop.Latitude, stop.Longitude) 
); 
संबंधित मुद्दे