我有一个问题: - 有男人和女人。男性可以与一个或多个女性共舞,也可以不与任何女性共舞。找到一对一的舞伴伴侣,这样: 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 我已经创建了这个代码,但我陷入了循环,无法继续。需要帮助
答案 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