func SolveTask(client ClientInfo, task_data []byte, task_id int) { fmt.Println("SolveTask: Start") task := tsp_types.TaskType{} task.FromXml(task_data) new_task := &TaskQueueItem{} new_task.Init(task_id) task_queue.PushBack(new_task) go TaskHandler(new_task) go AnswerCombiner(new_task) //split enabled, task1, task2 := tsp_solver.CrusherImpl(&task) for enabled { new_task.SubTasks <- task1 new_task.SentTasksCount.Inc() new_task.PreparedTasks <- true task2.MinCost = new_task.CurrMinCost.Get() enabled, task1, task2 = tsp_solver.CrusherImpl(task2) } new_task.PrepareFinished = true new_task.PreparedTasks <- false final_answer := <-new_task.FinalAnswer msg := []byte(final_answer.ToXml()) err := binary.Write(*client.Conn, binary.LittleEndian, int64(len(msg))) if err != nil { fmt.Printf("[SolveTask] Write data error: %v", err) return } (*client.Conn).Write(msg) task_queue.Remove(new_task.ID) fmt.Println("[SolveTask] Finish") }
func CrusherImpl(task *tsp_types.TaskType) (bool, *tsp_types.TaskType, *tsp_types.TaskType) { success, additional_cost := calculate_plus_cost(*task.Matrix, task.Size) if success != true { return false, nil, nil } task.CurrCost += additional_cost heavier_zero := find_heavier_zero(*task.Matrix, task.Size) //prepare data for recursive call sub_dt := generate_sub_task_data(task.Matrix, task.RowMapping, task.ColMapping, task.Jumps, heavier_zero, task.Size) //call this function recursively task1 := tsp_types.TaskType{sub_dt.Matrix, sub_dt.RowMapping, sub_dt.ColMapping, sub_dt.Jumps, task.CurrCost, task.MinCost, task.Size - 1} (*task.Matrix)[heavier_zero.Row*task.Size+heavier_zero.Col] = tsp_types.POSITIVE_INF return true, &task1, task }
func SolveImpl(task tsp_types.TaskType, gl_min_cost *tsp_types.GlobalCostType) (tsp_types.AnswerType, bool) { if gl_min_cost.Get() < task.MinCost { return tsp_types.ERROR_ANSWER, false } if (task.Size == 0) || (task.Size == 1) { return tsp_types.ERROR_ANSWER, true } success, additional_cost := calculate_plus_cost(*task.Matrix, task.Size) if !success { return tsp_types.ERROR_ANSWER, true } task.CurrCost += additional_cost heavier_zero := find_heavier_zero(*task.Matrix, task.Size) // if task.Size is 2 end recursion if task.Size == 2 { next_city := heavier_zero.Col previous_city := heavier_zero.Row if ((*task.Matrix)[(previous_city^1)*2+(next_city^1)] == 0) && ((*task.Matrix)[(previous_city^1)*2+next_city] == tsp_types.POSITIVE_INF) && ((*task.Matrix)[previous_city*2+(next_city^1)] == tsp_types.POSITIVE_INF) { jumps := make([]tsp_types.JumpType, 2) jumps[0] = tsp_types.JumpType{task.RowMapping[heavier_zero.Row], task.ColMapping[heavier_zero.Col]} jumps[1] = tsp_types.JumpType{task.RowMapping[heavier_zero.Row^1], task.ColMapping[heavier_zero.Col^1]} for j := range task.Jumps { jumps = append(jumps, task.Jumps[j]) } return tsp_types.AnswerType{jumps, task.CurrCost}, true } else { return tsp_types.ERROR_ANSWER, true } } // prepare data for recursive call sub_dt := generate_sub_task_data(task.Matrix, task.RowMapping, task.ColMapping, task.Jumps, heavier_zero, task.Size) //call this function recursively answer, less_global := SolveImpl(tsp_types.TaskType{sub_dt.Matrix, sub_dt.RowMapping, sub_dt.ColMapping, sub_dt.Jumps, task.CurrCost, task.MinCost, task.Size - 1}, gl_min_cost) if !less_global { return tsp_types.ERROR_ANSWER, false } //print_answer(answer, "GOT ANSWER") final_path := []tsp_types.JumpType{} if answer.Cost < task.MinCost { final_path = answer.Jumps task.MinCost = answer.Cost } //right_path if (task.CurrCost + heavier_zero.Weight) < task.MinCost { //correct first one (*task.Matrix)[heavier_zero.Row*task.Size+heavier_zero.Col] = tsp_types.POSITIVE_INF answer, less_global = SolveImpl(task, gl_min_cost) if !less_global { return tsp_types.ERROR_ANSWER, false } if answer.Cost < task.MinCost { final_path = answer.Jumps task.MinCost = answer.Cost } } // return answer if task.MinCost < tsp_types.POSITIVE_INF { return tsp_types.AnswerType{final_path, task.MinCost}, true } else { return tsp_types.ERROR_ANSWER, true } }