// doFlip setups the flipping algorithm. func doFlip(or *events.Recons, out chan []*events.Recons) { for p := 0; p < numProc; p++ { go func(px int) { hits := 1 var best []*events.Recons r := or.MakeCopy() best = append(best, or.MakeCopy()) var nodes []int for i := range r.Rec { if r.Rec[i].SetL != -1 { nodes = append(nodes, i) } } evs := makeEvents() for i := 0; i < numReps; i++ { if i > 0 { r.Copy(or) } r.Randomize(numRand, evs) flipRecons(r, nodes, evs) if r.Cost() < best[0].Cost() { if verbose { fmt.Printf("Replicate %s.%d.%d: %.3f [best so far]\n", r.Tree.ID, px, i, r.Cost()) } hits = 1 cp := r.MakeCopy() cp.ID = fmt.Sprintf("%d.%d", px, i) best = append([]*events.Recons{}, cp) } else if r.Cost() == best[0].Cost() { if verbose { fmt.Printf("Replicate %s.%d.%d: %.3f [hit best]\n", r.Tree.ID, px, i, r.Cost()) } hits++ diff := true for _, b := range best { if !r.IsDiff(b) { diff = false break } } if diff { cp := r.MakeCopy() cp.ID = fmt.Sprintf("%d.%d", px, i) best = append(best, cp) } } else if verbose { fmt.Printf("Replicate %s.%d.%d: %.3f\n", r.Tree.ID, px, i, r.Cost()) } } if verbose { fmt.Printf("Process: %s.%d hits: %d (of %d) best: %.3f stored: %d\n", or.Tree.ID, px, hits, numReps, best[0].Cost(), len(best)) } out <- best }(p) } }
// flipRecons permorms the flip algorithm on list of nodes an events. func flipRecons(r *events.Recons, nodes, evs []int) float64 { best := r.Cost() for doAgain := true; doAgain; { doAgain = false shuffle(nodes) for _, n := range nodes { prev := r.Rec[n].Flag shuffle(evs) for _, e := range evs { if e == prev { continue } r.Rec[n].Flag = e if r.DownPass(n) < best { break } } if r.Cost() < best { best = r.Cost() doAgain = true break } r.Rec[n].Flag = prev r.DownPass(n) } } return r.Cost() }