我在C#中名为Cluster
的类中有一个用于聚类目的的字典:
Dictionary<int, List<ClusterMember>>
而int
代表群集ID ,List<ClusterMember>>
代表群集ID 和{{中的成员 1}}是另一个类。我在这里展示了整个代码结构:
ClusterMember
虽然我在这个方法中使用了这些类:
public class ClusterMember
{
public string _name { get; set; }
}
public class Cluster
{
public Dictionary<int, List<ClusterMember>> _dic { get; set; }
public Cluster(int _id, List<ClusterMember> _clusMem)
{
_dic.Add(_id, _clusMem);
}
}
现在如何在public static List<Cluster> DP_Cluster(List<string> _customer, double _alpha)
{
var _currentClusters = 0; // current number of clusters i.e. "k"
var _memberNumber = 0; // running member number i.e. "n"
//var _dic = new Dictionary<int, List<string>>();
var _probOld = 0.0;
var _probNew = 0.0;
List<Cluster> _myClusters = new List<Cluster>();
//Cluster _cluster = new Cluster(?);
// How to Add cluster using above classes
// How to Add cluster Member using above classes
_myClusters.Add(_cluster);
//_dic.Add(_currentClusters, _customer.ElementAt(_memberNumber));
_currentClusters += 1;
for(int _i = 1; _i < _customer.Count - 1; _i++)
{
if( _i <= _currentClusters)
{
_probOld = myClusters[_i].Members.Count / ((_i+1) - 1 + _alpha);
}
else
{
_probNew = _alpha / ((_i+1) - 1 + _alpha);
}
if(_probNew > _probOld)
{
// Add _customer.ElementAt(_memberNumber+=1) to New Cluster
Cluster cluster = new Cluster( _currentClusters += 1 );
myClusters.Add(cluster);
}
else
{
// Add _customer.ElementAt(_memberNumber+=1) to Old Cluster
}
}
return myClusters;
}
中添加_dic
Dictionary
对象?此外,我可能不得不多次向同一for loop
添加多个集群成员
_id
,_id = 1
迭代中,_id = 2
,反之亦然。 此外,如果可以使用_id = 1
(默认情况下不是1
0
启动群集ID ,对我来说会更有意义} index )。
答案 0 :(得分:0)
此外,我可能需要将多个集群成员添加到同一个ID 不止一次
您可以检查每个循环迭代的关键字:
public void AddInCluster(int id, List<ClusterMember> _clusMem)
{
if (_dic.ContainsKey(id))
{
foreach (var clusterMember in _clusMem)
{
_dic[id].Add(clusterMember);
}
}
else
{
_dic.Add(id, _clusMem);
}
}
或者您可以使用词典中的TryGetValue:
public void AddInCluster(int id, List<ClusterMember> _clusMem)
{
List<ClusterMember> members;
if (_dic.TryGetValue(id, out members))
{
foreach (var clusterMember in _clusMem)
{
members.Add(clusterMember);
}
}
else
{
_dic.Add(id, _clusMem);
}
}
此外,如果有可能开始,对我来说会更有意义 群集ID为1
将int
包装到ClusterId
类中,如果id为0,可能会引发异常怎么样?
此外,您的Cluster类可以覆盖字典上的访问器运算符[],以在您的上下文中提供有意义的抽象(例如,从1开始而不是0)
您还可以像Get
一样添加Add
,以检查此ID是否存在:
public List<ClusterMember> GetFromCluster(ClusterId id)
{
if (_dic.ContainsKey(id))
{
return _dic[id];
}
throw new ClusterDoesNotContainsThisId(id);
}
答案 1 :(得分:0)
如何使用Dictionaries Add
方法?像:
if(needToAddNewCluster){
_dic.Add(index, new List<ClusterMember>());
}
if(needToExtendCluster){
_dic[index].Add(clusMem);
}
在此我假设needToAddNewCluster
检查_dic.ContainsKey(index)
。
答案 2 :(得分:0)
您可以将方法添加到Cluster类
public void AddToCluster(int id, ClusterMember member)
{
// checks if cluster with specific id is already in Dictionary
if(!_dic.ContainsKey(id))
_dic.Add(id,new List<ClusterMember>());
_dic[id].Add(member);
}
你可以像这样在迭代中使用它
int id = 1; // cluster id
foreach(var m in members)
{
// adding members to cluster with id = 1
cluster.AddToCluster(id,m);
}
更新
我们也可以获得每个群集ID的列表计数,即每个群集ID的群集成员数量?
您可以添加这两种方法
// get members count for specific cluster id
public int GetCount(int id)
{
return _dict[id].Count;
}
// get members count for all clusters
public Dictionary<int,int> GetCounts()
{
return _dict.ToDictionary(k=>k.Key,v=>v.Value.Count);
}
您可以像这样访问
var counts = cluster.GetCounts();
var c1Cnt=counts[1]; // 1 is cluster id
答案 3 :(得分:0)
我将稍微更改Culster
类的实现。 _dic
应该是带有初始化程序的仅getter属性。根据通常的.NET C#命名约定,属性应位于PascalCase中,因此我将其重命名为Dic
。 (更好的名称是MemberDictionary
或Members
)。带下划线的_camelCase标识符通常用于字段。方法参数和局部变量具有camelCase。
然后添加用于添加一个或几个成员的新方法。两种方法都首先检查列表是否已经存在。如果有,则将新成员添加到列表中,否则将使用新成员初始化一个新列表,然后将其添加到字典中。
public class Cluster
{
public Dictionary<int, List<ClusterMember>> Dic { get; }
= new Dictionary<int, List<ClusterMember>>();
// Initialize empty cluster.
public Cluster()
{
}
// Initialize cluster with one initial member.
public Cluster(int key, ClusterMember member)
{
Add(key, member);
}
// Initialize cluster with many members.
public Cluster(int key, IEnumerable<ClusterMember> members)
{
Add(key, members);
}
// Allows you to a one new member.
public void Add(int key, ClusterMember member)
{
if (Dic.TryGetValue(key, out var memberList)) {
memberList.Add(member);
} else {
memberList = new List<ClusterMember> { member };
Dic.Add(key, memberList);
}
}
// Allows you to add many members.
public void Add(int key, IEnumerable<ClusterMember> members)
{
if (Dic.TryGetValue(key, out var memberList)) {
memberList.AddRange(members);
} else {
memberList = new List<ClusterMember>(members);
Dic.Add(key, memberList);
}
}
}
此实现委派字典和列表的创建以及将成员添加到Cluster
类的详细信息。
顺便说一句:词典使用键而不是索引。
我不知道您从哪里获得会员编号,也不了解您的聚类算法;但是,我认为经过DP_Cluster
的这些更改可能看起来像这样:
public static List<Cluster> DP_Cluster(List<string> customers, double alpha)
{
double probOld = 0.0;
double probNew = 0.0;
var clusters = new List<Cluster>();
Cluster currentCluster = null;
for (int i = 0; i < customers.Count; i++) {
if (i <= clusters.Count) {
probOld = clusters[i].Dic.Count / (i + alpha);
} else {
probNew = alpha / (i + alpha);
}
if (probNew > probOld || currentCluster == null) {
currentCluster = new Cluster();
clusters.Add(currentCluster);
}
currentCluster.Add(_memberNumber, new ClusterMember { Name = customers[i] });
}
return clusters;
}
Cluster
中的某些构造函数和方法最终可能被证明是多余的,因为我们总是每次一次添加一个客户。