用于分组以解决冲突的算法
Algorithm for grouping to resolve collisions
来自谷歌的算法问题:
老师想把他的问题学生分成两组。他有一个名字列表(成对),代表不能被归入同一组的学生。我们的任务是检查是否有可能在没有碰撞的情况下将所有学生分开。
例如,如果列表为:
Jack Jim (cannot be in the same group)
Jim Rose (...)
Rose Jack (...)
那么就不可能在没有碰撞的情况下将它们全部分开。
我的想法是使用图的概念,并使用关联数组或映射来实现它。但是,我认为如果图有很多不连接的分支,那将非常复杂。有人可以帮忙吗?
您要检查图形是否为二分图。维基百科有关于如何做到这一点的细节。
这是一个相关的SO问题和一个来自普林斯顿的Java实现。
这听起来像是一个图形着色问题。 首先宣布杰克属于"黑色"组。 这意味着吉姆必须属于"红色"组。 这意味着"玫瑰"必须属于"黑色组"。 现在我们得到了碰撞:因为玫瑰是"黑色",杰克一定是"红色",但我们已经给他分配了黑色。
编辑:用于实现的伪代码(我没有编译它,我知道它会泄漏内存)
enum Group {
UNKNOWN,
RED,
BLACK
};
struct Person
{
string name;
Group group;
set<Person*> exclusionList;
}
class Class
{
public:
void addExclusion(const string& inPersonA, const string& inPersonB)
{
bool first = (mMembers.empty());
Person* personA = findPerson(inPersonA);
Person* personB = findPerson(inPersonB);
personA->exclusinList.insert(personB);
personB->exclusionList.insert(personA);
if (first) {
// special case, assign initial colors
personA->color = BLACK;
personB->color = RED;
} else {
switch (personA->color) {
case UNKNOWN:
switch(personB->color) {
case UNKNOWN:
break; // we can't do anything, nothing is known
case BLACK:
setColor(personA, RED);
break;
case RED:
setColor(personA, BLACK);
break;
}
break;
case RED:
switch (personB->color) {
case UNKNOWN:
setColor(personB, BLACK);
break;
case RED:
throw "EXCLUSION FAILURE";
case BLACK:
break;
}
case BLACK:
switch (personB->color) {
case UNKNOWN:
setColor(personB, BLACK);
break;
case RED:
break;
case BLACK:
throw "EXCLUSION FAILURE";
}
}
}
}
private:
Person* findPerson(const string& inString)
{
Person* rval = mMembers[inString];
if (rval == null) {
rval = new Person(inString, UNKNOWN);
mMembers[inString] = rval;
}
return rval;
}
void setColor(Person* inPerson, Group inColor)
{
if (inPerson->color == inColor)
return; // no op
if (inPerson->color != UNKNOWN && inPerson->color != inColor)
throw "EXCLUSION FAILURE";
// now we know inPerson was UNKNOWN
inPerson->color = inColor;
for (auto iter = inPerson->exclusionList.begin(); iter != inPerson->exclusionList.end(); ++iter) {
setColor(*iter, (inColor == RED) ? BLACK : RED);
}
unordered_map<string, Person*> mMembers;
};
#algorithm.coffee
#teacher wants to separate his/her problem prisoners into two groups by keeping
#separated certain individuals. we have a list of kids and need to decide how to
#separate them according to rules provided. only two groups allowed apparently. if
#more are required we are in collision situation.
reset = 'x1B[0m'
red = 'x1B[0;31m'
green = 'x1B[0;32m'
#we list all the kids, and such that the values are arrays holding all problems associated with that
# key=kid
contras =
"abe": []
"billy": []
"bella": []
"charles": []
"dafner": []
"echo": []
"ferris": []
"gomer": []
"gina": []
"heloise": []
#we have empty groups
group1 = []
group2 = []
# defining problem relationships
problems = [
["abe", "heloise"]
["bella", "dafner"]
["gomer", "echo"]
#["abe", "bella"]
["heloise", "dafner"]
["echo", "ferris"]
["abe", "dafner"]
]
# with the problems array we can populate the contras object
for item in problems
contras[item[0]].push item[1]
contras[item[1]].push item[0]
# with the populated contras object we can determine conflicts
for key, value of contras
for item in value
for item2 in value
for item3 in contras[item]
if item2 == item3 and item3 != item
console.log red + "There is a collision implicit in problem pair " + reset + key + red + " and " + reset + item + red + " because both " + reset + key + red + " and " + reset + item + red + " are problematic with " + reset + item3 + red + " who is also known as " + reset + item2 + red + ".n"
# if there are no unresolvable conflicts then this routine below
# will work, otherwise you'll see a bunch of
# red flags thrown by the routine above.
for item in problems
if group1.length == 0
group1.push item[0]
group2.push item[1]
else
duplicate = false
for item2 in group1
if item2 in contras[item[0]] then duplicate = true
if duplicate == true
group1.push item[1] unless item[1] in group1
group2.push item[0] unless item[0] in group2
else
group1.push item[0] unless item[0] in group1
group2.push item[1] unless item[1] in group2
### some tests
# checking if group1 contains problems
for item in group1
for item2 in problems
for item3 in item2
if item == item3
for item4 in item2
if item4 != item
for item5 in group1
if item4 == item5
duplicate = false
for item6 in collisions
if item2 == item6 then duplicate = true
if duplicate == false
collisions.push item2
# checking if group2 contains problems
for item in group2
for item2 in problems
for item3 in item2
if item == item3
for item4 in item2
if item4 != item
for item5 in group2
if item4 == item5
duplicate = false
for item6 in collisions
if item2 == item6 then duplicate = true
if duplicate == false
collisions.push item2
###
console.log green + "whole kids group is " + reset + kids
console.log green + "group1 is " +reset + group1
console.log green + "group2 is " + reset + group2
# console.log red + "collisions are " + reset + collisions
您所需要的只是检查您的图形是否是二分的(即图形的顶点是否能够以这样一种方式分配两种颜色之一,即没有边连接相同颜色的顶点)。如果您使用整数对班级中的学生进行编号:
1. Jack
2. Jim
3. Rose
您可以使用 Boost 图形库轻松解决此问题C++:
#include <iostream>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/bipartite.hpp>
using namespace boost;
int main (int argc, char **argv)
{
typedef adjacency_list <vecS, vecS, undirectedS> vector_graph_t;
typedef std::pair <int, int> E;
E edges[] = { E (1, 2), E (2, 3), E (3, 1)};
vector_graph_t students (&edges[0],&edges[0] + sizeof(edges) / sizeof(E), 3);
if ( is_bipartite(students) )
std::cout << "Bipartite graph" << std::endl;
else
std::cout << "Non bipartite graph" << std::endl;
return 0;
}
相关文章:
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 写入位置0x0000000C时发生访问冲突
- 基于ELO的团队匹配算法
- C++选择排序算法中的逻辑错误
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- C++A*算法并不总是在路径中具有目标节点
- 排序算法c++
- GL_SHADERSTORAGE_BUFFER位置是否与其他着色器位置冲突
- 使用cmake从源代码构建MySQL连接器/C++失败(与以前的声明冲突)
- 引发异常:读取访问冲突**dynamicArray**为0x1118235.发生
- 构建可组合有向图(扫描仪生成器的汤普森构造算法)
- 算法问题:查找从堆栈中弹出的所有序列
- 下面是排序算法O(n)吗
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- KMP算法和LPS表构造的运行时间
- 链表中写入访问冲突的未知原因
- 是否有具有用户定义的冲突处理程序的 std::唯一样式库算法
- 在避免代码重复和冲突名称的同时,如何实现多个版本的同一算法
- 编译哈希算法时出现内存访问冲突错误
- 用于分组以解决冲突的算法