A partire da permutazioni e combinazioni , penso che siamo interessati alle combinazioni:
Per 30 argomenti, avresti il conteggio follower delle combinazioni per ogni dimensione:
(In altre parole ci sono 30 combinazioni di dimensioni 1 e 435 combinazioni di dimensione 2 (anche 435 di dimensioni 28 come risulta)).
- 30
- 435
- 4060
- 27405
- 142506
- 593.775
- 2035800
- 5852925
- 14307150
- 30045015
- 54627300
- 86493225
- 119759850
- 145422675
- 155117520
- 145422675
- 119759850
- 86493225
- 54627300
- 30045015
- 14307150
- 5852925
- 2035800
- 593.775
- 142506
- 27405
- 4060
- 435
- 30
- 1
Penso che potresti generare ognuna delle combinazioni per ciascuna dimensione della combinazione da 1 a 30. Puoi google "generare tutte le combinazioni" e, inoltre, ne ho allegato uno che ho montato sotto.
Per ogni dimensione di combinazione, potremmo trovare le combinazioni e trovarne le occorrenze tra gli studenti e ordinarle in base al loro conteggio. Potresti avere un taglio di interesse, mantenendo solo la parte superiore del% per ogni dimensione.
Possiamo memorizzare il punteggio di ogni studente con un bit. Quindi, per 30 argomenti, abbiamo bisogno di 30 bit per studente. Su una macchina a 64 bit, possiamo memorizzare fino a 64 bit in un singolo numero intero.
Possiamo rappresentare una combinazione anche come un intero, i cui bit sono impostati per rappresentare quali elementi sono nella combinazione. In altre parole, una combinazione di dimensione 6 è rappresentata da un intero che ha esattamente 6 dei suoi bit impostati.
Quindi, data una combinazione, possiamo testare ciascuno dei ~ 200 studenti per la corrispondenza con una semplice operazione AND bitwise logica seguita da un confronto.
for ( var i = 0; i < 200; i++ )
if ( (studentScores [i] & currentCombinaton) == currentCombination )
// this combination matched for this student.
NOTA come scritto questo sta controllando le combinazioni di successo e non le combinazioni di errori, ma questo è facilmente reversibile (usando == 0
invece di == currentCombination
).
Quindi, questo è un inizio.
Penso che potresti fare un'analisi delle combinazioni l'una rispetto all'altra, ad esempio quali combinazioni popolari di dimensione 4 o 5 si trovano nelle popolari combinazioni di dimensione 16.
Di seguito è riportato un programma C # che ho scritto che genera combinazioni di valori T / F come bit mask. Potresti inserire il generatore combinato in un ciclo di dimensioni e utilizzare il ciclo di occorrenze studente sopra per ciascuna di queste dimensioni.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication17
{
class Program
{
static ulong NextCombination ( int outOf, ulong last )
{
int i;
for ( i = 0; i < outOf; i++ )
{
if ( (last & (1UL << i)) != 0 )
break;
}
int j;
for ( j = i + 1; j < outOf; j++ )
{
if ( (last & (1UL << j)) == 0 )
break;
}
// we alter the number by removing all the consecutive ones
// that occur followed by a zero (viewed from low order to high order)
// as in ...0111...
// replace with a single 1
// as in ...1000... and set low bits to bits in a row, i.e.
// ...1000.....011
int numberOfOnesInARowBeforeFirstZero = j - i;
var onesMask = ((1UL << numberOfOnesInARowBeforeFirstZero) - 1) << i;
last &= ~onesMask; // clear the series of one's
last |= 1UL << j; // set the first zero bit after the ones in a row
var lowOnesReplacement = (1UL << (numberOfOnesInARowBeforeFirstZero - 1)) - 1;
last |= lowOnesReplacement; // set the lowest bits to make up for the cleared bits
return last;
}
static void Main ( string [] args )
{
int comboSize = 3;
int outOfSize = 30;
int count = 1;
ulong currentCombination = (1UL << comboSize) - 1;
ulong lastCombination = currentCombination << (outOfSize - comboSize);
System.Console.WriteLine ( "Last Combination for size " + comboSize + " is " + Convert.ToString ( (long) lastCombination, 2 ).PadLeft ( outOfSize, '0' ) );
for ( ;; )
{
System.Console.WriteLine ( "Combination " + count + " is " + Convert.ToString ( (long) currentCombination, 2 ).PadLeft ( outOfSize, '0' ) );
if ( currentCombination == lastCombination )
break;
currentCombination = NextCombination ( outOfSize, currentCombination );
count++;
}
System.Console.ReadLine ();
}
}
}