示例#1
0
def _check_ooo_durations(layout):
    for i in range(layout.data.shape[0]):
        for j, _, _ in layout.out_of_order[i]:
            error_message = 'Out of order cell cannot be placed in {}-{} cell.'.format(i + 1, j + 1)
            if j >= layout.data[layout_config.OUT_DATES_COL].shape[0]:
                raise ErrorMessage(OOO_ILLEGAL_PLACE_ERROR_CODE, error_message)
            delta = (layout.data[layout_config.OUT_DATES_COL][j] - layout.data[layout_config.IN_DATES_COL][i]).days
            if np.isnan(delta) or delta > layout.duration_limit or layout.min_days <= delta <= layout.max_days:
                raise ErrorMessage(OOO_ILLEGAL_PLACE_ERROR_CODE, error_message)
示例#2
0
def _find_in_dates_to_remove_losses(layout: Layout, available_in_places):
    layout_data = layout.data
    height = layout_data.shape[0]
    width = layout.width
    losses = []
    cur_vertex_idx = 0
    for i in range(height):
        if pd.isnull(layout_data[layout_config.IN_PLACES_COL][i]):
            continue
        cur_sum = 0
        cur_idx = i % width
        for j in range(i, min(i + layout.max_days + 1, height)):
            delta = (layout_data[layout_config.OUT_DATES_COL][j] - layout_data[layout_config.IN_DATES_COL][i]).days
            if np.isnan(delta) or delta < layout.min_days:
                continue
            if delta > layout.max_days:
                break
            if not layout_data[get_required_col(cur_idx)][j] and not pd.isnull(layout_data[get_layout_col(cur_idx)][j]):
                cur_sum += int(layout_data[get_layout_col(cur_idx)][j])
        in_max_places = available_in_places[i]
        if in_max_places is not None and cur_sum > in_max_places:
            raise ErrorMessage(RESTRICTION_VIOLATION_ERROR_CODE,
                               'Sum of places is bigger than maximum of available {} in-places'.format(i))
        if in_max_places is not None and in_max_places - cur_sum > 0 and layout.no_losses[i][0]:
            losses.append((cur_vertex_idx, int(in_max_places - cur_sum)))
        cur_vertex_idx += 1
    return losses
示例#3
0
def _update_places(layout_data: LayoutData, layout: Layout):
    # transform new places values to dict to increase searching time
    new_places = {}
    for places in layout_data.places:
        in_date = layout_data.dates[places.in_date].in_date
        out_date = layout_data.dates[places.out_date].out_date
        new_places[in_date + '-' + out_date] = (places.amount, places.required)

    places = PlacesNumber.objects.filter(layout=layout).order_by(
        'in_max_places_id',
        'out_max_places_id').select_related('in_max_places', 'out_max_places')
    # update places values in db
    for pl in places:
        in_date = pl.in_max_places.date.strftime(DATE_FORMAT)
        out_date = pl.out_max_places.date.strftime(DATE_FORMAT)
        key = in_date + '-' + out_date
        try:
            (amount, required) = new_places[key]
        except KeyError:
            raise ErrorMessage(
                DATA_INTEGRITY_ERROR_CODE,
                'Amount value was not provided for {}-{} places'.format(
                    in_date, out_date))
        if pl.required != required or pl.amount != amount:
            pl.required = required
            pl.amount = amount
            pl.save()
示例#4
0
def _get_avail_in_places(layout):
    out_of_order = layout.out_of_order
    layout_data = layout.data
    height = layout_data.shape[0]
    width = layout.width
    out_of_order_places = [0] * height
    for i, data_list in enumerate(out_of_order):
        for _, amount, _ in data_list:
            out_of_order_places[i] += amount
    in_places = []
    for i in range(height):
        cur_sum = 0
        cur_idx = i % width
        for j in range(i, min(i + layout.max_days + 1, height)):
            delta = (layout_data[layout_config.OUT_DATES_COL][j] -
                     layout_data[layout_config.IN_DATES_COL][i]).days
            if np.isnan(delta) or delta < layout.min_days:
                continue
            if delta > layout.max_days:
                break
            if layout_data[get_required_col(cur_idx)][j]:
                cur_sum += layout_data[get_layout_col(cur_idx)][j]
        cur_sum += out_of_order_places[i]
        in_max_places = layout_data[layout_config.IN_PLACES_COL][i]
        if in_max_places is not None and cur_sum > in_max_places:
            raise ErrorMessage(
                RESTRICTION_VIOLATION_ERROR_CODE,
                'Sum of places is bigger than maximum of available {} in-places'
                .format(i))
        in_places.append(None if in_max_places is None else in_max_places -
                         cur_sum)
    return in_places
示例#5
0
def _get_avail_out_places(layout):
    out_of_order = layout.out_of_order
    layout_data = layout.data
    height = layout_data.shape[0]
    width = layout.width
    out_of_order_places = [0] * height
    for data_list in out_of_order:
        for i, amount, _ in data_list:
            out_of_order_places[i] += amount
    out_places = []
    for i in range(height):
        cur_sum = 0
        for j in range(width):
            cur_idx = get_layout_col(j)
            cur_req_idx = get_required_col(j)
            if layout_data[cur_req_idx][i]:
                cur_sum += layout_data[cur_idx][i]
        cur_sum += out_of_order_places[i]
        out_max_places = layout_data[layout_config.OUT_PLACES_COL][i]
        if out_max_places is not None and cur_sum > out_max_places:
            raise ErrorMessage(
                RESTRICTION_VIOLATION_ERROR_CODE,
                'Sum of places is bigger than maximum of available {} out-places'
                .format(i))
        out_places.append(None if out_max_places is None else out_max_places -
                          cur_sum)
    return out_places
示例#6
0
def _get_corrected_relations(layout, i, height, column_idx):
    data = layout.data
    max_places = data[layout_config.IN_PLACES_COL][i]
    if max_places is None:
        return max_places, None, [], 0
    _check_ooo_durations(layout, i)
    cur_idx = get_layout_col(column_idx)
    cur_req_idx = get_required_col(column_idx)
    relations = layout.relations if layout.date_relations[
        i] is None else layout.date_relations[i]
    relations_sum = 0
    used_sum = sum((amount for _, amount, _ in layout.out_of_order[i])) if len(
        layout.out_of_order[i]) > 0 else 0
    vars_num = 0
    for j in range(i, min(i + param_config.MAX_DAYS + 1, height)):
        delta = (data[layout_config.OUT_DATES_COL][j] -
                 data[layout_config.IN_DATES_COL][i]).days
        if np.isnan(delta) or delta < layout.min_days:
            continue
        if delta > layout.max_days:
            break
        if not data[cur_req_idx][j]:
            vars_num += 1
            relations_sum += relations[delta - layout.min_days]
        else:
            used_sum += data[cur_idx][j]
    if relations_sum > 0:
        coef = 1. / relations_sum
    else:
        coef = 0
    corrected_relations = [rel * coef for rel in relations]
    if used_sum > max_places:
        raise ErrorMessage(
            RESTRICTION_VIOLATION_ERROR_CODE,
            'Sum of places is bigger than maximum of available {} in-places'.
            format(i))
    else:
        avail_places = max_places - used_sum
    return max_places, avail_places, corrected_relations, vars_num
示例#7
0
def _find_out_dates_to_remove_losses(layout: Layout, available_out_places):
    layout_data = layout.data
    height = layout_data.shape[0]
    width = layout.width
    losses = []
    cur_vertex_idx = 0
    for i in range(height):
        if pd.isnull(layout_data[layout_config.OUT_PLACES_COL][i]):
            continue
        cur_sum = 0
        for j in range(width):
            cur_idx = get_layout_col(j)
            cur_req_idx = get_required_col(j)
            if pd.isnull(layout_data[cur_idx][i]) or layout_data[cur_req_idx][i]:
                continue
            cur_sum += int(layout_data[cur_idx][i])
        out_max_places = available_out_places[i]
        if out_max_places is not None and cur_sum > out_max_places:
            raise ErrorMessage(RESTRICTION_VIOLATION_ERROR_CODE,
                               'Sum of places is bigger than maximum of available {} out-places'.format(i))
        if out_max_places is not None and out_max_places - cur_sum > 0 and layout.no_losses[i][1]:
            losses.append((cur_vertex_idx, int(out_max_places - cur_sum)))
        cur_vertex_idx += 1
    return losses