zoukankan      html  css  js  c++  java
  • max spacing kclustering(类似kruskal最小生成树)并查集Debuging

    max spacing k-clustering问题:

    给N个点,给出点对之间距离的定义(比如欧几里德距离),spacing定义为任意两个属于不同类的点s和t距离的最小值,要求聚成k个类,使得spacing最大

    算法:

    类似kruskal算法,将所有边从小到大排序,开始每个点属于1个cluster,然后将距离最小的两个点合并,继续下去,直到只剩下k个cluster

    --

    调试这个程序花了不知多少时间……各种错误,数组忘记初始化(而且竟然每次运行结果都一样……),边界<=写成<,而且最重要的是,把并查集的实现写错了-_-

    下面是并查集的实现

    class UFS{
    public:
        UFS(int nodes):nsets(nodes), npoints(nodes){
            par.resize(nodes + 1);
            rank.resize(nodes + 1);
            for (int i = 1; i <= nodes; i++) {//从1开始编号
                par[i] = i;//make set
                rank[i] = 0;
            }
        }
        int find(int v){
            int p = par[v];
            if(p != v){
                return par[v] = find(p);//带路径压缩的find,参见算法概论
            }
            return v;//v is root
        }
        bool merge(int v1, int v2){//即union
            int x = find(v1);
            int y = find(v2);
            if(x == y){
                return false;//用返回值表示v1和v2是否在同一个set中
            }
            if(rank[x] < rank[y]){//这一段开始x,y写成了v1,v2,查了很久,实际上写完之后还翻了算法书(为了看rank的用法),都么有发现,因为确信不会写错,所以查不到
                par[x] = y;
            }else if(rank[x] > rank[y]){
                par[y] = x;
            }else{
                par[x] = y;
                rank[y]++;
            }
            nsets--;
            return true;
        }
        bool is_connected(int v1, int v2){
            return find(v1) == find(v2);
        }
        int get_num_sets(){
            return nsets;
        }
        int get_num_points(){
            return npoints;
        }
        void print(){//for debug
            bool *printed = new bool[par.size()];
            memset(printed, 0, sizeof(bool) * par.size());
            for (int i = 1; i < par.size() ; i++) {
                if (!printed[i]) {
                    printf("%d,", i);
                    printed[i] = true;
                    int x = find(i);
                    for (int j = 1; j < par.size() ; j++) {
                        if (!printed[j] && find(j) == x) {
                            printf("%d,", j);
                            printed[j] = true;
                        }
                    }
                    printf("\n");
                }
            }
            delete []printed;
        }
    private:
        vector<int> par;//vertex[i]'s parent
        vector<int> rank;//upper bound of the height of the subtree rooted at v[i]
        int nsets;
        int npoints;
    };

    还学到一个hamming距离的计算,这个有好多方法,可以参考http://en.wikipedia.org/wiki/Hamming_distance

    int hamming(int a, int b){//要求a,b>0,标准的是用unsigned,原理可以参考wiki
        int num = 0;
        int x = a ^ b;
        while (x) {
            x &= x - 1;
            num++;
        }
        return num;
    }

    感想:

    我觉得以后可以尝试用单元测试,应该比较好,起码debug的时候不会把程序搞得一团糟(我的代码最后充满了if检查(比如文件是否打开成功)printf之类的打印)

  • 相关阅读:
    Java的静态块与实例块(转)
    Programming Ability Test学习 1031. Hello World for U (20)
    Programming Ability Test学习 1011. World Cup Betting (20)
    Programming Ability Test学习 1027. Colors in Mars (20)
    Programming Ability Test学习 1064. Complete Binary Search Tree (30)
    Programming Ability Test学习 1008. Elevator (20)
    【maven详解-生命周期】Maven的生命周期和插件
    【maven详解-插件】maven插件学习之源码插件Source Xref
    $(document).ready(){}、$(fucntion(){})、(function(){})(jQuery)onload()的区别
    你还没真的努力过,就轻易输给了懒惰
  • 原文地址:https://www.cnblogs.com/fstang/p/2834991.html
Copyright © 2011-2022 走看看