计算差异指数dissimilarity index的C++源代码

这个C++程序是用来计算David Wong于2005年发表的一个用于测量空间(族群)隔离的差异指数
(dissimilarity index),简单的说就是衡量两个不同群体(比如黑人和白人,外来移民与本地居民)在一个
地域(比如州、省、市)上的居住隔离程度的指数。Duncan and Duncan(1955)是研究差异指数的先驱,
他们发表的指数被称为D。在此基础上,后来的学者们(如Morrill 1991,Wong 1993,)进一步对D指数做
了修正,从而发表了各种各样的变体D,即D(adj)。目前各种D(adj)只能测量当地的空间隔离(即,直接的邻
近地区,比如两个相邻县的隔离情况),但是不能测量更高层面的地域隔离(比如较之于两个临县的全省的
隔离程度),也不能测量地域分布的差异,更详细的讨论可见于Wong(2005)发表在The Professional
Geographer上的文章:Formulating a General Spatial Segregation Measure。在这篇文章中,Wong研究了一
种称为一般空间隔离指数(a general spatial segregation index),用GD来表示。其定义如下:
GD=1/2*Sigma{abs[CWi/sigma(CWi)-CBi/sigma(CBi)]},
其中Sigma表示求和符号,abs表示取绝对值,CWi的定义为CWi=Sigma[d(Wr)];其中Wr表示地区(比如县
)r中的白人(类似的,可以理解为外来移民)人口数,d(.)是个定义地区i的相邻地区的函数(这个函数可自
定义),需要注意的是地区r可以是地区i本身。CBi的定义与CWi相似,只不过是另一个不同的族群(比如黑
人,或本地居民)。
在运行程序之前,需要准备好数据,这包括两个.txt文件。第一个是包含两个族群人口数的数据文件,这个文
件中的第一列必须是每个地区的唯一可标识的id号(整数型),第二列和第三列分别是各个地区的两个不同
族群的人口数。文件的第一行如果有变量名的话,需要删去,换言之,文件中不应包含变量名,不能有缺省
值。第二个文件是用GeoDa(可google免费下载,该软件由UIUC地理系的Prof. Anselin领导的研究小组开发
,于2002年左右停止更新)生成的自定义的spatial matrix,也就是一个定义哪两个地区相邻的对称矩阵。这
样的一阶对称矩阵定义直接相邻的“邻居”地区,二阶矩阵定义二阶相邻地区,即“邻居”的“邻居”,更高阶矩阵
依此类推,更详细的讨论可参见Robert Haining(2003.Spatial Data Analysis: Theory and
Practice.Cambridge University Press.)幸运的是,GeoDa可以自动生成高阶矩阵。
准备好这两个数据文件后,就可以运行程序了。
下面是我写的C++的源代码,没有采用OOP。VC6.0下编译运行成功。如果用BCB的话,要更改一下循环语
句的初始化定义。我是修社会学的,所以没有精力,没有热情,更没有能力(没上过数据结构的课)来优化
代码。
最后要感谢Sukriti和Sam,如果不是你们的热情,我不会加入这个Spatial study group,更不会细读Wong的
这篇文章,也就不会写出这个小程序了。另,这个程序以及一份简单的user’s guide已经委托Scott发布给S4
共享了。
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
#include <string>
#include <cmath>
using namespace std;
typedef vector< vector<int> > Mat;
void main()
{
 /*Read data and weight matrix file names*/
 string dataname;
 string weightname;
 cout<<"Please enter the data file name:"<<endl;
 cin>>dataname;
 cout<<"Please enter the weight matrix finle name:"<<endl;
 cin>>weightname;
 /*Read number of white and black*/
 ifstream gdin (dataname.c_str());
 if (!gdin)
 {
  cerr<<"unable to open the data file: "
   <<dataname<<endl;
 }
 Mat cwcb;
 for(string s; getline(gdin,s);)
 {
  vector<int> record;
  int a;
  for(istringstream sin(s); sin>>a;)
   record.push_back(a);
  cwcb.push_back(record);
 }
 //cout<<"cwcb: "<<cwcb.size()<<endl;
 
 /*Read weight matrix*/
 ifstream weightin(weightname.c_str());
 if (!weightin)
 {
  cerr<<"unable to open the weight matrix file: "
   <<weightname<<endl;
 }
 ofstream out("temp.txt");
 vector<string> vs;
 for(string stmp; getline(weightin,stmp);)
  vs.push_back(stmp);
 for(int i=0; i<vs.size()-1; i+=2)
  out<<vs[i]<<" "<<vs[i+1]<<endl;
 ifstream rein("temp.txt");
 Mat wm;
 for(string snew; getline(rein,snew);)
 {
  vector<int> vi;
  int b;
  for(istringstream sin(snew); sin>>b;)
   vi.push_back(b);
  wm.push_back(vi);
 }
 //cout<<"wm: "<<wm.size()<<endl;
 
 Mat final;
 for(i=0; i<cwcb.size(); ++i)
 {
  vector<int> vout;
  vout.push_back(cwcb[i][0]);
  int sumwhite=0;
  int sumblack=0;
  for(int j=2; j<wm[i].size(); ++j)
  {
   for(int k=0; k<cwcb.size(); ++k)
   {
    if(wm[i][j]==cwcb[k][0])
    {
     sumwhite+=cwcb[k][1];
     sumblack+=cwcb[k][2];
    }
   }
  }
  vout.push_back(sumwhite);
  vout.push_back(sumblack);
  final.push_back(vout);
 }
 vector<long> cwi;
 vector<long> cbi;
 long sumcwi=0;
 long sumcbi=0;
 for(i=0; i<final.size(); ++i)
 {
  cwi.push_back(final[i][1]+cwcb[i][1]);
  cbi.push_back(final[i][2]+cwcb[i][2]);
  sumcwi+=cwi[i];
  sumcbi+=cbi[i];
 }
 vector<float> pctcw;
 vector<float> pctcb;
 vector<float> diff;
 for(i=0; i<final.size(); ++i)
 {
  pctcw.push_back(float(cwi[i])/float(sumcwi));
  pctcb.push_back(float(cbi[i])/float(sumcbi));
  diff.push_back(pctcw[i]-pctcb[i]);
 }
 for(i=0; i<diff.size(); ++i)
 {
  if(diff[i]<0)
   diff[i]=-diff[i];
 }
 float sumdiff=0;
 for(i=0; i<diff.size(); ++i)
  sumdiff+=diff[i];
 
 float GD=sumdiff/2;
 //cout<<"sumdiff= "<<sumdiff<<endl;
 cout<<"GD= "<<GD<<endl;
 cout<<"Done!"<<endl;
 system("pause");
}
 

About Hongwei Xu

I'm a social demographer, a single-child, a husband, and a father.
This entry was posted in 未分类. Bookmark the permalink.

1 条 计算差异指数dissimilarity index的C++源代码 的回复

  1. Unknown说道:

    Amberdigital Branch,Southern Stars Enterprises Co is specializing in the development and manufacturing of mp4 advertisement players, SD card players and advertisement LCD displays. Established in 1996, we have explored and developed the international market with professionalism. We have built a widespread marketing network, and set up a capable management team dedicated to provide beyond-expectation services to our customers.

    amberdigital Contact Us
    Southern Stars Enterprises Co (Hong Kong Office)
    Add:3 Fl, No.2, Lane 2, Kam Tsin Tsuen, Sheung Shui, Hong Kong
    Tel:+852 2681 4099
    Fax:+852 2681 4586
    Southern Stars Enterprises Co (Shenzhen Office)
    Add:DE, 16/F, Building 2, Nanguo Tower, Sungang Road, Shenzhen, China
    Tel:+86 755 2592 9100
    Fax:+86 755 2592 7171
    E-mail:sstar@netvigator.com
    website:www.amberdigital.com.hk
    alibaba:amberdigital.en.alibaba.com[b

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s