0

これは、純粋にアルゴリズムの観点から始まった質問の 3 回目の反復であり、私が理解できるコード サンプルを見つけるという必死の使命に変わりました。

私がやろうとしているのは、可能な限り多くの好みを満たすために、人々のリストのgグループを作成することです。各人は、割り当てを希望するリストの上位n人の他の人のリストをランク付けしていません。それ(私のプログラム)は、相互のリクエストを一方向よりも影響力があると見なす必要があり、(うまくいけば)最適なソリューションに近いものを見つける必要があります。

必要なアルゴリズムを理解し、プログラムを作成できるように、ある種のコード サンプル (実際には、C ベースの言語または詳細な疑似コード) が必要です。最初の質問の後、これにはおそらく安定した結婚問題の何らかの変形が必要になると判断しましたが、疑似コードまたは私が理解できる実際の言語で完全な例を見つけることができませんでした.

アルゴリズムHEREおよびHEREについて以前に質問しましたが、何も思いつきませんでした (これらの SE フォーラムのユーザー数が非常に少ないためだと思います)。今、私はここで質問をしています.プログラミング指向の質問と相まって、はるかに高い視聴率が私に答えをもたらすことを願っています.

はい、このような質問が以前にも寄せられたことは承知していますが、該当するものも答えられるものもありません。

誰も私がこれを行う方法を知っていますか?

詳細を追加するには (コメントに応じて): 人のリストがあります。各人について、メイン リストに他の人だけを含む、他の人の上位の好みのリストがあります。どのような方法でもリストはソートされません。優先リストの名前は、要求者が要求された人物と一緒にいたいことを意味します。指定された数のグループを作成する方法を探しています。各グループには、メイン リストにある人だけが含まれています。グループ化に優先リストを組み込みたい。リストでお互いに要求している場合は、同じグループに入れようとする必要があります。また、ある人 (この例では A さん) が他の人 (B さん) をリクエストし、B は A をリクエストしないというリクエストも組み込む必要があります。この場合、リクエストはカウントする必要がありますが、

編集: 繰り返しますが、要求に応じて、(うまくいけば) 私の目標を説明するのに役立つ JS 関数を次に示します。

/*
Scores a possible grouping
group would be an object, where the keys are names and the values are arrays of preferences. Ex:

    {
        "Person 1": ["Person 2"],
        "Person 2": ["Person 1"],
        "Person 3": ["Person 4"],
        "Person 4": ["Person 2"]
    }

*/
function getGroupScore(group) {
    var totalPoints = 0;

    //Add a point for each request
    for (var person in group) {
        for (var request in group[person]) {
            if(request != undefined && request.length > 0)
                totalPoints++;
        }
    }

    //Add two points for each two-way request
    for (var person in group) {
        for (var request in group[person]) {
            if (group[person][request] != undefined //String validation
                && group[person][request].length > 0 //More string validation
                && group[group[person][request]] != undefined //Array validation
                && group[group[person][request]].indexOf(person) != -1) //Check mutual request
                    totalPoints += 2;
        }
    }

    return totalPoints;
}

/*
Compares two possble groupings
*/
function compareGroups(groupA, groupB) {
    var scoreA = getGroupScore(groupA),
        scoreB = getGroupScore(groupB);

    if (scoreA > scoreB)
        return 1;
    else if (scoreA == ScoreB)
        return 0;
    else
        return -1;
}
4

1 に答える 1

2

OK、私はあなたの問題について考えてきました。完全に解決することはできませんが、方向性を示すことができると思います.

最初に、あなたの質問を少し言い換えてみます。間違っている場合は修正してください。

P 人のセットと、次のような好みのテーブルがあるとします。

ABCDという名前の4人の好み:
   あいうえお
 +---------+
あ| XX |
ビ| X |
C| XX |
D| X |
 +---------+

この例では、'A' は 'C' を好み、'B' は 'D' を好みます。対角線が自分自身を好むかどうかは重要ではありません。

ここでの問題は、P=G*N と仮定して、P 人をサイズ N の G 個の異なるセットに分割することです。N=2 の例:

  ACBD
 +--------|
A|xx| | |
C| x| x|
 +----+----
ビ| | | x|
D| |× |
 +---+---+
ここで、パーティションは {A, C} と {B, D} です。

分割が満たされる度合いは、対角ブロック内の X の数の合計であり、上記の例では 3+2=5 です。

私の知る限り、あなたが解決しようとしているものに最も似ている問題は、ブロック対角行列を構築するか、できるだけ近いものにすることです。あなたの場合、対角ブロックの外側の値はあなたに対してカウントされません。

問題を力ずくで解決すると、P!/N! が発生します。チェックするパーティション。P の値が小さく、N の値が大きい場合、これを直接実装する価値があるかもしれませんが、JS で実行すると問題が発生します。ソリューションが最適な結果でなければならない場合は、このような方法に頼る必要があるかもしれません.

「かなり良い」ソリューションを許可できる場合は、ランダム化されたアプローチがおそらく近づくでしょう。再配置が役に立たなくなるまで貪欲な再配置を行い、このプロセスを数回繰り返します。

また、別のフォーラムでこのスレッドを見つけました。これに関連する問題のほとんどは、すべての好みが満たされるソリューションが存在することを前提としており、それは幅優先探索に帰着します。明らかにそれが正しい場合、結果は最適なソリューションになりますが、一般的にはそうではないため、既知のアルゴリズムを変更するには、おそらくかなりの研究を行う必要があります。

よろしくお願いします〜

于 2013-09-26T03:12:08.743 に答える