Exemplo n.º 1
0
bool CPFAOptimize::CalPipeCloseSubtract( ComponentManager& ComManager, PFAOptimitationData& OptData, map< int, double >& OptimitationParameterMap, map< int, double >& OptimitationAssistantMap )
{
	//
	ASSERT( NULL != &ComManager );
	ASSERT( NULL != &OptData );

	double dTemp = 0.0;
	double dTempDummyFlux = 0.0;
	double dTempFactFlux = 0.0;
	double dTempLength = 0.0;
	Pipe* pPipe = NULL;
	Component* pPipeComponent = NULL; 
	map< int, double >::iterator IntDouMap;
	IteratorPtr<Component> PipeItPtr( ComManager.CreatPipeIterator() );
	for( PipeItPtr->Fist(); !PipeItPtr->IsDone(); PipeItPtr->Next() )
	{
		pPipeComponent = &PipeItPtr->CurrentItem();
		pPipe = dynamic_cast<Pipe*>( pPipeComponent );
		
		// 管道的属性:管道虚流量、管道流量和管道长度,如果其中有一个属性不存在
		if( !OptData.GetProperty( pPipe->GetKey(), 1, dTempFactFlux ) || !OptData.GetProperty( pPipe->GetKey(), 2, dTempLength) 
			|| !OptData.GetProperty( pPipe->GetKey(), 0, dTempDummyFlux ) )
		{
			return false;
		}
		
		// 每根管道的计算参数,都取绝对值是为了避免pow出现错误
		dTemp = pow( fabs( dTempFactFlux ), 2.0 * OptData.GetAlfaModulus() / ( OptData.GetAlfaModulus() + OptData.GetMModulus() ) )
			* pow( fabs( dTempLength ), ( OptData.GetAlfaModulus() + OptData.GetMModulus() ) / OptData.GetMModulus() )
			* pow( fabs( dTempDummyFlux ), -1.0 * OptData.GetMModulus() / ( OptData.GetAlfaModulus() + OptData.GetMModulus() ) );
		IntDouMap = OptimitationParameterMap.find( pPipe->GetKey() );
		if( OptimitationParameterMap.end() == IntDouMap )
		{
			OptimitationParameterMap.insert( map< int, double >::value_type( pPipe->GetKey(), dTemp ) );
		}
		else
		{
			IntDouMap->second = dTemp;
		}
		
		// 就最后虚流量的指数不同
		dTemp = pow( fabs( dTempFactFlux ), 2.0 * OptData.GetAlfaModulus() / ( OptData.GetAlfaModulus() + OptData.GetMModulus() ) )
			* pow( fabs( dTempLength ), ( OptData.GetAlfaModulus() + OptData.GetMModulus() ) / OptData.GetMModulus() )
			* pow( fabs( dTempDummyFlux ), -1.0 * ( OptData.GetAlfaModulus() + 2 * OptData.GetMModulus() ) / ( OptData.GetAlfaModulus() + OptData.GetMModulus() ) );
		IntDouMap = OptimitationAssistantMap.find( pPipe->GetKey() );
		if( OptimitationAssistantMap.end() == IntDouMap )
		{
			OptimitationAssistantMap.insert( map< int, double >::value_type( pPipe->GetKey(), dTemp ) );
		}
		else
		{
			IntDouMap->second = dTemp;
		}
	}
	return true;
}
Exemplo n.º 2
0
bool CPFAOptimize::CalFactFlux( ComponentManager& ComManager, const double& dPrecision, const long& lMaxIterative, PFAOptimitationData& OptData )
{
	// 
	ASSERT( NULL != & ComManager );
	ASSERT( 0 < dPrecision );
	ASSERT( 0 < lMaxIterative );

	vector< double > TempVector;
	vector< int >* pPipeVector = NULL;
	vector< int >* pJunVector = NULL;
	map< int, double > OptimitationParameterMap;                 // 管段的闭合差,用来计算环的闭合差
	map< int, double > PTempMap;                                 // 环的Sq_2,有正负的
	map< int, double > ATempMap;                                 // 环的Sq
	map< int, double > ResultMap;                                // 校正流量,int表示环
	double dTemp = 0.0;
	double dTempDiameter = 0.0;
	double dTempFactFlux = 0.0;
	double dTempLength = 0.0;
	bool bPrecisionFlag = false;                // 精度要求标志,为true表示全部计算参数都符合精度要求
	long lIterativeTime = 0;                    // 精度迭代次数
	Pipe* pPipe = NULL;
	Component* pPipeComponent = NULL; 
	IteratorPtr<Component> PipeItPtr( ComManager.CreatPipeIterator() );

	map< int, double > CircleCloseSubtract;                // 环的闭合差
	map< int, double > CircleMiddleVariable;               // 中间变量 
	map< int, vector< double > > FluxModulusMetrix;        // 求解流量的系数矩阵
    
	
	int i = 0;
	int j = 0;
	
	// 初始化流量系数矩阵,矩阵是从1开始的
	for( i = 0; i <= OptData.GetPropertyCount( 100 ); i++ )
	{
		vector< double > DoubleVector;
		for( j = 0; j <= OptData.GetPropertyCount( 100 ); j++ )
		{
			DoubleVector.push_back( 0.0 );
		}
		FluxModulusMetrix.insert( map< int, vector< double > >::value_type( i+1, DoubleVector ) );
	}

	// 计算每根管道
	for( PipeItPtr->Fist(); !PipeItPtr->IsDone(); PipeItPtr->Next() )
	{
		pPipeComponent = &PipeItPtr->CurrentItem();
	    pPipe = dynamic_cast<Pipe*>( pPipeComponent );

		// 管道的属性:管道流量和管道长度,如果其中有一个属性不存在
		if( !OptData.GetProperty( pPipe->GetKey(), 1, dTempFactFlux ) && !OptData.GetProperty( pPipe->GetKey(), 2, dTempLength) 
		    && !OptData.GetProperty( pPipe->GetKey(), 4, dTempDiameter ) )
		{
			return false;
		}

		// 每根管道的计算参数
		// 如果k和m都设置了值,就直接计算
		if( ( 0 > fabs( OptData.GetKModulus() - 1.0e-13 ) ) && ( 0 > fabs( OptData.GetMModulus() - 1.0e-6 ) ) )
		{
			if( 0 < fabs( dTempDiameter -1e-6 ) )               // 分母不能为0
			{
				dTemp = OptData.GetKModulus() * dTempLength / pow( fabs( dTempDiameter ), 5.3 );  // 公式?
			}
		}
		// Re
		if( 0 > fabs( dTempDiameter - 1e-6) )                   // 防止下面公式分母为0,而且直径为0也没意义
		{
			return false;
		}	
		double dSpeed = 4.0 * dTempFactFlux / ( PI * dTempDiameter * dTempDiameter );  // 每根管道的流速
        QuantityManager& qm = QuantityManager::Instance();     
		NumFlyWeight DynamicViscosity = ( ComManager.SysProperty().GetFuild() )->ms_Viscos; // 流体的动力粘度
		double dDynamicViscosity = DynamicViscosity.GetfValue();
		if( "kg/sec-m" != DynamicViscosity.GetUnit() )         // 转换到标准单位
		{	
			qm.TransformFromStd( dDynamicViscosity, DynamicViscosity.GetUnit().GetBuffer( 15 ), DynamicViscosity.GetfValue() );
		}
		if( 0 > fabs( dDynamicViscosity - 1e-6) )              // 动力粘度不能为0
		{
			return false;
		}
		double dRe = dSpeed * dTempDiameter / dDynamicViscosity;

		// 牛顿迭代法解柯尔勃洛克-魏特公式
		if( !ColebrookNewton( 4.572e-5, dTempDiameter, dRe, dTemp ) )       // 牛顿法迭代失败
		{
			return false;                               
		}
		dTemp = dTemp * 8.0 * dTempLength / ( 9.8 * PI * PI * pow( fabs( dTempDiameter ), 5 ) ); // S的计算,跟选的摩擦阻力公式有关
		
		OptimitationParameterMap.insert( map< int, double >::value_type( pPipe->GetKey(), dTemp ) );
	}


	// 为实际流量平差做准备
	map< int, vector< double > >::iterator FluxModMetIt = FluxModulusMetrix.begin();
	for( i = 1; i <= OptData.GetPropertyCount( 100 ); i++ )   // 从1号环开始
	{
		double dPTemp = 0.0;
		double dATemp = 0.0;
		int iKeyOfPipe = 0;                                   // 管道编号
		double dSTemp = 0.0;                                  // 上面算出来的OptimitationParameterMap中的值,即水管摩阻  
		vector< double >::iterator DouVecIt = ( FluxModMetIt->second ).begin();
		for( j = 0; j < OptData.GetPropertyCount( i, 100 ); j++ )  // 遍历每个环的管道
		{
			OptData.GetProperty( i, 100, j, iKeyOfPipe);
			OptData.GetProperty( abs( iKeyOfPipe ), 1, dTemp );         // 管道实际流量
			map< int, double >::iterator IntDoubleIt = OptimitationParameterMap.find( abs( iKeyOfPipe ) );
			dSTemp = IntDoubleIt->second;
			dPTemp = dPTemp + ( iKeyOfPipe > 0 ? 1 : -1) * dSTemp * dTemp * dTemp; 
			dATemp = dATemp + dSTemp * dTemp;
		}
		PTempMap.insert( map< int, double >::value_type( i, dPTemp ) );
		ATempMap.insert( map< int, double >::value_type( i, dATemp ) );
	}

	// 计算每个环的参数,如果有环参数大于精度要求dPrecision,则调整实际流量,直到每个环参数都小于精度要求dPrecision或迭代次数超过限制
	while( ( false == bPrecisionFlag ) && ( lMaxIterative > lIterativeTime ) )
	{
		bPrecisionFlag = true;                   // 每次迭代都先设置迭代成功标志为true,如果有某环精度不够,则置为false
		double dParameterTemp = 0.0;            
		map< int, vector< double > >::iterator FluxModMetIt = FluxModulusMetrix.begin();
		vector< double >::iterator DouVecIt;
		map< int, double >::iterator IntDouIt;
		for( i = 1; i <= OptData.GetPropertyCount( 100 ); i++ )   // 从1号环开始
		{
			dParameterTemp = 0.0;
			DouVecIt = ( FluxModMetIt->second ).begin(); 
			
			double dModulus = 0.0;
			*DouVecIt = 1.0;	
			for( j = 0; j < OptData.GetPropertyCount( i, 100 ); j++ )   // 遍历每个环的管道
			{
				DouVecIt = ( FluxModMetIt->second ).begin();
	            int iKeyOfPipe = 0;
				int iCloseCircle = 0;
				int n = 0;
				OptData.GetProperty( i, 100, j, iKeyOfPipe );
				while( OptData.GetProperty( iKeyOfPipe, 102, n, iCloseCircle ) )
				{
					if( abs( iCloseCircle ) == i )            // 如果是本环则跳过
					{
						n++;
						continue;
					}			
					double dATemp = 0.0;                               
					double dSTemp = 0.0;     
					IntDouIt = OptimitationParameterMap.find( abs( iKeyOfPipe ) );
					dSTemp = IntDouIt->second;                               // S
					OptData.GetProperty( abs( iKeyOfPipe ), 1, dTemp );      // 实际流量
					IntDouIt = ATempMap.find( i );
					dATemp = IntDouIt->second;                               // 环的Sq和
					if( 0 > fabs( dATemp - 1e-6) )                           // 防止下面表达式的分母为0
					{
						return false;
					}
					dModulus = -1 * dSTemp * fabs( dTemp ) / dATemp;

					// 把系数写入矩阵
					for( int m = 1; m < iCloseCircle; m++ )                   
					{
						DouVecIt++;
					}
					if( ( FluxModMetIt->second ).end() == DouVecIt )           // 防止越界写入数值
					{
						return false;
					}
					*DouVecIt = dModulus;
					n++;
				}
			}

			// 把常量向量也放入矩阵中,即等式的右边:AX=B中的B
			IntDouIt = PTempMap.find( i );
			dTemp = -1 * IntDouIt->second ;
			IntDouIt = ATempMap.find( i );
			if( 0 > fabs( IntDouIt->second - 1e-6 ) )            // 防止分母为0
			{
				return false;
			}
			dModulus = dTemp / ( 2 * IntDouIt->second );
			DouVecIt = ( FluxModMetIt->second ).begin(); 
			for(int k = 0; k <= OptData.GetPropertyCount( 100 ); k++ ) // 移动到每行最后一个位置,即移动 行数+1 个位置
			{
				DouVecIt++;
			}
			*DouVecIt = dModulus;

			FluxModMetIt++;                                  // 移动到下一行
		}

		// 解FluxModulusMetrix线性方程组,结果放入向量ResultMap
		//////////////////////////

		// 遍历所有环,
		IntDouIt = ResultMap.begin();
		for( ; ResultMap.end() != IntDouIt; IntDouIt++ )
		{
			dTemp = IntDouIt->second;
		    if( dPrecision < fabs( dTemp ) )   // 如果有环计算出来的校正流量不符合精度要求
			{
		    	bPrecisionFlag = false;             // 要重新迭代

			    // 修正此环上所有的管道实际流量,注意正负
				int iKeyOfPipe = 0;
				for( i = 1; i <= OptData.GetPropertyCount( 100 ); i++ )
				{
					for( j = 0; j < OptData.GetPropertyCount( i, 100); j++ )
					{
						OptData.GetProperty( i, 100, j, iKeyOfPipe );             // 取得环中的管道编号
						OptData.GetProperty( iKeyOfPipe, 1, dParameterTemp );     // 取的管道对应的实际流量
						dParameterTemp += dTemp;                                  // 修正流量
						OptData.SetProperty( iKeyOfPipe, 1, dParameterTemp );
					}
				}
			}
		}
		lIterativeTime++;              // 迭代次数加一
	}
	return bPrecisionFlag;
}
Exemplo n.º 3
0
bool CPFAOptimize::CalEconomyDiameterAndWaterHarmer( ComponentManager& ComManager, const double& dPrecision, const long& lMaxIterative, PFAOptimitationData& OptData )
{
	// 
	ASSERT( NULL != & ComManager );
	ASSERT( 0 < dPrecision );
	ASSERT( 0 < lMaxIterative );

	vector< double > TempVector;
	vector< int >* pPipeVector = NULL;
	vector< int >* pJunVector = NULL;
	map< int, double > OptimitationParameterMap;                 // 管段的闭合差,用来计算环的闭合差
	map< int, double > OptimitationAssistantMap;                 // 用在平差的时候
	int i = 0;
	int j = 0;
	double dTemp = 0.0;
	double dTempDummyFlux = 0.0;
	double dTempFactFlux = 0.0;
	double dTempLength = 0.0;
	bool bPrecisionFlag = false;                // 精度要求标志,为true表示全部计算参数都符合精度要求
	long lIterativeTime = 0;                    // 精度迭代次数
	Pipe* pPipe = NULL;
    CalPipeCloseSubtract( ComManager, OptData, OptimitationParameterMap, OptimitationAssistantMap );

	// 计算每个环的参数,如果有环参数大于精度要求dPrecision,则调整虚流量,直到每个环参数都小于精度要求dPrecision或迭代次数超过限制
	while( ( false == bPrecisionFlag ) && ( lMaxIterative > lIterativeTime ) )
	{
		bPrecisionFlag = true;                   // 每次迭代都先设置迭代成功标志为true,如果有某环精度不够,则置为false
		map< int, double >::iterator OptIt;
		vector< int >::iterator PipeIt;
		double dParameterTemp = 0.0;            // 环的闭合差
		double dAssistantTemp = 0.0;            // 虚流量修正时用的辅助变量

		/*

		// 哈代-克罗斯法,即把基环单独考虑,不考虑其他环对此基环造成的影响
		for( int i = 1; i <= OptData.GetCirPipeMatrixCount(); i++ )
		{
			dParameterTemp = 0.0;
			dAssistantTemp = 0.0;
			pPipeVector = OptData.GetCirPipeMatrix( i );
			pJunVector = OptData.GetCirJunMatrix( i );
			PipeIt = pPipeVector->begin();

			// 计算每个环的参数
			for( ; PipeIt != pPipeVector->end(); PipeIt++ )
			{
				pPipe = ComManager.LookUpPipe( abs( *PipeIt ) );
				if( 0 < *PipeIt )
				{
					OptIt = OptimitationParameterMap.find( abs( *PipeIt ) );
					dTemp = OptIt->second;
					dParameterTemp += fabs( OptIt->second );
					OptIt = OptimitationAssistantMap.find( abs( *PipeIt ) );
					dAssistantTemp += fabs( OptIt->second );
				}
				else
				{
					OptIt = OptimitationParameterMap.find( abs( *PipeIt ) );
					dTemp = OptIt->second;
					dParameterTemp -= fabs( OptIt->second );
					OptIt = OptimitationAssistantMap.find( abs( *PipeIt ) );
					dAssistantTemp -= fabs( OptIt->second );
				}
			}

			// 如果此环计算出来的结果不符合精度要求,因为是double,所以没加等号,把逻辑判断倒过来?
			if( dPrecision < fabs( dParameterTemp ) )
			{
				bPrecisionFlag = false;             // 要重新迭代

				// 防止分母为0,但这个断言还是不够全面,以后需要改进
				ASSERT( 0 < fabs( ( OptData.GetMModulus() * dAssistantTemp - 1e-9 ) ) );

				// 此环的虚流量校正流量
				dTemp = ( OptData.GetAlfaModulus() + OptData.GetMModulus() ) * dParameterTemp /
					( OptData.GetMModulus() * dAssistantTemp );

				// 修正此环上所有的管道虚流量,注意正负
				// 这里的修正方法是单一环修正,即只考虑了本环的影响,没有考虑邻环的影响,在精度上会造成一定损失,
				// 以后会考虑在PFAOptimitationData中加入属性,来把这个方法改为联立环修正
				PipeIt = pPipeVector->begin();
				for( ; PipeIt != pPipeVector->end(); PipeIt++ )
				{
					OptData.GetProperty( *PipeIt, 0, dAssistantTemp );
					dAssistantTemp += dTemp;
					OptData.SetProperty( *PipeIt, 0, dAssistantTemp );
				}

				// 重新计算管道的闭合差
				CalPipeCloseSubtract( ComManager, OptData, OptimitationParameterMap, OptimitationAssistantMap );
			}
		}


        */


		//////////////////
		map< int, double > CircleCloseSubtract;
		for( i = 1; i <= OptData.GetCirPipeMatrixCount(); i++ )
		{
			dParameterTemp = 0.0;
			dAssistantTemp = 0.0;
			pPipeVector = OptData.GetCirPipeMatrix( i );
			pJunVector = OptData.GetCirJunMatrix( i );
			PipeIt = pPipeVector->begin();
			
			// 计算每个环的参数
			for( ; PipeIt != pPipeVector->end(); PipeIt++ )
			{
				pPipe = ComManager.LookUpPipe( abs( *PipeIt ) );
				if( 0 < *PipeIt )
				{
					OptIt = OptimitationParameterMap.find( abs( *PipeIt ) );
					dTemp = OptIt->second;
					dParameterTemp += fabs( OptIt->second );
					OptIt = OptimitationAssistantMap.find( abs( *PipeIt ) );
					dAssistantTemp += fabs( OptIt->second );
				}
				else
				{
					OptIt = OptimitationParameterMap.find( abs( *PipeIt ) );
					dTemp = OptIt->second;
					dParameterTemp -= fabs( OptIt->second );
					OptIt = OptimitationAssistantMap.find( abs( *PipeIt ) );
					dAssistantTemp -= fabs( OptIt->second );
				}
			}
			CircleCloseSubtract.insert( map< int, double >::value_type( i, dParameterTemp ) );
		}

		map< int, double >::iterator IntDouMapIt;
		for( i = 1; i < OptData.GetPropertyCount( 102 ); i++ )
		{
			int iKeyOfPipe = i;
			j = 0;
			while( !OptData.GetPropertyCount( iKeyOfPipe, 102 ) )
			{
				iKeyOfPipe++;
				if( 5000 < j)                 // 防止死循环
				{
					return false;
				}
				j++;
			}
			int iKeyOfCircle = 0;
			dTemp = 0.0;
			for( j = 0; j < OptData.GetPropertyCount( iKeyOfPipe, 102 ); j++ )
			{
				OptData.GetProperty( iKeyOfPipe, 102, j, iKeyOfCircle );
				IntDouMapIt = CircleCloseSubtract.find( abs( iKeyOfCircle) );
				if( 0 < iKeyOfCircle )
				{
					dTemp += IntDouMapIt->second;
				}
				else
				{
					dTemp -= IntDouMapIt->second;
				}
			}
			OptData.GetProperty( iKeyOfPipe, 0, dParameterTemp );
			dParameterTemp += dTemp;
			OptData.SetProperty( iKeyOfPipe, 0, dParameterTemp );
		}
		lIterativeTime++;              // 迭代次数加一
	}

	// 如果虚流量平差成功
	if( ( false != bPrecisionFlag ) && ( lMaxIterative > lIterativeTime ) )
	{
		// 计算经济管径和水头损失
		ASSERT( 0 < OptData.GetEconomyFactor() );
		int iKeyOfPipe = 0;	
		Pipe* pPipe = NULL;
		Component* pPipeComponent = NULL; 
      
		// 遍历所有管道
        IteratorPtr<Component> PipeItPtr( ComManager.CreatPipeIterator() );
		for( PipeItPtr->Fist(); !PipeItPtr->IsDone(); PipeItPtr->Next() )
		{
			pPipeComponent = &PipeItPtr->CurrentItem();
	        pPipe = dynamic_cast<Pipe*>( pPipeComponent );
			if( NULL == pPipe )
			{
				return false;       // 找不到管道,是否应该发送个自定义消息或错误?
			}
			OptData.GetProperty( pPipe->GetKey(), 0, dTempDummyFlux );
			OptData.GetProperty( pPipe->GetKey(), 1, dTempFactFlux );
			OptData.GetProperty( pPipe->GetKey(), 2, dTempLength );
			dTemp = OptData.GetEconomyFactor() * OptData.GetFluxSummation() * dTempDummyFlux 
				* dTempFactFlux*dTempFactFlux;
			
			// 经济管径
			if( 0 > fabs( ( OptData.GetAlfaModulus() + OptData.GetMModulus() ) - 1e-6 ) )
			{
				AfxMessageBox( MODULUS_ZERO );
				return false;
			}
			dTemp = pow( fabs( dTemp ), 1.0 / ( OptData.GetAlfaModulus() + OptData.GetMModulus() ) );
			OptData.SetProperty( pPipe->GetKey(), 4, dTemp );
			
			// 水头损失
			dTemp = OptData.GetKModulus() * pow( fabs( dTempFactFlux ), OptData.GetNModulus() ) * dTempLength 
				/ pow( fabs( dTemp ), OptData.GetMModulus() );
			OptData.SetProperty( pPipe->GetKey(), 5, dTemp );
		}
	}
	return bPrecisionFlag;
}
Exemplo n.º 4
0
void CPFAOptimize::Example()
{
	
	CMainFrame* pMainFrame = NULL; 
	pMainFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;
	CChildFrame* pChildFrame = NULL;
	pChildFrame = (CChildFrame*)pMainFrame->GetActiveFrame();
	CAutoPFAView* pAutoView = NULL;
	pAutoView = (CAutoPFAView*)pChildFrame->GetActiveView();
	ComponentManager* pComManager = pAutoView->GetDocument()->m_scenarioManager.GetCurScenario()->GetCompManager();
	JunSystemTransformCircleSystem( *pComManager, OptData );
	DisplayMatrix( "F://CirPipe.txt", 100, OptData );
	InitializePipeCircle( OptData );
	DisplayMatrix( "F://Pipe.txt", 102, OptData );

	// 从pComManager中初始化OptData的 初始实际流量,管道长度,节点流量,配水源,控制点,
	// 先手动设置配水源和控制点
	int iTemp = 1;
	OptData.SetProperty( 0, 200, iTemp );          // 节点1为配水源
	iTemp = 6;
	OptData.SetProperty( 0, 201, iTemp );         // 节点10为控制点

	CMinimumSquareSum MinSquSum;

	//MinSquSum.InitializeFactFlux( *pComManager, OptData );   //  初始实际流量
	///////////////////////////////////////
	int i = 0;
	int iKeyOfPipe = 0;
	double Temp = 0.0;
    Temp = 0.03;
	OptData.SetProperty( 1, 1, Temp );
	OptData.SetProperty( 3, 1, Temp );
	OptData.SetProperty( 6, 1, Temp );
	OptData.SetProperty( 7, 1, Temp );
	Temp = 0.02;
	OptData.SetProperty( 2, 1, Temp );
	OptData.SetProperty( 4, 1, Temp );
	OptData.SetProperty( 5, 1, Temp );
	////////////////////////////////////////

	double dTemp = 0.0;
	Pipe* pPipe = NULL;
	Component* pComponent = NULL; 
	map< int, double > BeforeDiameterMap;                     // 存储了上一次计算的直径
	int iIteratorTime = 0;                                    // 迭代次数
	IteratorPtr<Component> PipeItPtr( pComManager->CreatPipeIterator() );
	for( PipeItPtr->Fist(); !PipeItPtr->IsDone(); PipeItPtr->Next() )
	{
		pComponent = &PipeItPtr->CurrentItem();
	    pPipe = dynamic_cast<Pipe*>( pComponent );
		dTemp = pPipe->Len();
		OptData.SetProperty( pPipe->GetKey(), 2, dTemp );    
		dTemp = pPipe->InDia();
		OptData.SetProperty( pPipe->GetKey(), 4, dTemp );
	}

	// 节点流量
	QuantityManager& qm = QuantityManager::Instance();
	CString strUnit = "";
	CString strValue = "";
	Jun* pJun = NULL;
	IteratorPtr<Component> JunItPtr( pComManager->CreatJunIterator() );
	for( JunItPtr->Fist(); !JunItPtr->IsDone(); JunItPtr->Next() )
	{
		pComponent = &JunItPtr->CurrentItem();
	    pJun = dynamic_cast<Jun*>( pComponent );	
		strUnit = pJun->ms_InitGuess.GetValue( 2 );                            // 获得单位
		strValue = pJun->ms_InitGuess.GetValue( 1 );
		TCHAR* pChar = NULL;
		qm.TransformToStd( dTemp, strUnit.GetBuffer( 32 ), _tcstod( strValue.GetBuffer( 32 ), &pChar ) ); // 转化成标准单位
		if( IDS_STRVOLUMEFLOW != _ttoi( pJun->ms_InitGuess.GetValue( 0 ).GetBuffer( 32 ) ) )            // 质量流量,要转化为体积流量
		{
			double dTempDensity = 0.0;
			NumFlyWeight *pDensity = &( ( pComManager->SysProperty().GetFuild() )->ms_Density );
			dTemp *= pDensity->GetNum();                                       // GetNum返回标准单位数
		}
		OptData.SetProperty( pJun->GetKey(), 3, dTemp );
	}

	////////////
	dTemp = 0.06;
	OptData.SetProperty( 1, 3, dTemp );
	dTemp = -0.06;
	OptData.SetProperty( 6, 3, dTemp );
	////////////


    // 初始化经济参数
	OptData.SetAModulus( 8.4 );
	OptData.SetBModulus( 107 );
	OptData.SetAlfaModulus( 1.6 );
	OptData.SetDisinvestmentTime( 1.0e3 );
	OptData.SetRepairModulus( 3.3 );
	OptData.SetEletricityPrice( 0.5 );
	OptData.SetAsymmetryModulus( 1.0 );
	OptData.SetPumpEfficiency( 0.7 );
	OptData.SetKModulus( 1.34e-10 );
	OptData.SetMModulus( 5.3 );
	OptData.SetNModulus( 2 );
	OptData.Initialization();
	
	BeforeDiameterMap.clear();
	iIteratorTime = 0;
	do
	{
	    // 初始化虚流量
	    MinSquSum.InitializeDummyFlux( *pComManager, OptData );

	    // 虚流量平差
	    CalEconomyDiameterAndWaterHarmer( *pComManager, 0.0001, 5000, OptData );

	    // 通过经济管径计算标准管径
	    FindStandardDiameter( OptData );

        // 实际流量平差
	    CalFactFlux( *pComManager, 0.0001, 5000, OptData );

	   // 迭代次数加一
		iIteratorTime++;
		
	}
	while( !DiameterIsEqual( OptData, BeforeDiameterMap ) && ( 5000 > iIteratorTime ) ); // 比较前后管径,不相等则跳到 初始化虚流量

	// 计算其他要素
    CalOthersVariable( *pComManager, OptData );

	// 输出结果
}
Exemplo n.º 5
0
BOOL CPFAOptimize::FindBaseCircle( ComponentManager& ComManager, Pipe& BasePipe, BaseCircleDirection Direction, ComMap& JunKeyMap, ComMap& PipeKeyMap, int iMostCircle[] )
{	
	//参数有效性判断
	ASSERT( NULL != &ComManager );
	ASSERT( NULL != &BasePipe );

	ComAndCloseComs JunAndCloseJuns;
	JunAndCenter CloseJuns;   // 记录节点和节点位置的Vector,形式如(节点编号,节点位置)
	Jun* pJun = NULL;
	Component* pJunComponent = NULL;
	Pipe* pPipe = NULL;
	Component* pPipeComponent = NULL;   
	Jun* pPreJun = NULL;
	Jun* pNextJun = NULL;
	Jun* pStartJun = NULL;
	Jun* pStartNextJun = NULL;

	// 图形的上、左、右、下四个顶点的位置,为确定最大环做准备
	int iTop = 2147483647;                       // 2的32次方减一
	int iLeft = 2147483647;
	int iRight = 0;
	int iBotton = 0;

	IteratorPtr<Component> JunItPtr( ComManager.CreatJunIterator() );

	// 把节点和与节点相连的节点信息都放入JunAndCloseJuns
	// 如节点1和节点3,4,5相连,则( 1, ( (3,节点3位置), (4,节点4位置), (5,节点5位置) ) )
	// 然后把管道和与管道相连的管道编号放入PipeAndClosePipes
	// 如管道1和管道3,4,5相连,则(1,(3,4,5))
	for( JunItPtr->Fist(); !JunItPtr->IsDone(); JunItPtr->Next() )
    {
		CloseJuns.clear();
		pJunComponent = &JunItPtr->CurrentItem();
    	pJun = dynamic_cast<Jun*>( pJunComponent );

		IteratorPtr<Component> PipeItPtr( ComManager.CreatPipeIterator() );
		for( PipeItPtr->Fist(); !PipeItPtr->IsDone(); PipeItPtr->Next() )
		{
			pPipeComponent = &PipeItPtr->CurrentItem();
	        pPipe = dynamic_cast<Pipe*>( pPipeComponent );
			if( pPipe->StartJun() == pJun->GetKey() )
			{	
				pair< int , CPoint > Temp( pPipe->EndJun(), pPipe->EndPt() );
				CloseJuns.push_back( Temp );
			}
			if( pPipe->EndJun() == pJun->GetKey() )	
			{
				pair< int , CPoint > Temp( pPipe->StartJun(), pPipe->StartPt() );
				CloseJuns.push_back( Temp );
			}
			if( pPipe->GetKey() == BasePipe.GetKey() )
			{
				if ( DEASIL_DIRECTION == Direction )
				{
					pPreJun = ComManager.LookUpJun( pPipe->StartJun() );
					pNextJun = ComManager.LookUpJun( pPipe->EndJun() );
				}
				else
				{
					pPreJun = ComManager.LookUpJun( pPipe->EndJun() );
					pNextJun = ComManager.LookUpJun( pPipe->StartJun() );
				}
			}
		}
		JunAndCloseJuns.insert( ComAndCloseComs::value_type( pJun->GetKey(), CloseJuns ) );

		// 确定四个顶点
		if( iTop > pJun->CenterPt().y )
		{
			iTop = pJun->CenterPt().y;
			iMostCircle[0] = pJun->GetKey();
		}
		if( iBotton < pJun->CenterPt().y )
		{
			iBotton = pJun->CenterPt().y;
			iMostCircle[1] = pJun->GetKey();
		}
		if( iLeft > pJun->CenterPt().x )
		{
			iLeft = pJun->CenterPt().x;
			iMostCircle[2] = pJun->GetKey();
		}
		if( iRight < pJun->CenterPt().x )
		{
			iRight = pJun->CenterPt().x;
			iMostCircle[3] = pJun->GetKey();
		}
	}

	JunItPtr->Fist();
	pJunComponent = &JunItPtr->CurrentItem();
    pJun = dynamic_cast<Jun*>( pJunComponent );
	CloseJuns.clear();
	ComAndCloseComs::iterator JunIt = JunAndCloseJuns.find( pJun->GetKey() );
	CopyVector( CloseJuns, JunIt->second );  
	
	// 寻找环—节点矩阵
	pStartJun = pPreJun;
	pStartNextJun = pNextJun;
	int iKeyOfChoiceJun = 0;                 // 用来标记哪个节点编号作为基环的下一节点编号
	JunKeyMap.push_back( pNextJun->GetKey() );
	BOOL bFirst = TRUE;
	while( ( pNextJun != pStartNextJun ) || ( pPreJun != pStartJun ) || bFirst )
	{
		bFirst = FALSE;
		FindJunOfCircle( *pPreJun, *pNextJun, JunAndCloseJuns, iKeyOfChoiceJun );
	    pPreJun = pNextJun;
		pNextJun = ComManager.LookUpJun( iKeyOfChoiceJun );
		JunKeyMap.push_back( pNextJun->GetKey() );
	}
	

	// 寻找环—管道矩阵
	ComMap::const_iterator JunKeyNextIterator = NULL;
	int iJunNextkey = 0;                        // 上面的环-节点矩阵中节点的编号, 下面的也一样
	int iJunPreKey = 0;
	map< int, int > PipeOrder;                             // (管道在环中的位置,管道编号)
	int iPipePosition = 0;                      // 管道在环中的位置
	IteratorPtr<Component> PipeItPtr( ComManager.CreatPipeIterator() );
	for( PipeItPtr->Fist(); !PipeItPtr->IsDone(); PipeItPtr->Next() )
	{
		pPipeComponent = &PipeItPtr->CurrentItem();
		pPipe = dynamic_cast<Pipe*>( pPipeComponent );
		JunKeyNextIterator = JunKeyMap.begin();
		iPipePosition = 0;
		iJunPreKey = *JunKeyNextIterator;
		JunKeyNextIterator++;
        for ( ; JunKeyNextIterator != JunKeyMap.end(); JunKeyNextIterator++ )
		{
			iJunNextkey = *JunKeyNextIterator;
			
			// 如果管道和环里的相邻节点相连,那么这根管道肯定是环里的管道
			if( ( ( pPipe->StartJun() == iJunPreKey ) && ( pPipe->EndJun() == iJunNextkey ) ))
			{
				PipeOrder.insert( map<int,int>::value_type( iPipePosition, pPipe->GetKey() ) );	
			}
			if( ( ( pPipe->EndJun() == iJunPreKey ) && ( pPipe->StartJun() == iJunNextkey ) ) )
			{
				int i = -1 * pPipe->GetKey();
                PipeOrder.insert( map<int,int>::value_type( iPipePosition, i ) );
			}
			iJunPreKey = iJunNextkey;
			iPipePosition++;
		}
	}
	
	// 把PipeOrder里的信息放入PipeKeyMap中
    // PipeOrder信息(管道在环中的位置,管道的编号)
	int iCountCircleJun = PipeOrder.size();
	int iPipeKey = 0;
	map< int, int >::iterator PipeIterator = NULL;
	for ( iPipePosition = 0, iPipeKey = 0; iPipePosition < iCountCircleJun; iPipePosition++ )
	{
		PipeIterator = PipeOrder.find( iPipePosition );
		if( PipeIterator == PipeOrder.end() )
		{
			break;
		}
		iPipeKey = PipeIterator->second;
		PipeKeyMap.push_back( iPipeKey );
	}

	return TRUE;
}
Exemplo n.º 6
0
// 最短路径,Dijkstra算法,网上抄的, 可能有点乱
bool CPFAOptimize::FindShortCut( ComponentManager& ComManager, const int& iKeyOfStartJun, const int& iKeyOfEndJun, vector< int >& JunToJunPipePath )
{
	map< int, vector< int > > AbutMatrix;           //图的邻接矩
	vector< int > MarkVector;                       //标记数组
	vector< int > DistanceVector;                   //距离数组
	vector< int > TempVector;                       //前缀节点
	vector< int > PipePathVector;                   //临时路径存放数组
	int iCountOfJun = ComManager.GetJunNum();
	int iCountOfPipe = ComManager.GetPipeNum();
	int iTemp = 0;
	int i = 0;
	int j = 0;
	int k = 0;
	int iMinDistance = 0;

	//读入数据
	Component *pComponent = NULL;
	Pipe *pPipe = NULL;
	int iStartJun = 0;
	int iEndJun = 0;
	IteratorPtr<Component> PipeItPtr( ComManager.CreatPipeIterator() );
	for( PipeItPtr->Fist(); !PipeItPtr->IsDone(); PipeItPtr->Next() )
    {
		pComponent = &PipeItPtr->CurrentItem();
	    pPipe = dynamic_cast<Pipe*>(pComponent);
		iStartJun = pPipe->StartJun();
		iEndJun = pPipe->EndJun();
		SetProperties( AbutMatrix, iStartJun, iEndJun, 1 );
		SetProperties( AbutMatrix, iEndJun, iStartJun, 1);
	}
	
    //赋初值	
	SetProperties( MarkVector, iKeyOfStartJun, 1 );
	SetProperties( TempVector, iKeyOfStartJun, 0 );
	for( i = 1; i <= iCountOfJun; i++ )
	{
		iTemp = GetProperties( AbutMatrix, 1, i );
		SetProperties( DistanceVector, i, iTemp );
		if( 0 < iTemp )
		{
			SetProperties( TempVector, i, 1 );
		}
	}

    //Dijkstra
	for( i = 0; i <= iCountOfJun; i++ )
	{
		//找到没有标号的最小dist下标
		iMinDistance = 32000;
		k = 0;
		for( j = 1; j <= iCountOfJun; j++ )
		{
			if( ( 0 == GetProperties( MarkVector, j ) ) && ( 0 < GetProperties( DistanceVector, j ) )
				&& ( iMinDistance > GetProperties( DistanceVector, j ) ) )
			{
				k = j;
				iMinDistance = GetProperties( DistanceVector, j );
			}
		}
		if( 0 == k )                                           //如果找不到就直接退出
		{
			break;
		}
		SetProperties( MarkVector, k, 1 );                      //标记

        //修改最短值和路径
		for( j = 1; j <= iCountOfJun; j++ )
		{
			if( ( 0 == GetProperties( MarkVector, j ) ) && ( 0 < GetProperties( AbutMatrix, k, j ) )
				&& ( ( 0 == GetProperties( DistanceVector, j ) ) 
				|| ( GetProperties( DistanceVector, k ) + GetProperties( AbutMatrix, k, j ) < GetProperties( DistanceVector, j ) ) ) )
			{
				iTemp = GetProperties( DistanceVector, k ) + GetProperties( AbutMatrix, k, j );
				SetProperties( DistanceVector, j, iTemp );
				SetProperties( TempVector, j, k );
			}
		}
	}
	
    //输出值和路径
	k = iKeyOfEndJun;
	i = 0;
	while( 0 < GetProperties( TempVector, k ) )
	{
		SetProperties( PipePathVector, i++, k );
		k = GetProperties( PipePathVector, k );
	}
	SetProperties( PipePathVector, i, 1 );

	// 根据节点把管道编号写进里,负号表示管道方向与前进方向相反
	JunToJunPipePath.clear();
	vector< int >::iterator IntVecIt = PipePathVector.begin();
	iStartJun = *IntVecIt;
	IntVecIt++;
	for( ; PipePathVector.end() != IntVecIt; IntVecIt++ )
	{
		iEndJun = *IntVecIt;
		for( PipeItPtr->Fist(); !PipeItPtr->IsDone(); PipeItPtr->Next() )
		{
			pComponent = &PipeItPtr->CurrentItem();
	        pPipe = dynamic_cast<Pipe*>(pComponent);
			if( ( pPipe->StartJun() == iStartJun ) && ( pPipe->EndJun() == iEndJun ) )
			{
				JunToJunPipePath.push_back( pPipe->GetKey() );
				break;
			}
			if( ( pPipe->StartJun() == iEndJun ) && ( pPipe->EndJun() == iStartJun ) )
			{
				JunToJunPipePath.push_back( -1 * pPipe->GetKey() );
				break;
			}
		}
		iStartJun = iEndJun;
	}
	return true;
}