ページ 11

ネットワークを作成するプログラムにおいて特定の条件下で起きるエラーについて

Posted: 2015年5月30日(土) 11:35
by RTEM
研究でシミュレーションを行っている大学院生です。
現在、ネットワークを作成するプログラムを作っているのですが、特定の条件下で異常終了が発生し、困っているところです。
そのネットワークの概要は以下のとおりです。
-CNNネットワーク-
設定パラメータ:U(0~1の実数)
初期状態はノード3つ(3人)でエッジは2つ。(0-1,0-2)がつながっている状態。
1,確率1-Uでノード(人)を追加する
2,確率Uでポテンシャルエッジ(友人を介してつながっている人)をエッジにする
(AとBとCがいて、AとB,BとCは友達同士。そこでBを介してAとCが友達になるというシチュエーションです)
これを目標とするノード数になるまで繰り返す。
--------
ここで特定の条件というのが設定パラメータUを大きく(およそ0.8以上)した場合のことです。
おおよその問題点は分かっておりまして、Uが大きい場合には初期にポテンシャルエッジが少ないために
過程2をうまく処理できなくなるというのが挙げられます。しかしながら、なぜ異常終了が起きるのか、何行目がおかしい、必要な処理が抜けているなど
ありましたら、教えていただけないかと思い、投稿させていただきました。宜しくお願いします

コード:

# define Nsize 300 //総人口
vector <vector<short>> Network;//[自分][相手]=0:エッジなし,1:エッジあり,-9:存在しない
vector <vector<short>> NeighbourID;//友達のID  NeighbourID[自分][何人目]=友達ID 
vector <int> NumLink;//友達の数
vector <vector<short>> PotentialID;//PotentialID[自分][何人目]=間接的友達ID
void IntVector(){
	
	NumLink.resize(Nsize);
	Network.resize(Nsize);
	NeighbourID.resize(Nsize);
	PotentialID.resize(Nsize); 

	for(int i=0; i<Nsize; ++i){
		NumLink[i]=0;
		Network[i].resize(Nsize);
		NeighbourID[i].resize(Nsize);
		PotentialID[i].resize(Nsize);
		
		for(int j=0; j<Nsize; ++j){
			if(i==j)
				Network[i][j]=-9;
			else
				Network[i][j]=0;
			NeighbourID[i][j]=-9;
			PotentialID[i][j]=-9;
		}
	}
}
int CNN(double para_U){
	
	double XX;
	int YY,ZZ;
	int NeigID,FNeigID,NLink,NFLink;
	int NPotential;
	int Potential_Real;
	///初期ネットワーク0,1,2///
	Network[0][1]=1;
	Network[0][2]=1;
	Network[1][0]=1;
	Network[2][0]=1;
	NeighbourID[0][0]=1;
	NeighbourID[0][1]=2;
	NeighbourID[1][0]=0;
	NeighbourID[2][0]=0;
	NumLink[0]=2;
	NumLink[1]=1;
	NumLink[2]=1;
	
	do{
	    XX=Rand();
		YY=int(Rand()*size);//focal
		
		if(XX<para_U){//potential edge⇒real edge
			  NLink=NumLink[YY];//focalのリンク数
			  NPotential=0;
			
			  for(int i=0;i<NLink;i++){
				NeigID=NeighbourID[YY][i];//友達ID
				NFLink=NumLink[NeigID];//友達の実リンク数
			
				  for(int j=0;j<NFLink;j++){
					
				    	FNeigID=NeighbourID[NeigID][j];//友達の友達ID
					
					  //Potential_edgeのチェック
					   if(Network[YY][FNeigID]==0){
			            PotentialID[YY][NPotential]=FNeigID;//ポテンシャル相手ID
				        NPotential++;//ポテンシャル本数
						
					  }
				  }
			  }
			  if(NPotential>0){
			  ZZ=int(Rand()*NPotential);
			  Potential_Real=PotentialID[YY][ZZ];//NewLinkの相手
			  Network[YY][Potential_Real]=1;
			  Network[Potential_Real][YY]=1;
			  NeighbourID[YY][NLink]=Potential_Real;
			  NeighbourID[Potential_Real][NumLink[Potential_Real]]=YY;
			  NumLink[YY]++;
		  	  NumLink[Potential_Real]++;
			  }
		}
		else{//Agent追加
			Network[size][YY]=1;
			Network[YY][size]=1;
			NeighbourID[YY][NumLink[YY]]=size;
			NeighbourID[size][0]=YY;
			NumLink[YY]++;
			NumLink[size]=1;
			size++;
		}
	}while(Nsize>size);
};
int main(){
	IntVector();
	double ParaU=0.5;//ここで設定
    int size=3;//固定
	CNN(ParaU);
	return 1;
};

Re: ネットワークを作成するプログラムにおいて特定の条件下で起きるエラーについて

Posted: 2015年5月30日(土) 12:02
by たいちう
取りあえず、コンパイルできるコードを載せてみては?
エラーの再現はおろか、Rand()の範囲やsizeの値すらわからない。

Re: ネットワークを作成するプログラムにおいて特定の条件下で起きるエラーについて

Posted: 2015年5月30日(土) 12:09
by たいちう
やりたいことは全くわからないけど、main()の変数sizeをグローバル変数にして、
Rand()を標準関数のrand()にしたところ、vectorの範囲外へのアクセスで落ちました。
51行目とかは正しいの?

Re: ネットワークを作成するプログラムにおいて特定の条件下で起きるエラーについて

Posted: 2015年5月30日(土) 13:47
by RTEM
失礼しました。
抜粋のため不適切な形になっておりました
Rand()は標準関数rand()から0,1を除いた乱数となります

コード:

include <iostream>
#include <fstream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <list>
#include <cstring>
#include <cstdlib>
#include <ctype.h>
#include <sstream>
#include <string>
#include <cstdio>
#include <ctime>
#include <algorithm>
#include <functional>

using namespace std;
# define Nsize 300 //総人口
vector <vector<short> > Network;//[自分][相手]=0:エッジなし,1:エッジあり,-9:存在しない
vector <vector<short> > NeighbourID;//友達のID  NeighbourID[自分][何人目]=友達ID
vector <int> NumLink;//友達の数
vector <vector<short> > PotentialID;//PotentialID[自分][何人目]=間接的友達IDvector<Deg> DegData;
int size=3;
double para_U=0.8;
/////////////////////////////////
inline double Rand(){
    double i;
    do{
        i=(double)rand()/RAND_MAX;
    }while(i==0 || i==1);
    return i;
};
/////////////初期化///////////
void IntVector(){
	
	NumLink.resize(Nsize);
    Network.resize(Nsize);
	NeighbourID.resize(Nsize);
	PotentialID.resize(Nsize);

	for(int i=0; i<Nsize; ++i){
		NumLink[i]=0;
		Network[i].resize(Nsize);
		NeighbourID[i].resize(Nsize);
		PotentialID[i].resize(Nsize);
		for(int j=0; j<Nsize; ++j){
			if(i==j)
				Network[i][j]=-9;
			else
				Network[i][j]=0;
			NeighbourID[i][j]=-9;
			PotentialID[i][j]=-9;
		}
	}
}
////////////////////////CNN(ConnectingNearestNeighbor)///////////////////////////////
int CNN(double para_U){
    
    double XX;
    int YY,ZZ;
    int NeigID,FNeigID,NLink,NFLink;
    int NPotential;
    int Potential_Real;
    ///初期ネットワーク0,1,2///
    Network[0][1]=1;
    Network[0][2]=1;
    Network[1][0]=1;
    Network[2][0]=1;
    NeighbourID[0][0]=1;
    NeighbourID[0][1]=2;
    NeighbourID[1][0]=0;
    NeighbourID[2][0]=0;
    NumLink[0]=2;
    NumLink[1]=1;
    NumLink[2]=1;
    
    do{
        XX=Rand();
        YY=int(Rand()*size);//focal
        
        if(XX<para_U){//potential edge⇒real edge
            NLink=NumLink[YY];//focalのリンク数
            NPotential=0;
            
            for(int i=0;i<NLink;i++){
                NeigID=NeighbourID[YY][i];//友達ID
                NFLink=NumLink[NeigID];//友達の実リンク数
                
                for(int j=0;j<NFLink;j++){
                    
                    FNeigID=NeighbourID[NeigID][j];//友達の友達ID
                    
                    //Potential_edgeのチェック
                    if(Network[YY][FNeigID]==0){
                        PotentialID[YY][NPotential]=FNeigID;//ポテンシャル相手ID
                        NPotential++;//ポテンシャル本数
                        
                    }
                }
            }
            if(NPotential>0){
                ZZ=int(Rand()*NPotential);
                Potential_Real=PotentialID[YY][ZZ];//NewLinkの相手
                Network[YY][Potential_Real]=1;
                Network[Potential_Real][YY]=1;
                NeighbourID[YY][NLink]=Potential_Real;
                NeighbourID[Potential_Real][NumLink[Potential_Real]]=YY;
                NumLink[YY]++;
                NumLink[Potential_Real]++;
            }
        }
        else{//Agent追加
            Network[size][YY]=1;
            Network[YY][size]=1;
            NeighbourID[YY][NumLink[YY]]=size;
            NeighbourID[size][0]=YY;
            NumLink[YY]++;
            NumLink[size]=1;
            size++;
        }
    }while(Nsize>size);
        return 1;
};
///////////////////////////////////////////////
//////////////////////////// M A I N ////////////////////////////////////////////////////////////////////////////
int main(){

	IntVector();
    CNN(para_U);
	return 0;
	
};

Re: ネットワークを作成するプログラムにおいて特定の条件下で起きるエラーについて

Posted: 2015年5月30日(土) 17:29
by たいちう
95行目でNPotentialが300になっていたため、実行時エラーが発生しています。
PotentialIDの配列のインデックスとして有効な範囲はわかりますか?

Re: ネットワークを作成するプログラムにおいて特定の条件下で起きるエラーについて

Posted: 2015年5月31日(日) 11:18
by RTEM
0~299で与えていました
解決しました
ありがとうございました