Esempio n. 1
0
    def _select_starting_pieces_from_clusters(self):
        """
        From the segment clusters, this function builds the starting pieces for each of the output puzzles.
        """

        piece_to_cluster_map = {}
        cluster_has_seed = {}
        for cluster in self._segment_clusters:
            # Used to determine if each cluster has a starting piece
            cluster_has_seed[MultiPuzzleSolver.create_cluster_key(cluster.id_number)] = False

            # Build a map from piece ID number to cluster
            for piece_id in cluster.get_pieces():
                key = PuzzlePiece.create_key(piece_id)

                # Verify no duplicates
                if config.PERFORM_ASSERT_CHECKS:
                    assert key not in piece_to_cluster_map
                piece_to_cluster_map[key] = cluster.id_number

        # Get the starting piece ordering
        starting_piece_ordering = self._paikin_tal_solver.get_initial_starting_piece_ordering()

        # Find the start pieces.
        self._final_starting_pieces = []
        starting_piece_cnt = 0
        while len(self._final_starting_pieces) != len(self._segment_clusters):

            # Get the cluster number (if any) for the starting piece candidate
            starting_piece_candidate = starting_piece_ordering[starting_piece_cnt]
            piece_key = PuzzlePiece.create_key(starting_piece_candidate)
            try:
                cluster_number = piece_to_cluster_map[piece_key]
                cluster_key = MultiPuzzleSolver.create_cluster_key(cluster_number)

                # If the cluster has no seed, use this seed piece
                if not cluster_has_seed[cluster_key]:
                    self._final_starting_pieces.append(starting_piece_candidate)
                    cluster_has_seed[cluster_key] = True

                    # Log the clustering information
                    piece_initial_puzzle = self._paikin_tal_solver.get_piece_original_puzzle_id(starting_piece_candidate)
                    logging.info("Seed piece for cluster %d is piece id %d from initial puzzle %d" % (cluster_number,
                                                                                                      starting_piece_candidate,
                                                                                                      piece_initial_puzzle))
            except KeyError:
                pass
            starting_piece_cnt += 1

        if MultiPuzzleSolver._ALLOW_POST_SELECT_STARTING_PIECES_PICKLE_EXPORT:
            self._pickle_export_after_select_starting_pieces()
Esempio n. 2
0
    def _get_stitching_pieces(self):
        """
        Iterates through all of the segments found by the initial solver, and builds a list of the piece identification
        numbers for all of the stitching pieces.

        Returns (List[List[StitchingPieceSegment]]): List of stitching pieces for each segment.
        """
        all_stitching_pieces = []
        existing_piece_ids = {}
        for segment_id_numb in xrange(0, len(self._segments)):

            # Verify the identification number matches what is stored in the array
            if config.PERFORM_ASSERT_CHECKS:
                assert segment_id_numb == self._segments[segment_id_numb].id_number

            # Separate the stitching pieces by segments
            all_stitching_pieces.append([])
            segment_stitching_pieces = self._segments[segment_id_numb].select_pieces_for_segment_stitching()
            for segmentation_piece_id in segment_stitching_pieces:
                all_stitching_pieces[segment_id_numb].append(StitchingPieceInfo(segmentation_piece_id, segment_id_numb))

                # Verify no duplicate stitching pieces
                if config.PERFORM_ASSERT_CHECKS:
                    key = PuzzlePiece.create_key(segmentation_piece_id)
                    assert key not in existing_piece_ids
                    existing_piece_ids[key] = segmentation_piece_id

        return all_stitching_pieces
Esempio n. 3
0
    def add_solver_piece(self, solved_piece_id, piece_segment_id):
        """
        After the solver is run using the stitching piece as the seed, pieces from the solved puzzle are added to the
        stitching piece information object.

        Args:
            solved_piece_id (int): Identification number of piece in stitching piece solver

            piece_segment_id (int): Identification number of the segment where the piece with identification
                number of "solved_piece_id" was assigned in initial segmentation.  This value is "None" if the piece
                has no associated segment.
        """
        self._total_numb_solved_pieces += 1

        # Ensure no duplicate pieces.
        if config.PERFORM_ASSERT_CHECKS:
            key = PuzzlePiece.create_key(solved_piece_id)
            assert key not in self._all_solver_pieces
            self._all_solver_pieces[key] = solved_piece_id

        # Handle the case where the piece was not assigned to any segment initially
        if piece_segment_id is None:
            self._solver_piece_without_segment.append(solved_piece_id)
            return

        while len(self._solver_piece_segments) < piece_segment_id + 1:
            self._solver_piece_segments.append([])
        self._solver_piece_segments[piece_segment_id].append(solved_piece_id)
Esempio n. 4
0
    def _select_segment_for_solver(self, selected_segment):
        """
        Segment is selected for use by the solver.

        Args:
            selected_segment (PuzzleSegment): Segment selected to be used by the solver
        """
        initial_segment_id = selected_segment.id_number

        # Add the segment to the list
        selected_segment.update_segment_for_multipuzzle_solver(len(self._segments))
        self._segments.append(selected_segment)

        # Store the segment
        for piece_id in selected_segment.get_piece_ids():
            self._paikin_tal_solver.disallow_piece_placement(piece_id)
            # Store the mapping of piece to segment.
            key = PuzzlePiece.create_key(piece_id)
            self._piece_id_to_segment_map[key] = selected_segment.id_number

        logging.info("Saved segment #%d has %d pieces." % (selected_segment.id_number, selected_segment.numb_pieces))

        # Optionally output the segment image to a file.
        if MultiPuzzleSolver._SAVE_SELECTED_SEGMENTS_TO_AN_IMAGE_FILE:
            zfill_width = 4
            filename_descriptor = "segment_number_" + str(selected_segment.id_number).zfill(zfill_width)
            filename_descriptor += "_puzzle_round_" + str(self._numb_segmentation_rounds).zfill(zfill_width)

            single_puzzle_id = 0
            self._paikin_tal_solver.save_segment_to_image_file(PuzzleSolver.MultiPuzzle, single_puzzle_id,
                                                               initial_segment_id, filename_descriptor,
                                                               self._image_filenames, self._start_timestamp)
Esempio n. 5
0
    def _process_stitching_piece_solver_result(self, segment_numb, stitching_piece_numb):
        """
        After the solver is run for a stitching piece, this function process those results including adding the
        pieces in the solved result to the StitchingPieceInfo object.  This includes tracking the segment to which
        each piece in the solved output belows (if any).

        Args:
            segment_numb (int): Identification number of the segment whose stitching piece is being processed

            stitching_piece_numb (int): Index of the stitching piece in the associated segment list
        """
        solved_puzzle, _ = self._paikin_tal_solver.get_solved_puzzles()

        single_puzzle_id_number = 0
        for piece in solved_puzzle[single_puzzle_id_number]:
            piece_id = piece.id_number
            # Get segment associated with the piece if any
            try:
                piece_segment_numb = self._piece_id_to_segment_map[PuzzlePiece.create_key(piece_id)]
            except KeyError:
                piece_segment_numb = None
            # Add the piece to the stitching piece information
            self._stitching_pieces[segment_numb][stitching_piece_numb].add_solver_piece(piece_id,
                                                                                        piece_segment_numb)

        self._stitching_pieces[segment_numb][stitching_piece_numb].log_piece_to_segment_mapping(len(self._segments))