- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
在我们的团队签到后,我们中断了与 (n) 名参与者的协调 session ,讨论了各种(唯一命名的)主题。
目前,人们站在一旁试图 self 组织,我们没有最大化 session 的并发性,和/或尽快释放团队成员返回工作岗位。
我们在 Google Spreadsheet 中保留了所有签到后的所有协调 session 的列表。 :
+-----------------------------------------------------------+
| Meetings |
+-----------------------------------------------------------+
| Topic A | Topic B | Topic C | Topic D | Topic E |
+-----------------------------------------------------------+
| Billy | JD | David | Tania | JB |
| Mel | Rowan | Emily | David | Fred |
| Tracey | Mike | | Mike | Tania |
| JB | Aaron | | Fred | |
| Luke | Billy | | | |
| Aaron | | | | |
| Michael | | | | |
+-----------------------------------------------------------+
作为起点,我有(肯定是非常低效的)代码迭代每次 session 并返回没有参与者冲突的对数组。
main()
的示例输出,上面作为输入数据(不用担心所有代码都在下面):
[["主题 A","主题 C"],["主题 A","主题 D"],["主题 B","主题 C"],["主题 B","主题 E"],["主题 C","主题 E"]]
理想情况下,我需要一个解决方案,该解决方案可以返回一个数组,该数组按可能一次运行的大多数 session 排序。要么使用从 main 返回的对数组()
或使用电子表格中的数据作为输入的完全不同的方法。
在我这里的示例中,它将采用以下形式:
[[主题 B、主题 C、主题 E]、[主题 A、主题 D]]
然后,我将在 Google 电子表格中按颜色对这些进行可视化分组,以便员工可以看到。
我试图创建一些代码 (main2()
) 来减少基于互斥对的数组,但这是完全错误的。例如:该代码输出:
[["主题 A","主题 C","主题 B","主题 E"],"主题 D"]
...这是不正确的,因为 A 和 B 显然有冲突。 (当然A和C,B和E连续就好了)。
function onOpen () {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Meeting Tools')
.addItem('Compute Optimal Meeting Order', 'main')
.addToUi();
}
function main() {
var ss = SpreadsheetApp.getActive();
var sss = ss.getActiveSheet();
//var sss = ss.getSheetByName("Sheet3");
var data = sss.getDataRange().getValues();
var ui = SpreadsheetApp.getUi();
var meetings = {};
var pairs = [];
var objKey;
// Structuring data to obj
for (var x=0; x < sss.getLastColumn(); x++) {
for (var y=1; y < data.length; y++) {
if (y==1) {
objKey = data[y][x];
meetings[objKey] = [];
}
else if (data[y][x]) {
meetings[objKey].push(data[y][x]);
}
}
}
var keys = Object.keys(meetings).sort();
var loc;
// Starting with "A"
for (var m in meetings) {
if (!meetings.hasOwnProperty(m)) continue;
Logger.log("-----------------------------");
Logger.log("SCANNING: " + m);
Logger.log("-----------------------------");
loc = keys.indexOf(m);
// check A, B, C, D, E
for (var m2 = 0; m2 < keys.length; m2++) {
var pointer = (m2 + loc) % keys.length;
// DO NOT CHECK SAME MEETING
if (keys[pointer] == m) {
Logger.log("||||||||| WE ARE COMPARING OURSELVES: (" + keys[pointer] + "/" + m + "). SKIPPING!");
continue;
}
// FOR EACH PARTICIPANT OF CURRENT MEETING
for (var p = 0; p < meetings[m].length; p++) {
Logger.log("");
Logger.log(" >>> COMPARING " + keys[pointer]);
Logger.log(" >>> >>> " + meetings[m][p] + " " + (p+1) +"/"+meetings[m]. length);
// SEEK THE LOCATION OF THE MEETING PARTICIPANT IN THE NEXT MEETING
var testIndex = meetings[keys[pointer]].indexOf(meetings[m][p]);
// IF THE MEETING PARTICIPANT IS ALSO IN THE NEXT MEETING
if (testIndex > -1) {
Logger.log("We have a match! Meeting "+ m + " has participant " + meetings[m][p] + " which unfortunately clashes with meeting " + keys[ pointer]);
Logger.log("Therefore Meeting " + m + " cannot run at the same time as " + keys[pointer]);
Logger.log("We need to bail out of compairing against: " + keys[pointer ]);
// WE BAIL OUT AS WE HAVE A CLASH
break;
}
// IF THE MEETING PARTICIPANT IS NOT IN THE NEXT MEETING AND WE HAVE CHECKED EVERYONE. WE SHOULD BE GOOD.
else if (testIndex == -1 && p+1 == meetings[m].length) {
Logger.log("This looks to be clear!!! Adding to pair group.");
pairs.push([m,keys[pointer]]);
}
}//loop
} //loop
} //obj_loop
// Logger.log("FINAL TALLY: " + JSON.stringify(pairs));
Logger.log("FINAL TALLY (CLEANED): " + JSON.stringify(removeRepeats(pairs.sort()) ));
// ui.alert(JSON.stringify(removeRepeats(pairs.sort())));
// ss.toast(JSON.stringify(removeRepeats(pairs.sort())));
// debugger;
return removeRepeats(pairs.sort());
}
function main2(array) {
// DEBUG
// array = [["A","C"],["A","D"],["B","C"],["B","E"],["C","E"]];
// array = [["A","C"],["A","D"],["B","C"],["B","E"],["C","E"]];
array = main();
var holdingArr = [];
for (var i = array.length - 1; i >= 1; i--) {
//DEBUG
//var pair = ["Z","X"];
var pair = array[i];
if (arrayPairCheck([array[0]], pair)) {
holdingArr.push(pair);
array.pop(i);
}
else {
array[0] = array[0].concat(array[i]);
array.pop(i);
}
} //loop
if (holdingArr && holdingArr.length > 0) {
for (var j=0; j < holdingArr.length; j++) {
var checkIndex = holdingMeetingExistsInPair(array[0],holdingArr[j]);
if (checkIndex !== false) {
array.push(holdingArr[j][checkIndex]);
}
} //loop
}
// DEBUG
debugger;
Logger.log(JSON.stringify(array));
}
function holdingMeetingExistsInPair(arrayFirstIndexGroup,holdingArrPair) {
if (arrayFirstIndexGroup && arrayFirstIndexGroup.length > 0) {
if (arrayFirstIndexGroup.indexOf(holdingArrPair[0]) === -1) {
return 0;
}
if (arrayFirstIndexGroup.indexOf(holdingArrPair[1]) === -1) {
return 1;
}
}
return false;
}
function arrayPairCheck(array,pair) {
// DEBUG
// array = [["A","C"],["A","D"],["B","C"],["B","E"],["C","E"]];
// pair = ["Z","X"];
var seen = false;
if (array && array.length > 0) {
for (var i=0; i < array.length; i++) {
array[i].map(function(item,item2) {
if (item === pair[0] || item === pair[1]) {
seen = true;
return true;
}
});
} //loop
}
if (seen) { return true; } else { return false; }
}
// http://stackoverflow.com/questions/27734661/javascript-arrays-ab-ba
function removeRepeats(list) {
var i;
var b = [];
var _c = [];
for (i = 0; i < list.length; i++) {
var a = list[i].sort();
var stra = a.join("-");
if(_c.indexOf(stra) === -1) {
b.push(a);
_c.push(stra);
}
}
return b;
}
我一直在阅读有关拼凑理解的一些途径如下。我的代表太低无法链接这些。有人可能会确认这是一个追求的方向?
Hopcroft–Karp 算法
感谢您花在这上面的时间。
对于以下情况,解决方案应正确地将 session 顺序设置为:
1) W, X, Z
2)V,Y
+-----------------------------------------------------------+
| Meetings |
+-----------------------------------------------------------+
| Topic V | Topic W | Topic X | Topic Y | Topic Z |
+-----------------------------------------------------------+
| Billy | JD | David | Tania | JB |
| Mel | Rowan | Emily | David | Fred |
| Tracey | Mike | | Mike | |
| JB | | | Fred | |
| Luke | | | | |
| Aaron | | | | |
| Michael | | | | |
+-----------------------------------------------------------+
最佳答案
这绝对是一个有趣的问题。我的方法是使用矩阵运算来找出哪些主题没有冲突。第一步是创建一个矩阵来表示没有冲突的对,类似于您的方法。
所以对于这个示例数据集
+-----------------------------------------------------------+
| Meetings |
+-----------------------------------------------------------+
| Topic A | Topic B | Topic C | Topic D | Topic E |
+-----------------------------------------------------------+
| Billy | JD | David | Tania | JB |
| Mel | Rowan | Emily | David | Fred |
| Tracey | Mike | | Mike | Tania |
| JB | Aaron | | Fred | |
| Luke | Billy | | | |
| Aaron | | | | |
| Michael | | | | |
+-----------------------------------------------------------+
我们可以说主题 A 与主题 C 和主题 D 没有冲突,我们可以像这样用矩阵/数组表示它:
+---------------------------------------------------------------+
|Topic A|Topic B |Topic C|Topic D|Topic E|
Topic A |1 |0 |1 |1 |0 |
但是,Topic C 和 Topic D 确实有冲突,我们稍后再讲。同样,我们像这样填充剩余的矩阵
Unique Pair Matrix
TopicA TopicB TopicC TopicD TopicE
TopicA 1 0 1 1 0
TopicB 0 1 1 0 1
TopicC 1 1 1 0 1
TopicD 1 0 0 1 0
TopicE 0 1 1 0 1
正如您从该表中注意到的,主题 C 行有 0 对应于主题 D 列,这表示冲突。另外,请注意,对 Angular 线设置为 1,因为相同的 session 不会相互冲突(同样对于下一步,我们需要将其设置为 1)。
接下来只需将矩阵乘以自身即可得到如下所示的矩阵。理想情况下,你会转置矩阵然后相乘,在这种情况下,你不需要(方阵)
Number of Unique Pair Matrix
Topic A Topic B Topic C Topic D Topic E
Topic A 3 1 2 2 1
Topic B 1 3 3 0 3
Topic C 2 3 4 1 3
Topic D 2 0 1 2 0
Topic E 1 3 3 0 3
此矩阵表示 session 不相互冲突的次数。因此,为了满足 A 和 C,它们不会冲突两次,一次是从第 1 行计算的,另一次是从第 3 行计算的。类似地,对于主题“D”和“A”,我们得到一个值 2。但是总的唯一对A(以对 Angular 线值表示)为 3,这意味着满足 C 和 D 有冲突,因为它们只与 A 形成唯一对两次。
在第 2 行中,您会注意到,主题 B、C、E 来自总共 3 个独特的对,这代表可以一起举行的 session 的最多数量以及这些 session 中可以举行的 session 。
使用此功能,您可以确定首先召开的 session 数量最多的 session ,然后是其余 session 。下面的代码正是这样做的:
function onOpen () {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Meeting Tools')
.addItem('Compute Optimal Meeting Order', 'Jmain')
.addToUi();
}
function Jmain() {
var ss = SpreadsheetApp.getActive();
var sss = ss.getActiveSheet();
var sss = ss.getSheetByName("Sheet2");
var data = sss.getRange(2,1,sss.getLastRow()-1,sss.getLastColumn()).getValues();
//This the matrix that will hold data for unique pairs
var shadowRel = []
var headers = data[0].slice()
data = transpose(data)
var shadowRel = []
for (var i = 0 ; i < data.length ; i ++){
shadowRel[i] = headers.slice() //Each Row is set Headers values to begin with
for (var j = 1 ; j < data[i].length ; j++){
var found = false
for(var k = 0 ; k < data.length ; k++){
if(k != i) {
if (data[k].indexOf(data[i][j]) != -1 && data[i][j] != ""){
//
shadowRel[i][k] = 0 // Whenver there is a clash the martix is set to zero
found = true
}
}
}
}
}
shadowRel = mMutliply (shadowRel) //Matrix Multiplication
sss = ss.getSheetByName("Sheet3")
sss.getRange(2,2,shadowRel.length,shadowRel[0].length).setValues(shadowRel) //Set the values of multiplied martix in sheet 3
var ui = SpreadsheetApp.getUi()
var meetingOrder = mostNoMeetings(shadowRel,headers)
Logger.log("Meeting Order: ")
Logger.log(meetingOrder)
var prompt = "Meeting Order: "
for (i = 0 ;i <meetingOrder.length; i++){
prompt += "\n"+(i+1)+") "+ meetingOrder[i]
}
ui.alert(prompt)
}
// Transpose the data so as to check match in each row.
function transpose(arr) {
return Object.keys(arr[0]).map(function (c) {
return arr.map(function (r) {
return r[c];
});
});
}
function mMutliply (arr){ //Number of row and column needs to be equal
var mMutRes = []
for (var i = 0; i < arr.length ; i++)
for(var j = 0; j<arr[0].length ; j++){
if(arr[i][j] !== 0)
arr[i][j] = 1 // Remaining Text is converted to 1, has no class
}
var ss = SpreadsheetApp.getActive()
var sss = ss.getSheetByName("Sheet3")
sss.getRange(arr.length+5,2,arr.length,arr[0].length).setValues(arr) //Set Value of unique pair to sheet 3
for (var i = 0; i < arr.length ; i++){
mMutRes[i] = []
for(var j = 0; j<arr[0].length ; j++){
var sumProd = 0
for(var k = 0 ; k < arr.length ; k ++)
{
sumProd += (arr[k][j] * arr[i][k])
}
mMutRes[i][j] = sumProd
}
}
return mMutRes
}
function mostNoMeetings(shadowRel,headers){
var UsedIndex = []
var MaxColIndex = []
var counter = 0
var MeetingGroups = []
for(var maxNo = shadowRel.length ; maxNo > 0 ; maxNo--) { //Look for most repeated pair, max possible is the numbers of topics/meetings at same time
var maxFound = false
for (var i = 0 ; i < shadowRel.length; i++){
for(var j= 0; j< shadowRel[0].length; j++){
if(i != j && UsedIndex.indexOf(i) == -1 && UsedIndex.indexOf(j) == -1) // Eliminate row / column corresponding to topics/Meetings already scheduled.
if(shadowRel[i][j] == maxNo){
MaxColIndex[counter] = j
counter++
maxFound = true
}
}
if(maxFound){
var temp = []
temp.push(headers[i])
for (var k in MaxColIndex){
if(temp.length < maxNo)
temp = temp.concat(headers[MaxColIndex[k]])
else
MaxColIndex.splice(k)
}
MaxColIndex[counter] = i
MeetingGroups.push(temp)
UsedIndex = UsedIndex.concat(MaxColIndex)
//Logger.log(UsedIndex)
MaxColIndex = []
counter = 0
maxFound = false
}
}
}
// Incase any are remaining meetings that didnt form pairs which have to be held independently
for ( i = 0 ; i < shadowRel.length; i++){
if(i != j && UsedIndex.indexOf(i) == -1 && UsedIndex.indexOf(j) == -1){
MeetingGroups.push(headers[i])
}
}
return MeetingGroups
}
最后,确保您的数据在工作表 2 中,而工作表 3 为空,将上述矩阵和相乘矩阵的输出发布到工作表 3,以直观地表示发生的情况。
希望对您有所帮助!
关于javascript - 给定参与者列表的最大并发 session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42875496/
是否为每个 Shiny session 分配了 session ID/ session key (如果部署在 Shiny 服务器上)?如果是,我如何访问该信息?我已阅读文档here然而上网查了一下,并
我正在使用 this koajs session 模块。 我检查了源代码,但我真的无法理解。 我想知道它保存 session 数据的位置,因为我没有看到创建的文件,并且当服务器重新启动时, sessi
实现高可扩展性的一种方法是使用网络负载平衡在多个服务器之间分配处理负载。 这种方法提出的一个挑战是服务器是否具有状态意识 - 将用户状态存储在“ session ”中。 此问题的一个解决方案是“粘性
在负载平衡服务器的上下文中, session 亲和性和粘性 session 之间有什么区别? 最佳答案 我见过这些术语可以互换使用,但有不同的实现方式: 在第一个响应中发送 cookie,然后在后续响
我希望其他人向我解释哪种方法更好:使用 session 或设计无 session 。我们正在开始开发一个新的 Web 应用程序,但尚未决定要遵循什么路径。 无 session 设计在我看来更可取: 优
现在用户在他的权限中有很多角色,我将允许他点击 href 并在新窗口中扮演另一个角色。每个角色都有自己的 session 。 既然浏览器打开窗口不能用新 session 打开,我必须在服务器端想办法。
我正在尝试为express.js Node 应用程序实现 session 存储我的问题是: 如何删除具有浏览器 session 生命周期的 cookie(根据连接文档标记有 expires = fal
在开始在 golang 中使用 session 之前,我需要回答一些问题 session 示例 import "github.com/gorilla/sessions" var store = ses
我读过 Namespaced Attributes . 我尝试使用此功能: #src/Controller/CartController.php public function addProduct(
我正在努力完成以下工作: 根据用户的类型更改用户的 session cookie 到期日期。 我有一个 CakePHP Web 应用程序,其中我使用 CakePHP session 创建了我的身份验证
这是我在这里的第一个问题,我希望我做对了。 我需要处理一个 Java EE 项目,所以在开始之前,我会尝试做一些简单的事情,看看我是否能做到。 我坚持使用有状态 session Bean。 这是问题:
ColdFusion session 与 J2EE session 相比有什么优势吗? ColdFusion session documentation提到了 J2EE session 的优点,但没有
在执行任何任务之前,我需要准确地在创建 session 时创建一个 session 范围变量(因为我的所有任务都需要一个初始 session 范围变量才能运行)。因为,创建 session 时,gra
我们当前的应用使用 HTTP session ,我们希望将其替换为 JWT。 该设置仅允许每个用户进行一次 session 。这意味着: 用户在设备 1 上登录 用户已在设备 1 上登录(已创建新 s
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
假设我在两个或更多设备上打开了两个或更多用户 session (同一用户没有管理员权限)。 在当前 session 中,如果我注销,是否意味着所有其他 session 也会关闭?如果没有,有没有办法通
我正在评估在 tomcat 中使用带有 session 复制的粘性 session 的情况。根据我的初步评估,我认为如果我们启用 session 复制,那么在一个 tomcat 节点中启动的 sess
我开始使用 golang 和 Angular2 构建一个常规的网络应用程序,最重要的是我试图在 auth0.com 的帮助下保护我的登录.我从 here 下载快速入门代码并尝试运行代码,它运行了一段时
我在 Spring Controller 中有一个方法,它接受两个相同类型的参数其中一个来自 session ,另一个来自表单提交(UI)。 问题是在 Controller 方法中我的非 sessio
在我登录之前,我可以点击我的安全约束目录之外的任何内容。如果我尝试转到安全约束目录内的某个位置,它会将我重定向到表单登录页面。如您所料。 登录后,我可以继续我的业务,并访问我的安全约束内外的资源。
我是一名优秀的程序员,十分优秀!