舞蹈对算法(男性可与一个或多个女性共舞)

时间:2016-09-04 11:05:46

标签: java algorithm

我有一个问题: - 有男人和女人。男性可以与一个或多个女性共舞,也可以不与任何女性共舞。找到一对一的舞伴伴侣,这样: 1.男性舞伴与自己选择的女性配对 2.没有男女舞者独自留下

public class DancePair 
{ 

    public static int totalmatching(int input1,String[] input2)
    {
        //Write code here
        String[] words=new String[input1];
        String[] words2=new String[input1];
        int i,j;
        System.out.println(input1);

        for(i=0;i<input1;i++)
        {
            words=input2[i].split("\\#");
            for(j=1;j<words.length;j++)
            {
                for(k=i+1;k<input1;k++)
                {
                    words2=input2[k].split("\\#");
                    for(p=1;p<words2.length;p++)
                    {
                        if(words[j]==words2.[p])
                        {
                            p++;
                            continue;
                        }
                        else
                        {
                            words3=input2[k+1].split("\\#");

                        }
                    }
                }

            }

        }
        return 0;
    }
}

输入如下: - M1#W2#W4,M2#W1#W2,M3#W1#W3#W4,M4#W4#W5,M5#W4 OUTPUT应该为此i / p为1 我已经创建了这个代码,但我陷入了循环,无法继续。需要帮助

3 个答案:

答案 0 :(得分:1)

此问题是变体Maximum Matching。您需要在此二分图中找到最大匹配。唯一的区别是男人可以与多个女人共舞。因此,当您构建图形时,对于每个人,您会根据其程度放置多个节点。请考虑以下示例:

M1: W1, W2
M2: W3

您必须为M1添加2个节点:

M1: W1, W2
M1': W1, W2
M2: W3

现在您可以在此图表上运行最大匹配,它将为您提供所需的结果。

答案 1 :(得分:0)

我不太了解图论和算法,我使用回溯开发了我的算法。这是几百行代码。

override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
 if (segue.identifier == "categoryviewcontroller") {
        var VC2 : VC2 = segue.destinationViewController as VC2
 }
 if (segue.identifier == "productviewcontroller") {
    var VC2 : VC2 = segue.destinationViewController as VC2
 }
}

程序打印:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DancePair {

    public static void main(String[] args) {
        new DancePair();
    }

    public DancePair() {
        totalMatching("M1#W2#W4,M2#W1#W2,M3#W1#W3#W4,M4#W4#W5,M5#W4");
    }

    List<Choice> choices = new ArrayList<>();

    /** solution */
    Choice[] pairs;

    private void totalMatching(String input) {
        // expect m men and m women
        int m = parseInput(input);
        // build m couples
        solve(m);
    }

    private int parseInput(String input) {
        List<Dancer> men = new ArrayList<>();
        Map<String, Dancer> women = new HashMap<>();
        choices.clear();
        String[] choiceInput = input.split(",");
        for (String choicesAsString : choiceInput) {
            String[] dancerNames = choicesAsString.split("#");
            if (dancerNames.length < 2) {
                throw new IllegalArgumentException("No chosen women: " + choicesAsString);
            }
            Dancer man = new Dancer(dancerNames[0]);
            men.add(man);
            for (int ix = 1; ix < dancerNames.length; ix++) {
                Dancer woman = findDancer(women, dancerNames[ix]);
                choices.add(new Choice(man, woman));
            }
        }
        System.out.println("" + men.size() + " men: " + men);
        System.out.println("" + women.size() + " women: " + women.values());
        if (men.size() != women.size()) {
            throw new IllegalArgumentException("Error: not the same number of men and women");
        }
        return men.size();
    }

    private Dancer findDancer(Map<String, Dancer> dancers, String name) {
        Dancer result = dancers.get(name);
        if (result == null) {
            result = new Dancer(name);
            dancers.put(name, result);
        }
        return result;
    }

    /** @param m Number of pairs required for a solution */
    private void solve(int m) {
        pairs = new Choice[m];
        tryPair(0, 0);
    }

    /** try to fill pairs[pairsStart] and onward using choices from choices.get(choicesStart) and onward */
    private void tryPair(int pairsStart, int choicesStart) {
        if (pairsStart == pairs.length) { // array is full, we have reached a solution
            printSolution();
        } else if (choicesStart < choices.size()) { // still choices to try
            Choice ch = choices.get(choicesStart);
            // try with and without ch
            if (ch.isOpen()) {
                ch.pair();
                pairs[pairsStart] = ch;
                tryPair(pairsStart + 1, choicesStart + 1);
                ch.unpair();
            }
            tryPair(pairsStart, choicesStart + 1);
        }
    }

    private void printSolution() {
        System.out.println("Solution: " + Arrays.toString(pairs));
    }

}

为了理解代码,你仍然应该阅读一两个关于回溯的教程。我确信有性能优化的空间。该代码使用了几个辅助类。这是5 men: [M1, M2, M3, M4, M5] 5 women: [W1, W2, W3, W4, W5] Solution: [M1+W2, M2+W1, M3+W3, M4+W5, M5+W4] (也可以命名为Choice):

PossiblePariring

最后非常简单import java.util.Objects; /** the fact that femaleDancer is included in maleDancer’s women of choice */ public class Choice { final Dancer maleDancer; final Dancer femaleDancer; public Choice(Dancer maleDancer, Dancer femaleDancer) { Objects.requireNonNull(maleDancer); Objects.requireNonNull(femaleDancer); this.maleDancer = maleDancer; this.femaleDancer = femaleDancer; } /** can this man and woman be paired? */ boolean isOpen() { return ! maleDancer.isPaired() && ! femaleDancer.isPaired(); } public void pair() { if (! isOpen()) { throw new IllegalStateException("Already paired? " + maleDancer.isPaired() + ' ' + femaleDancer.isPaired()); } maleDancer.setPaired(true); femaleDancer.setPaired(true); } /** undo pair() */ public void unpair() { if (! (maleDancer.isPaired() && femaleDancer.isPaired())) { throw new IllegalStateException("Paired? " + maleDancer.isPaired() + ' ' + femaleDancer.isPaired()); } maleDancer.setPaired(false); femaleDancer.setPaired(false); } @Override public String toString() { return "" + maleDancer + '+' + femaleDancer; } }

Dancer

答案 2 :(得分:0)

二分图了解不多,但我能够使用简单的回溯解决方案来解决这个问题。

下面是工作的C#解决方案(任何人都可以轻松修改Java):
(首先将M1#W2#W4,M2#W1#W2,M3#W1#W3#W4,M4#W4#W5,M5#W4转换为0和1的2d数组

public static bool countPairsBT(int[,] map, int[] occupiedCol, int curCol, int[] count, int N, int[,] solMap)
            {
                if (curCol == N)
                {
                    count[0]++; // inc count becuz it's a solution
                    printSol(solMap, N); // print this solution
                    Console.WriteLine();
                    return true;
                }
                for (int j = 0; j < N; j++)
                {
                    if (map[curCol, j] == 1 && occupiedCol[j] == 0)
                    {
                        occupiedCol[j] = 1;
                        solMap[curCol, j] = 1;
                        countPairsBT(map, occupiedCol, curCol + 1, count, N, solMap);

                        occupiedCol[j] = 0; // BACKTRACK
                        solMap[curCol, j] = 0;
                    }
                }
                return false;
            }

            public static void printSol(int[,] map, int N)
            {
                for (int i = 0; i < N; i++)
                {
                    for (int j = 0; j < N; j++)
                    {
                        Console.Write(map[i,j]);
                    }
                    Console.WriteLine();
                }
            }

            static void Main(string[] args)
            {
                int[,] map =
                {
                    {1 ,0 ,0 ,1 ,1 },
                    {1 ,0 ,1 ,1 ,0 },
                    {0 ,0 ,1 ,0 ,1 },
                    {0 ,1 ,0 ,0 ,1 },
                    {1 ,0 ,0 ,0 ,1 }
                };


            int[] count = new int[1];
            int N = map.GetLength(0); // get N for NxN 2d array
            int[] occupiedCol = new int[N];
            int[,] solMap = new int[N, N];
            countPairsBT(map, occupiedCol, 0, count, N, solMap);
            Console.WriteLine(count[0]); //print count
            Console.ReadKey();
            }

<强>输出:

10000
00010
00100
01000
00001

00010
10000
00100
01000
00001

00010
00100
00001
01000
10000

00001
00010
00100
01000
10000

4