설명
영화 별점을 메기는 사람마다 quality level을 결정하고 평균 값을 score로 사용한다.
알고리즘은 사람의 신뢰도가 수렴할때까지 수행된다.
신뢰도에대한 알고리즘의 수식은 다음과 같다.
rating score는 다음과 같다.
코드
{.cpp}
// ConsoleApplication24.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//
#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include<string.h>
#include<cmath>
using namespace std;
//main함수로부터의 도표를 읽어들여 값을 대입해주는 함수 readChart.
void readChart(int** pDataset, int voter, int election)
{
//초기화된 배열에 원하는값을 넣어준다.
for (int i = 0; i < election; i++)
{
for (int j = 0; j < voter; j++)
{
cin >> pDataset[i][j];
//chart[i] = new int[voter];
//memset(chart[i], 0, 4 * voter);
}
}
}
//정답만 바로 궁금하다면 사용해줄 함수 readmacro.
void readmacro(int** pDataset)
{
//초기화된 배열에 원하는값을 넣어준다.
pDataset[0][0] = 1;
pDataset[0][1] = 1;
pDataset[0][2] = 1;
pDataset[0][3] = 2;
pDataset[0][4] = 2;
pDataset[1][0] = 1;
pDataset[1][1] = 2;
pDataset[1][2] = 2;
pDataset[1][3] = 3;
pDataset[1][4] = 2;
pDataset[2][0] = 3;
pDataset[2][1] = 4;
pDataset[2][2] = 4;
pDataset[2][3] = 4;
pDataset[2][4] = 2;
pDataset[3][0] = 1;
pDataset[3][1] = 3;
pDataset[3][2] = 3;
pDataset[3][3] = 3;
pDataset[3][4] = 1;
pDataset[4][0] = 2;
pDataset[4][1] = 2;
pDataset[4][2] = 2;
pDataset[4][3] = 1;
pDataset[4][4] = 1;
pDataset[5][0] = 1;
pDataset[5][1] = 2;
pDataset[5][2] = 2;
pDataset[5][3] = 1;
pDataset[5][4] = 1;
}
//*T를 초기화하는 함수를 통하여 초기화. 일단 모든사람의 신뢰값으로 1을 준다.
void firstinitial(double* T, int voter)
{
for (int i = 0; i < voter; i++)
T[i] = 1;
}
//식2를 구현하는 함수 만들기
void modify2(double **rho, int** pDataset, int election, int item, int voter)
{
//해당작품의 해당점수를 선택한 사람들의 신뢰도의 합 구하기
//voter의값을 이용하기 위해 voter2 정의
int voter2 = voter;
for (int a = 0; a < election; a++)
{
//여기서부터 rho의 j열 i행에 어떠한 수가 들어갈지를 계산하여 준다.즉 식 (2)의 구현을 나타낸다.
//일단 식 2에서 분모의 계산을 해보겠다.
//1점을 고른 사람들의 신뢰도의 합을 c[1],2점을 고른 사람들의 신뢰도합을 c[2]...이런식으로 알고리즘을 구성하겠다.
//점수n의 사람에대한 신뢰도의합 c[n]으로 나타냄.
int squresum = 0;
double squreroot = 0;
int c[5];
c[0] = 0; c[1] = 0; c[2] = 0; c[3] = 0; c[4] = 0;
for (int l = 0; l < voter; l++)
{
for (int m = 0; m < 5; m++)
{
if (pDataset[a][l] == m + 1)
c[m] = c[m] + 1;
}
}
//제곱의 합을 더한후에 루트를 씌운다.
for (int n = 0; n < item; n++)
squresum = squresum + c[n] * c[n];
squreroot = sqrt(squresum);
for (int o = 0; o < item; o++)
{
rho[o][a] = c[o] / squreroot;
}
}
cout << endl << "<2nd answer>" << endl;
for (int a = 0; a < item; a++)
{
for (int j = 0; j < election; j++)
{
//소수점 두자리까지만 출력하여 간편히 보기위하여 다음과같은 설정을 만족하자.
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(2);
cout << rho[a][j] << "\t";
//chart[i] = new int[voter];
//memset(chart[i], 0, 4 * voter);
}
cout << endl;
}
}
int main()
{
cout << "<Iterative Method for Calculating Robust Rating Scores>\n*press keybord <anything+enter> ->answer of work.\n*press keybord <0+enter> ->change election and voter\n";
long double epsil;
long double ee;
int voter = 5;
int election = 6;
int sel;
cin >> sel;
int item = 5;
//동적할당 방식을 이용.new int[n] n숫자만큼의 배열을 할당시켜줌.
//pDataset 라는 포인터로 이중배열을 가리킴
int** pDataset = new int*[election];
//메모리 공간을 memset이라는 함수를 이용하여초기화
//루프를 지날수록 차트의행이 증가
for (int i = 0; i < election; i++)
{
pDataset[i] = new int[voter];
memset(pDataset[i], 0, 4 * voter);
}
//readchart에 voter와 election값을 같이 달아주는 이유는 도표를 읽는함수를 main함수로 return하기 위해서이다.(이차원은 길이가 동일해야한다.)
readmacro(pDataset);
if (sel == 0)
{
cout << "<number of voter>" << endl;
cin >> voter;
cout << "<number of election>" << endl;
cin >> election;
cout << "<item for election>" << endl;
readChart(pDataset, voter, election);
}
cout << endl << "<1st answer>" << endl;
for (int i = 0; i < election; i++)
{
for (int j = 0; j < voter; j++)
{
cout << pDataset[i][j] << "\t";
if (pDataset[i][j] > 5)
{
cout << endl << "You can have score maximum 5!!!";
return 0;
}
//chart[i] = new int[voter];
//memset(chart[i], 0, 4 * voter);
}
cout << endl;
}
double* T = new double[voter];
//*T를 초기화하는 함수를 통하여 초기화
firstinitial(T, voter);
//2차원 로우li를 담는 함수 rho 선언및 초기화
double** rho = new double*[item];
for (int i = 0; i < item; i++)
{
rho[i] = new double[election];
memset(rho[i], 0, 8 * election);
}
double** rho2 = new double*[item];
for (int i = 0; i < item; i++)
{
rho2[i] = new double[election];
memset(rho[i], 0, 8 * election);
}
//수식2를 계산하는 함수에 rho를 대입
modify2(rho, pDataset, election, item, voter);
epsil = 0;
ee = 0;
long double epsil2;
cout << endl;
///////////////////////////////////////////////////////////////////////////////
for (int p = 0; p < 20; p++)
{
for (int i = 0; i < voter; i++)
{
T[i] = 0;
}
//main함수에서 수식 3번함수 구현하기.
for (int i = 0; i < voter; i++)
{
for (int j = 0; j < election; j++)
{
//작품에 대하여 voter가 선택한 점수를 selectitem으로 선언
int selectitem = pDataset[j][i] - 1;
//T[i]에는 작품에 해당하는 점수의 신뢰도의 합이 들어있다.
T[i] = T[i] + rho[selectitem][j];
}
}
for (int a = 0; a < election; a++)
{
//여기서부터 rho의 j열 i행에 어떠한 수가 들어갈지를 계산하여 준다.즉 식 (2)의 구현을 나타낸다.
//일단 식 2에서 분모의 계산을 해보겠다.
//1점을 고른 사람들의 신뢰도의 합의제곱을 c[0],2점을 고른 사람들의 신뢰도합을 c[1]...이런식으로 알고리즘을 구성하겠다.
//점수n의 사람에대한 신뢰도의합 c[n]으로 나타냄. 즉 4번식의 분자에서 제곱안에 있는수를 의미한다.
double squresum = 0;
double squreroot = 0;
int c[5];
c[0] = 0; c[1] = 0; c[2] = 0; c[3] = 0; c[4] = 0;
//a가 작품,l은 사람, m 은 점수를 의미한다.
for (int l = 0; l < voter; l++)
{
for (int m = 0; m < 5; m++)
{
//a번째 작품에서 l번째 사람의 점수가 내가 구하고자하는점수일때 그사람의 신뢰도의 제곱을 c[m]에 제곱하여 더해준다.
if (pDataset[a][l] == m + 1)
c[m] = c[m] + T[l] * T[l];
}
}
//제곱의 합을 더한후에 루트를 씌운다.
for (int n = 0; n < item; n++)
{
squresum = squresum + c[n] * c[n];
}
squreroot = sqrt(squresum);
for (int o = 0; o < item; o++)
{
rho2[o][a] = c[o] / squreroot;
}
}
//입실론값을 구하기위하여 차의 제곱의 합의 루트을 구해준다.
epsil2 = epsil;
for (int a = 0; a < item; a++)
{
for (int j = 0; j < election; j++)
{
ee = rho2[a][j] - rho[a][j];
ee = ee*ee;
epsil = epsil + ee;
}
}
epsil = sqrt(epsil);
for (int a = 0; a < item; a++)
{
for (int j = 0; j < election; j++)
{
rho[a][j] = rho2[a][j];
}
}
//epsil - epsil2를 해준 이유는 epsil의 값에 대한 0의 초기화가 함수 4에대한 loop밖에 있으므로 그때그때 빼주어야한다.
if (epsil - epsil2 < 0.0001)
{
cout << endl << "<3rd answer>" << endl;
for (int a = 0; a < item; a++)
{
for (int j = 0; j < election; j++)
{
//소수점 두자리까지만 출력하여 간편히 보기위하여 다음과같은 설정을 만족하자.
cout << rho[a][j] << "\t";
//chart[i] = new int[voter];
//memset(chart[i], 0, 4 * voter);
}
cout << endl;
}
cout.precision(10);
cout << endl << "epsilon : " << epsil - epsil2 << endl << "counted loop:" << p;
break;
}
}//chart[i] = new int[voter];
//memset(chart[i], 0, 4 * voter);
//listpi 함수를 정의하겠다.
double* listpi = new double[election];
for (int l = 0; l < election; l++)
{
double denom = 0; //분모값을 denom으로 선언
double numer = 0;
listpi[l] = 0;
//분모
for (int i = 0; i < 5; i++)
{//squreroot변수*변수 가 변수^1.5임을 이용
double result1 = sqrt(rho[i][l])*rho[i][l];
denom = denom + result1;
}
//분자
for (int i = 0; i < 5; i++)
{
double result2 = sqrt(rho[i][l])*rho[i][l] * (i + 1);
numer = numer + result2;
}
listpi[l] = numer / denom;
}
cout << endl << endl << "<4th answer>\n";
cout.precision(5);
for (int i = 0; i < election; i++)
{
cout << "Rating score " << i + 1 << " election is:" << listpi[i] << endl;
}
}
결과
'언어 > CPP(cpp)' 카테고리의 다른 글
sort,structure(구조체) (0) | 2017.12.25 |
---|---|
array(배열) (0) | 2017.12.25 |
assert,debug,driver,stub,중단점,디버그,조사식 (0) | 2017.12.25 |
트러블 슈팅 <“현재 코드 페이지(949)에서 표시할 수 없는 문자가 파일에 들어 있습니다. 데이터가 손실되지 않게 하려면 해당 파일을 유니코드 형식으로 저장하십시오.”>_한글인식오류_ (0) | 2017.12.25 |
트러블 슈팅“현재 코드 페이지(949)에서 표시할 수 없는 문자가 파일에 들어있습니다. 데이터가 손실되지 않게 하려면 해당파일을 유니코드 형식으로 저장하십시오.” (0) | 2017.12.25 |