I have a class named ClusterMember
as:
public class ClusterMember
{
public string _name;
public ClusterMember(string _name)
{
this._name = _name;
}
public string _Name
{
get { return _name; }
set { _name = value; }
}
}
public class Cluster
{
private Dictionary<int, List<ClusterMember>> _dic;
public Cluster(Dictionary<int, List<ClusterMember>> _dic)
{
this._dic = _dic;
}
public Dictionary<int, List<ClusterMember>> _Dictionary
{
get { return _dic; }
set { _dic = value; }
}
// adding members to clusters
public void AddToCluster(int _id, ClusterMember _clusMem)
{
// checks if cluster with specific id is already in Dictionary
if (!_dic.ContainsKey(_id))
{
_dic.Add(_id, new List<ClusterMember>());
}
else
{
_dic[_id].Add(_clusMem);
}
}
// get members count for specific cluster id
public int GetCount(int id)
{
return _dic[id].Count;
}
// get members count for all clusters
public Dictionary<int, int> GetCounts()
{
return _dic.ToDictionary(k => k.Key, v => v.Value.Count);
}
public void Print_Clusters(List<Cluster> _clusterToPrint, double _alpha, int _length)
{
Console.WriteLine("\n" + "Number of Customers = " + _length + "\n");
Console.WriteLine("\n" + "Alpha = " + _alpha + "\n");
Console.WriteLine("\n" + "Number of Clusters = " + _clusterToPrint.Max() + "\n");
foreach ( var _clusters in _clusterToPrint )
{
Console.WriteLine("Cluster ID {0} - ClusterMember {1}", _clusters._Dictionary.Keys, _clusters._Dictionary.Values);
Console.Write("\n");
}
Console.ReadLine();
}
}
When I use these classes in this method as:
public static void DP_Cluster(List<string> _cust, double _alpha)
{
var _customer = new List<string>();
var _currentTables = 0; // current number of tables i.e. "k"
var _dicInitial = new Dictionary<int, List<ClusterMember>>();
var _customerNumber = 0; // running customer number i.e. "n"
var _probOld = new Dictionary<int, double>();
//var _probOld = new List<Double>(); // porbability to be in Old cluster
var _probNew = 0.0; // porbability to be in New cluster
List<Cluster> _myClusters = new List<Cluster>();
Cluster _cluster = new Cluster(_dicInitial);
// add first customer from "_cust" list directly to a new cluster
_cluster.AddToCluster(++_currentTables, new ClusterMember(_cust.ElementAt(_customerNumber)));
_myClusters.Add(_cluster);
_probOld.Add(_currentTables, Convert.ToDouble(1) / Convert.ToDouble(1 + _alpha));
for (int _i = 1; _i < _cust.Count - 1; _i++)
{
if (_i <= _currentTables)
{
// get customer Count in Cluster i / customerNumber + alpha
// Got ERROR here at "_myClusters[_i]"
double _probOldValue = _myClusters[_i].GetCount(_i) / ((_i + 1) - 1 + _alpha);
_probOld.Add(_currentTables, _probOldValue);
}
else if ( _i == _currentTables + 1)
{
_probNew =_alpha / ((_i + 1) - 1 + _alpha);
_currentTables++;
_probOld.Add(_currentTables, _probNew);
}
List<int> _keyList = new List<int>(_probOld.Keys);
Random _random = new Random();
int _randomKey = _keyList[_random.Next(_keyList.Count)];
_cluster.AddToCluster(_randomKey, new ClusterMember(_cust.ElementAt(_i)));
}
_myClusters.Add(_cluster);
_cluster.Print_Clusters(_myClusters, _alpha, _cust.Count);
}
public static List<string> GetRandomString(int _numOfStrings, int _stringLength)
{
string[] _arrStr = new string[_numOfStrings];
List<string> _listSt;
const string _chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var _random = new Random();
for (int _i = 0; _i < _arrStr.Length; _i++)
{
_arrStr[_i] = new string(Enumerable.Repeat(_chars, _stringLength).Select(s => s[_random.Next(s.Length)]).ToArray());
}
_listSt = new List<string>(_arrStr);
return _listSt;
}
static int Main()
{
double _alfa = 5;
int _n = 30;
List<string> _data = GetRandomString(_n, 8);
DP_Cluster(_data, _alfa);
return 0;
}
The ERROR is:
Index was out of range. Must be non-negative and less than the size of the collection.
whereas I have added ++_currentTables
in _cluster
i.e. object of class Cluster
here it should be 1
which is not out of range.
I'm wanting to take the Count at specific cluster id which has been added already in List whereas the error is demanding less than size of index value. I think the value which I have inserted at this line:
_cluster.AddToCluster(++_currentTables, new ClusterMember(_cust.ElementAt(_customerNumber)));
I have inserted 1
i.e. (_++currentTables
) as first index of _dic
member of class i.e. Cluster
whereas by default it should start with 0
.
Is this an error of index insertion? But I want to start the cluster number with 1
not with 0
. How to sort out this error?