Java 舞伴算法(男性可以与一个或多个女性跳舞)

Java 舞伴算法(男性可以与一个或多个女性跳舞),java,algorithm,Java,Algorithm,我有一个问题:- 有m个男人和m个女人。男性可以与一个或多个女性跳舞,也可以不与任何女性跳舞。找到一对一的舞伴,以便: 1.男舞伴与他选择的女性配对 2.没有男性或女性舞者被单独留下 public class DancePair { public static int totalmatching(int input1,String[] input2) { //Write code here String[] words=new String[

我有一个问题:- 有m个男人和m个女人。男性可以与一个或多个女性跳舞,也可以不与任何女性跳舞。找到一对一的舞伴,以便: 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;
    }
}
public-class-DancePair
{ 
公共静态int-totalmatching(int-input1,String[]input2)
{
//在这里写代码
String[]words=新字符串[input1];
String[]words2=新字符串[input1];
int i,j;
系统输出打印项次(输入1);

对于(i=0;i)这个问题是一个变化。你需要在这个二部图中找到最大匹配。唯一的区别是男人可以和多个女人跳舞。因此,当你构造你的图时,对于每个男人,你可以把多个节点放在它的度数上。
M1: W1, W2
M2: W3
必须为
M1
放置两个节点:

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

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

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

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));
    }

}
为了理解代码,您仍然应该阅读一两篇关于回溯的教程。我确信有性能优化的空间。代码使用了两个辅助类。以下是
选项
(也可以命名为
可能的回溯
):

最后是非常简单的舞蹈演员:

import java.util.Objects;

public class Dancer {
    final String name;
    boolean paired = false;

    public Dancer(String name) {
        Objects.requireNonNull(name);
        this.name = name;
    }

    public boolean isPaired() {
        return paired;
    }

    public void setPaired(boolean paired) {
        this.paired = paired;
    }

    @Override
    public String toString() {
        return name;
    }

}
我对二部图了解不多,但我能用简单的回溯解决方案来解决这个问题

下面是正在运行的C#解决方案(任何人都可以轻松地为Java修改):
(首先将M1#W2#W4、M2#W1#W2、M3#W1#W3#W4、M4#W4#W5、M5#W4
转换为0和1的二维数组)


我想你得读一些关于回溯的东西。试着把这个词放进你最喜欢的搜索引擎中。回溯是一个用于你所描述的问题的一类算法。可能并不总是有一个解决方案。考虑M1*W1,M2αW1,M3*W2*W3。通过这个输入,你将不得不离开M1或M2。,试着设计更好的变量名。在你的代码中,我本来希望读到关于舞者和选择的内容;像
input1
words
I
p
这样的名字可能对你自己和其他人都有意义。我忍不住,我已经写了一个解决方案。因为发布完整的解决方案并不太过分n当你所要求的只是帮助你自己解决问题时-如果你告诉我你愿意,我会发布我的。Ole V.V.如果M1或M2是单独的,那么输出必须是-1…是的,我真的需要帮助给出你的解决方案,有m个男人和m个女人,没有一个舞者独自跳舞,要求意味着每个男人只和一个女人跳舞,s我不知道你需要两个M1节点吗?这个问题很模糊。我解释了我对这个问题的理解。但是如果OP实际上是你所说的话,那么就不需要节点重复,一个简单的最大匹配就足够了。我赞成这个理论基础和它潜在的更好的性能。回溯。有5个男人和5个女人,表演并不重要,但有数百名舞者,这可能会有所不同。
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;
    }
}
import java.util.Objects;

public class Dancer {
    final String name;
    boolean paired = false;

    public Dancer(String name) {
        Objects.requireNonNull(name);
        this.name = name;
    }

    public boolean isPaired() {
        return paired;
    }

    public void setPaired(boolean paired) {
        this.paired = paired;
    }

    @Override
    public String toString() {
        return name;
    }

}
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