int* search(int* point, node* tree, int maxLeafsVisited, int pointDimensons)
{
	int i;
	int theBestPriorityIndex;
	int* result;
	double bestDistance;
	double rightDistance;
	double leftDistance;
	double* leftDistanceVector = NULL;
	double* rightDistanceVector = NULL;
	queue** queueArr;
	int queueCounter = 0;
	int queueIndexer = 0;
	int leafsVisited = 0;
	queue* queueItem;
	node* nodeToCheck;
	int queueSize = maxLeafsVisited*maxLeafsVisited;
	double theBestPriorityVal = 0;
	int queueIdx;
	nodeToCheck = NULL;
	double* distanceVector = NULL;
	double* zeroDistanceVector;
	double newBestDistance;

	zeroDistanceVector = (double*) malloc(pointDimensons * sizeof(double));

	for (i = 0; i < pointDimensons; i++)
	{
		zeroDistanceVector[i] = 0.0;
	}

	queueArr = (queue**) malloc (sizeof(queue*) * queueSize);
	bestDistance = 1000000000000000000000000000.0;
	result = (int*) malloc(pointDimensons * sizeof(int));

	for (i = 0; i < queueSize; i++ )
	{
		queueArr[i] = NULL;
	}
	
	// make initial node for the queue
	queueItem = (queue*) malloc(sizeof(queue));
	queueItem->nodeToCheck = tree;
	queueItem->priorityVal = 0.0;
	queueItem->distanceVector = (double*) malloc(pointDimensons * sizeof(double));
	memcpy(queueItem->distanceVector, zeroDistanceVector, pointDimensons * sizeof(double));

	queueArr[queueIndexer] = queueItem;
	queueIndexer++;
	queueCounter++;


	while( (queueCounter > 0) && (leafsVisited < maxLeafsVisited))
	{
		//take the node from the queue with the lowest priorityVal value
		theBestPriorityVal = bestDistance;
		theBestPriorityIndex = -1;
		// search for lowest value
		for (i = 0; i < queueIndexer; i++ )
		{
			if (queueArr[i] != NULL)
			{
				if (queueArr[i]->priorityVal <= theBestPriorityVal )
				{
					theBestPriorityVal = queueArr[i]->priorityVal;
					nodeToCheck = queueArr[i]->nodeToCheck;
					distanceVector = queueArr[i]->distanceVector;
					theBestPriorityIndex = i;
				}
			}
		}

		// all points with the possible smallest distances checked -> interrupt the loop 
		if (theBestPriorityIndex == -1)
		{
			break;
		}


		if (nodeToCheck->isLeaf)
		{
			// TO DO calculation of the best distance and winner leaf
			newBestDistance = getDistance(point, nodeToCheck->leafVector, pointDimensons);
			
			if (bestDistance > newBestDistance)
			{
				bestDistance = newBestDistance;
				memcpy(result, nodeToCheck->leafVector, pointDimensons * sizeof(int));

			}

			leafsVisited++;
		}
		else
		{
			// put the branches of the node into the queue

			leftDistanceVector = (double*) malloc(pointDimensons * sizeof(double));
			rightDistanceVector = (double*) malloc(pointDimensons * sizeof(double));
			
			// check the distance - decide where to go
			if(nodeToCheck->dimVal > ((double)point[nodeToCheck->dimNumber]))
			{
				// go left branch
				leftDistance = 0.0;
				memcpy(leftDistanceVector, distanceVector, pointDimensons * sizeof(double));

				//---------------
				memcpy(rightDistanceVector, distanceVector, pointDimensons * sizeof(double));
				
				if (nodeToCheck->right->isLeaf)
				{
					rightDistance = 0.0;
				}
				else
				{
					rightDistance = getVectorSum(rightDistanceVector, pointDimensons);
					rightDistanceVector[nodeToCheck->dimNumber] = (((double)point[nodeToCheck->dimNumber]) - nodeToCheck->dimVal) * (((double)point[nodeToCheck->dimNumber]) - nodeToCheck->dimVal);
				}
			}
			else
			{
				// go right branch
				memcpy(leftDistanceVector, distanceVector, pointDimensons * sizeof(double));
				
				if (nodeToCheck->left->isLeaf)
				{
					leftDistance = 0.0;
				}
				else
				{
					leftDistance = getVectorSum(leftDistanceVector, pointDimensons);
					leftDistanceVector[nodeToCheck->dimNumber] = (((double)point[nodeToCheck->dimNumber]) - nodeToCheck->dimVal) * (((double)point[nodeToCheck->dimNumber]) - nodeToCheck->dimVal);
				}

				//---------------
				rightDistance = 0.0;
				memcpy(rightDistanceVector, distanceVector, pointDimensons * sizeof(double));

			}
		
			// add two nodes to priority queue
			queue* leftNodeQueueItem = (queue*) malloc(sizeof(queue));
			queue* rightNodeQueueItem = (queue*) malloc(sizeof(queue));
			
			leftNodeQueueItem->nodeToCheck = nodeToCheck->left;
			leftNodeQueueItem->priorityVal = leftDistance;
			leftNodeQueueItem->distanceVector = leftDistanceVector;

			queueArr[queueIndexer] = leftNodeQueueItem;
			queueIndexer++;
			queueCounter++;

			rightNodeQueueItem->nodeToCheck = nodeToCheck->right;
			rightNodeQueueItem->priorityVal = rightDistance;
			rightNodeQueueItem->distanceVector = rightDistanceVector;

			queueArr[queueIndexer] = rightNodeQueueItem;
			queueIndexer++;
			queueCounter++;
		}

		queueItem = queueArr[theBestPriorityIndex];
		queueArr[theBestPriorityIndex] = NULL;
		free(queueItem);

		queueCounter--;
	}

	free(queueArr);
//	free(queueItem);
	return result;
}
Пример #2
0
void NeuralNetwork::predict(int times){


    sourceKeys   = reader->getKeys();
    sourceValues = reader->getValues();

    switch ( seriesType ) {

        case ( WITHOUT_SEASONAL_VARIATON ) : {

        vector<int> keys;
        for (unsigned int i=1;i<=sourceKeys.size();i++)
            keys.push_back(i);

        vector<double> keysMulValues;
        vector<int> keysPow2;
        for(unsigned int i=0;i<keys.size();i++) {
            keysMulValues.push_back(keys[i] * sourceValues[i]);
            keysPow2.push_back(keys[i] * keys[i]);
        }

        //coefficients
        double a = (getVectorSum(keysMulValues) - (getVectorSum(keys) * getVectorSum(sourceValues)) / sourceValues.size()) / (getVectorSum(keysPow2) - pow(getVectorSum(keys), 2) / sourceValues.size());
        double b = getVectorSum(sourceValues) / sourceValues.size() - a * (getVectorSum(keys)) / sourceValues.size();

        /*
            //calculation of the average relative error
            vector<double> avarageErrorValues;
            for (int i=0; i<keys.size(); i++)
                avarageErrorValues.push_back( (fabs(sourceValues[i] - (a * keys[i] + b)) / sourceValues[i]) * 100 );
            cout << "prediction error=" <<getVectorSum(avarageErrorValues)/sourceValues.size() <<"%" <<endl;
        */

        for(int i=0;i<times;i++) {
            //calculated (smoothed) value for the series
            keys.push_back(keys[keys.size() - 1] + 1);
            resultValues.push_back(a * keys[keys.size() - 1] + b);
        }

        break;

        }
        case (WITH_SEASONAL_VARIATON) : {
            int seasons = sourceValues.size() / partsInSeason;
            int seasSumAmnt = seasons * partsInSeason - partsInSeason + 1;

            double seasonSum [seasSumAmnt];
            double seasonAver[seasSumAmnt];

            for (int i = 0; i < seasSumAmnt; ++i)
            {
                seasonSum[i] = 0;

                for (int j = i; j < i + seasons; ++j)
                {
                    seasonSum[i] += sourceValues[j];
                }
                std::cout << "\nseas sum " << seasonSum[i];
            }

            for (int i = 0; i < seasSumAmnt; ++i)
            {
                seasonAver[i] = seasonSum[i] / seasons;
                std::cout << "\nseas aver " << seasonAver[i];
            }

            double centeredAver[seasSumAmnt-1];

            for (int i = 0; i < seasSumAmnt-1; ++i)
            {
                 centeredAver[i] = (seasonAver[i] + seasonAver[i+1]) / 2.0;
                 std::cout << "\ncenter sum " << centeredAver[i];
            }

            double seasMark[seasSumAmnt-1];
            double temp     [seasSumAmnt-1];

            int indexes = seasons * partsInSeason - partsInSeason;

            for (int i = 0 ; i < indexes; ++i)
            {
                temp[i] = sourceValues[i+partsInSeason/2] / centeredAver[i];
            }

            for (int i = 0; i < partsInSeason/2; ++i)
            {
                seasMark[i] = temp[(seasons-1)*partsInSeason- partsInSeason/2 +i];
            }

            for (int i = partsInSeason/2; i < indexes; ++i)
            {
                seasMark[i] = temp[i - partsInSeason/2];
            }

            double partIndexes[partsInSeason];

            for (int i = 0; i < partsInSeason; ++i)
            {
                partIndexes[i] = 0;

                for (int j = 0; j < seasons-1; ++j)
                {
                    partIndexes[i] += seasMark[partsInSeason*j + i];
                }

                partIndexes[i] /= seasons-1;
                partIndexes[i] *= (0.8 + (random()%4)/10.0);

                 std :: cout << partIndexes[i] << std::endl;
            }

            double Yx = 0, sumX= 0, xq= 0, Y= 0;

            std::cout << "size=" << sourceValues.size();

            for (unsigned int i = 1 ; i <= sourceValues.size(); ++i ) {
                Yx 	 += i * sourceValues[i-1];
                std :: cout << i * sourceValues[i-1] << '\n';
                sumX += i;
                xq   += i * i;
                Y += sourceValues[i-1];
            }

            std :: cout << " Yx  == " << Yx << std::endl;
            std::cout << " sum x " << sumX << std::endl;
            std::cout << "xQ =  " << xq << std::endl;
            std::cout << "Y == " << Y << std::endl;


            double a = 0, b = 0;

            a = -(Yx - (sumX*Y)/sourceValues.size())/(xq - (sumX * sumX)/sourceValues.size());

            std::cout << std::endl << a << '\n';

            b = Y/sourceValues.size() - a*sumX/sourceValues.size();

            std::cout << std::endl << b << '\n';



            for (unsigned int i = sourceValues.size(); i < sourceValues.size() + times; i++) {
                resultKeys  .push_back(sourceKeys[i%sourceValues.size()]);
                resultValues.push_back((a*i+b)*partIndexes[i%partsInSeason]);
            }

            double sum = 0;
            int counter = 0;

           for (int i = 0; i < resultKeys.size(); ++i)
            {
               std::cout << resultKeys[i] << "  " << resultValues[i] << std::endl;

                counter++;
               sum += resultValues[i];

                if (counter == partsInSeason) {
                    std::cout << "\nTotal : " << sum <<"\n\n";
                    counter = 0;
                    sum = 0;
                }

            }


            break;
        }
    }

}