2013-08-15 5 views
1

Например: У меня есть массив Humans:Сортировка массив несколько весов

Human{ 
private int eyeColor; 
private int hairColor; 
private int height; 
} 

Я хотел бы, чтобы отсортировать массив по нескольким весам:

цвета глаза является наиболее ценным (выше, тем лучше) после палат - по высоте, и, наконец, цвета волоса

и т.д ..

предположения, что все Интсам ранжированы 0-10 Я думал о создании поля «ранга» для человеческого лица: чем умножить его на следующей логике:

rank+= 10000 * eyeColor; 
rank+= 1000 * height; 
rank+= 100 * hairColor; 

потом просто сортировать по рангу

Я чувствую, что это примитивный способ сортировки весами (если его даже правильно). Есть ли еще более элегантные способы для этого?

+1

Вы должны * добавить * свои значения ранга, а не умножать их. – fero

+0

так я и имел в виду. спасибо – Urbanleg

+0

На каком языке это? – anaximander

ответ

0

Возможно, мой ответ был сфокусирован слишком сильно на деталях реализации. Ваш вопрос в том, есть ли для этого более элегантные способы? И я говорю «нет». Вы в основном должны сопоставить объект с 3 целыми числами с одним целым числом, которое вы можете сравнить позже.

Если в вашем классе будет гораздо больше атрибутов, которые вы должны включить в сравнение в будущем, я предлагаю вам сделать еще одну общую версию вашего кода, где каждый атрибут состоит из атрибута и соответствующего веса , Таким образом, вы можете создать более общую форму метода compareTo. Но преждевременно не оптимизируйте.

Я рекомендовал бы реализовать интерфейс Comparable так:

public Human(int eyeColor, int hairColor, int height) { 
    this.eyeColor = eyeColor; 
    this.hairColor = hairColor; 
    this.height = height; 
} 

public static void main(String[] args) { 
    List<Human> humans = new ArrayList<Human>(); 
    humans.add(new Human(20, 10, 5)); 
    humans.add(new Human(50, 50, 2)); 

    Collections.sort(humans); 
    for(Human human : humans) { 
     System.out.println(human); 
    } 
} 

@Override 
public int compareTo(Human o) { 

    int thisRank = 10000 * eyeColor; 
    thisRank += 1000 * height; 
    thisRank += 100 * hairColor; 

    int otherRank = 10000 * o.eyeColor; 
    otherRank += 1000 * o.height; 
    otherRank += 100 * o.hairColor; 

    return thisRank - otherRank; 
} 
0

Короткий ответ будет нет. Когда речь идет о рейтинге с несколькими атрибутами/критериев, один из самых простых формул, которые можно использовать в:

ранг = (weight1 * attribute1) + (weight2 * attribute2) + ... + (weightN * attributeN)

, который в значительной степени отличается тем, что у вас уже есть.

Значения весов полностью зависят от вас, но, как вы знаете, они могут иметь такое же влияние на ранг, что и сами атрибуты. Таким образом, при достижении хорошей эвристики (т. Е. Набора значений для весов) очень важно для системы ранжирования. К сожалению, чаще всего это связано с проб и ошибок (очень болезненным и трудоемким).

Просто fyi, вы можете заставить машину автоматизировать этот процесс и самостоятельно настроить весы с помощью контура обратной связи. Вам нужно будет немного изучить примерно машинное обучение.