public static PuzzleStateAndGenerator ApplyOrientation(CubePuzzle puzzle, CubeMove[] randomOrientation, PuzzleStateAndGenerator psag, bool discardRedundantMoves) { if (randomOrientation.Length == 0) { return(psag); } // Append reorientation to scramble. try { var ab = new AlgorithmBuilder(MergingMode.NoMerging, puzzle.GetSolvedState()); ab.AppendAlgorithm(psag.Generator); foreach (var cm in randomOrientation) { ab.AppendMove(cm.ToString()); } psag = ab.GetStateAndGenerator(); return(psag); } catch (InvalidMoveException e) { azzert(false, e.Message); return(null); } }
public override PuzzleStateAndGenerator GenerateRandomMoves(Random r) { var scramble = _threePhaseSearcher.RandomState(r); var ab = new AlgorithmBuilder(MergingMode.CanonicalizeMoves, GetSolvedState()); try { ab.AppendAlgorithm(scramble); } catch (InvalidMoveException e) { azzert(false, e.Message); //, new InvalidScrambleException(scramble, e)); } return(ab.GetStateAndGenerator()); }
public override PuzzleStateAndGenerator GenerateRandomMoves(Random r) { var state = _twoSolver.RandomState(r); var scramble = _twoSolver.GenerateExactly(state, TwoByTwoMinScrambleLength); var ab = new AlgorithmBuilder(MergingMode.CanonicalizeMoves, GetSolvedState()); try { ab.AppendAlgorithm(scramble); } catch (InvalidMoveException e) { azzert(false, e.Message, new InvalidScrambleException(scramble, e)); } return(ab.GetStateAndGenerator()); }
public ClusterSettingsViewModel( MultiAlignAnalysis analysis, ObservableCollection <DatasetInformationViewModel> datasets, IClusterViewFactory clusterViewFactory = null, IProgress <int> progressReporter = null) { this.progress = progressReporter ?? new Progress <int>(); this.analysis = analysis; this.Datasets = datasets; this.options = analysis.Options; this.builder = new AlgorithmBuilder(); this.clusterViewFactory = clusterViewFactory ?? new ClusterViewFactory(analysis.DataProviders); // When dataset state changes, update can executes. this.MessengerInstance.Register <PropertyChangedMessage <DatasetInformationViewModel.DatasetStates> >(this, args => { if (args.Sender is DatasetInformationViewModel && args.PropertyName == "DatasetState") { ThreadSafeDispatcher.Invoke(() => this.ClusterFeaturesCommand.RaiseCanExecuteChanged()); ThreadSafeDispatcher.Invoke(() => this.DisplayClustersCommand.RaiseCanExecuteChanged()); } }); this.ClusterFeaturesCommand = new RelayCommand(this.AsyncClusterFeatures, () => this.Datasets.Any(ds => ds.FeaturesFound)); this.DisplayClustersCommand = new RelayCommand( async() => await this.DisplayFeatures(), () => this.Datasets.Any(ds => ds.IsClustered)); this.DistanceMetrics = new ObservableCollection <DistanceMetric>(); Enum.GetValues(typeof(DistanceMetric)).Cast <DistanceMetric>().ToList().ForEach(x => this.DistanceMetrics.Add(x)); this.CentroidRepresentations = new ObservableCollection <ClusterCentroidRepresentation> { ClusterCentroidRepresentation.Mean, ClusterCentroidRepresentation.Median }; this.ClusteringMethods = new ObservableCollection <LcmsFeatureClusteringAlgorithmType>(); Enum.GetValues(typeof(LcmsFeatureClusteringAlgorithmType)).Cast <LcmsFeatureClusteringAlgorithmType>().ToList().ForEach(x => this.ClusteringMethods.Add(x)); this.PostProcessingComparisonType = new ObservableCollection <ClusterPostProcessingOptions.ClusterComparisonType>( Enum.GetValues(typeof(ClusterPostProcessingOptions.ClusterComparisonType)).Cast <ClusterPostProcessingOptions.ClusterComparisonType>()); }
public PuzzleStateAndGenerator GenerateRandomMoves(Random r, string firstAxisRestriction, string lastAxisRestriction) { var randomState = Tools.RandomCube(r); var scramble = _twoPhaseSearcher.Solution(randomState, ThreeByThreeMaxScrambleLength, ThreeByThreeTimeout, ThreeByThreeTimemin, Search.INVERSE_SOLUTION, firstAxisRestriction, lastAxisRestriction).Trim(); var ab = new AlgorithmBuilder(MergingMode.CanonicalizeMoves, GetSolvedState()); try { ab.AppendAlgorithm(scramble); } catch (InvalidMoveException e) { azzert(false, e.Message); //, new InvalidScrambleException(scramble, e)); } return(ab.GetStateAndGenerator()); }
public static PuzzleStateAndGenerator ApplyOrientation(CubePuzzle puzzle, CubeMove[] randomOrientation, PuzzleStateAndGenerator psag, bool discardRedundantMoves) { if (randomOrientation.Length == 0) { return(psag); } // Append reorientation to scramble. try { var ab = new AlgorithmBuilder(MergingMode.NoMerging, puzzle.GetSolvedState()); ab.AppendAlgorithm(psag.Generator); // Check if our reorientation is going to cancel with the last // turn of our scramble. If it does, then we just discard // that last turn of our scramble. This ensures we have a scramble // with no redundant turns, and I can't see how it could hurt the // quality of our scrambles to do this. var firstReorientMove = randomOrientation[0].ToString(); while (ab.IsRedundant(firstReorientMove)) { //azzert(discardRedundantMoves); var im = ab.FindBestIndexForMove(firstReorientMove, MergingMode.CanonicalizeMoves); ab.PopMove(im.Index); } foreach (var cm in randomOrientation) { ab.AppendMove(cm.ToString()); } psag = ab.GetStateAndGenerator(); return(psag); } catch (InvalidMoveException e) { azzert(false, e.Message); return(null); } }
/// <summary> /// Initializes a new instance of the <see cref="AlignmentSettingsViewModel"/> class. /// </summary> /// <param name="analysis">The analysis information to run alignment on.</param> /// <param name="datasets">List of all potential datasets to run alignment on.</param> /// <param name="alignmentWindowFactory"> /// Factory for creating windows related to alignment (such as alignment plot windows). /// </param> public AlignmentSettingsViewModel(MultiAlignAnalysis analysis, ObservableCollection <DatasetInformationViewModel> datasets, IAlignmentWindowFactory alignmentWindowFactory = null) { this.analysis = analysis; this.Datasets = datasets; if (analysis.MetaData.BaselineDataset != null) { // Don't set baseline if there are no files to choose from yet this.selectedBaseline = datasets.First(x => x.Name == analysis.MetaData.BaselineDataset.DatasetName); } this.alignmentWindowFactory = alignmentWindowFactory ?? new AlignmentViewFactory(); this.aligner = new LCMSFeatureAligner(); this.builder = new AlgorithmBuilder(); this.CalibrationOptions = new ObservableCollection <LcmsWarpAlignmentType>(Enum.GetValues(typeof(LcmsWarpAlignmentType)).Cast <LcmsWarpAlignmentType>()); this.AlignmentAlgorithms = new ObservableCollection <FeatureAlignmentType>( Enum.GetValues(typeof(FeatureAlignmentType)).Cast <FeatureAlignmentType>()); this.alignmentInformation = new List <AlignmentData>(); this.DatabaseSelectionViewModel = DatabaseSelectionViewModel.Instance; // When dataset is selected/unselected, update CanExecutes for alignment and plotting commands. this.MessengerInstance.Register <PropertyChangedMessage <bool> >( this, args => { if (args.Sender is DatasetInformationViewModel && args.PropertyName == "IsSelected") { ThreadSafeDispatcher.Invoke(() => this.AlignCommand.RaiseCanExecuteChanged()); ThreadSafeDispatcher.Invoke(() => this.DisplayAlignmentCommand.RaiseCanExecuteChanged()); ThreadSafeDispatcher.Invoke(() => this.SaveAlignmentPlotsCommand.RaiseCanExecuteChanged()); } }); // When dataset state changes, update CanExecutes for alignment and plotting commands. this.MessengerInstance.Register <PropertyChangedMessage <DatasetInformationViewModel.DatasetStates> >( this, args => { if (args.Sender is DatasetInformationViewModel && args.PropertyName == "DatasetState") { ThreadSafeDispatcher.Invoke(() => this.AlignCommand.RaiseCanExecuteChanged()); ThreadSafeDispatcher.Invoke(() => this.DisplayAlignmentCommand.RaiseCanExecuteChanged()); ThreadSafeDispatcher.Invoke(() => this.SaveAlignmentPlotsCommand.RaiseCanExecuteChanged()); } }); // When database server is selected, update CanExecute for the alignment command. this.MessengerInstance.Register <PropertyChangedMessage <DmsDatabaseServerViewModel> >( this, args => { if (args.Sender is DatabaseSelectionViewModel && args.PropertyName == "SelectedDatabase") { ThreadSafeDispatcher.Invoke(() => this.AlignCommand.RaiseCanExecuteChanged()); } }); this.AlignCommand = new RelayCommand(this.AsyncAlign, this.CanAlign); // Executable if the selected files are aligned and alignment information is available. this.DisplayAlignmentCommand = new RelayCommand( this.DisplayAlignment, () => this.Datasets.Any(file => file.IsAligned && file.IsSelected && this.alignmentInformation.Any(data => data.DatasetID == file.DatasetId))); // Executable if the selected files are aligned and alignment information is available. this.SaveAlignmentPlotsCommand = new RelayCommand( this.SaveAlignmentPlots, () => this.Datasets.Any(file => file.IsAligned && file.IsSelected && this.alignmentInformation.Any(data => data.DatasetID == file.DatasetId))); this.RestoreDefaultsCommand = new RelayCommand(this.RestoreDefaults); }
public override PuzzleStateAndGenerator GenerateRandomMoves(Random r) { // For fewest moves, we want to minimize the probability that the // scramble has useful "stuff" in it. The problem with conventional // Kociemba 2 phase solutions is that there's a pretty obvious // orientation step, which competitors might intentionally (or even // accidentally!) use in their solution. To lower the probability of this happening, // we intentionally generate dumbed down solutions. // We eventually decided to go with "Tom2", which is described by Tom // Rokicki (https://groups.google.com/d/msg/wca-admin/vVnuhk92hqg/P5oaJJQjDQAJ): // START TOM MESSAGE // If we're going this direction, and the exact length isn't critical, why not combine a bunch of the // ideas we've seen so far into something this simple: // // 1. Fix a set of prefix/suffix moves, say, U F R / U F R. // 2. For a given position p, find *any* solution where that solution prefixed and suffixed with // the appropriate moves is canonical. // // That's it. So we generate a random position, then find any two-phase solution g such // that U F R g U F R is a canonical sequence, and that's our FMC scramble. // // The prefix/suffix will be easily recognizable and memorable and ideally finger-trick // friendly (if it matters). // // Someone wanting to practice speed FMC (hehe) can make up their own scrambles just // by manually doing the prefix/suffix thing on any existing scrambler. // // It does not perturb the uniformity of the random position selection. // // It's simple enough that it is less likely to suffer from subtle defects due to the // perturbation of the two-phase search (unlikely those these may be). // // And even if the two-phase solution is short, adding U F R to the front and back makes it // no longer be unusually short (with high probability). // END TOM MESSAGE // Michael Young suggested using R' U' F as our padding (https://groups.google.com/d/msg/wca-admin/vVnuhk92hqg/EzQfG_vPBgAJ): // START MICHAEL MESSSAGE // I think that something more like R' U' F (some sequence that // involves a quarter-turn on all three "axes") is better because it // guarantees at least one bad edge in every orientation; with EO-first // options becoming more popular, "guaranteeing" that solving EO // optimally can't be derived from the scramble is a nice thing to // have, I think. (Someone who was both unscrupulous and lucky could // see that R' F R doesn't affect U2/D2 EO, and therefore find out how // to solve EO by looking at the solution ignoring the R' F R. That // being said, it still does change things, and I like how // finger-tricky/reversible the current prefix is.) Just my two cents, // 'tho. // END MICHAEL MESSSAGE var scramblePrefix = SplitAlgorithm("R' U' F"); var scrambleSuffix = SplitAlgorithm("R' U' F"); // super.generateRandomMoves(...) will pick a random state S and find a solution: // solution = sol_0, sol_1, ..., sol_n-1, sol_n // We then invert that solution to create a scramble: // scramble = sol_n' + sol_(n-1)' + ... + sol_1' + sol_0' // We then prefix the scramble with scramblePrefix and suffix it with // scrambleSuffix to create paddedScramble: // paddedScramble = scramblePrefix + scramble + scrambleSuffix // paddedScramble = scramblePrefix + (sol_n' + sol_(n-1)' + ... + sol_1' + sol_0') + scrambleSuffix // // We don't want any moves to cancel here, so we need to make sure that // sol_n' doesn't cancel with the first move of scramblePrefix: var solutionLastAxisRestriction = scramblePrefix[scramblePrefix.Length - 1].Substring(0, 1); // and we need to make sure that sol_0' doesn't cancel with the first move of // scrambleSuffix: var solutionFirstAxisRestriction = scrambleSuffix[0].Substring(0, 1); var psag = GenerateRandomMoves(r, solutionFirstAxisRestriction, solutionLastAxisRestriction); var ab = new AlgorithmBuilder(MergingMode.NoMerging, GetSolvedState()); try { ab.AppendAlgorithms(scramblePrefix); ab.AppendAlgorithm(psag.Generator); ab.AppendAlgorithms(scrambleSuffix); } catch (InvalidMoveException e) { azzert(false, e.Message, e); return(null); } return(ab.GetStateAndGenerator()); }