|
34 | 34 | k_cluster(Map, Centroites, Objects, Clusters0),
|
35 | 35 | ( Clusters0 == Old
|
36 | 36 | -> Clusters = Old
|
37 |
| - ; partition(==([]), Clusters0, Empty, NonEmpty), |
38 |
| - fill_empty(Empty, NonEmpty, Clusters1), |
| 37 | + ; length(Centroites, Needed), |
| 38 | + length(Clusters0, CCount), |
| 39 | + ( CCount < Needed |
| 40 | + -> Extra is Needed-CCount, |
| 41 | + fill_empty(Extra, Clusters0, Clusters1) |
| 42 | + ; Clusters1 = Clusters0 |
| 43 | + ), |
39 | 44 | Iteration2 is Iteration+1,
|
40 | 45 | ( Iteration2 < MaxIter
|
41 | 46 | -> maplist(k_mean(Map), Clusters1, NewCentroites),
|
|
50 | 55 | % If we end up with empty clusters, take some random element
|
51 | 56 | % from the remaining clusters to fill them up.
|
52 | 57 |
|
53 |
| -fill_empty([], Clusters, Clusters). |
54 |
| -fill_empty([_|T], Clusters0, Clusters) :- |
| 58 | +fill_empty(0, Clusters, Clusters). |
| 59 | +fill_empty(N, Clusters0, Clusters) :- |
55 | 60 | repeat,
|
56 | 61 | random_select(Cluster, Clusters0, Clusters1),
|
57 | 62 | Cluster = [_,_|_], !,
|
58 | 63 | random_select(Obj, Cluster, RestCluster),
|
59 |
| - fill_empty(T, [[Obj],RestCluster|Clusters1], Clusters). |
| 64 | + succ(N2, N), |
| 65 | + fill_empty(N2, [[Obj],RestCluster|Clusters1], Clusters). |
60 | 66 |
|
| 67 | +%% k_cluster(:Map, +Centroites, +Objects, -Clusters) is det. |
61 | 68 |
|
62 | 69 | k_cluster(Map, Centroites, Objects, Clusters) :-
|
63 | 70 | CTerm =.. [c|Centroites],
|
64 |
| - functor(CTerm, _, Arity), |
65 |
| - length(Empty, Arity), |
66 |
| - maplist(=([]), Empty), |
67 |
| - ClusterTerm =.. [c|Empty], |
68 |
| - k_cluster_t(Objects, Map, CTerm, ClusterTerm), |
69 |
| - ClusterTerm =.. [_|Clusters]. |
70 |
| - |
71 |
| -k_cluster_t([], _, _, _). |
72 |
| -k_cluster_t([H|T], Map, Centroites, Clusters) :- |
73 |
| - center(Map, H, CH), |
74 |
| - closest_centroit(CH, Centroites, I), |
75 |
| - arg(I, Clusters, Cluster), |
76 |
| - setarg(I, Clusters, [H|Cluster]), |
77 |
| - k_cluster_t(T, Map, Centroites, Clusters). |
| 71 | + maplist(closest_centroit_pair(Map, CTerm), Objects, Pairs), |
| 72 | + keysort(Pairs, Sorted), |
| 73 | + group_pairs_by_key(Sorted, Grouped), |
| 74 | + pairs_values(Grouped, Clusters). |
| 75 | + |
| 76 | +closest_centroit_pair(Map, CTerm, Object, Centroit-Object) :- |
| 77 | + center(Map, Object, Center), |
| 78 | + closest_centroit(Center, CTerm, Centroit). |
78 | 79 |
|
79 | 80 | closest_centroit(C0, Centroites, I) :-
|
80 | 81 | functor(Centroites, _, Arity),
|
|
0 commit comments