2011-04-18 2 views
2

나는 평가자가 뭔가를 평가할 수있게 해주는 코드를 작성 중입니다. 평가가 이루어지기 전에 제출 된 항목을 무작위로 추출해야합니다. 그 부분은 오히려 간단합니다.동일한 개수의 랜덤 한 쌍이

나를 괴롭히는 부분은 각 항목을 두 명의 다른 평가자가 평가해야하며 각 평가자가 수행하는 최종 평가 수가 가능한 한 고르게 배분되어야한다는 요구 사항입니다.

예 : 10 개의 항목이있는 경우 20 개의 평가 (항목 당 2 개의 평가)가 나와야합니다. 평가자를 4 명으로 나눈 20 명을 평가자 당 5 명으로 나눕니다. 분명히 숫자가 항상이 깨끗한 것으로 나오지는 않을 것입니다 (11 개 항목은 평가자 당 5 개, 나머지 2 개는 모든 사람이 퇴장 한 후에 상단에 지정됩니다).

일부 알고리즘 도움말을 찾고 있습니다. 내가 가장 가까웠 던 종소리는 내가 좋아할 것보다 더 많은 벨 커브가되었다.

답변

1

나를 위해 그것은 모든 평가자가 자신의 평등을 달성하거나 최대한 가깝도록 N 관리자들 사이에 N 항목의 2N 평가를 배포해야하는 것처럼 보입니다.

정체성이있다 : 그 목적을 위해 사용할 수 있습니다

2N = ceil(2N/M) + ceil((2N-1)/M) + ... + ceil((2N-M+1)/M) 

. ceil 여기에 가장 가까운 비 작은 정수 : CEIL (2.3) = 3, 천장을 만들다 (4) = 4

당신을 위해 당신이해야합니다 11 개 항목의 예 (22) = 5 + 5 + 4 + 4 + 4

어떻게 작동합니까? 내가 크 누스, Patashnik에 의해 "콘크리트 수학"을 참조 할 & 그레이엄 설명 : 내가 Anttis '접근과 "콘크리트 수학"에 설명 된 코딩 한

에 대한 제 3 장, 제 4 부 :

public static void main(String[] args) { 
    wayOne(5, 7); 
    System.out.println("======"); 
    wayTwo(5, 7); 
} 

private static void wayOne(int assessors, int items) { 
    Integer assessments[][] = new Integer[2][items]; 
    int assessor = 0; 
    for (int pass = 0; pass < 2; pass++) { 
     for (int item = 0; item < items; item++) { 
      while (assessments[pass][item] != null) 
       assessor = (assessor + 1) % assessors; 
      assessments[pass][item] = assessor; 
      assessor = (assessor + 1) % assessors; 
     } 
    } 

    for (int pass = 0; pass < assessments.length; pass++) { 
     for (int item = 0; item < assessments[pass].length; item++) 
      System.out.println("Pass " + pass + " item " + item + " is assessed by " + assessments[pass][item]); 
    } 
} 


private static void wayTwo(int assessors, int items) { 
    Integer distribution[][] = new Integer[2][items]; 
    int assessments = 2 * items; 
    int step = 0, prevBatch = 0; 
    while (assessments > 0) { 
     int batch = (int) Math.ceil((2.0 * items - step)/assessors); 
     assessments -= batch; 
     for (int i = prevBatch; i < batch + prevBatch; i++) { 
      distribution[i/items][i % items] = i % assessors; 
     } 
     prevBatch += batch; 
     step++; 
    } 

    for (int pass = 0; pass < distribution.length; pass++) { 
     for (int item = 0; item < distribution[pass].length; item++) 
      System.out.println("Pass " + pass + " item " + item + " is assessed by " + distribution[pass][item]); 
    } 
} 

내가 맞으면 두 번째 방법으로 원하는 결과물을 얻을 수 있습니다. 예를 들어, 7 개 항목과 5 명의 평가자를 위해 시도하십시오. 또는 11 개 항목 및 4 명의 평가자.

업데이트 Antti가 지적한 버그가 수정 된 후 두 개의 루틴에서 동일한 결과가 나타납니다.

+0

예. 알고리즘 구현에 버그가 있습니다. 전체적으로 다른 알고리즘과 확실히 나쁜 성능으로 이끄는 패스 사이에 평가자 지수를 재설정합니다! 할당 감정가 = 0은 내 코드에서 루프를 벗어납니다! :) 그것은 반복을 반복하기 전에 속합니다. 당신이 나쁜 결과를 얻는 것은 놀라운 일이 아닙니다. –

+0

@antti 이것을 지적 해 주셔서 감사합니다! 대답을 업데이트했습니다. –

+0

알고리즘의 버그가 여전히 있습니다 :'while (assessment [pass] [item]! = null)'줄에서'pass'의 현재 값뿐만 아니라 모든 패스에 대해 이것을 검사해야합니다. –

2

어렵지 않습니다. 접근 자와 항목이 있다고 가정 해 보겠습니다.

a = 0 
for 0 <= r < 2: 
    for 0 <= i < I: 
    while (assessor a is already assessing item i): 
     a = (a + 1) mod A 
    assessor a will assess item i on round r 
    a = (a + 1) mod A 

이 단순히 라운드 로빈 방식으로 평가자를 할당하지만, 같은 평가자가 두 번 같은 항목을 평가하는 것이다 이러한 경우를 건너 것 : 그냥 (모든 제로 기반 색인입니다) 다음 루프를 실행합니다.